* processIndirection - take care of array and subfield assignment * * We strip any top-level FieldStore or assignment SubscriptingRef nodes that * appear in the input, printing them as decoration for the base column * name (which we assume the caller just printed). We might also need to * strip CoerceToDomain nodes, but only ones that appear above assignment * nodes. * * Returns the subex
| 11782 | * Returns the subexpression that's to be assigned. |
| 11783 | */ |
| 11784 | static Node * |
| 11785 | processIndirection(Node *node, deparse_context *context) |
| 11786 | { |
| 11787 | StringInfo buf = context->buf; |
| 11788 | CoerceToDomain *cdomain = NULL; |
| 11789 | |
| 11790 | for (;;) |
| 11791 | { |
| 11792 | if (node == NULL) |
| 11793 | break; |
| 11794 | if (IsA(node, FieldStore)) |
| 11795 | { |
| 11796 | FieldStore *fstore = (FieldStore *) node; |
| 11797 | Oid typrelid; |
| 11798 | char *fieldname; |
| 11799 | |
| 11800 | /* lookup tuple type */ |
| 11801 | typrelid = get_typ_typrelid(fstore->resulttype); |
| 11802 | if (!OidIsValid(typrelid)) |
| 11803 | elog(ERROR, "argument type %s of FieldStore is not a tuple type", |
| 11804 | format_type_be(fstore->resulttype)); |
| 11805 | |
| 11806 | /* |
| 11807 | * Print the field name. There should only be one target field in |
| 11808 | * stored rules. There could be more than that in executable |
| 11809 | * target lists, but this function cannot be used for that case. |
| 11810 | */ |
| 11811 | Assert(list_length(fstore->fieldnums) == 1); |
| 11812 | fieldname = get_attname(typrelid, |
| 11813 | linitial_int(fstore->fieldnums), false); |
| 11814 | appendStringInfo(buf, ".%s", quote_identifier(fieldname)); |
| 11815 | |
| 11816 | /* |
| 11817 | * We ignore arg since it should be an uninteresting reference to |
| 11818 | * the target column or subcolumn. |
| 11819 | */ |
| 11820 | node = (Node *) linitial(fstore->newvals); |
| 11821 | } |
| 11822 | else if (IsA(node, SubscriptingRef)) |
| 11823 | { |
| 11824 | SubscriptingRef *sbsref = (SubscriptingRef *) node; |
| 11825 | |
| 11826 | if (sbsref->refassgnexpr == NULL) |
| 11827 | break; |
| 11828 | |
| 11829 | printSubscripts(sbsref, context); |
| 11830 | |
| 11831 | /* |
| 11832 | * We ignore refexpr since it should be an uninteresting reference |
| 11833 | * to the target column or subcolumn. |
| 11834 | */ |
| 11835 | node = (Node *) sbsref->refassgnexpr; |
| 11836 | } |
| 11837 | else if (IsA(node, CoerceToDomain)) |
| 11838 | { |
| 11839 | cdomain = (CoerceToDomain *) node; |
| 11840 | /* If it's an explicit domain coercion, we're done */ |
| 11841 | if (cdomain->coercionformat != COERCE_IMPLICIT_CAST) |
no test coverage detected