aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2021-10-19 13:54:46 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2021-10-19 13:54:46 -0400
commit30e61a8cdc8624102ebdb1abbbb1e45457877c5c (patch)
treee54d5d4eb7ae361c96d077ad99d9dad755b7aac6 /src/backend/executor
parentcf33fb7f4a199213a0a83209b81caa728f5c7750 (diff)
downloadpostgresql-30e61a8cdc8624102ebdb1abbbb1e45457877c5c.tar.gz
postgresql-30e61a8cdc8624102ebdb1abbbb1e45457877c5c.zip
Fix assignment to array of domain over composite.
An update such as "UPDATE ... SET fld[n].subfld = whatever" failed if the array elements were domains rather than plain composites. That's because isAssignmentIndirectionExpr() failed to cope with the CoerceToDomain node that would appear in the expression tree in this case. The result would typically be a crash, and even if we accidentally didn't crash, we'd not correctly preserve other fields of the same array element. Per report from Onder Kalaci. Back-patch to v11 where arrays of domains came in. Discussion: https://postgr.es/m/PH0PR21MB132823A46AA36F0685B7A29AD8BD9@PH0PR21MB1328.namprd21.prod.outlook.com
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execExpr.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index 5ee59ef6692..209318680e3 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -2783,11 +2783,14 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref,
* (We could use this in FieldStore too, but in that case passing the old
* value is so cheap there's no need.)
*
- * Note: it might seem that this needs to recurse, but it does not; the
- * CaseTestExpr, if any, will be directly the arg or refexpr of the top-level
- * node. Nested-assignment situations give rise to expression trees in which
- * each level of assignment has its own CaseTestExpr, and the recursive
- * structure appears within the newvals or refassgnexpr field.
+ * Note: it might seem that this needs to recurse, but in most cases it does
+ * not; the CaseTestExpr, if any, will be directly the arg or refexpr of the
+ * top-level node. Nested-assignment situations give rise to expression
+ * trees in which each level of assignment has its own CaseTestExpr, and the
+ * recursive structure appears within the newvals or refassgnexpr field.
+ * There is an exception, though: if the array is an array-of-domain, we will
+ * have a CoerceToDomain as the refassgnexpr, and we need to be able to look
+ * through that.
*/
static bool
isAssignmentIndirectionExpr(Expr *expr)
@@ -2808,6 +2811,12 @@ isAssignmentIndirectionExpr(Expr *expr)
if (sbsRef->refexpr && IsA(sbsRef->refexpr, CaseTestExpr))
return true;
}
+ else if (IsA(expr, CoerceToDomain))
+ {
+ CoerceToDomain *cd = (CoerceToDomain *) expr;
+
+ return isAssignmentIndirectionExpr(cd->arg);
+ }
return false;
}