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
No known key found for this signature in database
GPG Key ID: 1C20ACB9D5C564AE
1 changed files with 7 additions and 8 deletions

View File

@ -2967,21 +2967,20 @@ lmerge_matched:
*/
/*
* If cpUpdateRetrySlot is set, ExecCrossPartitionUpdate()
* must have detected that the tuple was concurrently
* updated, so we restart the search for an appropriate
* WHEN MATCHED clause to process the updated tuple.
* During an UPDATE, if cpUpdateRetrySlot is set, then
* ExecCrossPartitionUpdate() must have detected that the
* tuple was concurrently updated, so we restart the
* search for an appropriate WHEN MATCHED clause to
* process the updated tuple.
*
* In this case, ExecDelete() would already have performed
* EvalPlanQual() on the latest version of the tuple,
* which in turn would already have been loaded into
* ri_oldTupleSlot, so no need to do either of those
* 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;
/*