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
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/62d1a5f8be836faa5547789fe19d34bac1b908f4

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