aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeModifyTable.c
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2023-02-15 20:37:44 +0100
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2023-02-15 20:37:44 +0100
commit5d8ec1b9f625be800c8db93408e7c0553356fcd3 (patch)
tree727a9d90ab2db7ee4d9563e3cf92143b988a3342 /src/backend/executor/nodeModifyTable.c
parent5fd61055eacf3d0c45be20b90402a87c9848db43 (diff)
downloadpostgresql-5d8ec1b9f625be800c8db93408e7c0553356fcd3.tar.gz
postgresql-5d8ec1b9f625be800c8db93408e7c0553356fcd3.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.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index 30fe932aee0..508dcc4cbea 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -2975,21 +2975,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;
/*