aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2017-07-15 16:57:43 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2017-07-15 16:57:43 -0400
commitde2af6e001a3d6aeb2a10a802e73af8c7d1d3405 (patch)
tree6799bc41e809b24b94fc173bcce399ef544e3d1f
parente9b64824a067f8180e2553127467d7522516122c (diff)
downloadpostgresql-de2af6e001a3d6aeb2a10a802e73af8c7d1d3405.tar.gz
postgresql-de2af6e001a3d6aeb2a10a802e73af8c7d1d3405.zip
Improve comments for execExpr.c's handling of FieldStore subexpressions.
Given this code's general eagerness to use subexpressions' output variables as temporary workspace, it's not exactly clear that it is safe for FieldStore to tell a newval subexpression that it can write into the same variable that is being supplied as a potential input. Document the chain of assumptions needed for that to be safe.
-rw-r--r--src/backend/executor/execExpr.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index d1c2bbbd44a..5267a011bbb 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -1116,6 +1116,18 @@ ExecInitExprRec(Expr *node, PlanState *parent, ExprState *state,
* field assignment can't be within a CASE either. (So
* saving and restoring innermost_caseval is just
* paranoia, but let's do it anyway.)
+ *
+ * Another non-obvious point is that it's safe to use the
+ * field's values[]/nulls[] entries as both the caseval
+ * source and the result address for this subexpression.
+ * That's okay only because (1) both FieldStore and
+ * ArrayRef evaluate their arg or refexpr inputs first,
+ * and (2) any such CaseTestExpr is directly the arg or
+ * refexpr input. So any read of the caseval will occur
+ * before there's a chance to overwrite it. Also, if
+ * multiple entries in the newvals/fieldnums lists target
+ * the same field, they'll effectively be applied
+ * left-to-right which is what we want.
*/
save_innermost_caseval = state->innermost_caseval;
save_innermost_casenull = state->innermost_casenull;