aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/subselect.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/subselect.c')
-rw-r--r--src/backend/optimizer/plan/subselect.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index 4c6f84a6755..cde52114a7d 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -914,20 +914,54 @@ SS_make_multiexprs_unique(PlannerInfo *root, PlannerInfo *subroot)
/*
* Now we must find the Param nodes that reference the MULTIEXPR outputs
* and update their sublink IDs so they'll reference the new outputs.
- * Fortunately, those too must be at top level of the cloned targetlist.
+ * Fortunately, those too must be in the cloned targetlist, but they could
+ * be buried under FieldStores and SubscriptingRefs and CoerceToDomains
+ * (cf processIndirection()), and underneath those there could be an
+ * implicit type coercion.
*/
offset = list_length(root->multiexpr_params);
foreach(lc, subroot->parse->targetList)
{
TargetEntry *tent = (TargetEntry *) lfirst(lc);
+ Node *expr;
Param *p;
int subqueryid;
int colno;
- if (!IsA(tent->expr, Param))
+ expr = (Node *) tent->expr;
+ while (expr)
+ {
+ if (IsA(expr, FieldStore))
+ {
+ FieldStore *fstore = (FieldStore *) expr;
+
+ expr = (Node *) linitial(fstore->newvals);
+ }
+ else if (IsA(expr, SubscriptingRef))
+ {
+ SubscriptingRef *sbsref = (SubscriptingRef *) expr;
+
+ if (sbsref->refassgnexpr == NULL)
+ break;
+
+ expr = (Node *) sbsref->refassgnexpr;
+ }
+ else if (IsA(expr, CoerceToDomain))
+ {
+ CoerceToDomain *cdomain = (CoerceToDomain *) expr;
+
+ if (cdomain->coercionformat != COERCE_IMPLICIT_CAST)
+ break;
+ expr = (Node *) cdomain->arg;
+ }
+ else
+ break;
+ }
+ expr = strip_implicit_coercions(expr);
+ if (expr == NULL || !IsA(expr, Param))
continue;
- p = (Param *) tent->expr;
+ p = (Param *) expr;
if (p->paramkind != PARAM_MULTIEXPR)
continue;
subqueryid = p->paramid >> 16;