Improve comments for execExpr.c's handling of FieldStore subexpressions.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 15 Jul 2017 20:57:43 +0000 (16:57 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 15 Jul 2017 20:57:43 +0000 (16:57 -0400)
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.

src/backend/executor/execExpr.c

index d1c2bbbd44ab5972eb203a7b5a1578b5198093bf..5267a011bbbb17b87fe9df6ce4c63f1fc3e4f973 100644 (file)
@@ -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;