diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2023-02-15 20:37:44 +0100 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2023-02-15 20:37:44 +0100 |
commit | fd923b5de94cdd3a7d05dcb843667dc228ea7fa3 (patch) | |
tree | 7b8ee930097f44f5e9b0dd51e7ef639e5a8efe44 /src/backend/executor/nodeModifyTable.c | |
parent | 5352ca22e0012d48055453ca9992a9515d811291 (diff) | |
download | postgresql-fd923b5de94cdd3a7d05dcb843667dc228ea7fa3.tar.gz postgresql-fd923b5de94cdd3a7d05dcb843667dc228ea7fa3.zip |
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
Diffstat (limited to 'src/backend/executor/nodeModifyTable.c')
-rw-r--r-- | src/backend/executor/nodeModifyTable.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 1ac65172e44..f8e71ef1cc1 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -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; /* |