0001-Fix-MERGE-match-do-update-in-RR-isolation-level.patch
text/plain
Filename: 0001-Fix-MERGE-match-do-update-in-RR-isolation-level.patch
Type: text/plain
Part: 0
Patch
Format: format-patch
Series: patch 0001
Subject: Fix MERGE match do update in RR isolation level.
| File | + | − |
|---|---|---|
| src/backend/executor/nodeModifyTable.c | 4 | 0 |
| src/test/isolation/expected/merge-match-do-update.out | 26 | 0 |
| src/test/isolation/isolation_schedule | 1 | 0 |
| src/test/isolation/specs/merge-match-do-update.spec | 43 | 0 |
From 9f7267cdc3bf5b34eb95686f288d39b5766142ac Mon Sep 17 00:00:00 2001
From: Tender Wang <tndrwang@gmail.com>
Date: Tue, 24 Feb 2026 11:04:26 +0800
Subject: [PATCH] Fix MERGE match do update in RR isolation level.
---
src/backend/executor/nodeModifyTable.c | 4 ++
.../expected/merge-match-do-update.out | 26 +++++++++++
src/test/isolation/isolation_schedule | 1 +
.../specs/merge-match-do-update.spec | 43 +++++++++++++++++++
4 files changed, 74 insertions(+)
create mode 100644 src/test/isolation/expected/merge-match-do-update.out
create mode 100644 src/test/isolation/specs/merge-match-do-update.spec
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index 793c76d4f82..8d8c9fb54e3 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -3547,6 +3547,10 @@ lmerge_matched:
*inputslot;
LockTupleMode lockmode;
+ if (IsolationUsesXactSnapshot())
+ ereport(ERROR,
+ (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
+ errmsg("could not serialize access due to concurrent update")));
/*
* The target tuple was concurrently updated by some other
* transaction. If we are currently processing a MATCHED
diff --git a/src/test/isolation/expected/merge-match-do-update.out b/src/test/isolation/expected/merge-match-do-update.out
new file mode 100644
index 00000000000..c2cde0de606
--- /dev/null
+++ b/src/test/isolation/expected/merge-match-do-update.out
@@ -0,0 +1,26 @@
+Parsed test spec with 2 sessions
+
+starting permutation: b2 update2 b1 merge1 c2 select1 c1
+step b2: BEGIN;
+step update2:
+ UPDATE test SET val = val + 100;
+
+step b1:
+ BEGIN ISOLATION LEVEL REPEATABLE READ;
+
+step merge1:
+ MERGE INTO test t USING (VALUES (1, 100)) AS s (id, inc)
+ ON t.id = s.id
+ WHEN MATCHED THEN
+ UPDATE SET val = t.val + s.inc
+ WHEN NOT MATCHED THEN
+ INSERT (id, val) VALUES (s.id, s.inc);
+ <waiting ...>
+step c2: COMMIT;
+step merge1: <... completed>
+ERROR: could not serialize access due to concurrent update
+step select1:
+ SELECT * FROM test;
+
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+step c1: COMMIT;
diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule
index 4e466580cd4..95d8597e204 100644
--- a/src/test/isolation/isolation_schedule
+++ b/src/test/isolation/isolation_schedule
@@ -58,6 +58,7 @@ test: insert-conflict-do-select
test: merge-insert-update
test: merge-delete
test: merge-update
+test: merge-match-do-update
test: merge-match-recheck
test: merge-join
test: delete-abort-savept
diff --git a/src/test/isolation/specs/merge-match-do-update.spec b/src/test/isolation/specs/merge-match-do-update.spec
new file mode 100644
index 00000000000..046c78826b9
--- /dev/null
+++ b/src/test/isolation/specs/merge-match-do-update.spec
@@ -0,0 +1,43 @@
+# MERGE UPDATE
+
+setup
+{
+ CREATE TABLE test (id int primary key, val int);
+ INSERT INTO test VALUES (1,0);
+}
+
+teardown
+{
+ DROP TABLE test;
+}
+
+session "s1"
+step "b1"
+{
+ BEGIN ISOLATION LEVEL REPEATABLE READ;
+}
+step "merge1"
+{
+ MERGE INTO test t USING (VALUES (1, 100)) AS s (id, inc)
+ ON t.id = s.id
+ WHEN MATCHED THEN
+ UPDATE SET val = t.val + s.inc
+ WHEN NOT MATCHED THEN
+ INSERT (id, val) VALUES (s.id, s.inc);
+}
+step "select1"
+{
+ SELECT * FROM test;
+}
+step "c1" { COMMIT; }
+
+session "s2"
+step "b2" { BEGIN; }
+step "update2"
+{
+ UPDATE test SET val = val + 100;
+}
+step "c2" { COMMIT; }
+
+# Now with concurrency
+permutation "b2" "update2" "b1" "merge1" "c2" "select1" "c1"
\ No newline at end of file
--
2.34.1