1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-27 23:21:58 +03:00

Don't rely on uninitialized value in MERGE / DELETE

On MERGE / WHEN MATCHED DELETE it's not possible to get cross-partition
updates, so we don't initialize cpUpdateRetrySlot; however, the code was
not careful to ignore the value in that case.  Make it do so.

Backpatch to 15.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com>
Discussion: https://postgr.es/m/17792-0f89452029662c36@postgresql.org
This commit is contained in:
Alvaro Herrera
2023-02-15 20:37:44 +01:00
parent 5352ca22e0
commit fd923b5de9

View File

@ -2967,21 +2967,20 @@ lmerge_matched:
*/ */
/* /*
* If cpUpdateRetrySlot is set, ExecCrossPartitionUpdate() * During an UPDATE, if cpUpdateRetrySlot is set, then
* must have detected that the tuple was concurrently * ExecCrossPartitionUpdate() must have detected that the
* updated, so we restart the search for an appropriate * tuple was concurrently updated, so we restart the
* WHEN MATCHED clause to process the updated tuple. * search for an appropriate WHEN MATCHED clause to
* process the updated tuple.
* *
* In this case, ExecDelete() would already have performed * In this case, ExecDelete() would already have performed
* EvalPlanQual() on the latest version of the tuple, * EvalPlanQual() on the latest version of the tuple,
* which in turn would already have been loaded into * which in turn would already have been loaded into
* ri_oldTupleSlot, so no need to do either of those * ri_oldTupleSlot, so no need to do either of those
* things. * things.
*
* XXX why do we not check the WHEN NOT MATCHED list in
* this case?
*/ */
if (!TupIsNull(context->cpUpdateRetrySlot)) if (commandType == CMD_UPDATE &&
!TupIsNull(context->cpUpdateRetrySlot))
goto lmerge_matched; goto lmerge_matched;
/* /*