* Process indirection (field selection or subscripting) of the target * column in INSERT/UPDATE/assignment. This routine recurses for multiple * levels of indirection --- but note that several adjacent A_Indices nodes * in the indirection list are treated as a single multidimensional subscript * operation. * * In the initial call, basenode is a Var for the target column in UPDATE, * or a n
| 684 | * in which case the location argument could probably be dropped.) |
| 685 | */ |
| 686 | Node * |
| 687 | transformAssignmentIndirection(ParseState *pstate, |
| 688 | Node *basenode, |
| 689 | const char *targetName, |
| 690 | bool targetIsSubscripting, |
| 691 | Oid targetTypeId, |
| 692 | int32 targetTypMod, |
| 693 | Oid targetCollation, |
| 694 | List *indirection, |
| 695 | ListCell *indirection_cell, |
| 696 | Node *rhs, |
| 697 | CoercionContext ccontext, |
| 698 | int location) |
| 699 | { |
| 700 | Node *result; |
| 701 | List *subscripts = NIL; |
| 702 | bool isSlice = false; |
| 703 | ListCell *i; |
| 704 | |
| 705 | if (indirection_cell && !basenode) |
| 706 | { |
| 707 | /* |
| 708 | * Set up a substitution. We abuse CaseTestExpr for this. It's safe |
| 709 | * to do so because the only nodes that will be above the CaseTestExpr |
| 710 | * in the finished expression will be FieldStore and SubscriptingRef |
| 711 | * nodes. (There could be other stuff in the tree, but it will be |
| 712 | * within other child fields of those node types.) |
| 713 | */ |
| 714 | CaseTestExpr *ctest = makeNode(CaseTestExpr); |
| 715 | |
| 716 | ctest->typeId = targetTypeId; |
| 717 | ctest->typeMod = targetTypMod; |
| 718 | ctest->collation = targetCollation; |
| 719 | basenode = (Node *) ctest; |
| 720 | } |
| 721 | |
| 722 | /* |
| 723 | * We have to split any field-selection operations apart from |
| 724 | * subscripting. Adjacent A_Indices nodes have to be treated as a single |
| 725 | * multidimensional subscript operation. |
| 726 | */ |
| 727 | for_each_cell(i, indirection, indirection_cell) |
| 728 | { |
| 729 | Node *n = lfirst(i); |
| 730 | |
| 731 | if (IsA(n, A_Indices)) |
| 732 | { |
| 733 | subscripts = lappend(subscripts, n); |
| 734 | if (((A_Indices *) n)->is_slice) |
| 735 | isSlice = true; |
| 736 | } |
| 737 | else if (IsA(n, A_Star)) |
| 738 | { |
| 739 | ereport(ERROR, |
| 740 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 741 | errmsg("row expansion via \"*\" is not supported here"), |
| 742 | parser_errposition(pstate, location))); |
| 743 | } |
no test coverage detected