]> granicus.if.org Git - postgresql/commitdiff
Make some isolationtester specs more complete
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 4 Oct 2013 17:24:46 +0000 (14:24 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 4 Oct 2013 18:59:22 +0000 (15:59 -0300)
Also, make sure they pass on all transaction isolation levels.

src/test/isolation/expected/fk-deadlock2_1.out
src/test/isolation/expected/fk-deadlock2_2.out
src/test/isolation/expected/fk-deadlock_1.out
src/test/isolation/expected/fk-deadlock_2.out [deleted file]
src/test/isolation/expected/lock-update-delete.out
src/test/isolation/expected/lock-update-delete_1.out [new file with mode: 0644]
src/test/isolation/expected/lock-update-traversal.out
src/test/isolation/specs/lock-update-delete.spec
src/test/isolation/specs/lock-update-traversal.spec

index 382734811cbbce0bde1a5e4ef2963e23dc096661..384bb9d742fbee0c42f0e995e468b78c53b5c962 100644 (file)
@@ -19,6 +19,31 @@ step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
 ERROR:  current transaction is aborted, commands ignored until end of transaction block
 step s2c: COMMIT;
 
+starting permutation: s1u1 s1u2 s2u1 s2u2 s1c s2c
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+invalid permutation detected
+
+starting permutation: s1u1 s1u2 s2u1 s2u2 s2c s1c
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+invalid permutation detected
+
+starting permutation: s1u1 s2u1 s1u2 s1c s2u2 s2c
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+invalid permutation detected
+
+starting permutation: s1u1 s2u1 s1u2 s2u2 s1c s2c
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
+invalid permutation detected
+
 starting permutation: s1u1 s2u1 s1u2 s2u2 s2c s1c
 step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
 step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
@@ -29,6 +54,13 @@ step s1u2: <... completed>
 error in steps s2c s1u2: ERROR:  could not serialize access due to concurrent update
 step s1c: COMMIT;
 
+starting permutation: s1u1 s2u1 s2u2 s1u2 s1c s2c
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+invalid permutation detected
+
 starting permutation: s1u1 s2u1 s2u2 s1u2 s2c s1c
 step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
 step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
@@ -48,6 +80,19 @@ step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
 ERROR:  could not serialize access due to read/write dependencies among transactions
 step s1c: COMMIT;
 
+starting permutation: s2u1 s1u1 s1u2 s1c s2u2 s2c
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+invalid permutation detected
+
+starting permutation: s2u1 s1u1 s1u2 s2u2 s1c s2c
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
+invalid permutation detected
+
 starting permutation: s2u1 s1u1 s1u2 s2u2 s2c s1c
 step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
@@ -58,6 +103,13 @@ step s1u2: <... completed>
 error in steps s2c s1u2: ERROR:  could not serialize access due to concurrent update
 step s1c: COMMIT;
 
+starting permutation: s2u1 s1u1 s2u2 s1u2 s1c s2c
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+invalid permutation detected
+
 starting permutation: s2u1 s1u1 s2u2 s1u2 s2c s1c
 step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
@@ -77,6 +129,13 @@ step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
 ERROR:  could not serialize access due to read/write dependencies among transactions
 step s1c: COMMIT;
 
+starting permutation: s2u1 s2u2 s1u1 s1u2 s1c s2c
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+invalid permutation detected
+
 starting permutation: s2u1 s2u2 s1u1 s1u2 s2c s1c
 step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
index b6be4b98926be0e1c9a6b9bd73826abe1fc1b9ad..b6538a5751fdb8c2ddeef895f83fcd998e5a1def 100644 (file)
@@ -19,6 +19,31 @@ step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
 ERROR:  current transaction is aborted, commands ignored until end of transaction block
 step s2c: COMMIT;
 
+starting permutation: s1u1 s1u2 s2u1 s2u2 s1c s2c
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+invalid permutation detected
+
+starting permutation: s1u1 s1u2 s2u1 s2u2 s2c s1c
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+invalid permutation detected
+
+starting permutation: s1u1 s2u1 s1u2 s1c s2u2 s2c
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+invalid permutation detected
+
+starting permutation: s1u1 s2u1 s1u2 s2u2 s1c s2c
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
+invalid permutation detected
+
 starting permutation: s1u1 s2u1 s1u2 s2u2 s2c s1c
 step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
 step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
@@ -29,6 +54,13 @@ step s1u2: <... completed>
 error in steps s2c s1u2: ERROR:  could not serialize access due to concurrent update
 step s1c: COMMIT;
 
+starting permutation: s1u1 s2u1 s2u2 s1u2 s1c s2c
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+invalid permutation detected
+
 starting permutation: s1u1 s2u1 s2u2 s1u2 s2c s1c
 step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
 step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
@@ -48,6 +80,19 @@ step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
 ERROR:  could not serialize access due to concurrent update
 step s1c: COMMIT;
 
+starting permutation: s2u1 s1u1 s1u2 s1c s2u2 s2c
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+invalid permutation detected
+
+starting permutation: s2u1 s1u1 s1u2 s2u2 s1c s2c
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
+invalid permutation detected
+
 starting permutation: s2u1 s1u1 s1u2 s2u2 s2c s1c
 step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
@@ -58,6 +103,13 @@ step s1u2: <... completed>
 error in steps s2c s1u2: ERROR:  could not serialize access due to concurrent update
 step s1c: COMMIT;
 
+starting permutation: s2u1 s1u1 s2u2 s1u2 s1c s2c
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+invalid permutation detected
+
 starting permutation: s2u1 s1u1 s2u2 s1u2 s2c s1c
 step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
@@ -77,6 +129,13 @@ step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
 ERROR:  could not serialize access due to concurrent update
 step s1c: COMMIT;
 
+starting permutation: s2u1 s2u2 s1u1 s1u2 s1c s2c
+step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
+step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
+step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
+invalid permutation detected
+
 starting permutation: s2u1 s2u2 s1u1 s1u2 s2c s1c
 step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
index d648e48c480cb3eb63b9c2ecf6d0aa2d4ab689fd..6687505b590259cb94f1527de5bae2eb4f2a282e 100644 (file)
@@ -14,7 +14,33 @@ step s1u: UPDATE parent SET aux = 'bar';
 step s2i: INSERT INTO child VALUES (2, 1);
 step s1c: COMMIT;
 step s2u: UPDATE parent SET aux = 'baz';
-ERROR:  could not serialize access due to read/write dependencies among transactions
+ERROR:  could not serialize access due to concurrent update
+step s2c: COMMIT;
+
+starting permutation: s1i s1u s2i s2u s1c s2c
+step s1i: INSERT INTO child VALUES (1, 1);
+step s1u: UPDATE parent SET aux = 'bar';
+step s2i: INSERT INTO child VALUES (2, 1);
+step s2u: UPDATE parent SET aux = 'baz'; <waiting ...>
+step s1c: COMMIT;
+step s2u: <... completed>
+error in steps s1c s2u: ERROR:  could not serialize access due to concurrent update
+step s2c: COMMIT;
+
+starting permutation: s1i s1u s2i s2u s2c s1c
+step s1i: INSERT INTO child VALUES (1, 1);
+step s1u: UPDATE parent SET aux = 'bar';
+step s2i: INSERT INTO child VALUES (2, 1);
+step s2u: UPDATE parent SET aux = 'baz'; <waiting ...>
+invalid permutation detected
+
+starting permutation: s1i s2i s1u s1c s2u s2c
+step s1i: INSERT INTO child VALUES (1, 1);
+step s2i: INSERT INTO child VALUES (2, 1);
+step s1u: UPDATE parent SET aux = 'bar';
+step s1c: COMMIT;
+step s2u: UPDATE parent SET aux = 'baz';
+ERROR:  could not serialize access due to concurrent update
 step s2c: COMMIT;
 
 starting permutation: s1i s2i s1u s2u s1c s2c
@@ -27,6 +53,20 @@ step s2u: <... completed>
 error in steps s1c s2u: ERROR:  could not serialize access due to concurrent update
 step s2c: COMMIT;
 
+starting permutation: s1i s2i s1u s2u s2c s1c
+step s1i: INSERT INTO child VALUES (1, 1);
+step s2i: INSERT INTO child VALUES (2, 1);
+step s1u: UPDATE parent SET aux = 'bar';
+step s2u: UPDATE parent SET aux = 'baz'; <waiting ...>
+invalid permutation detected
+
+starting permutation: s1i s2i s2u s1u s1c s2c
+step s1i: INSERT INTO child VALUES (1, 1);
+step s2i: INSERT INTO child VALUES (2, 1);
+step s2u: UPDATE parent SET aux = 'baz';
+step s1u: UPDATE parent SET aux = 'bar'; <waiting ...>
+invalid permutation detected
+
 starting permutation: s1i s2i s2u s1u s2c s1c
 step s1i: INSERT INTO child VALUES (1, 1);
 step s2i: INSERT INTO child VALUES (2, 1);
@@ -37,6 +77,24 @@ step s1u: <... completed>
 error in steps s2c s1u: ERROR:  could not serialize access due to concurrent update
 step s1c: COMMIT;
 
+starting permutation: s1i s2i s2u s2c s1u s1c
+step s1i: INSERT INTO child VALUES (1, 1);
+step s2i: INSERT INTO child VALUES (2, 1);
+step s2u: UPDATE parent SET aux = 'baz';
+step s2c: COMMIT;
+step s1u: UPDATE parent SET aux = 'bar';
+ERROR:  could not serialize access due to concurrent update
+step s1c: COMMIT;
+
+starting permutation: s2i s1i s1u s1c s2u s2c
+step s2i: INSERT INTO child VALUES (2, 1);
+step s1i: INSERT INTO child VALUES (1, 1);
+step s1u: UPDATE parent SET aux = 'bar';
+step s1c: COMMIT;
+step s2u: UPDATE parent SET aux = 'baz';
+ERROR:  could not serialize access due to concurrent update
+step s2c: COMMIT;
+
 starting permutation: s2i s1i s1u s2u s1c s2c
 step s2i: INSERT INTO child VALUES (2, 1);
 step s1i: INSERT INTO child VALUES (1, 1);
@@ -47,6 +105,20 @@ step s2u: <... completed>
 error in steps s1c s2u: ERROR:  could not serialize access due to concurrent update
 step s2c: COMMIT;
 
+starting permutation: s2i s1i s1u s2u s2c s1c
+step s2i: INSERT INTO child VALUES (2, 1);
+step s1i: INSERT INTO child VALUES (1, 1);
+step s1u: UPDATE parent SET aux = 'bar';
+step s2u: UPDATE parent SET aux = 'baz'; <waiting ...>
+invalid permutation detected
+
+starting permutation: s2i s1i s2u s1u s1c s2c
+step s2i: INSERT INTO child VALUES (2, 1);
+step s1i: INSERT INTO child VALUES (1, 1);
+step s2u: UPDATE parent SET aux = 'baz';
+step s1u: UPDATE parent SET aux = 'bar'; <waiting ...>
+invalid permutation detected
+
 starting permutation: s2i s1i s2u s1u s2c s1c
 step s2i: INSERT INTO child VALUES (2, 1);
 step s1i: INSERT INTO child VALUES (1, 1);
@@ -57,11 +129,45 @@ step s1u: <... completed>
 error in steps s2c s1u: ERROR:  could not serialize access due to concurrent update
 step s1c: COMMIT;
 
+starting permutation: s2i s1i s2u s2c s1u s1c
+step s2i: INSERT INTO child VALUES (2, 1);
+step s1i: INSERT INTO child VALUES (1, 1);
+step s2u: UPDATE parent SET aux = 'baz';
+step s2c: COMMIT;
+step s1u: UPDATE parent SET aux = 'bar';
+ERROR:  could not serialize access due to concurrent update
+step s1c: COMMIT;
+
+starting permutation: s2i s2u s1i s1u s1c s2c
+step s2i: INSERT INTO child VALUES (2, 1);
+step s2u: UPDATE parent SET aux = 'baz';
+step s1i: INSERT INTO child VALUES (1, 1);
+step s1u: UPDATE parent SET aux = 'bar'; <waiting ...>
+invalid permutation detected
+
+starting permutation: s2i s2u s1i s1u s2c s1c
+step s2i: INSERT INTO child VALUES (2, 1);
+step s2u: UPDATE parent SET aux = 'baz';
+step s1i: INSERT INTO child VALUES (1, 1);
+step s1u: UPDATE parent SET aux = 'bar'; <waiting ...>
+step s2c: COMMIT;
+step s1u: <... completed>
+error in steps s2c s1u: ERROR:  could not serialize access due to concurrent update
+step s1c: COMMIT;
+
 starting permutation: s2i s2u s1i s2c s1u s1c
 step s2i: INSERT INTO child VALUES (2, 1);
 step s2u: UPDATE parent SET aux = 'baz';
 step s1i: INSERT INTO child VALUES (1, 1);
 step s2c: COMMIT;
 step s1u: UPDATE parent SET aux = 'bar';
-ERROR:  could not serialize access due to read/write dependencies among transactions
+ERROR:  could not serialize access due to concurrent update
+step s1c: COMMIT;
+
+starting permutation: s2i s2u s2c s1i s1u s1c
+step s2i: INSERT INTO child VALUES (2, 1);
+step s2u: UPDATE parent SET aux = 'baz';
+step s2c: COMMIT;
+step s1i: INSERT INTO child VALUES (1, 1);
+step s1u: UPDATE parent SET aux = 'bar';
 step s1c: COMMIT;
diff --git a/src/test/isolation/expected/fk-deadlock_2.out b/src/test/isolation/expected/fk-deadlock_2.out
deleted file mode 100644 (file)
index 503a7d2..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-Parsed test spec with 2 sessions
-
-starting permutation: s1i s1u s1c s2i s2u s2c
-step s1i: INSERT INTO child VALUES (1, 1);
-step s1u: UPDATE parent SET aux = 'bar';
-step s1c: COMMIT;
-step s2i: INSERT INTO child VALUES (2, 1);
-step s2u: UPDATE parent SET aux = 'baz';
-step s2c: COMMIT;
-
-starting permutation: s1i s1u s2i s1c s2u s2c
-step s1i: INSERT INTO child VALUES (1, 1);
-step s1u: UPDATE parent SET aux = 'bar';
-step s2i: INSERT INTO child VALUES (2, 1);
-step s1c: COMMIT;
-step s2u: UPDATE parent SET aux = 'baz';
-ERROR:  could not serialize access due to concurrent update
-step s2c: COMMIT;
-
-starting permutation: s1i s2i s1u s2u s1c s2c
-step s1i: INSERT INTO child VALUES (1, 1);
-step s2i: INSERT INTO child VALUES (2, 1);
-step s1u: UPDATE parent SET aux = 'bar';
-step s2u: UPDATE parent SET aux = 'baz'; <waiting ...>
-step s1c: COMMIT;
-step s2u: <... completed>
-error in steps s1c s2u: ERROR:  could not serialize access due to concurrent update
-step s2c: COMMIT;
-
-starting permutation: s1i s2i s2u s1u s2c s1c
-step s1i: INSERT INTO child VALUES (1, 1);
-step s2i: INSERT INTO child VALUES (2, 1);
-step s2u: UPDATE parent SET aux = 'baz';
-step s1u: UPDATE parent SET aux = 'bar'; <waiting ...>
-step s2c: COMMIT;
-step s1u: <... completed>
-error in steps s2c s1u: ERROR:  could not serialize access due to concurrent update
-step s1c: COMMIT;
-
-starting permutation: s2i s1i s1u s2u s1c s2c
-step s2i: INSERT INTO child VALUES (2, 1);
-step s1i: INSERT INTO child VALUES (1, 1);
-step s1u: UPDATE parent SET aux = 'bar';
-step s2u: UPDATE parent SET aux = 'baz'; <waiting ...>
-step s1c: COMMIT;
-step s2u: <... completed>
-error in steps s1c s2u: ERROR:  could not serialize access due to concurrent update
-step s2c: COMMIT;
-
-starting permutation: s2i s1i s2u s1u s2c s1c
-step s2i: INSERT INTO child VALUES (2, 1);
-step s1i: INSERT INTO child VALUES (1, 1);
-step s2u: UPDATE parent SET aux = 'baz';
-step s1u: UPDATE parent SET aux = 'bar'; <waiting ...>
-step s2c: COMMIT;
-step s1u: <... completed>
-error in steps s2c s1u: ERROR:  could not serialize access due to concurrent update
-step s1c: COMMIT;
-
-starting permutation: s2i s2u s1i s2c s1u s1c
-step s2i: INSERT INTO child VALUES (2, 1);
-step s2u: UPDATE parent SET aux = 'baz';
-step s1i: INSERT INTO child VALUES (1, 1);
-step s2c: COMMIT;
-step s1u: UPDATE parent SET aux = 'bar';
-ERROR:  could not serialize access due to concurrent update
-step s1c: COMMIT;
index c4248657df8e397b3f2ec01286e0b50314be3891..344a6ecb9a4c0b6a08c10e97593957c2531a4e48 100644 (file)
 Parsed test spec with 2 sessions
 
-starting permutation: s1b s2b s1s s2u s2d s1l s2c s1c
-step s1b: BEGIN ISOLATION LEVEL REPEATABLE READ;
+starting permutation: s2b s1l s2u s2_blocker1 s2_unlock s2c
+pg_advisory_lock
+
+               
 step s2b: BEGIN;
-step s1s: SELECT * FROM foo;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker1: DELETE FROM foo;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s2c: COMMIT;
+step s1l: <... completed>
 key            value          
 
-1              1              
+
+starting permutation: s2b s1l s2u s2_blocker2 s2_unlock s2c
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
 step s2u: UPDATE foo SET value = 2 WHERE key = 1;
-step s2d: DELETE FROM foo;
-step s1l: SELECT * FROM foo FOR KEY SHARE; <waiting ...>
+step s2_blocker2: UPDATE foo SET key = 2 WHERE key = 1;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
 step s2c: COMMIT;
 step s1l: <... completed>
-error in steps s2c s1l: ERROR:  could not serialize access due to concurrent update
-step s1c: COMMIT;
+key            value          
+
+
+starting permutation: s2b s1l s2u s2_blocker3 s2_unlock s2c
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker3: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s1l: <... completed>
+key            value          
+
+1              1              
+step s2c: COMMIT;
+
+starting permutation: s2b s1l s2u s2_blocker1 s2_unlock s2r
+pg_advisory_lock
 
-starting permutation: s1b s2b s1s s2u s2d s1l s2r s1c
-step s1b: BEGIN ISOLATION LEVEL REPEATABLE READ;
+               
 step s2b: BEGIN;
-step s1s: SELECT * FROM foo;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker1: DELETE FROM foo;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s2r: ROLLBACK;
+step s1l: <... completed>
 key            value          
 
 1              1              
+
+starting permutation: s2b s1l s2u s2_blocker2 s2_unlock s2r
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
 step s2u: UPDATE foo SET value = 2 WHERE key = 1;
-step s2d: DELETE FROM foo;
-step s1l: SELECT * FROM foo FOR KEY SHARE; <waiting ...>
+step s2_blocker2: UPDATE foo SET key = 2 WHERE key = 1;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
 step s2r: ROLLBACK;
 step s1l: <... completed>
 key            value          
 
 1              1              
-step s1c: COMMIT;
 
-starting permutation: s1b s2b s1s s2u s2u2 s1l s2c s1c
-step s1b: BEGIN ISOLATION LEVEL REPEATABLE READ;
+starting permutation: s2b s1l s2u s2_blocker3 s2_unlock s2r
+pg_advisory_lock
+
+               
 step s2b: BEGIN;
-step s1s: SELECT * FROM foo;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker3: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s1l: <... completed>
 key            value          
 
 1              1              
+step s2r: ROLLBACK;
+
+starting permutation: s2b s1l s2u s2_blocker1 s2c s2_unlock
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
 step s2u: UPDATE foo SET value = 2 WHERE key = 1;
-step s2u2: UPDATE foo SET key = 2 WHERE key = 1;
-step s1l: SELECT * FROM foo FOR KEY SHARE; <waiting ...>
+step s2_blocker1: DELETE FROM foo;
 step s2c: COMMIT;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
 step s1l: <... completed>
-error in steps s2c s1l: ERROR:  could not serialize access due to concurrent update
-step s1c: COMMIT;
+key            value          
+
+
+starting permutation: s2b s1l s2u s2_blocker2 s2c s2_unlock
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker2: UPDATE foo SET key = 2 WHERE key = 1;
+step s2c: COMMIT;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s1l: <... completed>
+key            value          
 
-starting permutation: s1b s2b s1s s2u s2u2 s1l s2r s1c
-step s1b: BEGIN ISOLATION LEVEL REPEATABLE READ;
+
+starting permutation: s2b s1l s2u s2_blocker3 s2c s2_unlock
+pg_advisory_lock
+
+               
 step s2b: BEGIN;
-step s1s: SELECT * FROM foo;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker3: UPDATE foo SET value = 2 WHERE key = 1;
+step s2c: COMMIT;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s1l: <... completed>
+key            value          
+
+1              2              
+
+starting permutation: s2b s1l s2u s2_blocker1 s2r s2_unlock
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker1: DELETE FROM foo;
+step s2r: ROLLBACK;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s1l: <... completed>
 key            value          
 
 1              1              
+
+starting permutation: s2b s1l s2u s2_blocker2 s2r s2_unlock
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
 step s2u: UPDATE foo SET value = 2 WHERE key = 1;
-step s2u2: UPDATE foo SET key = 2 WHERE key = 1;
-step s1l: SELECT * FROM foo FOR KEY SHARE; <waiting ...>
+step s2_blocker2: UPDATE foo SET key = 2 WHERE key = 1;
 step s2r: ROLLBACK;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s1l: <... completed>
+key            value          
+
+1              1              
+
+starting permutation: s2b s1l s2u s2_blocker3 s2r s2_unlock
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker3: UPDATE foo SET value = 2 WHERE key = 1;
+step s2r: ROLLBACK;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
 step s1l: <... completed>
 key            value          
 
 1              1              
-step s1c: COMMIT;
diff --git a/src/test/isolation/expected/lock-update-delete_1.out b/src/test/isolation/expected/lock-update-delete_1.out
new file mode 100644 (file)
index 0000000..4203573
--- /dev/null
@@ -0,0 +1,207 @@
+Parsed test spec with 2 sessions
+
+starting permutation: s2b s1l s2u s2_blocker1 s2_unlock s2c
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker1: DELETE FROM foo;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s2c: COMMIT;
+step s1l: <... completed>
+error in steps s2c s1l: ERROR:  could not serialize access due to concurrent update
+
+starting permutation: s2b s1l s2u s2_blocker2 s2_unlock s2c
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker2: UPDATE foo SET key = 2 WHERE key = 1;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s2c: COMMIT;
+step s1l: <... completed>
+error in steps s2c s1l: ERROR:  could not serialize access due to concurrent update
+
+starting permutation: s2b s1l s2u s2_blocker3 s2_unlock s2c
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker3: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s1l: <... completed>
+key            value          
+
+1              1              
+step s2c: COMMIT;
+
+starting permutation: s2b s1l s2u s2_blocker1 s2_unlock s2r
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker1: DELETE FROM foo;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s2r: ROLLBACK;
+step s1l: <... completed>
+key            value          
+
+1              1              
+
+starting permutation: s2b s1l s2u s2_blocker2 s2_unlock s2r
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker2: UPDATE foo SET key = 2 WHERE key = 1;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s2r: ROLLBACK;
+step s1l: <... completed>
+key            value          
+
+1              1              
+
+starting permutation: s2b s1l s2u s2_blocker3 s2_unlock s2r
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker3: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s1l: <... completed>
+key            value          
+
+1              1              
+step s2r: ROLLBACK;
+
+starting permutation: s2b s1l s2u s2_blocker1 s2c s2_unlock
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker1: DELETE FROM foo;
+step s2c: COMMIT;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s1l: <... completed>
+error in steps s2_unlock s1l: ERROR:  could not serialize access due to concurrent update
+
+starting permutation: s2b s1l s2u s2_blocker2 s2c s2_unlock
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker2: UPDATE foo SET key = 2 WHERE key = 1;
+step s2c: COMMIT;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s1l: <... completed>
+error in steps s2_unlock s1l: ERROR:  could not serialize access due to concurrent update
+
+starting permutation: s2b s1l s2u s2_blocker3 s2c s2_unlock
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker3: UPDATE foo SET value = 2 WHERE key = 1;
+step s2c: COMMIT;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s1l: <... completed>
+error in steps s2_unlock s1l: ERROR:  could not serialize access due to concurrent update
+
+starting permutation: s2b s1l s2u s2_blocker1 s2r s2_unlock
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker1: DELETE FROM foo;
+step s2r: ROLLBACK;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s1l: <... completed>
+key            value          
+
+1              1              
+
+starting permutation: s2b s1l s2u s2_blocker2 s2r s2_unlock
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker2: UPDATE foo SET key = 2 WHERE key = 1;
+step s2r: ROLLBACK;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s1l: <... completed>
+key            value          
+
+1              1              
+
+starting permutation: s2b s1l s2u s2_blocker3 s2r s2_unlock
+pg_advisory_lock
+
+               
+step s2b: BEGIN;
+step s1l: SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; <waiting ...>
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s2_blocker3: UPDATE foo SET value = 2 WHERE key = 1;
+step s2r: ROLLBACK;
+step s2_unlock: SELECT pg_advisory_unlock(0);
+pg_advisory_unlock
+
+t              
+step s1l: <... completed>
+key            value          
+
+1              1              
index c8e90661b2026fd6406804908584bbe154d0c719..e4e640575796e469da9e11934ebfdc50e24cb095 100644 (file)
@@ -1,6 +1,6 @@
 Parsed test spec with 2 sessions
 
-starting permutation: s1b s2b s1s s2u s1l s2c s2d s1c
+starting permutation: s1b s2b s1s s2u s1l s2c s2d1 s1c
 step s1b: BEGIN ISOLATION LEVEL REPEATABLE READ;
 step s2b: BEGIN;
 step s1s: SELECT * FROM foo;
@@ -13,6 +13,39 @@ key            value
 
 1              1              
 step s2c: COMMIT;
-step s2d: DELETE FROM foo WHERE key = 1; <waiting ...>
+step s2d1: DELETE FROM foo WHERE key = 1; <waiting ...>
+step s1c: COMMIT;
+step s2d1: <... completed>
+
+starting permutation: s1b s2b s1s s2u s1l s2c s2d2 s1c
+step s1b: BEGIN ISOLATION LEVEL REPEATABLE READ;
+step s2b: BEGIN;
+step s1s: SELECT * FROM foo;
+key            value          
+
+1              1              
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s1l: SELECT * FROM foo FOR KEY SHARE;
+key            value          
+
+1              1              
+step s2c: COMMIT;
+step s2d2: UPDATE foo SET key = 3 WHERE key = 1; <waiting ...>
+step s1c: COMMIT;
+step s2d2: <... completed>
+
+starting permutation: s1b s2b s1s s2u s1l s2c s2d3 s1c
+step s1b: BEGIN ISOLATION LEVEL REPEATABLE READ;
+step s2b: BEGIN;
+step s1s: SELECT * FROM foo;
+key            value          
+
+1              1              
+step s2u: UPDATE foo SET value = 2 WHERE key = 1;
+step s1l: SELECT * FROM foo FOR KEY SHARE;
+key            value          
+
+1              1              
+step s2c: COMMIT;
+step s2d3: UPDATE foo SET value = 3 WHERE key = 1;
 step s1c: COMMIT;
-step s2d: <... completed>
index 4b9a5a64ed06c0bda9f2d1af07a321fc644ee9d9..b7b796fc0195d35db6f0aa152c6dab45ae774259 100644 (file)
@@ -1,10 +1,23 @@
-# If we update a tuple, and then delete (or update that touches the key) it,
-# and later somebody tries to come along and traverse that update chain,
-# he should get an error when locking the latest version, if the delete
-# committed; or succeed, when the deleting transaction rolls back.
+# This test verifies behavior when traversing an update chain during
+# locking an old version of the tuple.  There are three tests here:
+# 1. update the tuple, then delete it; a second transaction locks the
+# first version.  This should raise an error if the DELETE succeeds,
+# but be allowed to continue if it aborts.
+# 2. Same as (1), except that instead of deleting the tuple, we merely
+# update its key.  The behavior should be the same as for (1).
+# 3. Same as (2), except that we update the tuple without modifying its
+# key. In this case, no error should be raised.
+# When run in REPEATABLE READ or SERIALIZABLE transaction isolation levels, all
+# permutations that commit s2 cause a serializability error; all permutations
+# that rollback s2 can get through.
+#
+# We use an advisory lock (which is locked during s1's setup) to let s2 obtain
+# its snapshot early and only allow it to actually traverse the update chain
+# when s1 is done creating it.
 
 setup
 {
+  DROP TABLE IF EXISTS foo;
   CREATE TABLE foo (
        key             int PRIMARY KEY,
        value   int
@@ -19,20 +32,30 @@ teardown
 }
 
 session "s1"
-step "s1b"     { BEGIN ISOLATION LEVEL REPEATABLE READ; }
-step "s1s"     { SELECT * FROM foo; }  # obtain snapshot
-step "s1l"     { SELECT * FROM foo FOR KEY SHARE; } # obtain lock
-step "s1c"     { COMMIT; }
+# obtain lock on the tuple, traversing its update chain
+step "s1l"     { SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; }
 
 session "s2"
+setup          { SELECT pg_advisory_lock(0); }
 step "s2b"     { BEGIN; }
 step "s2u"     { UPDATE foo SET value = 2 WHERE key = 1; }
-step "s2d"     { DELETE FROM foo; }
-step "s2u2"    { UPDATE foo SET key = 2 WHERE key = 1; }
+step "s2_blocker1"     { DELETE FROM foo; }
+step "s2_blocker2"     { UPDATE foo SET key = 2 WHERE key = 1; }
+step "s2_blocker3"     { UPDATE foo SET value = 2 WHERE key = 1; }
+step "s2_unlock" { SELECT pg_advisory_unlock(0); }
 step "s2c"     { COMMIT; }
 step "s2r"     { ROLLBACK; }
 
-permutation "s1b" "s2b" "s1s" "s2u" "s2d" "s1l" "s2c" "s1c"
-permutation "s1b" "s2b" "s1s" "s2u" "s2d" "s1l" "s2r" "s1c"
-permutation "s1b" "s2b" "s1s" "s2u" "s2u2" "s1l" "s2c" "s1c"
-permutation "s1b" "s2b" "s1s" "s2u" "s2u2" "s1l" "s2r" "s1c"
+permutation "s2b" "s1l" "s2u" "s2_blocker1" "s2_unlock" "s2c"
+permutation "s2b" "s1l" "s2u" "s2_blocker2" "s2_unlock" "s2c"
+permutation "s2b" "s1l" "s2u" "s2_blocker3" "s2_unlock" "s2c"
+permutation "s2b" "s1l" "s2u" "s2_blocker1" "s2_unlock" "s2r"
+permutation "s2b" "s1l" "s2u" "s2_blocker2" "s2_unlock" "s2r"
+permutation "s2b" "s1l" "s2u" "s2_blocker3" "s2_unlock" "s2r"
+
+permutation "s2b" "s1l" "s2u" "s2_blocker1" "s2c" "s2_unlock"
+permutation "s2b" "s1l" "s2u" "s2_blocker2" "s2c" "s2_unlock"
+permutation "s2b" "s1l" "s2u" "s2_blocker3" "s2c" "s2_unlock"
+permutation "s2b" "s1l" "s2u" "s2_blocker1" "s2r" "s2_unlock"
+permutation "s2b" "s1l" "s2u" "s2_blocker2" "s2r" "s2_unlock"
+permutation "s2b" "s1l" "s2u" "s2_blocker3" "s2r" "s2_unlock"
index 6c6c805d50e877444d068283c2c4295880b3252a..7042b9399cf4832232abaee6b30b8e218e18f150 100644 (file)
@@ -1,6 +1,8 @@
-# When a tuple that has been updated is locked, the locking command
-# should traverse the update chain; thus, a DELETE should not be able
-# to proceed until the lock has been released.
+# When a tuple that has been updated is locked, the locking command must
+# traverse the update chain; thus, a DELETE (on the newer version of the tuple)
+# should not be able to proceed until the lock has been released.  An UPDATE
+# that changes the key should not be allowed to continue either; but an UPDATE
+# that doesn't modify the key should be able to continue immediately.
 
 setup
 {
@@ -27,6 +29,10 @@ session "s2"
 step "s2b"     { BEGIN; }
 step "s2u"     { UPDATE foo SET value = 2 WHERE key = 1; }
 step "s2c"     { COMMIT; }
-step "s2d"     { DELETE FROM foo WHERE key = 1; }
+step "s2d1"    { DELETE FROM foo WHERE key = 1; }
+step "s2d2"    { UPDATE foo SET key = 3 WHERE key = 1; }
+step "s2d3"    { UPDATE foo SET value = 3 WHERE key = 1; }
 
-permutation "s1b" "s2b" "s1s" "s2u" "s1l" "s2c" "s2d" "s1c"
+permutation "s1b" "s2b" "s1s" "s2u" "s1l" "s2c" "s2d1" "s1c"
+permutation "s1b" "s2b" "s1s" "s2u" "s1l" "s2c" "s2d2" "s1c"
+permutation "s1b" "s2b" "s1s" "s2u" "s1l" "s2c" "s2d3" "s1c"