diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 0d8a66aa9f0..2005674838d 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -3077,6 +3077,11 @@ 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. Run EvalPlanQual() with the new version of diff --git a/src/test/isolation/expected/merge-update.out b/src/test/isolation/expected/merge-update.out index f5f7e3ba19b..5170f6ee019 100644 --- a/src/test/isolation/expected/merge-update.out +++ b/src/test/isolation/expected/merge-update.out @@ -355,3 +355,28 @@ step c1: COMMIT; step pa_merge2c_dup: <... completed> ERROR: MERGE command cannot affect row a second time step a2: ABORT; + +starting permutation: merge2a c1 s1beginrr merge1 c2 +step merge2a: + MERGE INTO target t + USING (SELECT 1 as key, 'merge2a' as val) s + ON s.key = t.key + WHEN NOT MATCHED THEN + INSERT VALUES (s.key, s.val) + WHEN MATCHED THEN + UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; + +step c1: COMMIT; +step s1beginrr: BEGIN ISOLATION LEVEL REPEATABLE READ; +step merge1: + MERGE INTO target t + USING (SELECT 1 as key, 'merge1' as val) s + ON s.key = t.key + WHEN NOT MATCHED THEN + INSERT VALUES (s.key, s.val) + WHEN MATCHED THEN + UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; + +step c2: COMMIT; +step merge1: <... completed> +ERROR: could not serialize access due to concurrent update diff --git a/src/test/isolation/specs/merge-update.spec b/src/test/isolation/specs/merge-update.spec index 3ccd4664498..293cdb46b56 100644 --- a/src/test/isolation/specs/merge-update.spec +++ b/src/test/isolation/specs/merge-update.spec @@ -78,6 +78,7 @@ step "pa_merge3" } step "c1" { COMMIT; } step "a1" { ABORT; } +step "s1beginrr" { BEGIN ISOLATION LEVEL REPEATABLE READ; } session "s2" setup @@ -167,3 +168,4 @@ permutation "pa_merge2" "c1" "pa_merge2a" "pa_select2" "c2" # succeeds permutation "pa_merge3" "pa_merge2b_when" "c1" "pa_select2" "c2" # WHEN not satisfied by updated tuple permutation "pa_merge1" "pa_merge2b_when" "c1" "pa_select2" "c2" # WHEN satisfied by updated tuple permutation "pa_merge1" "pa_merge2c_dup" "c1" "a2" +permutation "merge2a" "c1" "s1beginrr" "merge1" "c2"