Avoid RETURNING side effects for FOR PORTION OF leftovers.

UPDATE/DELETE ... FOR PORTION OF inserts leftover rows for the
untouched parts of the original row. These hidden inserts should not
affect the command tag or ROW_COUNT, so they call ExecInsert() with
canSetTag set to false.

However, ExecInsert() still processed the RETURNING list whenever the
target ResultRelInfo had ri_projectReturning set. That caused
RETURNING expressions to be evaluated for leftover rows even though
their results were discarded. As a result, expressions with side
effects and information-leaking functions could be executed on the
leftover rows, in addition to the visibly updated or deleted row.

Fix by having ExecInsert() skip RETURNING processing when it is
handling an internal FOR PORTION OF leftover insert. Use both the
presence of a FOR PORTION OF clause and mtstate->operation ==
CMD_INSERT for this check, so that the auxiliary INSERT of a
cross-partition UPDATE with a FOR PORTION OF clause still processes
RETURNING normally.

Back-patch to v19, where support for FOR PORTION OF was added.

Author: Chao Li <[email protected]>
Reviewed-by: Dean Rasheed <[email protected]>
Reviewed-by: Paul A Jungwirth <[email protected]>
Discussion: https://postgr.es/m/[email protected]
Backpatch-through: 19

Branch
------
REL_19_STABLE

Details
-------
https://git.postgresql.org/pg/commitdiff/fd92f74b91d079430ef4544713a90b7b6aa8faee

Modified Files
--------------
src/backend/executor/nodeModifyTable.c       | 14 +++++++++--
src/test/regress/expected/for_portion_of.out | 36 +++++++++++++++++++++-------
src/test/regress/sql/for_portion_of.sql      | 16 ++++++++++---
3 files changed, 52 insertions(+), 14 deletions(-)

Reply via email to