Commit a443c1b2 authored by Tom Lane's avatar Tom Lane

Allow non-quoted identifiers as isolation test session/step names.

For no obvious reason, isolationtester has always insisted that
session and step names be written with double quotes.  This is
fairly tedious and does little for test readability, especially
since the names that people actually choose almost always look
like normal identifiers.  Hence, let's tweak the lexer to allow
SQL-like identifiers not only double-quoted strings.

(They're SQL-like, not exactly SQL, because I didn't add any
case-folding logic.  Also there's no provision for U&"..." names,
not that anyone's likely to care.)

There is one incompatibility introduced by this change: if you write
"foo""bar" with no space, that used to be taken as two identifiers,
but now it's just one identifier with an embedded quote mark.

I converted all the src/test/isolation/ specfiles to remove
unnecessary double quotes, but stopped there because my
eyes were glazing over already.

Like 741d7f10, back-patch to all supported branches, so that this
isn't a stumbling block for back-patching isolation test changes.

Discussion: https://postgr.es/m/759113.1623861959@sss.pgh.pa.us
parent 2031e166
...@@ -39,4 +39,4 @@ step "s1_commit" { COMMIT; } ...@@ -39,4 +39,4 @@ step "s1_commit" { COMMIT; }
# composite type is a rare form of DDL which allows T1 to see the tuple which # composite type is a rare form of DDL which allows T1 to see the tuple which
# will be removed (xmax set) before T1 commits. That is, interlocking doesn't # will be removed (xmax set) before T1 commits. That is, interlocking doesn't
# forbid modifying catalog after someone read it (and didn't commit yet). # forbid modifying catalog after someone read it (and didn't commit yet).
permutation "s0_begin" "s0_getxid" "s1_begin" "s1_insert" "s0_alter" "s0_commit" "s0_checkpoint" "s0_get_changes" "s0_get_changes""s1_commit" "s0_vacuum" "s0_get_changes" permutation "s0_begin" "s0_getxid" "s1_begin" "s1_insert" "s0_alter" "s0_commit" "s0_checkpoint" "s0_get_changes" "s0_get_changes" "s1_commit" "s0_vacuum" "s0_get_changes"
...@@ -80,7 +80,7 @@ teardown { <SQL> } ...@@ -80,7 +80,7 @@ teardown { <SQL> }
this to clean up in preparation for the next permutation, e.g dropping this to clean up in preparation for the next permutation, e.g dropping
any test tables created by setup. This part is optional. any test tables created by setup. This part is optional.
session "<name>" session <name>
There are normally several "session" parts in a spec file. Each There are normally several "session" parts in a spec file. Each
session is executed in its own connection. A session part consists session is executed in its own connection. A session part consists
...@@ -91,17 +91,17 @@ session "<name>" ...@@ -91,17 +91,17 @@ session "<name>"
Each step has the syntax Each step has the syntax
step "<name>" { <SQL> } step <name> { <SQL> }
where <name> is a name identifying this step, and SQL is a SQL statement where <name> is a name identifying this step, and <SQL> is a SQL statement
(or statements, separated by semicolons) that is executed in the step. (or statements, separated by semicolons) that is executed in the step.
Step names must be unique across the whole spec file. Step names must be unique across the whole spec file.
permutation "<step name>" ... permutation <step name> ...
A permutation line specifies a list of steps that are run in that order. A permutation line specifies a list of steps that are run in that order.
Any number of permutation lines can appear. If no permutation lines are Any number of permutation lines can appear. If no permutation lines are
given, the test program automatically generates all possible orderings given, the test program automatically runs all possible interleavings
of the steps from each session (running the steps of any one session in of the steps from each session (running the steps of any one session in
order). Note that the list of steps in a manually specified order). Note that the list of steps in a manually specified
"permutation" line doesn't actually have to be a permutation of the "permutation" line doesn't actually have to be a permutation of the
...@@ -109,7 +109,17 @@ permutation "<step name>" ... ...@@ -109,7 +109,17 @@ permutation "<step name>" ...
or leave others out. Also, each step name can be annotated with some or leave others out. Also, each step name can be annotated with some
parenthesized markers, which are described below. parenthesized markers, which are described below.
Lines beginning with a # are considered comments. Session and step names are SQL identifiers, either plain or double-quoted.
A difference from standard SQL is that no case-folding occurs, so that
FOO and "FOO" are the same name while FOO and Foo are different,
whether you quote them or not. You must use quotes if you want to use
an isolation test keyword (such as "permutation") as a name.
A # character begins a comment, which extends to the end of the line.
(This does not work inside <SQL> blocks, however. Use the usual SQL
comment conventions there.)
There is no way to include a "}" character in an <SQL> block.
For each permutation of the session steps (whether these are manually For each permutation of the session steps (whether these are manually
specified in the spec file, or automatically generated), the isolation specified in the spec file, or automatically generated), the isolation
......
...@@ -49,7 +49,7 @@ TestSpec parseresult; /* result of parsing is left here */ ...@@ -49,7 +49,7 @@ TestSpec parseresult; /* result of parsing is left here */
%type <permutationstep> permutation_step %type <permutationstep> permutation_step
%type <blocker> blocker %type <blocker> blocker
%token <str> sqlblock string_literal %token <str> sqlblock identifier
%token <integer> INTEGER %token <integer> INTEGER
%token NOTICES PERMUTATION SESSION SETUP STEP TEARDOWN TEST %token NOTICES PERMUTATION SESSION SETUP STEP TEARDOWN TEST
...@@ -117,7 +117,7 @@ session_list: ...@@ -117,7 +117,7 @@ session_list:
; ;
session: session:
SESSION string_literal opt_setup step_list opt_teardown SESSION identifier opt_setup step_list opt_teardown
{ {
$$ = pg_malloc(sizeof(Session)); $$ = pg_malloc(sizeof(Session));
$$->name = $2; $$->name = $2;
...@@ -146,7 +146,7 @@ step_list: ...@@ -146,7 +146,7 @@ step_list:
step: step:
STEP string_literal sqlblock STEP identifier sqlblock
{ {
$$ = pg_malloc(sizeof(Step)); $$ = pg_malloc(sizeof(Step));
$$->name = $2; $$->name = $2;
...@@ -211,7 +211,7 @@ permutation_step_list: ...@@ -211,7 +211,7 @@ permutation_step_list:
; ;
permutation_step: permutation_step:
string_literal identifier
{ {
$$ = pg_malloc(sizeof(PermutationStep)); $$ = pg_malloc(sizeof(PermutationStep));
$$->name = $1; $$->name = $1;
...@@ -219,7 +219,7 @@ permutation_step: ...@@ -219,7 +219,7 @@ permutation_step:
$$->nblockers = 0; $$->nblockers = 0;
$$->step = NULL; $$->step = NULL;
} }
| string_literal '(' blocker_list ')' | identifier '(' blocker_list ')'
{ {
$$ = pg_malloc(sizeof(PermutationStep)); $$ = pg_malloc(sizeof(PermutationStep));
$$->name = $1; $$->name = $1;
...@@ -246,7 +246,7 @@ blocker_list: ...@@ -246,7 +246,7 @@ blocker_list:
; ;
blocker: blocker:
string_literal identifier
{ {
$$ = pg_malloc(sizeof(PermutationStepBlocker)); $$ = pg_malloc(sizeof(PermutationStepBlocker));
$$->stepname = $1; $$->stepname = $1;
...@@ -255,7 +255,7 @@ blocker: ...@@ -255,7 +255,7 @@ blocker:
$$->step = NULL; $$->step = NULL;
$$->target_notices = -1; $$->target_notices = -1;
} }
| string_literal NOTICES INTEGER | identifier NOTICES INTEGER
{ {
$$ = pg_malloc(sizeof(PermutationStepBlocker)); $$ = pg_malloc(sizeof(PermutationStepBlocker));
$$->stepname = $1; $$->stepname = $1;
......
...@@ -17,30 +17,30 @@ teardown ...@@ -17,30 +17,30 @@ teardown
DROP TABLE foo; DROP TABLE foo;
} }
session "s1" session s1
setup { BEGIN; } setup { BEGIN; }
step "s1s" { SAVEPOINT f; } step s1s { SAVEPOINT f; }
step "s1u" { UPDATE foo SET key = 2; } # obtain KEY REVOKE step s1u { UPDATE foo SET key = 2; } # obtain KEY REVOKE
step "s1r" { ROLLBACK TO f; } # lose KEY REVOKE step s1r { ROLLBACK TO f; } # lose KEY REVOKE
step "s1l" { SELECT * FROM foo FOR KEY SHARE; } step s1l { SELECT * FROM foo FOR KEY SHARE; }
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
setup { BEGIN; } setup { BEGIN; }
step "s2l" { SELECT * FROM foo FOR KEY SHARE; } step s2l { SELECT * FROM foo FOR KEY SHARE; }
step "s2c" { COMMIT; } step s2c { COMMIT; }
permutation "s1s" "s1u" "s1r" "s1l" "s1c" "s2l" "s2c" permutation s1s s1u s1r s1l s1c s2l s2c
permutation "s1s" "s1u" "s1r" "s1l" "s2l" "s1c" "s2c" permutation s1s s1u s1r s1l s2l s1c s2c
permutation "s1s" "s1u" "s1r" "s1l" "s2l" "s2c" "s1c" permutation s1s s1u s1r s1l s2l s2c s1c
permutation "s1s" "s1u" "s1r" "s2l" "s1l" "s1c" "s2c" permutation s1s s1u s1r s2l s1l s1c s2c
permutation "s1s" "s1u" "s1r" "s2l" "s1l" "s2c" "s1c" permutation s1s s1u s1r s2l s1l s2c s1c
permutation "s1s" "s1u" "s1r" "s2l" "s2c" "s1l" "s1c" permutation s1s s1u s1r s2l s2c s1l s1c
permutation "s1s" "s1u" "s2l" "s1r" "s1l" "s1c" "s2c" permutation s1s s1u s2l s1r s1l s1c s2c
permutation "s1s" "s1u" "s2l" "s1r" "s1l" "s2c" "s1c" permutation s1s s1u s2l s1r s1l s2c s1c
permutation "s1s" "s1u" "s2l" "s1r" "s2c" "s1l" "s1c" permutation s1s s1u s2l s1r s2c s1l s1c
permutation "s1s" "s2l" "s1u" "s2c" "s1r" "s1l" "s1c" permutation s1s s2l s1u s2c s1r s1l s1c
permutation "s1s" "s2l" "s2c" "s1u" "s1r" "s1l" "s1c" permutation s1s s2l s2c s1u s1r s1l s1c
permutation "s2l" "s1s" "s1u" "s2c" "s1r" "s1l" "s1c" permutation s2l s1s s1u s2c s1r s1l s1c
permutation "s2l" "s1s" "s2c" "s1u" "s1r" "s1l" "s1c" permutation s2l s1s s2c s1u s1r s1l s1c
permutation "s2l" "s2c" "s1s" "s1u" "s1r" "s1l" "s1c" permutation s2l s2c s1s s1u s1r s1l s1c
This diff is collapsed.
...@@ -16,64 +16,64 @@ teardown ...@@ -16,64 +16,64 @@ teardown
DROP TABLE a, b; DROP TABLE a, b;
} }
session "s1" session s1
step "s1a" { BEGIN; } step s1a { BEGIN; }
step "s1b" { ALTER TABLE b ADD CONSTRAINT bfk FOREIGN KEY (a_id) REFERENCES a (i) NOT VALID; } step s1b { ALTER TABLE b ADD CONSTRAINT bfk FOREIGN KEY (a_id) REFERENCES a (i) NOT VALID; }
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
step "s2a" { BEGIN; } step s2a { BEGIN; }
step "s2b" { SELECT * FROM a WHERE i = 1 LIMIT 1 FOR UPDATE; } step s2b { SELECT * FROM a WHERE i = 1 LIMIT 1 FOR UPDATE; }
step "s2c" { SELECT * FROM b WHERE a_id = 3 LIMIT 1 FOR UPDATE; } step s2c { SELECT * FROM b WHERE a_id = 3 LIMIT 1 FOR UPDATE; }
step "s2d" { INSERT INTO b VALUES (0); } step s2d { INSERT INTO b VALUES (0); }
step "s2e" { INSERT INTO a VALUES (4); } step s2e { INSERT INTO a VALUES (4); }
step "s2f" { COMMIT; } step s2f { COMMIT; }
permutation "s1a" "s1b" "s1c" "s2a" "s2b" "s2c" "s2d" "s2e" "s2f" permutation s1a s1b s1c s2a s2b s2c s2d s2e s2f
permutation "s1a" "s1b" "s2a" "s1c" "s2b" "s2c" "s2d" "s2e" "s2f" permutation s1a s1b s2a s1c s2b s2c s2d s2e s2f
permutation "s1a" "s1b" "s2a" "s2b" "s1c" "s2c" "s2d" "s2e" "s2f" permutation s1a s1b s2a s2b s1c s2c s2d s2e s2f
permutation "s1a" "s1b" "s2a" "s2b" "s2c" "s1c" "s2d" "s2e" "s2f" permutation s1a s1b s2a s2b s2c s1c s2d s2e s2f
permutation "s1a" "s1b" "s2a" "s2b" "s2c" "s2d" "s1c" "s2e" "s2f" permutation s1a s1b s2a s2b s2c s2d s1c s2e s2f
permutation "s1a" "s2a" "s1b" "s1c" "s2b" "s2c" "s2d" "s2e" "s2f" permutation s1a s2a s1b s1c s2b s2c s2d s2e s2f
permutation "s1a" "s2a" "s1b" "s2b" "s1c" "s2c" "s2d" "s2e" "s2f" permutation s1a s2a s1b s2b s1c s2c s2d s2e s2f
permutation "s1a" "s2a" "s1b" "s2b" "s2c" "s1c" "s2d" "s2e" "s2f" permutation s1a s2a s1b s2b s2c s1c s2d s2e s2f
permutation "s1a" "s2a" "s1b" "s2b" "s2c" "s2d" "s1c" "s2e" "s2f" permutation s1a s2a s1b s2b s2c s2d s1c s2e s2f
permutation "s1a" "s2a" "s2b" "s1b" "s1c" "s2c" "s2d" "s2e" "s2f" permutation s1a s2a s2b s1b s1c s2c s2d s2e s2f
permutation "s1a" "s2a" "s2b" "s1b" "s2c" "s1c" "s2d" "s2e" "s2f" permutation s1a s2a s2b s1b s2c s1c s2d s2e s2f
permutation "s1a" "s2a" "s2b" "s1b" "s2c" "s2d" "s1c" "s2e" "s2f" permutation s1a s2a s2b s1b s2c s2d s1c s2e s2f
permutation "s1a" "s2a" "s2b" "s2c" "s1b" "s1c" "s2d" "s2e" "s2f" permutation s1a s2a s2b s2c s1b s1c s2d s2e s2f
permutation "s1a" "s2a" "s2b" "s2c" "s1b" "s2d" "s1c" "s2e" "s2f" permutation s1a s2a s2b s2c s1b s2d s1c s2e s2f
permutation "s1a" "s2a" "s2b" "s2c" "s2d" "s1b" "s2e" "s2f" "s1c" permutation s1a s2a s2b s2c s2d s1b s2e s2f s1c
permutation "s1a" "s2a" "s2b" "s2c" "s2d" "s2e" "s1b" "s2f" "s1c" permutation s1a s2a s2b s2c s2d s2e s1b s2f s1c
permutation "s1a" "s2a" "s2b" "s2c" "s2d" "s2e" "s2f" "s1b" "s1c" permutation s1a s2a s2b s2c s2d s2e s2f s1b s1c
permutation "s2a" "s1a" "s1b" "s1c" "s2b" "s2c" "s2d" "s2e" "s2f" permutation s2a s1a s1b s1c s2b s2c s2d s2e s2f
permutation "s2a" "s1a" "s1b" "s2b" "s1c" "s2c" "s2d" "s2e" "s2f" permutation s2a s1a s1b s2b s1c s2c s2d s2e s2f
permutation "s2a" "s1a" "s1b" "s2b" "s2c" "s1c" "s2d" "s2e" "s2f" permutation s2a s1a s1b s2b s2c s1c s2d s2e s2f
permutation "s2a" "s1a" "s1b" "s2b" "s2c" "s2d" "s1c" "s2e" "s2f" permutation s2a s1a s1b s2b s2c s2d s1c s2e s2f
permutation "s2a" "s1a" "s2b" "s1b" "s1c" "s2c" "s2d" "s2e" "s2f" permutation s2a s1a s2b s1b s1c s2c s2d s2e s2f
permutation "s2a" "s1a" "s2b" "s1b" "s2c" "s1c" "s2d" "s2e" "s2f" permutation s2a s1a s2b s1b s2c s1c s2d s2e s2f
permutation "s2a" "s1a" "s2b" "s1b" "s2c" "s2d" "s1c" "s2e" "s2f" permutation s2a s1a s2b s1b s2c s2d s1c s2e s2f
permutation "s2a" "s1a" "s2b" "s2c" "s1b" "s1c" "s2d" "s2e" "s2f" permutation s2a s1a s2b s2c s1b s1c s2d s2e s2f
permutation "s2a" "s1a" "s2b" "s2c" "s1b" "s2d" "s1c" "s2e" "s2f" permutation s2a s1a s2b s2c s1b s2d s1c s2e s2f
permutation "s2a" "s1a" "s2b" "s2c" "s2d" "s1b" "s2e" "s2f" "s1c" permutation s2a s1a s2b s2c s2d s1b s2e s2f s1c
permutation "s2a" "s1a" "s2b" "s2c" "s2d" "s2e" "s1b" "s2f" "s1c" permutation s2a s1a s2b s2c s2d s2e s1b s2f s1c
permutation "s2a" "s1a" "s2b" "s2c" "s2d" "s2e" "s2f" "s1b" "s1c" permutation s2a s1a s2b s2c s2d s2e s2f s1b s1c
permutation "s2a" "s2b" "s1a" "s1b" "s1c" "s2c" "s2d" "s2e" "s2f" permutation s2a s2b s1a s1b s1c s2c s2d s2e s2f
permutation "s2a" "s2b" "s1a" "s1b" "s2c" "s1c" "s2d" "s2e" "s2f" permutation s2a s2b s1a s1b s2c s1c s2d s2e s2f
permutation "s2a" "s2b" "s1a" "s1b" "s2c" "s2d" "s1c" "s2e" "s2f" permutation s2a s2b s1a s1b s2c s2d s1c s2e s2f
permutation "s2a" "s2b" "s1a" "s2c" "s1b" "s1c" "s2d" "s2e" "s2f" permutation s2a s2b s1a s2c s1b s1c s2d s2e s2f
permutation "s2a" "s2b" "s1a" "s2c" "s1b" "s2d" "s1c" "s2e" "s2f" permutation s2a s2b s1a s2c s1b s2d s1c s2e s2f
permutation "s2a" "s2b" "s1a" "s2c" "s2d" "s1b" "s2e" "s2f" "s1c" permutation s2a s2b s1a s2c s2d s1b s2e s2f s1c
permutation "s2a" "s2b" "s1a" "s2c" "s2d" "s2e" "s1b" "s2f" "s1c" permutation s2a s2b s1a s2c s2d s2e s1b s2f s1c
permutation "s2a" "s2b" "s1a" "s2c" "s2d" "s2e" "s2f" "s1b" "s1c" permutation s2a s2b s1a s2c s2d s2e s2f s1b s1c
permutation "s2a" "s2b" "s2c" "s1a" "s1b" "s1c" "s2d" "s2e" "s2f" permutation s2a s2b s2c s1a s1b s1c s2d s2e s2f
permutation "s2a" "s2b" "s2c" "s1a" "s1b" "s2d" "s1c" "s2e" "s2f" permutation s2a s2b s2c s1a s1b s2d s1c s2e s2f
permutation "s2a" "s2b" "s2c" "s1a" "s2d" "s1b" "s2e" "s2f" "s1c" permutation s2a s2b s2c s1a s2d s1b s2e s2f s1c
permutation "s2a" "s2b" "s2c" "s1a" "s2d" "s2e" "s1b" "s2f" "s1c" permutation s2a s2b s2c s1a s2d s2e s1b s2f s1c
permutation "s2a" "s2b" "s2c" "s1a" "s2d" "s2e" "s2f" "s1b" "s1c" permutation s2a s2b s2c s1a s2d s2e s2f s1b s1c
permutation "s2a" "s2b" "s2c" "s2d" "s1a" "s1b" "s2e" "s2f" "s1c" permutation s2a s2b s2c s2d s1a s1b s2e s2f s1c
permutation "s2a" "s2b" "s2c" "s2d" "s1a" "s2e" "s1b" "s2f" "s1c" permutation s2a s2b s2c s2d s1a s2e s1b s2f s1c
permutation "s2a" "s2b" "s2c" "s2d" "s1a" "s2e" "s2f" "s1b" "s1c" permutation s2a s2b s2c s2d s1a s2e s2f s1b s1c
permutation "s2a" "s2b" "s2c" "s2d" "s2e" "s1a" "s1b" "s2f" "s1c" permutation s2a s2b s2c s2d s2e s1a s1b s2f s1c
permutation "s2a" "s2b" "s2c" "s2d" "s2e" "s1a" "s2f" "s1b" "s1c" permutation s2a s2b s2c s2d s2e s1a s2f s1b s1c
permutation "s2a" "s2b" "s2c" "s2d" "s2e" "s2f" "s1a" "s1b" "s1c" permutation s2a s2b s2c s2d s2e s2f s1a s1b s1c
...@@ -17,63 +17,63 @@ teardown ...@@ -17,63 +17,63 @@ teardown
DROP FUNCTION f(); DROP FUNCTION f();
} }
session "s1" session s1
step "s1a" { BEGIN; } step s1a { BEGIN; }
step "s1b" { ALTER TABLE a DISABLE TRIGGER t; } step s1b { ALTER TABLE a DISABLE TRIGGER t; }
step "s1c" { ALTER TABLE a ENABLE TRIGGER t; } step s1c { ALTER TABLE a ENABLE TRIGGER t; }
step "s1d" { COMMIT; } step s1d { COMMIT; }
session "s2" session s2
step "s2a" { BEGIN; } step s2a { BEGIN; }
step "s2b" { SELECT * FROM a WHERE i = 1 LIMIT 1 FOR UPDATE; } step s2b { SELECT * FROM a WHERE i = 1 LIMIT 1 FOR UPDATE; }
step "s2c" { INSERT INTO a VALUES (0); } step s2c { INSERT INTO a VALUES (0); }
step "s2d" { COMMIT; } step s2d { COMMIT; }
permutation "s1a" "s1b" "s1c" "s1d" "s2a" "s2b" "s2c" "s2d" permutation s1a s1b s1c s1d s2a s2b s2c s2d
permutation "s1a" "s1b" "s1c" "s2a" "s1d" "s2b" "s2c" "s2d" permutation s1a s1b s1c s2a s1d s2b s2c s2d
permutation "s1a" "s1b" "s1c" "s2a" "s2b" "s1d" "s2c" "s2d" permutation s1a s1b s1c s2a s2b s1d s2c s2d
permutation "s1a" "s1b" "s1c" "s2a" "s2b" "s2c" "s1d" "s2d" permutation s1a s1b s1c s2a s2b s2c s1d s2d
permutation "s1a" "s1b" "s2a" "s1c" "s1d" "s2b" "s2c" "s2d" permutation s1a s1b s2a s1c s1d s2b s2c s2d
permutation "s1a" "s1b" "s2a" "s1c" "s2b" "s1d" "s2c" "s2d" permutation s1a s1b s2a s1c s2b s1d s2c s2d
permutation "s1a" "s1b" "s2a" "s1c" "s2b" "s2c" "s1d" "s2d" permutation s1a s1b s2a s1c s2b s2c s1d s2d
permutation "s1a" "s1b" "s2a" "s2b" "s1c" "s1d" "s2c" "s2d" permutation s1a s1b s2a s2b s1c s1d s2c s2d
permutation "s1a" "s1b" "s2a" "s2b" "s1c" "s2c" "s1d" "s2d" permutation s1a s1b s2a s2b s1c s2c s1d s2d
permutation "s1a" "s1b" "s2a" "s2b" "s2c" "s1c" "s1d" "s2d" permutation s1a s1b s2a s2b s2c s1c s1d s2d
permutation "s1a" "s2a" "s1b" "s1c" "s1d" "s2b" "s2c" "s2d" permutation s1a s2a s1b s1c s1d s2b s2c s2d
permutation "s1a" "s2a" "s1b" "s1c" "s2b" "s1d" "s2c" "s2d" permutation s1a s2a s1b s1c s2b s1d s2c s2d
permutation "s1a" "s2a" "s1b" "s1c" "s2b" "s2c" "s1d" "s2d" permutation s1a s2a s1b s1c s2b s2c s1d s2d
permutation "s1a" "s2a" "s1b" "s2b" "s1c" "s1d" "s2c" "s2d" permutation s1a s2a s1b s2b s1c s1d s2c s2d
permutation "s1a" "s2a" "s1b" "s2b" "s1c" "s2c" "s1d" "s2d" permutation s1a s2a s1b s2b s1c s2c s1d s2d
permutation "s1a" "s2a" "s1b" "s2b" "s2c" "s1c" "s1d" "s2d" permutation s1a s2a s1b s2b s2c s1c s1d s2d
permutation "s1a" "s2a" "s2b" "s1b" "s1c" "s1d" "s2c" "s2d" permutation s1a s2a s2b s1b s1c s1d s2c s2d
permutation "s1a" "s2a" "s2b" "s1b" "s1c" "s2c" "s1d" "s2d" permutation s1a s2a s2b s1b s1c s2c s1d s2d
permutation "s1a" "s2a" "s2b" "s1b" "s2c" "s1c" "s1d" "s2d" permutation s1a s2a s2b s1b s2c s1c s1d s2d
permutation "s1a" "s2a" "s2b" "s2c" "s1b" "s1c" "s1d" "s2d" permutation s1a s2a s2b s2c s1b s1c s1d s2d
permutation "s1a" "s2a" "s2b" "s2c" "s1b" "s1c" "s2d" "s1d" permutation s1a s2a s2b s2c s1b s1c s2d s1d
permutation "s1a" "s2a" "s2b" "s2c" "s1b" "s2d" "s1c" "s1d" permutation s1a s2a s2b s2c s1b s2d s1c s1d
permutation "s1a" "s2a" "s2b" "s2c" "s2d" "s1b" "s1c" "s1d" permutation s1a s2a s2b s2c s2d s1b s1c s1d
permutation "s2a" "s1a" "s1b" "s1c" "s1d" "s2b" "s2c" "s2d" permutation s2a s1a s1b s1c s1d s2b s2c s2d
permutation "s2a" "s1a" "s1b" "s1c" "s2b" "s1d" "s2c" "s2d" permutation s2a s1a s1b s1c s2b s1d s2c s2d
permutation "s2a" "s1a" "s1b" "s1c" "s2b" "s2c" "s1d" "s2d" permutation s2a s1a s1b s1c s2b s2c s1d s2d
permutation "s2a" "s1a" "s1b" "s2b" "s1c" "s1d" "s2c" "s2d" permutation s2a s1a s1b s2b s1c s1d s2c s2d
permutation "s2a" "s1a" "s1b" "s2b" "s1c" "s2c" "s1d" "s2d" permutation s2a s1a s1b s2b s1c s2c s1d s2d
permutation "s2a" "s1a" "s1b" "s2b" "s2c" "s1c" "s1d" "s2d" permutation s2a s1a s1b s2b s2c s1c s1d s2d
permutation "s2a" "s1a" "s2b" "s1b" "s1c" "s1d" "s2c" "s2d" permutation s2a s1a s2b s1b s1c s1d s2c s2d
permutation "s2a" "s1a" "s2b" "s1b" "s1c" "s2c" "s1d" "s2d" permutation s2a s1a s2b s1b s1c s2c s1d s2d
permutation "s2a" "s1a" "s2b" "s1b" "s2c" "s1c" "s1d" "s2d" permutation s2a s1a s2b s1b s2c s1c s1d s2d
permutation "s2a" "s1a" "s2b" "s2c" "s1b" "s1c" "s1d" "s2d" permutation s2a s1a s2b s2c s1b s1c s1d s2d
permutation "s2a" "s1a" "s2b" "s2c" "s1b" "s1c" "s2d" "s1d" permutation s2a s1a s2b s2c s1b s1c s2d s1d
permutation "s2a" "s1a" "s2b" "s2c" "s1b" "s2d" "s1c" "s1d" permutation s2a s1a s2b s2c s1b s2d s1c s1d
permutation "s2a" "s1a" "s2b" "s2c" "s2d" "s1b" "s1c" "s1d" permutation s2a s1a s2b s2c s2d s1b s1c s1d
permutation "s2a" "s2b" "s1a" "s1b" "s1c" "s1d" "s2c" "s2d" permutation s2a s2b s1a s1b s1c s1d s2c s2d
permutation "s2a" "s2b" "s1a" "s1b" "s1c" "s2c" "s1d" "s2d" permutation s2a s2b s1a s1b s1c s2c s1d s2d
permutation "s2a" "s2b" "s1a" "s1b" "s2c" "s1c" "s1d" "s2d" permutation s2a s2b s1a s1b s2c s1c s1d s2d
permutation "s2a" "s2b" "s1a" "s2c" "s1b" "s1c" "s1d" "s2d" permutation s2a s2b s1a s2c s1b s1c s1d s2d
permutation "s2a" "s2b" "s1a" "s2c" "s1b" "s1c" "s2d" "s1d" permutation s2a s2b s1a s2c s1b s1c s2d s1d
permutation "s2a" "s2b" "s1a" "s2c" "s1b" "s2d" "s1c" "s1d" permutation s2a s2b s1a s2c s1b s2d s1c s1d
permutation "s2a" "s2b" "s1a" "s2c" "s2d" "s1b" "s1c" "s1d" permutation s2a s2b s1a s2c s2d s1b s1c s1d
permutation "s2a" "s2b" "s2c" "s1a" "s1b" "s1c" "s1d" "s2d" permutation s2a s2b s2c s1a s1b s1c s1d s2d
permutation "s2a" "s2b" "s2c" "s1a" "s1b" "s1c" "s2d" "s1d" permutation s2a s2b s2c s1a s1b s1c s2d s1d
permutation "s2a" "s2b" "s2c" "s1a" "s1b" "s2d" "s1c" "s1d" permutation s2a s2b s2c s1a s1b s2d s1c s1d
permutation "s2a" "s2b" "s2c" "s1a" "s2d" "s1b" "s1c" "s1d" permutation s2a s2b s2c s1a s2d s1b s1c s1d
permutation "s2a" "s2b" "s2c" "s2d" "s1a" "s1b" "s1c" "s1d" permutation s2a s2b s2c s2d s1a s1b s1c s1d
...@@ -15,23 +15,23 @@ teardown ...@@ -15,23 +15,23 @@ teardown
DROP TABLE IF EXISTS c1, c2, p; DROP TABLE IF EXISTS c1, c2, p;
} }
session "s1" session s1
step "s1b" { BEGIN; } step s1b { BEGIN; }
step "s1delc1" { ALTER TABLE c1 NO INHERIT p; } step s1delc1 { ALTER TABLE c1 NO INHERIT p; }
step "s1modc1a" { ALTER TABLE c1 ALTER COLUMN a TYPE float; } step s1modc1a { ALTER TABLE c1 ALTER COLUMN a TYPE float; }
step "s1addc2" { ALTER TABLE c2 INHERIT p; } step s1addc2 { ALTER TABLE c2 INHERIT p; }
step "s1dropc1" { DROP TABLE c1; } step s1dropc1 { DROP TABLE c1; }
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
step "s2sel" { SELECT SUM(a) FROM p; } step s2sel { SELECT SUM(a) FROM p; }
# NO INHERIT will not be visible to concurrent select, # NO INHERIT will not be visible to concurrent select,
# since we identify children before locking them # since we identify children before locking them
permutation "s1b" "s1delc1" "s2sel" "s1c" "s2sel" permutation s1b s1delc1 s2sel s1c s2sel
# adding inheritance likewise is not seen if s1 commits after s2 locks p # adding inheritance likewise is not seen if s1 commits after s2 locks p
permutation "s1b" "s1delc1" "s1addc2" "s2sel" "s1c" "s2sel" permutation s1b s1delc1 s1addc2 s2sel s1c s2sel
# but we do cope with DROP on a child table # but we do cope with DROP on a child table
permutation "s1b" "s1dropc1" "s2sel" "s1c" "s2sel" permutation s1b s1dropc1 s2sel s1c s2sel
# this case currently results in an error; doesn't seem worth preventing # this case currently results in an error; doesn't seem worth preventing
permutation "s1b" "s1delc1" "s1modc1a" "s2sel" "s1c" "s2sel" permutation s1b s1delc1 s1modc1a s2sel s1c s2sel
...@@ -5,15 +5,15 @@ ...@@ -5,15 +5,15 @@
# Note we assume that each step is delivered to the backend as a single Query # Note we assume that each step is delivered to the backend as a single Query
# message so it will run as one transaction. # message so it will run as one transaction.
session "notifier" session notifier
step "listenc" { LISTEN c1; LISTEN c2; } step listenc { LISTEN c1; LISTEN c2; }
step "notify1" { NOTIFY c1; } step notify1 { NOTIFY c1; }
step "notify2" { NOTIFY c2, 'payload'; } step notify2 { NOTIFY c2, 'payload'; }
step "notify3" { NOTIFY c3, 'payload3'; } # not listening to c3 step notify3 { NOTIFY c3, 'payload3'; } # not listening to c3
step "notifyf" { SELECT pg_notify('c2', NULL); } step notifyf { SELECT pg_notify('c2', NULL); }
step "notifyd1" { NOTIFY c2, 'payload'; NOTIFY c1; NOTIFY "c2", 'payload'; } step notifyd1 { NOTIFY c2, 'payload'; NOTIFY c1; NOTIFY "c2", 'payload'; }
step "notifyd2" { NOTIFY c1; NOTIFY c1; NOTIFY c1, 'p1'; NOTIFY c1, 'p2'; } step notifyd2 { NOTIFY c1; NOTIFY c1; NOTIFY c1, 'p1'; NOTIFY c1, 'p2'; }
step "notifys1" { step notifys1 {
BEGIN; BEGIN;
NOTIFY c1, 'payload'; NOTIFY "c2", 'payload'; NOTIFY c1, 'payload'; NOTIFY "c2", 'payload';
NOTIFY c1, 'payload'; NOTIFY "c2", 'payload'; NOTIFY c1, 'payload'; NOTIFY "c2", 'payload';
...@@ -31,47 +31,47 @@ step "notifys1" { ...@@ -31,47 +31,47 @@ step "notifys1" {
ROLLBACK TO SAVEPOINT s2; ROLLBACK TO SAVEPOINT s2;
COMMIT; COMMIT;
} }
step "usage" { SELECT pg_notification_queue_usage() > 0 AS nonzero; } step usage { SELECT pg_notification_queue_usage() > 0 AS nonzero; }
step "bignotify" { SELECT count(pg_notify('c1', s::text)) FROM generate_series(1, 1000) s; } step bignotify { SELECT count(pg_notify('c1', s::text)) FROM generate_series(1, 1000) s; }
teardown { UNLISTEN *; } teardown { UNLISTEN *; }
# The listener session is used for cross-backend notify checks. # The listener session is used for cross-backend notify checks.
session "listener" session listener
step "llisten" { LISTEN c1; LISTEN c2; } step llisten { LISTEN c1; LISTEN c2; }
step "lcheck" { SELECT 1 AS x; } step lcheck { SELECT 1 AS x; }
step "lbegin" { BEGIN; } step lbegin { BEGIN; }
step "lbegins" { BEGIN ISOLATION LEVEL SERIALIZABLE; } step lbegins { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "lcommit" { COMMIT; } step lcommit { COMMIT; }
teardown { UNLISTEN *; } teardown { UNLISTEN *; }
# In some tests we need a second listener, just to block the queue. # In some tests we need a second listener, just to block the queue.
session "listener2" session listener2
step "l2listen" { LISTEN c1; } step l2listen { LISTEN c1; }
step "l2begin" { BEGIN; } step l2begin { BEGIN; }
step "l2commit" { COMMIT; } step l2commit { COMMIT; }
step "l2stop" { UNLISTEN *; } step l2stop { UNLISTEN *; }
# Trivial cases. # Trivial cases.
permutation "listenc" "notify1" "notify2" "notify3" "notifyf" permutation listenc notify1 notify2 notify3 notifyf
# Check simple and less-simple deduplication. # Check simple and less-simple deduplication.
permutation "listenc" "notifyd1" "notifyd2" "notifys1" permutation listenc notifyd1 notifyd2 notifys1
# Cross-backend notification delivery. We use a "select 1" to force the # Cross-backend notification delivery. We use a "select 1" to force the
# listener session to check for notifies. In principle we could just wait # listener session to check for notifies. In principle we could just wait
# for delivery, but that would require extra support in isolationtester # for delivery, but that would require extra support in isolationtester
# and might have portability-of-timing issues. # and might have portability-of-timing issues.
permutation "llisten" "notify1" "notify2" "notify3" "notifyf" "lcheck" permutation llisten notify1 notify2 notify3 notifyf lcheck
# Again, with local delivery too. # Again, with local delivery too.
permutation "listenc" "llisten" "notify1" "notify2" "notify3" "notifyf" "lcheck" permutation listenc llisten notify1 notify2 notify3 notifyf lcheck
# Check for bug when initial listen is only action in a serializable xact, # Check for bug when initial listen is only action in a serializable xact,
# and notify queue is not empty # and notify queue is not empty
permutation "l2listen" "l2begin" "notify1" "lbegins" "llisten" "lcommit" "l2commit" "l2stop" permutation l2listen l2begin notify1 lbegins llisten lcommit l2commit l2stop
# Verify that pg_notification_queue_usage correctly reports a non-zero result, # Verify that pg_notification_queue_usage correctly reports a non-zero result,
# after submitting notifications while another connection is listening for # after submitting notifications while another connection is listening for
...@@ -81,4 +81,4 @@ permutation "l2listen" "l2begin" "notify1" "lbegins" "llisten" "lcommit" "l2comm ...@@ -81,4 +81,4 @@ permutation "l2listen" "l2begin" "notify1" "lbegins" "llisten" "lcommit" "l2comm
# commit the listener's transaction, so that it never reports these events. # commit the listener's transaction, so that it never reports these events.
# Hence, this should be the last test in this script. # Hence, this should be the last test in this script.
permutation "llisten" "lbegin" "usage" "bignotify" "usage" permutation llisten lbegin usage bignotify usage
...@@ -16,14 +16,14 @@ teardown ...@@ -16,14 +16,14 @@ teardown
DROP TABLE room_reservation; DROP TABLE room_reservation;
} }
session "s1" session s1
setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } setup { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "rx1" { SELECT count(*) FROM room_reservation WHERE room_id = '101' AND start_time < TIMESTAMP WITH TIME ZONE '2010-04-01 14:00' AND end_time > TIMESTAMP WITH TIME ZONE '2010-04-01 13:00'; } step rx1 { SELECT count(*) FROM room_reservation WHERE room_id = '101' AND start_time < TIMESTAMP WITH TIME ZONE '2010-04-01 14:00' AND end_time > TIMESTAMP WITH TIME ZONE '2010-04-01 13:00'; }
step "wy1" { INSERT INTO room_reservation VALUES ('101', TIMESTAMP WITH TIME ZONE '2010-04-01 13:00', TIMESTAMP WITH TIME ZONE '2010-04-01 14:00', 'Carol'); } step wy1 { INSERT INTO room_reservation VALUES ('101', TIMESTAMP WITH TIME ZONE '2010-04-01 13:00', TIMESTAMP WITH TIME ZONE '2010-04-01 14:00', 'Carol'); }
step "c1" { COMMIT; } step c1 { COMMIT; }
session "s2" session s2
setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } setup { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "ry2" { SELECT count(*) FROM room_reservation WHERE room_id = '101' AND start_time < TIMESTAMP WITH TIME ZONE '2010-04-01 14:30' AND end_time > TIMESTAMP WITH TIME ZONE '2010-04-01 13:30'; } step ry2 { SELECT count(*) FROM room_reservation WHERE room_id = '101' AND start_time < TIMESTAMP WITH TIME ZONE '2010-04-01 14:30' AND end_time > TIMESTAMP WITH TIME ZONE '2010-04-01 13:30'; }
step "wx2" { UPDATE room_reservation SET start_time = TIMESTAMP WITH TIME ZONE '2010-04-01 13:30', end_time = TIMESTAMP WITH TIME ZONE '2010-04-01 14:30' WHERE room_id = '101' AND start_time = TIMESTAMP WITH TIME ZONE '2010-04-01 10:00'; } step wx2 { UPDATE room_reservation SET start_time = TIMESTAMP WITH TIME ZONE '2010-04-01 13:30', end_time = TIMESTAMP WITH TIME ZONE '2010-04-01 14:30' WHERE room_id = '101' AND start_time = TIMESTAMP WITH TIME ZONE '2010-04-01 10:00'; }
step "c2" { COMMIT; } step c2 { COMMIT; }
...@@ -16,39 +16,39 @@ teardown ...@@ -16,39 +16,39 @@ teardown
DROP FUNCTION f(); DROP FUNCTION f();
} }
session "s1" session s1
step "s1a" { BEGIN; } step s1a { BEGIN; }
step "s1b" { CREATE TRIGGER t AFTER UPDATE ON a EXECUTE PROCEDURE f(); } step s1b { CREATE TRIGGER t AFTER UPDATE ON a EXECUTE PROCEDURE f(); }
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
step "s2a" { BEGIN; } step s2a { BEGIN; }
step "s2b" { SELECT * FROM a WHERE i = 1 FOR UPDATE; } step s2b { SELECT * FROM a WHERE i = 1 FOR UPDATE; }
step "s2c" { UPDATE a SET i = 4 WHERE i = 3; } step s2c { UPDATE a SET i = 4 WHERE i = 3; }
step "s2d" { COMMIT; } step s2d { COMMIT; }
permutation "s1a" "s1b" "s1c" "s2a" "s2b" "s2c" "s2d" permutation s1a s1b s1c s2a s2b s2c s2d
permutation "s1a" "s1b" "s2a" "s1c" "s2b" "s2c" "s2d" permutation s1a s1b s2a s1c s2b s2c s2d
permutation "s1a" "s1b" "s2a" "s2b" "s1c" "s2c" "s2d" permutation s1a s1b s2a s2b s1c s2c s2d
permutation "s1a" "s1b" "s2a" "s2b" "s2c" "s1c" "s2d" permutation s1a s1b s2a s2b s2c s1c s2d
permutation "s1a" "s2a" "s1b" "s1c" "s2b" "s2c" "s2d" permutation s1a s2a s1b s1c s2b s2c s2d
permutation "s1a" "s2a" "s1b" "s2b" "s1c" "s2c" "s2d" permutation s1a s2a s1b s2b s1c s2c s2d
permutation "s1a" "s2a" "s1b" "s2b" "s2c" "s1c" "s2d" permutation s1a s2a s1b s2b s2c s1c s2d
permutation "s1a" "s2a" "s2b" "s1b" "s1c" "s2c" "s2d" permutation s1a s2a s2b s1b s1c s2c s2d
permutation "s1a" "s2a" "s2b" "s1b" "s2c" "s1c" "s2d" permutation s1a s2a s2b s1b s2c s1c s2d
permutation "s1a" "s2a" "s2b" "s2c" "s1b" "s2d" "s1c" permutation s1a s2a s2b s2c s1b s2d s1c
permutation "s1a" "s2a" "s2b" "s2c" "s2d" "s1b" "s1c" permutation s1a s2a s2b s2c s2d s1b s1c
permutation "s2a" "s1a" "s1b" "s1c" "s2b" "s2c" "s2d" permutation s2a s1a s1b s1c s2b s2c s2d
permutation "s2a" "s1a" "s1b" "s2b" "s1c" "s2c" "s2d" permutation s2a s1a s1b s2b s1c s2c s2d
permutation "s2a" "s1a" "s1b" "s2b" "s2c" "s1c" "s2d" permutation s2a s1a s1b s2b s2c s1c s2d
permutation "s2a" "s1a" "s2b" "s1b" "s1c" "s2c" "s2d" permutation s2a s1a s2b s1b s1c s2c s2d
permutation "s2a" "s1a" "s2b" "s1b" "s2c" "s1c" "s2d" permutation s2a s1a s2b s1b s2c s1c s2d
permutation "s2a" "s1a" "s2b" "s2c" "s1b" "s2d" "s1c" permutation s2a s1a s2b s2c s1b s2d s1c
permutation "s2a" "s1a" "s2b" "s2c" "s2d" "s1b" "s1c" permutation s2a s1a s2b s2c s2d s1b s1c
permutation "s2a" "s2b" "s1a" "s1b" "s1c" "s2c" "s2d" permutation s2a s2b s1a s1b s1c s2c s2d
permutation "s2a" "s2b" "s1a" "s1b" "s2c" "s1c" "s2d" permutation s2a s2b s1a s1b s2c s1c s2d
permutation "s2a" "s2b" "s1a" "s2c" "s1b" "s2d" "s1c" permutation s2a s2b s1a s2c s1b s2d s1c
permutation "s2a" "s2b" "s1a" "s2c" "s2d" "s1b" "s1c" permutation s2a s2b s1a s2c s2d s1b s1c
permutation "s2a" "s2b" "s2c" "s1a" "s1b" "s2d" "s1c" permutation s2a s2b s2c s1a s1b s2d s1c
permutation "s2a" "s2b" "s2c" "s1a" "s2d" "s1b" "s1c" permutation s2a s2b s2c s1a s2d s1b s1c
permutation "s2a" "s2b" "s2c" "s2d" "s1a" "s1b" "s1c" permutation s2a s2b s2c s2d s1a s1b s1c
...@@ -20,53 +20,53 @@ teardown ...@@ -20,53 +20,53 @@ teardown
DROP TABLE a1, a2, a3, a4, a5, a6, a7, a8; DROP TABLE a1, a2, a3, a4, a5, a6, a7, a8;
} }
session "s1" session s1
setup { BEGIN; SET deadlock_timeout = '100s'; } setup { BEGIN; SET deadlock_timeout = '100s'; }
step "s1a1" { LOCK TABLE a1; } step s1a1 { LOCK TABLE a1; }
step "s1a2" { LOCK TABLE a2; } step s1a2 { LOCK TABLE a2; }
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
setup { BEGIN; SET deadlock_timeout = '100s'; } setup { BEGIN; SET deadlock_timeout = '100s'; }
step "s2a2" { LOCK TABLE a2; } step s2a2 { LOCK TABLE a2; }
step "s2a3" { LOCK TABLE a3; } step s2a3 { LOCK TABLE a3; }
step "s2c" { COMMIT; } step s2c { COMMIT; }
session "s3" session s3
setup { BEGIN; SET deadlock_timeout = '100s'; } setup { BEGIN; SET deadlock_timeout = '100s'; }
step "s3a3" { LOCK TABLE a3; } step s3a3 { LOCK TABLE a3; }
step "s3a4" { LOCK TABLE a4; } step s3a4 { LOCK TABLE a4; }
step "s3c" { COMMIT; } step s3c { COMMIT; }
session "s4" session s4
setup { BEGIN; SET deadlock_timeout = '100s'; } setup { BEGIN; SET deadlock_timeout = '100s'; }
step "s4a4" { LOCK TABLE a4; } step s4a4 { LOCK TABLE a4; }
step "s4a5" { LOCK TABLE a5; } step s4a5 { LOCK TABLE a5; }
step "s4c" { COMMIT; } step s4c { COMMIT; }
session "s5" session s5
setup { BEGIN; SET deadlock_timeout = '100s'; } setup { BEGIN; SET deadlock_timeout = '100s'; }
step "s5a5" { LOCK TABLE a5; } step s5a5 { LOCK TABLE a5; }
step "s5a6" { LOCK TABLE a6; } step s5a6 { LOCK TABLE a6; }
step "s5c" { COMMIT; } step s5c { COMMIT; }
session "s6" session s6
setup { BEGIN; SET deadlock_timeout = '100s'; } setup { BEGIN; SET deadlock_timeout = '100s'; }
step "s6a6" { LOCK TABLE a6; } step s6a6 { LOCK TABLE a6; }
step "s6a7" { LOCK TABLE a7; } step s6a7 { LOCK TABLE a7; }
step "s6c" { COMMIT; } step s6c { COMMIT; }
session "s7" session s7
setup { BEGIN; SET deadlock_timeout = '100s'; } setup { BEGIN; SET deadlock_timeout = '100s'; }
step "s7a7" { LOCK TABLE a7; } step s7a7 { LOCK TABLE a7; }
step "s7a8" { LOCK TABLE a8; } step s7a8 { LOCK TABLE a8; }
step "s7c" { COMMIT; } step s7c { COMMIT; }
session "s8" session s8
setup { BEGIN; SET deadlock_timeout = '10ms'; } setup { BEGIN; SET deadlock_timeout = '10ms'; }
step "s8a8" { LOCK TABLE a8; } step s8a8 { LOCK TABLE a8; }
step "s8a1" { LOCK TABLE a1; } step s8a1 { LOCK TABLE a1; }
step "s8c" { COMMIT; } step s8c { COMMIT; }
# Note: when s8a1 detects the deadlock and fails, s7a8 is released, making # Note: when s8a1 detects the deadlock and fails, s7a8 is released, making
# it timing-dependent which query completion is received first by the tester. # it timing-dependent which query completion is received first by the tester.
...@@ -76,4 +76,4 @@ step "s8c" { COMMIT; } ...@@ -76,4 +76,4 @@ step "s8c" { COMMIT; }
# dummy blocking mark to s8a1 to ensure it will be reported as "waiting" # dummy blocking mark to s8a1 to ensure it will be reported as "waiting"
# regardless of that. # regardless of that.
permutation "s1a1" "s2a2" "s3a3" "s4a4" "s5a5" "s6a6" "s7a7" "s8a8" "s1a2" "s2a3" "s3a4" "s4a5" "s5a6" "s6a7" "s7a8"("s8a1") "s8a1"(*) "s8c" "s7c" "s6c" "s5c" "s4c" "s3c" "s2c" "s1c" permutation s1a1 s2a2 s3a3 s4a4 s5a5 s6a6 s7a7 s8a8 s1a2 s2a3 s3a4 s4a5 s5a6 s6a7 s7a8(s8a1) s8a1(*) s8c s7c s6c s5c s4c s3c s2c s1c
...@@ -53,33 +53,33 @@ teardown ...@@ -53,33 +53,33 @@ teardown
drop table bigt; drop table bigt;
} }
session "d1" session d1
setup { BEGIN isolation level repeatable read; setup { BEGIN isolation level repeatable read;
SET force_parallel_mode = off; SET force_parallel_mode = off;
SET deadlock_timeout = '10s'; SET deadlock_timeout = '10s';
} }
# these locks will be taken in the leader, so they will persist: # these locks will be taken in the leader, so they will persist:
step "d1a1" { SELECT lock_share(1,x), lock_excl(3,x) FROM bigt LIMIT 1; } step d1a1 { SELECT lock_share(1,x), lock_excl(3,x) FROM bigt LIMIT 1; }
# this causes all the parallel workers to take locks: # this causes all the parallel workers to take locks:
step "d1a2" { SET force_parallel_mode = on; step d1a2 { SET force_parallel_mode = on;
SET parallel_setup_cost = 0; SET parallel_setup_cost = 0;
SET parallel_tuple_cost = 0; SET parallel_tuple_cost = 0;
SET min_parallel_table_scan_size = 0; SET min_parallel_table_scan_size = 0;
SET parallel_leader_participation = off; SET parallel_leader_participation = off;
SET max_parallel_workers_per_gather = 3; SET max_parallel_workers_per_gather = 3;
SELECT sum(lock_share(2,x)) FROM bigt; } SELECT sum(lock_share(2,x)) FROM bigt; }
step "d1c" { COMMIT; } step d1c { COMMIT; }
session "d2" session d2
setup { BEGIN isolation level repeatable read; setup { BEGIN isolation level repeatable read;
SET force_parallel_mode = off; SET force_parallel_mode = off;
SET deadlock_timeout = '10ms'; SET deadlock_timeout = '10ms';
} }
# this lock will be taken in the leader, so it will persist: # this lock will be taken in the leader, so it will persist:
step "d2a2" { select lock_share(2,x) FROM bigt LIMIT 1; } step d2a2 { select lock_share(2,x) FROM bigt LIMIT 1; }
# this causes all the parallel workers to take locks; # this causes all the parallel workers to take locks;
# after which, make the leader take lock 3 to prevent client-driven deadlock # after which, make the leader take lock 3 to prevent client-driven deadlock
step "d2a1" { SET force_parallel_mode = on; step d2a1 { SET force_parallel_mode = on;
SET parallel_setup_cost = 0; SET parallel_setup_cost = 0;
SET parallel_tuple_cost = 0; SET parallel_tuple_cost = 0;
SET min_parallel_table_scan_size = 0; SET min_parallel_table_scan_size = 0;
...@@ -90,24 +90,24 @@ step "d2a1" { SET force_parallel_mode = on; ...@@ -90,24 +90,24 @@ step "d2a1" { SET force_parallel_mode = on;
RESET parallel_setup_cost; RESET parallel_setup_cost;
RESET parallel_tuple_cost; RESET parallel_tuple_cost;
SELECT lock_share(3,x) FROM bigt LIMIT 1; } SELECT lock_share(3,x) FROM bigt LIMIT 1; }
step "d2c" { COMMIT; } step d2c { COMMIT; }
session "e1" session e1
setup { BEGIN isolation level repeatable read; setup { BEGIN isolation level repeatable read;
SET force_parallel_mode = on; SET force_parallel_mode = on;
SET deadlock_timeout = '10s'; SET deadlock_timeout = '10s';
} }
# this lock will be taken in a parallel worker, but we don't need it to persist # this lock will be taken in a parallel worker, but we don't need it to persist
step "e1l" { SELECT lock_excl(1,x) FROM bigt LIMIT 1; } step e1l { SELECT lock_excl(1,x) FROM bigt LIMIT 1; }
step "e1c" { COMMIT; } step e1c { COMMIT; }
session "e2" session e2
setup { BEGIN isolation level repeatable read; setup { BEGIN isolation level repeatable read;
SET force_parallel_mode = on; SET force_parallel_mode = on;
SET deadlock_timeout = '10s'; SET deadlock_timeout = '10s';
} }
# this lock will be taken in a parallel worker, but we don't need it to persist # this lock will be taken in a parallel worker, but we don't need it to persist
step "e2l" { SELECT lock_excl(2,x) FROM bigt LIMIT 1; } step e2l { SELECT lock_excl(2,x) FROM bigt LIMIT 1; }
step "e2c" { COMMIT; } step e2c { COMMIT; }
permutation "d1a1" "d2a2" "e1l" "e2l" "d1a2" "d2a1" "d1c" "e1c" "d2c" "e2c" permutation d1a1 d2a2 e1l e2l d1a2 d2a1 d1c e1c d2c e2c
...@@ -14,16 +14,16 @@ teardown ...@@ -14,16 +14,16 @@ teardown
DROP TABLE a1; DROP TABLE a1;
} }
session "s1" session s1
setup { BEGIN; } setup { BEGIN; }
step "s1as" { LOCK TABLE a1 IN ACCESS SHARE MODE; } step s1as { LOCK TABLE a1 IN ACCESS SHARE MODE; }
step "s1ae" { LOCK TABLE a1 IN ACCESS EXCLUSIVE MODE; } step s1ae { LOCK TABLE a1 IN ACCESS EXCLUSIVE MODE; }
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
setup { BEGIN; } setup { BEGIN; }
step "s2as" { LOCK TABLE a1 IN ACCESS SHARE MODE; } step s2as { LOCK TABLE a1 IN ACCESS SHARE MODE; }
step "s2ae" { LOCK TABLE a1 IN ACCESS EXCLUSIVE MODE; } step s2ae { LOCK TABLE a1 IN ACCESS EXCLUSIVE MODE; }
step "s2c" { COMMIT; } step s2c { COMMIT; }
permutation "s1as" "s2as" "s1ae" "s2ae" "s1c" "s2c" permutation s1as s2as s1ae s2ae s1c s2c
...@@ -13,31 +13,31 @@ teardown ...@@ -13,31 +13,31 @@ teardown
DROP TABLE a1, a2; DROP TABLE a1, a2;
} }
session "s1" session s1
setup { BEGIN; SET deadlock_timeout = '10ms'; } setup { BEGIN; SET deadlock_timeout = '10ms'; }
step "s1a" { LOCK TABLE a1 IN SHARE UPDATE EXCLUSIVE MODE; } step s1a { LOCK TABLE a1 IN SHARE UPDATE EXCLUSIVE MODE; }
step "s1b" { LOCK TABLE a2 IN SHARE UPDATE EXCLUSIVE MODE; } step s1b { LOCK TABLE a2 IN SHARE UPDATE EXCLUSIVE MODE; }
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
setup { BEGIN; SET deadlock_timeout = '100s'; } setup { BEGIN; SET deadlock_timeout = '100s'; }
step "s2a" { LOCK TABLE a2 IN ACCESS SHARE MODE; } step s2a { LOCK TABLE a2 IN ACCESS SHARE MODE; }
step "s2b" { LOCK TABLE a1 IN SHARE UPDATE EXCLUSIVE MODE; } step s2b { LOCK TABLE a1 IN SHARE UPDATE EXCLUSIVE MODE; }
step "s2c" { COMMIT; } step s2c { COMMIT; }
session "s3" session s3
setup { BEGIN; SET deadlock_timeout = '100s'; } setup { BEGIN; SET deadlock_timeout = '100s'; }
step "s3a" { LOCK TABLE a2 IN ACCESS EXCLUSIVE MODE; } step s3a { LOCK TABLE a2 IN ACCESS EXCLUSIVE MODE; }
step "s3c" { COMMIT; } step s3c { COMMIT; }
session "s4" session s4
setup { BEGIN; SET deadlock_timeout = '100s'; } setup { BEGIN; SET deadlock_timeout = '100s'; }
step "s4a" { LOCK TABLE a2 IN ACCESS EXCLUSIVE MODE; } step s4a { LOCK TABLE a2 IN ACCESS EXCLUSIVE MODE; }
step "s4c" { COMMIT; } step s4c { COMMIT; }
# The expected output for this test assumes that isolationtester will # The expected output for this test assumes that isolationtester will
# detect step s1b as waiting before the deadlock detector runs and # detect step s1b as waiting before the deadlock detector runs and
# releases s1 from its blocked state. To ensure that happens even in # releases s1 from its blocked state. To ensure that happens even in
# very slow (CLOBBER_CACHE_ALWAYS) cases, apply a (*) annotation. # very slow (CLOBBER_CACHE_ALWAYS) cases, apply a (*) annotation.
permutation "s1a" "s2a" "s2b" "s3a" "s4a" "s1b"(*) "s1c" "s2c" "s3c" "s4c" permutation s1a s2a s2b s3a s4a s1b(*) s1c s2c s3c s4c
...@@ -15,26 +15,26 @@ teardown ...@@ -15,26 +15,26 @@ teardown
DROP TABLE a1, a2; DROP TABLE a1, a2;
} }
session "d1" session d1
setup { BEGIN; SET deadlock_timeout = '10s'; } setup { BEGIN; SET deadlock_timeout = '10s'; }
step "d1a1" { LOCK TABLE a1 IN ACCESS SHARE MODE; } step d1a1 { LOCK TABLE a1 IN ACCESS SHARE MODE; }
step "d1a2" { LOCK TABLE a2 IN ACCESS SHARE MODE; } step d1a2 { LOCK TABLE a2 IN ACCESS SHARE MODE; }
step "d1c" { COMMIT; } step d1c { COMMIT; }
session "d2" session d2
setup { BEGIN; SET deadlock_timeout = '10ms'; } setup { BEGIN; SET deadlock_timeout = '10ms'; }
step "d2a2" { LOCK TABLE a2 IN ACCESS SHARE MODE; } step d2a2 { LOCK TABLE a2 IN ACCESS SHARE MODE; }
step "d2a1" { LOCK TABLE a1 IN ACCESS SHARE MODE; } step d2a1 { LOCK TABLE a1 IN ACCESS SHARE MODE; }
step "d2c" { COMMIT; } step d2c { COMMIT; }
session "e1" session e1
setup { BEGIN; SET deadlock_timeout = '10s'; } setup { BEGIN; SET deadlock_timeout = '10s'; }
step "e1l" { LOCK TABLE a1 IN ACCESS EXCLUSIVE MODE; } step e1l { LOCK TABLE a1 IN ACCESS EXCLUSIVE MODE; }
step "e1c" { COMMIT; } step e1c { COMMIT; }
session "e2" session e2
setup { BEGIN; SET deadlock_timeout = '10s'; } setup { BEGIN; SET deadlock_timeout = '10s'; }
step "e2l" { LOCK TABLE a2 IN ACCESS EXCLUSIVE MODE; } step e2l { LOCK TABLE a2 IN ACCESS EXCLUSIVE MODE; }
step "e2c" { COMMIT; } step e2c { COMMIT; }
permutation "d1a1" "d2a2" "e1l" "e2l" "d1a2" "d2a1" "d1c" "e1c" "d2c" "e2c" permutation d1a1 d2a2 e1l e2l d1a2 d2a1 d1c e1c d2c e2c
...@@ -14,21 +14,21 @@ teardown ...@@ -14,21 +14,21 @@ teardown
DROP TABLE foo; DROP TABLE foo;
} }
session "s1" session s1
setup { BEGIN; } setup { BEGIN; }
step "s1l" { SELECT * FROM foo FOR KEY SHARE; } step s1l { SELECT * FROM foo FOR KEY SHARE; }
step "s1svp" { SAVEPOINT f; } step s1svp { SAVEPOINT f; }
step "s1d" { SELECT * FROM foo FOR NO KEY UPDATE; } step s1d { SELECT * FROM foo FOR NO KEY UPDATE; }
step "s1r" { ROLLBACK TO f; } step s1r { ROLLBACK TO f; }
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
setup { BEGIN; } setup { BEGIN; }
step "s2l" { SELECT * FROM foo FOR UPDATE; } step s2l { SELECT * FROM foo FOR UPDATE; }
step "s2l2" { SELECT * FROM foo FOR NO KEY UPDATE; } step s2l2 { SELECT * FROM foo FOR NO KEY UPDATE; }
step "s2c" { COMMIT; } step s2c { COMMIT; }
permutation "s1l" "s1svp" "s1d" "s1r" "s2l" "s1c" "s2c" permutation s1l s1svp s1d s1r s2l s1c s2c
permutation "s1l" "s1svp" "s1d" "s2l" "s1r" "s1c" "s2c" permutation s1l s1svp s1d s2l s1r s1c s2c
permutation "s1l" "s1svp" "s1d" "s1r" "s2l2" "s1c" "s2c" permutation s1l s1svp s1d s1r s2l2 s1c s2c
permutation "s1l" "s1svp" "s1d" "s2l2" "s1r" "s1c" "s2c" permutation s1l s1svp s1d s2l2 s1r s1c s2c
...@@ -15,23 +15,23 @@ teardown ...@@ -15,23 +15,23 @@ teardown
DROP TABLE foo; DROP TABLE foo;
} }
session "s1" session s1
setup { BEGIN; } setup { BEGIN; }
step "s1l" { SELECT * FROM foo FOR KEY SHARE; } step s1l { SELECT * FROM foo FOR KEY SHARE; }
step "s1svp" { SAVEPOINT f; } step s1svp { SAVEPOINT f; }
step "s1d" { DELETE FROM foo; } step s1d { DELETE FROM foo; }
step "s1r" { ROLLBACK TO f; } step s1r { ROLLBACK TO f; }
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
setup { BEGIN; } setup { BEGIN; }
step "s2l" { SELECT * FROM foo FOR UPDATE; } step s2l { SELECT * FROM foo FOR UPDATE; }
step "s2c" { COMMIT; } step s2c { COMMIT; }
permutation "s1l" "s1svp" "s1d" "s1r" "s1c" "s2l" "s2c" permutation s1l s1svp s1d s1r s1c s2l s2c
permutation "s1l" "s1svp" "s1d" "s1r" "s2l" "s1c" "s2c" permutation s1l s1svp s1d s1r s2l s1c s2c
permutation "s1l" "s1svp" "s1d" "s2l" "s1r" "s1c" "s2c" permutation s1l s1svp s1d s2l s1r s1c s2c
permutation "s1l" "s1svp" "s2l" "s1d" "s1r" "s1c" "s2c" permutation s1l s1svp s2l s1d s1r s1c s2c
permutation "s1l" "s2l" "s1svp" "s1d" "s1r" "s1c" "s2c" permutation s1l s2l s1svp s1d s1r s1c s2c
permutation "s2l" "s1l" "s2c" "s1svp" "s1d" "s1r" "s1c" permutation s2l s1l s2c s1svp s1d s1r s1c
permutation "s2l" "s2c" "s1l" "s1svp" "s1d" "s1r" "s1c" permutation s2l s2c s1l s1svp s1d s1r s1c
...@@ -14,56 +14,56 @@ teardown { ...@@ -14,56 +14,56 @@ teardown {
DROP TABLE IF EXISTS d_listp, d_listp2, d_listp_foobar; DROP TABLE IF EXISTS d_listp, d_listp2, d_listp_foobar;
} }
session "s1" session s1
step "s1b" { BEGIN; } step s1b { BEGIN; }
step "s1brr" { BEGIN ISOLATION LEVEL REPEATABLE READ; } step s1brr { BEGIN ISOLATION LEVEL REPEATABLE READ; }
step "s1s" { SELECT * FROM d_listp; } step s1s { SELECT * FROM d_listp; }
step "s1ins" { INSERT INTO d_listp VALUES (1); } step s1ins { INSERT INTO d_listp VALUES (1); }
step "s1ins2" { INSERT INTO d_listp VALUES (2); } step s1ins2 { INSERT INTO d_listp VALUES (2); }
step "s1prep" { PREPARE f(int) AS INSERT INTO d_listp VALUES ($1); } step s1prep { PREPARE f(int) AS INSERT INTO d_listp VALUES ($1); }
step "s1prep1" { PREPARE f(int) AS INSERT INTO d_listp VALUES (1); } step s1prep1 { PREPARE f(int) AS INSERT INTO d_listp VALUES (1); }
step "s1prep2" { PREPARE f(int) AS INSERT INTO d_listp VALUES (2); } step s1prep2 { PREPARE f(int) AS INSERT INTO d_listp VALUES (2); }
step "s1exec1" { EXECUTE f(1); } step s1exec1 { EXECUTE f(1); }
step "s1exec2" { EXECUTE f(2); } step s1exec2 { EXECUTE f(2); }
step "s1dealloc" { DEALLOCATE f; } step s1dealloc { DEALLOCATE f; }
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
step "s2detach" { ALTER TABLE d_listp DETACH PARTITION d_listp2 CONCURRENTLY; } step s2detach { ALTER TABLE d_listp DETACH PARTITION d_listp2 CONCURRENTLY; }
step "s2drop" { DROP TABLE d_listp2; } step s2drop { DROP TABLE d_listp2; }
session "s3" session s3
step "s3s" { SELECT * FROM d_listp; } step s3s { SELECT * FROM d_listp; }
step "s3i" { SELECT relpartbound IS NULL FROM pg_class where relname = 'd_listp2'; } step s3i { SELECT relpartbound IS NULL FROM pg_class where relname = 'd_listp2'; }
step "s3ins2" { INSERT INTO d_listp VALUES (2); } step s3ins2 { INSERT INTO d_listp VALUES (2); }
# The transaction that detaches hangs until it sees any older transaction # The transaction that detaches hangs until it sees any older transaction
# terminate, as does anybody else. # terminate, as does anybody else.
permutation "s1b" "s1s" "s2detach" "s1s" "s1c" "s1s" permutation s1b s1s s2detach s1s s1c s1s
# relpartbound remains set until s1 commits # relpartbound remains set until s1 commits
# XXX this could be timing dependent :-( # XXX this could be timing dependent :-(
permutation "s1b" "s1s" "s2detach" "s1s" "s3s" "s3i" "s1c" "s3i" "s2drop" "s1s" permutation s1b s1s s2detach s1s s3s s3i s1c s3i s2drop s1s
# In read-committed mode, the partition disappears from view of concurrent # In read-committed mode, the partition disappears from view of concurrent
# transactions immediately. But if a write lock is held, then the detach # transactions immediately. But if a write lock is held, then the detach
# has to wait. # has to wait.
permutation "s1b" "s1s" "s2detach" "s1ins" "s1s" "s1c" permutation s1b s1s s2detach s1ins s1s s1c
permutation "s1b" "s1s" "s1ins2" "s2detach" "s1ins" "s1s" "s1c" permutation s1b s1s s1ins2 s2detach s1ins s1s s1c
# In repeatable-read mode, the partition remains visible until commit even # In repeatable-read mode, the partition remains visible until commit even
# if the to-be-detached partition is not locked for write. # if the to-be-detached partition is not locked for write.
permutation "s1brr" "s1s" "s2detach" "s1ins" "s1s" "s1c" permutation s1brr s1s s2detach s1ins s1s s1c
permutation "s1brr" "s1s" "s2detach" "s1s" "s1c" permutation s1brr s1s s2detach s1s s1c
# Another process trying to acquire a write lock will be blocked behind the # Another process trying to acquire a write lock will be blocked behind the
# detacher # detacher
permutation "s1b" "s1ins2" "s2detach" "s3ins2" "s1c" permutation s1b s1ins2 s2detach s3ins2 s1c
# a prepared query is not blocked # a prepared query is not blocked
permutation "s1brr" "s1prep" "s1s" "s2detach" "s1s" "s1exec1" "s3s" "s1dealloc" "s1c" permutation s1brr s1prep s1s s2detach s1s s1exec1 s3s s1dealloc s1c
permutation "s1brr" "s1prep" "s1exec2" "s2detach" "s1s" "s1exec2" "s3s" "s1c" "s1dealloc" permutation s1brr s1prep s1exec2 s2detach s1s s1exec2 s3s s1c s1dealloc
permutation "s1brr" "s1prep" "s1s" "s2detach" "s1s" "s1exec2" "s1c" "s1dealloc" permutation s1brr s1prep s1s s2detach s1s s1exec2 s1c s1dealloc
permutation "s1brr" "s1prep" "s2detach" "s1s" "s1exec2" "s1c" "s1dealloc" permutation s1brr s1prep s2detach s1s s1exec2 s1c s1dealloc
permutation "s1brr" "s1prep1" "s2detach" "s1s" "s1exec2" "s1c" "s1dealloc" permutation s1brr s1prep1 s2detach s1s s1exec2 s1c s1dealloc
permutation "s1brr" "s1prep2" "s2detach" "s1s" "s1exec2" "s1c" "s1dealloc" permutation s1brr s1prep2 s2detach s1s s1exec2 s1c s1dealloc
...@@ -15,27 +15,27 @@ setup ...@@ -15,27 +15,27 @@ setup
teardown { DROP TABLE IF EXISTS d_lp_fk, d_lp_fk_1, d_lp_fk_2, d_lp_fk_r; } teardown { DROP TABLE IF EXISTS d_lp_fk, d_lp_fk_1, d_lp_fk_2, d_lp_fk_r; }
session "s1" session s1
step "s1b" { BEGIN; } step s1b { BEGIN; }
step "s1s" { SELECT * FROM d_lp_fk; } step s1s { SELECT * FROM d_lp_fk; }
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
step "s2d" { ALTER TABLE d_lp_fk DETACH PARTITION d_lp_fk_1 CONCURRENTLY; } step s2d { ALTER TABLE d_lp_fk DETACH PARTITION d_lp_fk_1 CONCURRENTLY; }
session "s3" session s3
step "s3b" { BEGIN; } step s3b { BEGIN; }
step "s3i1" { INSERT INTO d_lp_fk_r VALUES (1); } step s3i1 { INSERT INTO d_lp_fk_r VALUES (1); }
step "s3i2" { INSERT INTO d_lp_fk_r VALUES (2); } step s3i2 { INSERT INTO d_lp_fk_r VALUES (2); }
step "s3c" { COMMIT; } step s3c { COMMIT; }
# The transaction that detaches hangs until it sees any older transaction # The transaction that detaches hangs until it sees any older transaction
# terminate. # terminate.
permutation "s1b" "s1s" "s2d" "s3i1" "s1c" permutation s1b s1s s2d s3i1 s1c
permutation "s1b" "s1s" "s2d" "s3i2" "s3i2" "s1c" permutation s1b s1s s2d s3i2 s3i2 s1c
permutation "s1b" "s1s" "s3i1" "s2d" "s1c" permutation s1b s1s s3i1 s2d s1c
permutation "s1b" "s1s" "s3i2" "s2d" "s1c" permutation s1b s1s s3i2 s2d s1c
# what if s3 has an uncommitted insertion? # what if s3 has an uncommitted insertion?
permutation "s1b" "s1s" "s3b" "s2d" "s3i1" "s1c" "s3c" permutation s1b s1s s3b s2d s3i1 s1c s3c
...@@ -20,67 +20,67 @@ teardown { ...@@ -20,67 +20,67 @@ teardown {
DROP TABLE IF EXISTS d3_listp, d3_listp1, d3_listp2, d3_pid; DROP TABLE IF EXISTS d3_listp, d3_listp1, d3_listp2, d3_pid;
} }
session "s1" session s1
step "s1b" { BEGIN; } step s1b { BEGIN; }
step "s1brr" { BEGIN ISOLATION LEVEL REPEATABLE READ; } step s1brr { BEGIN ISOLATION LEVEL REPEATABLE READ; }
step "s1s" { SELECT * FROM d3_listp; } step s1s { SELECT * FROM d3_listp; }
step "s1spart" { SELECT * FROM d3_listp1; } step s1spart { SELECT * FROM d3_listp1; }
step "s1cancel" { SELECT pg_cancel_backend(pid) FROM d3_pid; } step s1cancel { SELECT pg_cancel_backend(pid) FROM d3_pid; }
step "s1noop" { } step s1noop { }
step "s1c" { COMMIT; } step s1c { COMMIT; }
step "s1alter" { ALTER TABLE d3_listp1 ALTER a DROP NOT NULL; } step s1alter { ALTER TABLE d3_listp1 ALTER a DROP NOT NULL; }
step "s1insert" { INSERT INTO d3_listp VALUES (1); } step s1insert { INSERT INTO d3_listp VALUES (1); }
step "s1insertpart" { INSERT INTO d3_listp1 VALUES (1); } step s1insertpart { INSERT INTO d3_listp1 VALUES (1); }
step "s1drop" { DROP TABLE d3_listp; } step s1drop { DROP TABLE d3_listp; }
step "s1droppart" { DROP TABLE d3_listp1; } step s1droppart { DROP TABLE d3_listp1; }
step "s1trunc" { TRUNCATE TABLE d3_listp; } step s1trunc { TRUNCATE TABLE d3_listp; }
step "s1list" { SELECT relname FROM pg_catalog.pg_class step s1list { SELECT relname FROM pg_catalog.pg_class
WHERE relname LIKE 'd3_listp%' ORDER BY 1; } WHERE relname LIKE 'd3_listp%' ORDER BY 1; }
step "s1describe" { SELECT 'd3_listp' AS root, * FROM pg_partition_tree('d3_listp') step s1describe { SELECT 'd3_listp' AS root, * FROM pg_partition_tree('d3_listp')
UNION ALL SELECT 'd3_listp1', * FROM pg_partition_tree('d3_listp1'); } UNION ALL SELECT 'd3_listp1', * FROM pg_partition_tree('d3_listp1'); }
session "s2" session s2
step "s2begin" { BEGIN; } step s2begin { BEGIN; }
step "s2snitch" { INSERT INTO d3_pid SELECT pg_backend_pid(); } step s2snitch { INSERT INTO d3_pid SELECT pg_backend_pid(); }
step "s2detach" { ALTER TABLE d3_listp DETACH PARTITION d3_listp1 CONCURRENTLY; } step s2detach { ALTER TABLE d3_listp DETACH PARTITION d3_listp1 CONCURRENTLY; }
step "s2detach2" { ALTER TABLE d3_listp DETACH PARTITION d3_listp2 CONCURRENTLY; } step s2detach2 { ALTER TABLE d3_listp DETACH PARTITION d3_listp2 CONCURRENTLY; }
step "s2detachfinal" { ALTER TABLE d3_listp DETACH PARTITION d3_listp1 FINALIZE; } step s2detachfinal { ALTER TABLE d3_listp DETACH PARTITION d3_listp1 FINALIZE; }
step "s2drop" { DROP TABLE d3_listp1; } step s2drop { DROP TABLE d3_listp1; }
step "s2commit" { COMMIT; } step s2commit { COMMIT; }
# Try various things while the partition is in "being detached" state, with # Try various things while the partition is in "being detached" state, with
# no session waiting. # no session waiting.
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s1describe" "s1alter" permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s1describe s1alter
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1insert" "s1c" permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1insert s1c
permutation "s2snitch" "s1brr" "s1s" "s2detach"("s1cancel") "s1cancel" "s1insert" "s1c" "s1spart" permutation s2snitch s1brr s1s s2detach(s1cancel) s1cancel s1insert s1c s1spart
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s1insertpart" permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s1insertpart
# Test partition descriptor caching # Test partition descriptor caching
permutation "s2snitch" "s1b" "s1s" "s2detach2"("s1cancel") "s1cancel" "s1c" "s1brr" "s1insert" "s1s" "s1insert" "s1c" permutation s2snitch s1b s1s s2detach2(s1cancel) s1cancel s1c s1brr s1insert s1s s1insert s1c
permutation "s2snitch" "s1b" "s1s" "s2detach2"("s1cancel") "s1cancel" "s1c" "s1brr" "s1s" "s1insert" "s1s" "s1c" permutation s2snitch s1b s1s s2detach2(s1cancel) s1cancel s1c s1brr s1s s1insert s1s s1c
# "drop" here does both tables # "drop" here does both tables
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s1drop" "s1list" permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s1drop s1list
# "truncate" only does parent, not partition # "truncate" only does parent, not partition
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s1trunc" "s1spart" permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s1trunc s1spart
# If a partition pending detach exists, we cannot drop another one # If a partition pending detach exists, we cannot drop another one
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1noop" "s2detach2" "s1c" permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1noop s2detach2 s1c
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1noop" "s2detachfinal" "s1c" "s2detach2" permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1noop s2detachfinal s1c s2detach2
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s1droppart" "s2detach2" permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s1droppart s2detach2
# When a partition with incomplete detach is dropped, we grab lock on parent too. # When a partition with incomplete detach is dropped, we grab lock on parent too.
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s2begin" "s2drop" "s1s" "s2commit" permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s2begin s2drop s1s s2commit
# Partially detach, then select and try to complete the detach. Reading # Partially detach, then select and try to complete the detach. Reading
# from partition blocks (AEL is required on partition); reading from parent # from partition blocks (AEL is required on partition); reading from parent
# does not block. # does not block.
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s1b" "s1spart" "s2detachfinal" "s1c" permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s1b s1spart s2detachfinal s1c
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s1b" "s1s" "s2detachfinal" "s1c" permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s1b s1s s2detachfinal s1c
# DETACH FINALIZE in a transaction block. No insert/select on the partition # DETACH FINALIZE in a transaction block. No insert/select on the partition
# is allowed concurrently with that. # is allowed concurrently with that.
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s1b" "s1spart" "s2detachfinal" "s1c" permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s1b s1spart s2detachfinal s1c
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s2begin" "s2detachfinal" "s2commit" permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s2begin s2detachfinal s2commit
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s2begin" "s2detachfinal" "s1spart" "s2commit" permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s2begin s2detachfinal s1spart s2commit
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s2begin" "s2detachfinal" "s1insertpart" "s2commit" permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s2begin s2detachfinal s1insertpart s2commit
...@@ -23,61 +23,61 @@ setup { ...@@ -23,61 +23,61 @@ setup {
create table d4_pid (pid int); create table d4_pid (pid int);
} }
session "s1" session s1
step "s1b" { begin; } step s1b { begin; }
step "s1brr" { begin isolation level repeatable read; } step s1brr { begin isolation level repeatable read; }
step "s1s" { select * from d4_primary; } step s1s { select * from d4_primary; }
step "s1cancel" { select pg_cancel_backend(pid) from d4_pid; } step s1cancel { select pg_cancel_backend(pid) from d4_pid; }
step "s1noop" { } step s1noop { }
step "s1insert" { insert into d4_fk values (1); } step s1insert { insert into d4_fk values (1); }
step "s1c" { commit; } step s1c { commit; }
step "s1declare" { declare f cursor for select * from d4_primary; } step s1declare { declare f cursor for select * from d4_primary; }
step "s1declare2" { declare f cursor for select * from d4_fk where a = 2; } step s1declare2 { declare f cursor for select * from d4_fk where a = 2; }
step "s1fetchall" { fetch all from f; } step s1fetchall { fetch all from f; }
step "s1fetchone" { fetch 1 from f; } step s1fetchone { fetch 1 from f; }
step "s1updcur" { update d4_fk set a = 1 where current of f; } step s1updcur { update d4_fk set a = 1 where current of f; }
step "s1svpt" { savepoint f; } step s1svpt { savepoint f; }
step "s1rollback" { rollback to f; } step s1rollback { rollback to f; }
session "s2" session s2
step "s2snitch" { insert into d4_pid select pg_backend_pid(); } step s2snitch { insert into d4_pid select pg_backend_pid(); }
step "s2detach" { alter table d4_primary detach partition d4_primary1 concurrently; } step s2detach { alter table d4_primary detach partition d4_primary1 concurrently; }
session "s3" session s3
step "s3brr" { begin isolation level repeatable read; } step s3brr { begin isolation level repeatable read; }
step "s3insert" { insert into d4_fk values (1); } step s3insert { insert into d4_fk values (1); }
step "s3commit" { commit; } step s3commit { commit; }
step "s3vacfreeze" { vacuum freeze pg_catalog.pg_inherits; } step s3vacfreeze { vacuum freeze pg_catalog.pg_inherits; }
# Trying to insert into a partially detached partition is rejected # Trying to insert into a partially detached partition is rejected
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1insert" "s1c" permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1insert s1c
permutation "s2snitch" "s1b" "s1s" "s2detach" "s1insert" "s1c" permutation s2snitch s1b s1s s2detach s1insert s1c
# ... even under REPEATABLE READ mode. # ... even under REPEATABLE READ mode.
permutation "s2snitch" "s1brr" "s1s" "s2detach"("s1cancel") "s1cancel" "s1insert" "s1c" permutation s2snitch s1brr s1s s2detach(s1cancel) s1cancel s1insert s1c
permutation "s2snitch" "s1brr" "s1s" "s2detach" "s1insert" "s1c" permutation s2snitch s1brr s1s s2detach s1insert s1c
# If you read the referenced table using a cursor, you can see a row that the # If you read the referenced table using a cursor, you can see a row that the
# RI query does not see. # RI query does not see.
permutation "s2snitch" "s1b" "s1declare" "s2detach"("s1cancel") "s1cancel" "s1fetchall" "s1insert" "s1c" permutation s2snitch s1b s1declare s2detach(s1cancel) s1cancel s1fetchall s1insert s1c
permutation "s2snitch" "s1b" "s1declare" "s2detach" "s1fetchall" "s1insert" "s1c" permutation s2snitch s1b s1declare s2detach s1fetchall s1insert s1c
permutation "s2snitch" "s1b" "s1declare" "s2detach"("s1cancel") "s1cancel" "s1svpt" "s1insert" "s1rollback" "s1fetchall" "s1c" permutation s2snitch s1b s1declare s2detach(s1cancel) s1cancel s1svpt s1insert s1rollback s1fetchall s1c
permutation "s2snitch" "s1b" "s1declare" "s2detach" "s1svpt" "s1insert" "s1rollback" "s1fetchall" "s1c" permutation s2snitch s1b s1declare s2detach s1svpt s1insert s1rollback s1fetchall s1c
permutation "s2snitch" "s1b" "s2detach"("s1cancel") "s1declare" "s1cancel" "s1fetchall" "s1insert" "s1c" permutation s2snitch s1b s2detach(s1cancel) s1declare s1cancel s1fetchall s1insert s1c
permutation "s2snitch" "s1b" "s2detach" "s1declare" "s1fetchall" "s1insert" "s1c" permutation s2snitch s1b s2detach s1declare s1fetchall s1insert s1c
permutation "s2snitch" "s1b" "s2detach"("s1cancel") "s1declare" "s1cancel" "s1svpt" "s1insert" "s1rollback" "s1fetchall" "s1c" permutation s2snitch s1b s2detach(s1cancel) s1declare s1cancel s1svpt s1insert s1rollback s1fetchall s1c
permutation "s2snitch" "s1b" "s2detach" "s1declare" "s1svpt" "s1insert" "s1rollback" "s1fetchall" "s1c" permutation s2snitch s1b s2detach s1declare s1svpt s1insert s1rollback s1fetchall s1c
# Creating the referencing row using a cursor # Creating the referencing row using a cursor
permutation "s2snitch" "s1brr" "s1declare2" "s1fetchone" "s2detach"("s1cancel") "s1cancel" "s1updcur" "s1c" permutation s2snitch s1brr s1declare2 s1fetchone s2detach(s1cancel) s1cancel s1updcur s1c
permutation "s2snitch" "s1brr" "s1declare2" "s1fetchone" "s2detach" "s1updcur" "s1c" permutation s2snitch s1brr s1declare2 s1fetchone s2detach s1updcur s1c
permutation "s2snitch" "s1brr" "s1declare2" "s1fetchone" "s1updcur" "s2detach" "s1c" permutation s2snitch s1brr s1declare2 s1fetchone s1updcur s2detach s1c
# Try reading the table from an independent session. # Try reading the table from an independent session.
permutation "s2snitch" "s1b" "s1s" "s2detach" "s3insert" "s1c" permutation s2snitch s1b s1s s2detach s3insert s1c
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s3brr" "s3insert" "s3commit" "s1cancel" "s1c" permutation s2snitch s1b s1s s2detach(s1cancel) s3brr s3insert s3commit s1cancel s1c
permutation "s2snitch" "s1b" "s1s" "s2detach" "s3brr" "s3insert" "s3commit" "s1c" permutation s2snitch s1b s1s s2detach s3brr s3insert s3commit s1c
# Try one where we VACUUM FREEZE pg_inherits (to verify that xmin change is # Try one where we VACUUM FREEZE pg_inherits (to verify that xmin change is
# handled correctly). # handled correctly).
permutation "s2snitch" "s1brr" "s1s" "s2detach"("s1cancel") "s1cancel" "s1noop" "s3vacfreeze" "s1s" "s1insert" "s1c" permutation s2snitch s1brr s1s s2detach(s1cancel) s1cancel s1noop s3vacfreeze s1s s1insert s1c
permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1noop" "s3vacfreeze" "s1s" "s1insert" "s1c" permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1noop s3vacfreeze s1s s1insert s1c
...@@ -17,25 +17,25 @@ teardown ...@@ -17,25 +17,25 @@ teardown
DROP TABLE test_dc; DROP TABLE test_dc;
} }
session "s1" session s1
step "noseq" { SET enable_seqscan = false; } step noseq { SET enable_seqscan = false; }
step "chkiso" { SELECT (setting in ('read committed','read uncommitted')) AS is_read_committed FROM pg_settings WHERE name = 'default_transaction_isolation'; } step chkiso { SELECT (setting in ('read committed','read uncommitted')) AS is_read_committed FROM pg_settings WHERE name = 'default_transaction_isolation'; }
step "prepi" { PREPARE getrow_idx AS SELECT * FROM test_dc WHERE data=34 ORDER BY id,data; } step prepi { PREPARE getrow_idx AS SELECT * FROM test_dc WHERE data=34 ORDER BY id,data; }
step "preps" { PREPARE getrow_seq AS SELECT * FROM test_dc WHERE data::text=34::text ORDER BY id,data; } step preps { PREPARE getrow_seq AS SELECT * FROM test_dc WHERE data::text=34::text ORDER BY id,data; }
step "begin" { BEGIN; } step begin { BEGIN; }
step "explaini" { EXPLAIN (COSTS OFF) EXECUTE getrow_idx; } step explaini { EXPLAIN (COSTS OFF) EXECUTE getrow_idx; }
step "explains" { EXPLAIN (COSTS OFF) EXECUTE getrow_seq; } step explains { EXPLAIN (COSTS OFF) EXECUTE getrow_seq; }
step "selecti" { EXECUTE getrow_idx; } step selecti { EXECUTE getrow_idx; }
step "selects" { EXECUTE getrow_seq; } step selects { EXECUTE getrow_seq; }
step "end" { COMMIT; } step end { COMMIT; }
session "s2" session s2
setup { BEGIN; } setup { BEGIN; }
step "select2" { SELECT * FROM test_dc WHERE data=34 ORDER BY id,data; } step select2 { SELECT * FROM test_dc WHERE data=34 ORDER BY id,data; }
step "insert2" { INSERT INTO test_dc(data) SELECT * FROM generate_series(1, 100); } step insert2 { INSERT INTO test_dc(data) SELECT * FROM generate_series(1, 100); }
step "end2" { COMMIT; } step end2 { COMMIT; }
session "s3" session s3
step "drop" { DROP INDEX CONCURRENTLY test_dc_data; } step drop { DROP INDEX CONCURRENTLY test_dc_data; }
permutation "noseq" "chkiso" "prepi" "preps" "begin" "explaini" "explains" "select2" "drop" "insert2" "end2" "selecti" "selects" "end" permutation noseq chkiso prepi preps begin explaini explains select2 drop insert2 end2 selecti selects end
...@@ -10,10 +10,10 @@ teardown ...@@ -10,10 +10,10 @@ teardown
DROP TABLE foo, bar; DROP TABLE foo, bar;
} }
session "s1" session s1
setup { BEGIN; } setup { BEGIN; }
step "ins" { INSERT INTO bar VALUES (42); } step ins { INSERT INTO bar VALUES (42); }
step "com" { COMMIT; } step com { COMMIT; }
session "s2" session s2
step "upd" { UPDATE foo SET b = 'Hello World'; } step upd { UPDATE foo SET b = 'Hello World'; }
...@@ -18,29 +18,29 @@ teardown ...@@ -18,29 +18,29 @@ teardown
DROP TABLE parent, child; DROP TABLE parent, child;
} }
session "s1" session s1
setup { BEGIN; SET deadlock_timeout = '100ms'; } setup { BEGIN; SET deadlock_timeout = '100ms'; }
step "s1i" { INSERT INTO child VALUES (1, 1); } step s1i { INSERT INTO child VALUES (1, 1); }
step "s1u" { UPDATE parent SET aux = 'bar'; } step s1u { UPDATE parent SET aux = 'bar'; }
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
setup { BEGIN; SET deadlock_timeout = '10s'; } setup { BEGIN; SET deadlock_timeout = '10s'; }
step "s2i" { INSERT INTO child VALUES (2, 1); } step s2i { INSERT INTO child VALUES (2, 1); }
step "s2u" { UPDATE parent SET aux = 'baz'; } step s2u { UPDATE parent SET aux = 'baz'; }
step "s2c" { COMMIT; } step s2c { COMMIT; }
permutation "s1i" "s1u" "s1c" "s2i" "s2u" "s2c" permutation s1i s1u s1c s2i s2u s2c
permutation "s1i" "s1u" "s2i" "s1c" "s2u" "s2c" permutation s1i s1u s2i s1c s2u s2c
permutation "s1i" "s1u" "s2i" "s2u" "s1c" "s2c" permutation s1i s1u s2i s2u s1c s2c
permutation "s1i" "s2i" "s1u" "s1c" "s2u" "s2c" permutation s1i s2i s1u s1c s2u s2c
permutation "s1i" "s2i" "s1u" "s2u" "s1c" "s2c" permutation s1i s2i s1u s2u s1c s2c
permutation "s1i" "s2i" "s2u" "s1u" "s2c" "s1c" permutation s1i s2i s2u s1u s2c s1c
permutation "s1i" "s2i" "s2u" "s2c" "s1u" "s1c" permutation s1i s2i s2u s2c s1u s1c
permutation "s2i" "s1i" "s1u" "s1c" "s2u" "s2c" permutation s2i s1i s1u s1c s2u s2c
permutation "s2i" "s1i" "s1u" "s2u" "s1c" "s2c" permutation s2i s1i s1u s2u s1c s2c
permutation "s2i" "s1i" "s2u" "s1u" "s2c" "s1c" permutation s2i s1i s2u s1u s2c s1c
permutation "s2i" "s1i" "s2u" "s2c" "s1u" "s1c" permutation s2i s1i s2u s2c s1u s1c
permutation "s2i" "s2u" "s1i" "s1u" "s2c" "s1c" permutation s2i s2u s1i s1u s2c s1c
permutation "s2i" "s2u" "s1i" "s2c" "s1u" "s1c" permutation s2i s2u s1i s2c s1u s1c
permutation "s2i" "s2u" "s2c" "s1i" "s1u" "s1c" permutation s2i s2u s2c s1i s1u s1c
...@@ -23,26 +23,26 @@ teardown ...@@ -23,26 +23,26 @@ teardown
DROP TABLE a, b; DROP TABLE a, b;
} }
session "s1" session s1
setup { BEGIN; SET deadlock_timeout = '100ms'; } setup { BEGIN; SET deadlock_timeout = '100ms'; }
step "s1u1" { UPDATE A SET Col1 = 1 WHERE AID = 1; } step s1u1 { UPDATE A SET Col1 = 1 WHERE AID = 1; }
step "s1u2" { UPDATE B SET Col2 = 1 WHERE BID = 2; } step s1u2 { UPDATE B SET Col2 = 1 WHERE BID = 2; }
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
setup { BEGIN; SET deadlock_timeout = '10s'; } setup { BEGIN; SET deadlock_timeout = '10s'; }
step "s2u1" { UPDATE B SET Col2 = 1 WHERE BID = 2; } step s2u1 { UPDATE B SET Col2 = 1 WHERE BID = 2; }
step "s2u2" { UPDATE B SET Col2 = 1 WHERE BID = 2; } step s2u2 { UPDATE B SET Col2 = 1 WHERE BID = 2; }
step "s2c" { COMMIT; } step s2c { COMMIT; }
permutation "s1u1" "s1u2" "s1c" "s2u1" "s2u2" "s2c" permutation s1u1 s1u2 s1c s2u1 s2u2 s2c
permutation "s1u1" "s1u2" "s2u1" "s1c" "s2u2" "s2c" permutation s1u1 s1u2 s2u1 s1c s2u2 s2c
permutation "s1u1" "s2u1" "s1u2" "s2u2" "s2c" "s1c" permutation s1u1 s2u1 s1u2 s2u2 s2c s1c
permutation "s1u1" "s2u1" "s2u2" "s1u2" "s2c" "s1c" permutation s1u1 s2u1 s2u2 s1u2 s2c s1c
permutation "s1u1" "s2u1" "s2u2" "s2c" "s1u2" "s1c" permutation s1u1 s2u1 s2u2 s2c s1u2 s1c
permutation "s2u1" "s1u1" "s1u2" "s2u2" "s2c" "s1c" permutation s2u1 s1u1 s1u2 s2u2 s2c s1c
permutation "s2u1" "s1u1" "s2u2" "s1u2" "s2c" "s1c" permutation s2u1 s1u1 s2u2 s1u2 s2c s1c
permutation "s2u1" "s1u1" "s2u2" "s2c" "s1u2" "s1c" permutation s2u1 s1u1 s2u2 s2c s1u2 s1c
permutation "s2u1" "s2u2" "s1u1" "s1u2" "s2c" "s1c" permutation s2u1 s2u2 s1u1 s1u2 s2c s1c
permutation "s2u1" "s2u2" "s1u1" "s2c" "s1u2" "s1c" permutation s2u1 s2u2 s1u1 s2c s1u2 s1c
permutation "s2u1" "s2u2" "s2c" "s1u1" "s1u2" "s1c" permutation s2u1 s2u2 s2c s1u1 s1u2 s1c
...@@ -11,35 +11,35 @@ drop table if exists ppk, pfk, pfk1; ...@@ -11,35 +11,35 @@ drop table if exists ppk, pfk, pfk1;
insert into pfk1 values (1); insert into pfk1 values (1);
} }
session "s1" session s1
step "s1b" { begin; } step s1b { begin; }
step "s1d" { delete from ppk1 where a = 1; } step s1d { delete from ppk1 where a = 1; }
step "s1c" { commit; } step s1c { commit; }
session "s2" session s2
step "s2b" { begin; } step s2b { begin; }
step "s2a" { alter table pfk attach partition pfk1 for values in (1); } step s2a { alter table pfk attach partition pfk1 for values in (1); }
step "s2c" { commit; } step s2c { commit; }
teardown { drop table ppk, pfk, pfk1; } teardown { drop table ppk, pfk, pfk1; }
permutation "s1b" "s1d" "s1c" "s2b" "s2a" "s2c" permutation s1b s1d s1c s2b s2a s2c
permutation "s1b" "s1d" "s2b" "s1c" "s2a" "s2c" permutation s1b s1d s2b s1c s2a s2c
permutation "s1b" "s1d" "s2b" "s2a" "s1c" "s2c" permutation s1b s1d s2b s2a s1c s2c
#permutation "s1b" "s1d" "s2b" "s2a" "s2c" "s1c" #permutation s1b s1d s2b s2a s2c s1c
permutation "s1b" "s2b" "s1d" "s1c" "s2a" "s2c" permutation s1b s2b s1d s1c s2a s2c
permutation "s1b" "s2b" "s1d" "s2a" "s1c" "s2c" permutation s1b s2b s1d s2a s1c s2c
#permutation "s1b" "s2b" "s1d" "s2a" "s2c" "s1c" #permutation s1b s2b s1d s2a s2c s1c
#permutation "s1b" "s2b" "s2a" "s1d" "s1c" "s2c" #permutation s1b s2b s2a s1d s1c s2c
permutation "s1b" "s2b" "s2a" "s1d" "s2c" "s1c" permutation s1b s2b s2a s1d s2c s1c
permutation "s1b" "s2b" "s2a" "s2c" "s1d" "s1c" permutation s1b s2b s2a s2c s1d s1c
permutation "s2b" "s1b" "s1d" "s1c" "s2a" "s2c" permutation s2b s1b s1d s1c s2a s2c
permutation "s2b" "s1b" "s1d" "s2a" "s1c" "s2c" permutation s2b s1b s1d s2a s1c s2c
#permutation "s2b" "s1b" "s1d" "s2a" "s2c" "s1c" #permutation s2b s1b s1d s2a s2c s1c
#permutation "s2b" "s1b" "s2a" "s1d" "s1c" "s2c" #permutation s2b s1b s2a s1d s1c s2c
permutation "s2b" "s1b" "s2a" "s1d" "s2c" "s1c" permutation s2b s1b s2a s1d s2c s1c
permutation "s2b" "s1b" "s2a" "s2c" "s1d" "s1c" permutation s2b s1b s2a s2c s1d s1c
#permutation "s2b" "s2a" "s1b" "s1d" "s1c" "s2c" #permutation s2b s2a s1b s1d s1c s2c
permutation "s2b" "s2a" "s1b" "s1d" "s2c" "s1c" permutation s2b s2a s1b s1d s2c s1c
permutation "s2b" "s2a" "s1b" "s2c" "s1d" "s1c" permutation s2b s2a s1b s2c s1d s1c
permutation "s2b" "s2a" "s2c" "s1b" "s1d" "s1c" permutation s2b s2a s2c s1b s1d s1c
...@@ -8,22 +8,22 @@ setup { ...@@ -8,22 +8,22 @@ setup {
create table pfk1 partition of pfk for values in (1); create table pfk1 partition of pfk for values in (1);
} }
session "s1" session s1
step "s1b" { begin; } step s1b { begin; }
step "s1d" { delete from ppk where a = 1; } step s1d { delete from ppk where a = 1; }
step "s1c" { commit; } step s1c { commit; }
session "s2" session s2
step "s2b" { begin; } step s2b { begin; }
step "s2bs" { begin isolation level serializable; select 1; } step s2bs { begin isolation level serializable; select 1; }
step "s2i" { insert into pfk values (1); } step s2i { insert into pfk values (1); }
step "s2c" { commit; } step s2c { commit; }
teardown { drop table ppk, pfk, pfk1; } teardown { drop table ppk, pfk, pfk1; }
permutation "s1b" "s1d" "s2b" "s2i" "s1c" "s2c" permutation s1b s1d s2b s2i s1c s2c
permutation "s1b" "s1d" "s2bs" "s2i" "s1c" "s2c" permutation s1b s1d s2bs s2i s1c s2c
permutation "s1b" "s2b" "s1d" "s2i" "s1c" "s2c" permutation s1b s2b s1d s2i s1c s2c
permutation "s1b" "s2bs" "s1d" "s2i" "s1c" "s2c" permutation s1b s2bs s1d s2i s1c s2c
permutation "s1b" "s2b" "s2i" "s1d" "s2c" "s1c" permutation s1b s2b s2i s1d s2c s1c
permutation "s1b" "s2bs" "s2i" "s1d" "s2c" "s1c" permutation s1b s2bs s2i s1d s2c s1c
...@@ -15,29 +15,29 @@ teardown ...@@ -15,29 +15,29 @@ teardown
DROP TABLE tab_freeze; DROP TABLE tab_freeze;
} }
session "s1" session s1
step "s1_begin" { BEGIN; } step s1_begin { BEGIN; }
step "s1_update" { UPDATE tab_freeze SET x = x + 1 WHERE id = 3; } step s1_update { UPDATE tab_freeze SET x = x + 1 WHERE id = 3; }
step "s1_commit" { COMMIT; } step s1_commit { COMMIT; }
step "s1_selectone" { step s1_selectone {
BEGIN; BEGIN;
SET LOCAL enable_seqscan = false; SET LOCAL enable_seqscan = false;
SET LOCAL enable_bitmapscan = false; SET LOCAL enable_bitmapscan = false;
SELECT * FROM tab_freeze WHERE id = 3; SELECT * FROM tab_freeze WHERE id = 3;
COMMIT; COMMIT;
} }
step "s1_selectall" { SELECT * FROM tab_freeze ORDER BY name, id; } step s1_selectall { SELECT * FROM tab_freeze ORDER BY name, id; }
session "s2" session s2
step "s2_begin" { BEGIN; } step s2_begin { BEGIN; }
step "s2_key_share" { SELECT id FROM tab_freeze WHERE id = 3 FOR KEY SHARE; } step s2_key_share { SELECT id FROM tab_freeze WHERE id = 3 FOR KEY SHARE; }
step "s2_commit" { COMMIT; } step s2_commit { COMMIT; }
step "s2_vacuum" { VACUUM FREEZE tab_freeze; } step s2_vacuum { VACUUM FREEZE tab_freeze; }
session "s3" session s3
step "s3_begin" { BEGIN; } step s3_begin { BEGIN; }
step "s3_key_share" { SELECT id FROM tab_freeze WHERE id = 3 FOR KEY SHARE; } step s3_key_share { SELECT id FROM tab_freeze WHERE id = 3 FOR KEY SHARE; }
step "s3_commit" { COMMIT; } step s3_commit { COMMIT; }
# This permutation verifies that a previous bug # This permutation verifies that a previous bug
# https://postgr.es/m/E5711E62-8FDF-4DCA-A888-C200BF6B5742@amazon.com # https://postgr.es/m/E5711E62-8FDF-4DCA-A888-C200BF6B5742@amazon.com
...@@ -45,12 +45,12 @@ step "s3_commit" { COMMIT; } ...@@ -45,12 +45,12 @@ step "s3_commit" { COMMIT; }
# is not reintroduced. We used to make wrong pruning / freezing # is not reintroduced. We used to make wrong pruning / freezing
# decision for multixacts, which could lead to a) broken hot chains b) # decision for multixacts, which could lead to a) broken hot chains b)
# dead rows being revived. # dead rows being revived.
permutation "s1_begin" "s2_begin" "s3_begin" # start transactions permutation s1_begin s2_begin s3_begin # start transactions
"s1_update" "s2_key_share" "s3_key_share" # have xmax be a multi with an updater, updater being oldest xid s1_update s2_key_share s3_key_share # have xmax be a multi with an updater, updater being oldest xid
"s1_update" # create additional row version that has multis s1_update # create additional row version that has multis
"s1_commit" "s2_commit" # commit both updater and share locker s1_commit s2_commit # commit both updater and share locker
"s2_vacuum" # due to bug in freezing logic, we used to *not* prune updated row, and then froze it s2_vacuum # due to bug in freezing logic, we used to *not* prune updated row, and then froze it
"s1_selectone" # if hot chain is broken, the row can't be found via index scan s1_selectone # if hot chain is broken, the row can't be found via index scan
"s3_commit" # commit remaining open xact s3_commit # commit remaining open xact
"s2_vacuum" # pruning / freezing in broken hot chains would unset xmax, reviving rows s2_vacuum # pruning / freezing in broken hot chains would unset xmax, reviving rows
"s1_selectall" # show borkedness s1_selectall # show borkedness
...@@ -23,19 +23,19 @@ teardown { ...@@ -23,19 +23,19 @@ teardown {
DROP FUNCTION explain_json(text); DROP FUNCTION explain_json(text);
} }
session "lifeline" session lifeline
# Start a transaction, force a snapshot to be held # Start a transaction, force a snapshot to be held
step "ll_start" step ll_start
{ {
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT 1; SELECT 1;
} }
step "ll_commit" { COMMIT; } step ll_commit { COMMIT; }
session "pruner" session pruner
setup setup
{ {
...@@ -44,13 +44,13 @@ setup ...@@ -44,13 +44,13 @@ setup
SET enable_bitmapscan = false; SET enable_bitmapscan = false;
} }
step "pruner_create_temp" step pruner_create_temp
{ {
CREATE TEMPORARY TABLE horizons_tst (data int unique) WITH (autovacuum_enabled = off); CREATE TEMPORARY TABLE horizons_tst (data int unique) WITH (autovacuum_enabled = off);
INSERT INTO horizons_tst(data) VALUES(1),(2); INSERT INTO horizons_tst(data) VALUES(1),(2);
} }
step "pruner_create_perm" step pruner_create_perm
{ {
CREATE TABLE horizons_tst (data int unique) WITH (autovacuum_enabled = off); CREATE TABLE horizons_tst (data int unique) WITH (autovacuum_enabled = off);
INSERT INTO horizons_tst(data) VALUES(1),(2); INSERT INTO horizons_tst(data) VALUES(1),(2);
...@@ -58,20 +58,20 @@ step "pruner_create_perm" ...@@ -58,20 +58,20 @@ step "pruner_create_perm"
# Temp tables cannot be dropped in the teardown, so just always do so # Temp tables cannot be dropped in the teardown, so just always do so
# as part of the permutation # as part of the permutation
step "pruner_drop" step pruner_drop
{ {
DROP TABLE horizons_tst; DROP TABLE horizons_tst;
} }
step "pruner_delete" step pruner_delete
{ {
DELETE FROM horizons_tst; DELETE FROM horizons_tst;
} }
step "pruner_begin" { BEGIN; } step pruner_begin { BEGIN; }
step "pruner_commit" { COMMIT; } step pruner_commit { COMMIT; }
step "pruner_vacuum" step pruner_vacuum
{ {
VACUUM horizons_tst; VACUUM horizons_tst;
} }
...@@ -79,7 +79,7 @@ step "pruner_vacuum" ...@@ -79,7 +79,7 @@ step "pruner_vacuum"
# Show the heap fetches of an ordered index-only-scan (other plans # Show the heap fetches of an ordered index-only-scan (other plans
# have been forbidden above) - that tells us how many non-killed leaf # have been forbidden above) - that tells us how many non-killed leaf
# entries there are. # entries there are.
step "pruner_query" step pruner_query
{ {
SELECT explain_json($$ SELECT explain_json($$
EXPLAIN (FORMAT json, BUFFERS, ANALYZE) EXPLAIN (FORMAT json, BUFFERS, ANALYZE)
...@@ -87,7 +87,7 @@ step "pruner_query" ...@@ -87,7 +87,7 @@ step "pruner_query"
} }
# Verify that the query plan still is an IOS # Verify that the query plan still is an IOS
step "pruner_query_plan" step pruner_query_plan
{ {
EXPLAIN (COSTS OFF) SELECT * FROM horizons_tst ORDER BY data; EXPLAIN (COSTS OFF) SELECT * FROM horizons_tst ORDER BY data;
} }
...@@ -96,74 +96,74 @@ step "pruner_query_plan" ...@@ -96,74 +96,74 @@ step "pruner_query_plan"
# Show that with a permanent relation deleted rows cannot be pruned # Show that with a permanent relation deleted rows cannot be pruned
# away if there's a concurrent session still seeing the rows. # away if there's a concurrent session still seeing the rows.
permutation permutation
"pruner_create_perm" pruner_create_perm
"ll_start" ll_start
"pruner_query_plan" pruner_query_plan
# Run query that could do pruning twice, first has chance to prune, # Run query that could do pruning twice, first has chance to prune,
# second would not perform heap fetches if first query did. # second would not perform heap fetches if first query did.
"pruner_query" pruner_query
"pruner_query" pruner_query
"pruner_delete" pruner_delete
"pruner_query" pruner_query
"pruner_query" pruner_query
"ll_commit" ll_commit
"pruner_drop" pruner_drop
# Show that with a temporary relation deleted rows can be pruned away, # Show that with a temporary relation deleted rows can be pruned away,
# even if there's a concurrent session with a snapshot from before the # even if there's a concurrent session with a snapshot from before the
# deletion. That's safe because the session with the older snapshot # deletion. That's safe because the session with the older snapshot
# cannot access the temporary table. # cannot access the temporary table.
permutation permutation
"pruner_create_temp" pruner_create_temp
"ll_start" ll_start
"pruner_query_plan" pruner_query_plan
"pruner_query" pruner_query
"pruner_query" pruner_query
"pruner_delete" pruner_delete
"pruner_query" pruner_query
"pruner_query" pruner_query
"ll_commit" ll_commit
"pruner_drop" pruner_drop
# Verify that pruning in temporary relations doesn't remove rows still # Verify that pruning in temporary relations doesn't remove rows still
# visible in the current session # visible in the current session
permutation permutation
"pruner_create_temp" pruner_create_temp
"ll_start" ll_start
"pruner_query" pruner_query
"pruner_query" pruner_query
"pruner_begin" pruner_begin
"pruner_delete" pruner_delete
"pruner_query" pruner_query
"pruner_query" pruner_query
"ll_commit" ll_commit
"pruner_commit" pruner_commit
"pruner_drop" pruner_drop
# Show that vacuum cannot remove deleted rows still visible to another # Show that vacuum cannot remove deleted rows still visible to another
# session's snapshot, when accessing a permanent table. # session's snapshot, when accessing a permanent table.
permutation permutation
"pruner_create_perm" pruner_create_perm
"ll_start" ll_start
"pruner_query" pruner_query
"pruner_query" pruner_query
"pruner_delete" pruner_delete
"pruner_vacuum" pruner_vacuum
"pruner_query" pruner_query
"pruner_query" pruner_query
"ll_commit" ll_commit
"pruner_drop" pruner_drop
# Show that vacuum can remove deleted rows still visible to another # Show that vacuum can remove deleted rows still visible to another
# session's snapshot, when accessing a temporary table. # session's snapshot, when accessing a temporary table.
permutation permutation
"pruner_create_temp" pruner_create_temp
"ll_start" ll_start
"pruner_query" pruner_query
"pruner_query" pruner_query
"pruner_delete" pruner_delete
"pruner_vacuum" pruner_vacuum
"pruner_query" pruner_query
"pruner_query" pruner_query
"ll_commit" ll_commit
"pruner_drop" pruner_drop
...@@ -23,7 +23,7 @@ teardown ...@@ -23,7 +23,7 @@ teardown
DROP TABLE taby; DROP TABLE taby;
} }
session "s1" session s1
setup setup
{ {
BEGIN ISOLATION LEVEL SERIALIZABLE; BEGIN ISOLATION LEVEL SERIALIZABLE;
...@@ -31,10 +31,10 @@ setup ...@@ -31,10 +31,10 @@ setup
SET LOCAL random_page_cost = 0.1; SET LOCAL random_page_cost = 0.1;
SET LOCAL cpu_tuple_cost = 0.03; SET LOCAL cpu_tuple_cost = 0.03;
} }
step "rxwy1" { DELETE FROM taby WHERE id = (SELECT min(id) FROM tabx); } step rxwy1 { DELETE FROM taby WHERE id = (SELECT min(id) FROM tabx); }
step "c1" { COMMIT; } step c1 { COMMIT; }
session "s2" session s2
setup setup
{ {
BEGIN ISOLATION LEVEL SERIALIZABLE; BEGIN ISOLATION LEVEL SERIALIZABLE;
...@@ -42,5 +42,5 @@ setup ...@@ -42,5 +42,5 @@ setup
SET LOCAL random_page_cost = 0.1; SET LOCAL random_page_cost = 0.1;
SET LOCAL cpu_tuple_cost = 0.03; SET LOCAL cpu_tuple_cost = 0.03;
} }
step "rywx2" { DELETE FROM tabx WHERE id = (SELECT min(id) FROM taby); } step rywx2 { DELETE FROM tabx WHERE id = (SELECT min(id) FROM taby); }
step "c2" { COMMIT; } step c2 { COMMIT; }
...@@ -19,60 +19,60 @@ teardown ...@@ -19,60 +19,60 @@ teardown
# Session 1 executes actions which act directly on both the parent and # Session 1 executes actions which act directly on both the parent and
# its child. Abbreviation "c" is used for queries working on the child # its child. Abbreviation "c" is used for queries working on the child
# and "p" on the parent. # and "p" on the parent.
session "s1" session s1
setup setup
{ {
CREATE TEMPORARY TABLE inh_temp_child_s1 () INHERITS (inh_parent); CREATE TEMPORARY TABLE inh_temp_child_s1 () INHERITS (inh_parent);
} }
step "s1_begin" { BEGIN; } step s1_begin { BEGIN; }
step "s1_truncate_p" { TRUNCATE inh_parent; } step s1_truncate_p { TRUNCATE inh_parent; }
step "s1_select_p" { SELECT a FROM inh_parent; } step s1_select_p { SELECT a FROM inh_parent; }
step "s1_select_c" { SELECT a FROM inh_temp_child_s1; } step s1_select_c { SELECT a FROM inh_temp_child_s1; }
step "s1_insert_p" { INSERT INTO inh_parent VALUES (1), (2); } step s1_insert_p { INSERT INTO inh_parent VALUES (1), (2); }
step "s1_insert_c" { INSERT INTO inh_temp_child_s1 VALUES (3), (4); } step s1_insert_c { INSERT INTO inh_temp_child_s1 VALUES (3), (4); }
step "s1_update_p" { UPDATE inh_parent SET a = 11 WHERE a = 1; } step s1_update_p { UPDATE inh_parent SET a = 11 WHERE a = 1; }
step "s1_update_c" { UPDATE inh_parent SET a = 13 WHERE a IN (3, 5); } step s1_update_c { UPDATE inh_parent SET a = 13 WHERE a IN (3, 5); }
step "s1_delete_p" { DELETE FROM inh_parent WHERE a = 2; } step s1_delete_p { DELETE FROM inh_parent WHERE a = 2; }
step "s1_delete_c" { DELETE FROM inh_parent WHERE a IN (4, 6); } step s1_delete_c { DELETE FROM inh_parent WHERE a IN (4, 6); }
step "s1_commit" { COMMIT; } step s1_commit { COMMIT; }
teardown teardown
{ {
DROP TABLE inh_temp_child_s1; DROP TABLE inh_temp_child_s1;
} }
# Session 2 executes actions on the parent which act only on the child. # Session 2 executes actions on the parent which act only on the child.
session "s2" session s2
setup setup
{ {
CREATE TEMPORARY TABLE inh_temp_child_s2 () INHERITS (inh_parent); CREATE TEMPORARY TABLE inh_temp_child_s2 () INHERITS (inh_parent);
} }
step "s2_truncate_p" { TRUNCATE inh_parent; } step s2_truncate_p { TRUNCATE inh_parent; }
step "s2_select_p" { SELECT a FROM inh_parent; } step s2_select_p { SELECT a FROM inh_parent; }
step "s2_select_c" { SELECT a FROM inh_temp_child_s2; } step s2_select_c { SELECT a FROM inh_temp_child_s2; }
step "s2_insert_c" { INSERT INTO inh_temp_child_s2 VALUES (5), (6); } step s2_insert_c { INSERT INTO inh_temp_child_s2 VALUES (5), (6); }
step "s2_update_c" { UPDATE inh_parent SET a = 15 WHERE a IN (3, 5); } step s2_update_c { UPDATE inh_parent SET a = 15 WHERE a IN (3, 5); }
step "s2_delete_c" { DELETE FROM inh_parent WHERE a IN (4, 6); } step s2_delete_c { DELETE FROM inh_parent WHERE a IN (4, 6); }
teardown teardown
{ {
DROP TABLE inh_temp_child_s2; DROP TABLE inh_temp_child_s2;
} }
# Check INSERT behavior across sessions # Check INSERT behavior across sessions
permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s1_select_p" "s1_select_c" "s2_select_p" "s2_select_c" permutation s1_insert_p s1_insert_c s2_insert_c s1_select_p s1_select_c s2_select_p s2_select_c
# Check UPDATE behavior across sessions # Check UPDATE behavior across sessions
permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s1_update_p" "s1_update_c" "s1_select_p" "s1_select_c" "s2_select_p" "s2_select_c" permutation s1_insert_p s1_insert_c s2_insert_c s1_update_p s1_update_c s1_select_p s1_select_c s2_select_p s2_select_c
permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s2_update_c" "s1_select_p" "s1_select_c" "s2_select_p" "s2_select_c" permutation s1_insert_p s1_insert_c s2_insert_c s2_update_c s1_select_p s1_select_c s2_select_p s2_select_c
# Check DELETE behavior across sessions # Check DELETE behavior across sessions
permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s1_delete_p" "s1_delete_c" "s1_select_p" "s1_select_c" "s2_select_p" "s2_select_c" permutation s1_insert_p s1_insert_c s2_insert_c s1_delete_p s1_delete_c s1_select_p s1_select_c s2_select_p s2_select_c
permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s2_delete_c" "s1_select_p" "s1_select_c" "s2_select_p" "s2_select_c" permutation s1_insert_p s1_insert_c s2_insert_c s2_delete_c s1_select_p s1_select_c s2_select_p s2_select_c
# Check TRUNCATE behavior across sessions # Check TRUNCATE behavior across sessions
permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s1_truncate_p" "s1_select_p" "s1_select_c" "s2_select_p" "s2_select_c" permutation s1_insert_p s1_insert_c s2_insert_c s1_truncate_p s1_select_p s1_select_c s2_select_p s2_select_c
permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s2_truncate_p" "s1_select_p" "s1_select_c" "s2_select_p" "s2_select_c" permutation s1_insert_p s1_insert_c s2_insert_c s2_truncate_p s1_select_p s1_select_c s2_select_p s2_select_c
# TRUNCATE on a parent tree does not block access to temporary child relation # TRUNCATE on a parent tree does not block access to temporary child relation
# of another session, and blocks when scanning the parent. # of another session, and blocks when scanning the parent.
permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s1_begin" "s1_truncate_p" "s2_select_p" "s1_commit" permutation s1_insert_p s1_insert_c s2_insert_c s1_begin s1_truncate_p s2_select_p s1_commit
permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s1_begin" "s1_truncate_p" "s2_select_c" "s1_commit" permutation s1_insert_p s1_insert_c s2_insert_c s1_begin s1_truncate_p s2_select_c s1_commit
...@@ -11,24 +11,24 @@ teardown ...@@ -11,24 +11,24 @@ teardown
DROP TABLE ints; DROP TABLE ints;
} }
session "s1" session s1
step "beginrr1" { BEGIN ISOLATION LEVEL REPEATABLE READ; } step beginrr1 { BEGIN ISOLATION LEVEL REPEATABLE READ; }
step "begins1" { BEGIN ISOLATION LEVEL SERIALIZABLE; } step begins1 { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "donothing1" { INSERT INTO ints(key, val) VALUES(1, 'donothing1') ON CONFLICT DO NOTHING; } step donothing1 { INSERT INTO ints(key, val) VALUES(1, 'donothing1') ON CONFLICT DO NOTHING; }
step "c1" { COMMIT; } step c1 { COMMIT; }
step "show" { SELECT * FROM ints; } step show { SELECT * FROM ints; }
session "s2" session s2
step "beginrr2" { BEGIN ISOLATION LEVEL REPEATABLE READ; } step beginrr2 { BEGIN ISOLATION LEVEL REPEATABLE READ; }
step "begins2" { BEGIN ISOLATION LEVEL SERIALIZABLE; } step begins2 { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "donothing2" { INSERT INTO ints(key, val) VALUES(1, 'donothing2'), (1, 'donothing3') ON CONFLICT DO NOTHING; } step donothing2 { INSERT INTO ints(key, val) VALUES(1, 'donothing2'), (1, 'donothing3') ON CONFLICT DO NOTHING; }
step "c2" { COMMIT; } step c2 { COMMIT; }
permutation "beginrr1" "beginrr2" "donothing1" "c1" "donothing2" "c2" "show" permutation beginrr1 beginrr2 donothing1 c1 donothing2 c2 show
permutation "beginrr1" "beginrr2" "donothing2" "c2" "donothing1" "c1" "show" permutation beginrr1 beginrr2 donothing2 c2 donothing1 c1 show
permutation "beginrr1" "beginrr2" "donothing1" "donothing2" "c1" "c2" "show" permutation beginrr1 beginrr2 donothing1 donothing2 c1 c2 show
permutation "beginrr1" "beginrr2" "donothing2" "donothing1" "c2" "c1" "show" permutation beginrr1 beginrr2 donothing2 donothing1 c2 c1 show
permutation "begins1" "begins2" "donothing1" "c1" "donothing2" "c2" "show" permutation begins1 begins2 donothing1 c1 donothing2 c2 show
permutation "begins1" "begins2" "donothing2" "c2" "donothing1" "c1" "show" permutation begins1 begins2 donothing2 c2 donothing1 c1 show
permutation "begins1" "begins2" "donothing1" "donothing2" "c1" "c2" "show" permutation begins1 begins2 donothing1 donothing2 c1 c2 show
permutation "begins1" "begins2" "donothing2" "donothing1" "c2" "c1" "show" permutation begins1 begins2 donothing2 donothing1 c2 c1 show
...@@ -16,25 +16,25 @@ teardown ...@@ -16,25 +16,25 @@ teardown
DROP TABLE ints; DROP TABLE ints;
} }
session "s1" session s1
setup setup
{ {
BEGIN ISOLATION LEVEL READ COMMITTED; BEGIN ISOLATION LEVEL READ COMMITTED;
} }
step "donothing1" { INSERT INTO ints(key, val) VALUES(1, 'donothing1') ON CONFLICT DO NOTHING; } step donothing1 { INSERT INTO ints(key, val) VALUES(1, 'donothing1') ON CONFLICT DO NOTHING; }
step "c1" { COMMIT; } step c1 { COMMIT; }
step "a1" { ABORT; } step a1 { ABORT; }
session "s2" session s2
setup setup
{ {
BEGIN ISOLATION LEVEL READ COMMITTED; BEGIN ISOLATION LEVEL READ COMMITTED;
} }
step "donothing2" { INSERT INTO ints(key, val) VALUES(1, 'donothing2') ON CONFLICT DO NOTHING; } step donothing2 { INSERT INTO ints(key, val) VALUES(1, 'donothing2') ON CONFLICT DO NOTHING; }
step "select2" { SELECT * FROM ints; } step select2 { SELECT * FROM ints; }
step "c2" { COMMIT; } step c2 { COMMIT; }
# Regular case where one session block-waits on another to determine if it # Regular case where one session block-waits on another to determine if it
# should proceed with an insert or do nothing. # should proceed with an insert or do nothing.
permutation "donothing1" "donothing2" "c1" "select2" "c2" permutation donothing1 donothing2 c1 select2 c2
permutation "donothing1" "donothing2" "a1" "select2" "c2" permutation donothing1 donothing2 a1 select2 c2
...@@ -15,26 +15,26 @@ teardown ...@@ -15,26 +15,26 @@ teardown
DROP TABLE upsert; DROP TABLE upsert;
} }
session "s1" session s1
setup setup
{ {
BEGIN ISOLATION LEVEL READ COMMITTED; BEGIN ISOLATION LEVEL READ COMMITTED;
} }
step "insert1" { INSERT INTO upsert(key, payload) VALUES('FooFoo', 'insert1') ON CONFLICT (lower(key)) DO UPDATE set key = EXCLUDED.key, payload = upsert.payload || ' updated by insert1'; } step insert1 { INSERT INTO upsert(key, payload) VALUES('FooFoo', 'insert1') ON CONFLICT (lower(key)) DO UPDATE set key = EXCLUDED.key, payload = upsert.payload || ' updated by insert1'; }
step "c1" { COMMIT; } step c1 { COMMIT; }
step "a1" { ABORT; } step a1 { ABORT; }
session "s2" session s2
setup setup
{ {
BEGIN ISOLATION LEVEL READ COMMITTED; BEGIN ISOLATION LEVEL READ COMMITTED;
} }
step "insert2" { INSERT INTO upsert(key, payload) VALUES('FOOFOO', 'insert2') ON CONFLICT (lower(key)) DO UPDATE set key = EXCLUDED.key, payload = upsert.payload || ' updated by insert2'; } step insert2 { INSERT INTO upsert(key, payload) VALUES('FOOFOO', 'insert2') ON CONFLICT (lower(key)) DO UPDATE set key = EXCLUDED.key, payload = upsert.payload || ' updated by insert2'; }
step "select2" { SELECT * FROM upsert; } step select2 { SELECT * FROM upsert; }
step "c2" { COMMIT; } step c2 { COMMIT; }
# One session (session 2) block-waits on another (session 1) to determine if it # One session (session 2) block-waits on another (session 1) to determine if it
# should proceed with an insert or update. The user can still usefully UPDATE # should proceed with an insert or update. The user can still usefully UPDATE
# a column constrained by a unique index, as the example illustrates. # a column constrained by a unique index, as the example illustrates.
permutation "insert1" "insert2" "c1" "select2" "c2" permutation insert1 insert2 c1 select2 c2
permutation "insert1" "insert2" "a1" "select2" "c2" permutation insert1 insert2 a1 select2 c2
...@@ -37,12 +37,12 @@ teardown ...@@ -37,12 +37,12 @@ teardown
DROP TABLE colors; DROP TABLE colors;
} }
session "s1" session s1
setup setup
{ {
BEGIN ISOLATION LEVEL READ COMMITTED; BEGIN ISOLATION LEVEL READ COMMITTED;
} }
step "insert1" { step insert1 {
WITH t AS ( WITH t AS (
INSERT INTO colors(key, color, is_active) INSERT INTO colors(key, color, is_active)
VALUES(1, 'Brown', true), (2, 'Gray', true) VALUES(1, 'Brown', true), (2, 'Gray', true)
...@@ -50,20 +50,20 @@ step "insert1" { ...@@ -50,20 +50,20 @@ step "insert1" {
SET color = EXCLUDED.color SET color = EXCLUDED.color
WHERE colors.is_active) WHERE colors.is_active)
SELECT * FROM colors ORDER BY key;} SELECT * FROM colors ORDER BY key;}
step "select1surprise" { SELECT * FROM colors ORDER BY key; } step select1surprise { SELECT * FROM colors ORDER BY key; }
step "c1" { COMMIT; } step c1 { COMMIT; }
session "s2" session s2
setup setup
{ {
BEGIN ISOLATION LEVEL READ COMMITTED; BEGIN ISOLATION LEVEL READ COMMITTED;
} }
step "update2" { UPDATE colors SET is_active = true WHERE key = 1; } step update2 { UPDATE colors SET is_active = true WHERE key = 1; }
step "c2" { COMMIT; } step c2 { COMMIT; }
# Perhaps surprisingly, the session 1 MVCC-snapshot-visible tuple (the tuple # Perhaps surprisingly, the session 1 MVCC-snapshot-visible tuple (the tuple
# with the pre-populated color 'Red') is denied the opportunity to prevent the # with the pre-populated color 'Red') is denied the opportunity to prevent the
# UPDATE from taking place -- only the conclusively-locked tuple version # UPDATE from taking place -- only the conclusively-locked tuple version
# matters, and so the tuple with key value 1 was updated to 'Brown' (but not # matters, and so the tuple with key value 1 was updated to 'Brown' (but not
# tuple with key value 2, since nothing changed there): # tuple with key value 2, since nothing changed there):
permutation "update2" "insert1" "c2" "select1surprise" "c1" permutation update2 insert1 c2 select1surprise c1
...@@ -13,27 +13,27 @@ teardown ...@@ -13,27 +13,27 @@ teardown
DROP TABLE upsert; DROP TABLE upsert;
} }
session "s1" session s1
setup setup
{ {
BEGIN ISOLATION LEVEL READ COMMITTED; BEGIN ISOLATION LEVEL READ COMMITTED;
} }
step "insert1" { INSERT INTO upsert(key, val) VALUES(1, 'insert1') ON CONFLICT (key) DO UPDATE set val = upsert.val || ' updated by insert1'; } step insert1 { INSERT INTO upsert(key, val) VALUES(1, 'insert1') ON CONFLICT (key) DO UPDATE set val = upsert.val || ' updated by insert1'; }
step "c1" { COMMIT; } step c1 { COMMIT; }
step "a1" { ABORT; } step a1 { ABORT; }
session "s2" session s2
setup setup
{ {
BEGIN ISOLATION LEVEL READ COMMITTED; BEGIN ISOLATION LEVEL READ COMMITTED;
} }
step "insert2" { INSERT INTO upsert(key, val) VALUES(1, 'insert2') ON CONFLICT (key) DO UPDATE set val = upsert.val || ' updated by insert2'; } step insert2 { INSERT INTO upsert(key, val) VALUES(1, 'insert2') ON CONFLICT (key) DO UPDATE set val = upsert.val || ' updated by insert2'; }
step "select2" { SELECT * FROM upsert; } step select2 { SELECT * FROM upsert; }
step "c2" { COMMIT; } step c2 { COMMIT; }
# One session (session 2) block-waits on another (session 1) to determine if it # One session (session 2) block-waits on another (session 1) to determine if it
# should proceed with an insert or update. Notably, this entails updating a # should proceed with an insert or update. Notably, this entails updating a
# tuple while there is no version of that tuple visible to the updating # tuple while there is no version of that tuple visible to the updating
# session's snapshot. This is permitted only in READ COMMITTED mode. # session's snapshot. This is permitted only in READ COMMITTED mode.
permutation "insert1" "insert2" "c1" "select2" "c2" permutation insert1 insert2 c1 select2 c2
permutation "insert1" "insert2" "a1" "select2" "c2" permutation insert1 insert2 a1 select2 c2
...@@ -18,49 +18,49 @@ teardown ...@@ -18,49 +18,49 @@ teardown
DROP TABLE lcku_table; DROP TABLE lcku_table;
} }
session "s1" session s1
step "s1b" { BEGIN; } step s1b { BEGIN; }
step "s1l" { SELECT pg_advisory_lock(578902068); } step s1l { SELECT pg_advisory_lock(578902068); }
step "s1u" { UPDATE lcku_table SET id = 2 WHERE id = 3; } step s1u { UPDATE lcku_table SET id = 2 WHERE id = 3; }
step "s1hint" { SELECT * FROM lcku_table; } step s1hint { SELECT * FROM lcku_table; }
step "s1ul" { SELECT pg_advisory_unlock(578902068); } step s1ul { SELECT pg_advisory_unlock(578902068); }
step "s1c" { COMMIT; } step s1c { COMMIT; }
teardown { SELECT pg_advisory_unlock_all(); } teardown { SELECT pg_advisory_unlock_all(); }
session "s2" session s2
step "s2b1" { BEGIN ISOLATION LEVEL READ COMMITTED; } step s2b1 { BEGIN ISOLATION LEVEL READ COMMITTED; }
step "s2b2" { BEGIN ISOLATION LEVEL REPEATABLE READ; } step s2b2 { BEGIN ISOLATION LEVEL REPEATABLE READ; }
step "s2b3" { BEGIN ISOLATION LEVEL SERIALIZABLE; } step s2b3 { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "s2l" { SELECT * FROM lcku_table WHERE pg_advisory_lock(578902068) IS NOT NULL FOR KEY SHARE; } step s2l { SELECT * FROM lcku_table WHERE pg_advisory_lock(578902068) IS NOT NULL FOR KEY SHARE; }
step "s2c" { COMMIT; } step s2c { COMMIT; }
teardown { SELECT pg_advisory_unlock_all(); } teardown { SELECT pg_advisory_unlock_all(); }
permutation "s1b" "s2b1" "s1l" "s2l" "s1u" "s1c" "s1ul" "s2c" permutation s1b s2b1 s1l s2l s1u s1c s1ul s2c
permutation "s1b" "s2b1" "s1l" "s1u" "s2l" "s1c" "s1ul" "s2c" permutation s1b s2b1 s1l s1u s2l s1c s1ul s2c
#permutation "s1b" "s2b1" "s1l" "s2l" "s1ul" "s1u" "s1c" "s2c" #permutation s1b s2b1 s1l s2l s1ul s1u s1c s2c
permutation "s1b" "s2b1" "s1l" "s1u" "s1ul" "s2l" "s1c" "s2c" permutation s1b s2b1 s1l s1u s1ul s2l s1c s2c
permutation "s1b" "s2b1" "s1l" "s2l" "s1u" "s1c" "s1hint" "s1ul" "s2c" permutation s1b s2b1 s1l s2l s1u s1c s1hint s1ul s2c
permutation "s1b" "s2b1" "s1l" "s1u" "s2l" "s1c" "s1hint" "s1ul" "s2c" permutation s1b s2b1 s1l s1u s2l s1c s1hint s1ul s2c
#permutation "s1b" "s2b1" "s1l" "s2l" "s1ul" "s1u" "s1c" "s1hint" "s2c" #permutation s1b s2b1 s1l s2l s1ul s1u s1c s1hint s2c
permutation "s1b" "s2b1" "s1l" "s1u" "s1ul" "s2l" "s1c" "s1hint" "s2c" permutation s1b s2b1 s1l s1u s1ul s2l s1c s1hint s2c
permutation "s1b" "s2b2" "s1l" "s2l" "s1u" "s1c" "s1ul" "s2c" permutation s1b s2b2 s1l s2l s1u s1c s1ul s2c
permutation "s1b" "s2b2" "s1l" "s1u" "s2l" "s1c" "s1ul" "s2c" permutation s1b s2b2 s1l s1u s2l s1c s1ul s2c
#permutation "s1b" "s2b2" "s1l" "s2l" "s1ul" "s1u" "s1c" "s2c" #permutation s1b s2b2 s1l s2l s1ul s1u s1c s2c
permutation "s1b" "s2b2" "s1l" "s1u" "s1ul" "s2l" "s1c" "s2c" permutation s1b s2b2 s1l s1u s1ul s2l s1c s2c
permutation "s1b" "s2b2" "s1l" "s2l" "s1u" "s1c" "s1hint" "s1ul" "s2c" permutation s1b s2b2 s1l s2l s1u s1c s1hint s1ul s2c
permutation "s1b" "s2b2" "s1l" "s1u" "s2l" "s1c" "s1hint" "s1ul" "s2c" permutation s1b s2b2 s1l s1u s2l s1c s1hint s1ul s2c
#permutation "s1b" "s2b2" "s1l" "s2l" "s1ul" "s1u" "s1c" "s1hint" "s2c" #permutation s1b s2b2 s1l s2l s1ul s1u s1c s1hint s2c
permutation "s1b" "s2b2" "s1l" "s1u" "s1ul" "s2l" "s1c" "s1hint" "s2c" permutation s1b s2b2 s1l s1u s1ul s2l s1c s1hint s2c
permutation "s1b" "s2b3" "s1l" "s2l" "s1u" "s1c" "s1ul" "s2c" permutation s1b s2b3 s1l s2l s1u s1c s1ul s2c
permutation "s1b" "s2b3" "s1l" "s1u" "s2l" "s1c" "s1ul" "s2c" permutation s1b s2b3 s1l s1u s2l s1c s1ul s2c
#permutation "s1b" "s2b3" "s1l" "s2l" "s1ul" "s1u" "s1c" "s2c" #permutation s1b s2b3 s1l s2l s1ul s1u s1c s2c
permutation "s1b" "s2b3" "s1l" "s1u" "s1ul" "s2l" "s1c" "s2c" permutation s1b s2b3 s1l s1u s1ul s2l s1c s2c
permutation "s1b" "s2b3" "s1l" "s2l" "s1u" "s1c" "s1hint" "s1ul" "s2c" permutation s1b s2b3 s1l s2l s1u s1c s1hint s1ul s2c
permutation "s1b" "s2b3" "s1l" "s1u" "s2l" "s1c" "s1hint" "s1ul" "s2c" permutation s1b s2b3 s1l s1u s2l s1c s1hint s1ul s2c
#permutation "s1b" "s2b3" "s1l" "s2l" "s1ul" "s1u" "s1c" "s1hint" "s2c" #permutation s1b s2b3 s1l s2l s1ul s1u s1c s1hint s2c
permutation "s1b" "s2b3" "s1l" "s1u" "s1ul" "s2l" "s1c" "s1hint" "s2c" permutation s1b s2b3 s1l s1u s1ul s2l s1c s1hint s2c
...@@ -14,49 +14,49 @@ teardown ...@@ -14,49 +14,49 @@ teardown
DROP TABLE lcu_table; DROP TABLE lcu_table;
} }
session "s1" session s1
step "s1b" { BEGIN; } step s1b { BEGIN; }
step "s1l" { SELECT pg_advisory_lock(380170116); } step s1l { SELECT pg_advisory_lock(380170116); }
step "s1u" { UPDATE lcu_table SET value = 'two' WHERE id = 1; } step s1u { UPDATE lcu_table SET value = 'two' WHERE id = 1; }
step "s1hint" { SELECT * FROM lcu_table; } step s1hint { SELECT * FROM lcu_table; }
step "s1ul" { SELECT pg_advisory_unlock(380170116); } step s1ul { SELECT pg_advisory_unlock(380170116); }
step "s1c" { COMMIT; } step s1c { COMMIT; }
teardown { SELECT pg_advisory_unlock_all(); } teardown { SELECT pg_advisory_unlock_all(); }
session "s2" session s2
step "s2b1" { BEGIN ISOLATION LEVEL READ COMMITTED; } step s2b1 { BEGIN ISOLATION LEVEL READ COMMITTED; }
step "s2b2" { BEGIN ISOLATION LEVEL REPEATABLE READ; } step s2b2 { BEGIN ISOLATION LEVEL REPEATABLE READ; }
step "s2b3" { BEGIN ISOLATION LEVEL SERIALIZABLE; } step s2b3 { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "s2l" { SELECT * FROM lcu_table WHERE pg_advisory_lock(380170116) IS NOT NULL FOR KEY SHARE; } step s2l { SELECT * FROM lcu_table WHERE pg_advisory_lock(380170116) IS NOT NULL FOR KEY SHARE; }
step "s2c" { COMMIT; } step s2c { COMMIT; }
teardown { SELECT pg_advisory_unlock_all(); } teardown { SELECT pg_advisory_unlock_all(); }
permutation "s1b" "s2b1" "s1l" "s2l" "s1u" "s1c" "s1ul" "s2c" permutation s1b s2b1 s1l s2l s1u s1c s1ul s2c
permutation "s1b" "s2b1" "s1l" "s1u" "s2l" "s1c" "s1ul" "s2c" permutation s1b s2b1 s1l s1u s2l s1c s1ul s2c
permutation "s1b" "s2b1" "s1l" "s2l" "s1ul" "s1u" "s1c" "s2c" permutation s1b s2b1 s1l s2l s1ul s1u s1c s2c
permutation "s1b" "s2b1" "s1l" "s1u" "s1ul" "s2l" "s1c" "s2c" permutation s1b s2b1 s1l s1u s1ul s2l s1c s2c
permutation "s1b" "s2b1" "s1l" "s2l" "s1u" "s1c" "s1hint" "s1ul" "s2c" permutation s1b s2b1 s1l s2l s1u s1c s1hint s1ul s2c
permutation "s1b" "s2b1" "s1l" "s1u" "s2l" "s1c" "s1hint" "s1ul" "s2c" permutation s1b s2b1 s1l s1u s2l s1c s1hint s1ul s2c
permutation "s1b" "s2b1" "s1l" "s2l" "s1ul" "s1u" "s1c" "s1hint" "s2c" permutation s1b s2b1 s1l s2l s1ul s1u s1c s1hint s2c
permutation "s1b" "s2b1" "s1l" "s1u" "s1ul" "s2l" "s1c" "s1hint" "s2c" permutation s1b s2b1 s1l s1u s1ul s2l s1c s1hint s2c
permutation "s1b" "s2b2" "s1l" "s2l" "s1u" "s1c" "s1ul" "s2c" permutation s1b s2b2 s1l s2l s1u s1c s1ul s2c
permutation "s1b" "s2b2" "s1l" "s1u" "s2l" "s1c" "s1ul" "s2c" permutation s1b s2b2 s1l s1u s2l s1c s1ul s2c
permutation "s1b" "s2b2" "s1l" "s2l" "s1ul" "s1u" "s1c" "s2c" permutation s1b s2b2 s1l s2l s1ul s1u s1c s2c
permutation "s1b" "s2b2" "s1l" "s1u" "s1ul" "s2l" "s1c" "s2c" permutation s1b s2b2 s1l s1u s1ul s2l s1c s2c
permutation "s1b" "s2b2" "s1l" "s2l" "s1u" "s1c" "s1hint" "s1ul" "s2c" permutation s1b s2b2 s1l s2l s1u s1c s1hint s1ul s2c
permutation "s1b" "s2b2" "s1l" "s1u" "s2l" "s1c" "s1hint" "s1ul" "s2c" permutation s1b s2b2 s1l s1u s2l s1c s1hint s1ul s2c
permutation "s1b" "s2b2" "s1l" "s2l" "s1ul" "s1u" "s1c" "s1hint" "s2c" permutation s1b s2b2 s1l s2l s1ul s1u s1c s1hint s2c
permutation "s1b" "s2b2" "s1l" "s1u" "s1ul" "s2l" "s1c" "s1hint" "s2c" permutation s1b s2b2 s1l s1u s1ul s2l s1c s1hint s2c
permutation "s1b" "s2b3" "s1l" "s2l" "s1u" "s1c" "s1ul" "s2c" permutation s1b s2b3 s1l s2l s1u s1c s1ul s2c
permutation "s1b" "s2b3" "s1l" "s1u" "s2l" "s1c" "s1ul" "s2c" permutation s1b s2b3 s1l s1u s2l s1c s1ul s2c
permutation "s1b" "s2b3" "s1l" "s2l" "s1ul" "s1u" "s1c" "s2c" permutation s1b s2b3 s1l s2l s1ul s1u s1c s2c
permutation "s1b" "s2b3" "s1l" "s1u" "s1ul" "s2l" "s1c" "s2c" permutation s1b s2b3 s1l s1u s1ul s2l s1c s2c
permutation "s1b" "s2b3" "s1l" "s2l" "s1u" "s1c" "s1hint" "s1ul" "s2c" permutation s1b s2b3 s1l s2l s1u s1c s1hint s1ul s2c
permutation "s1b" "s2b3" "s1l" "s1u" "s2l" "s1c" "s1hint" "s1ul" "s2c" permutation s1b s2b3 s1l s1u s2l s1c s1hint s1ul s2c
permutation "s1b" "s2b3" "s1l" "s2l" "s1ul" "s1u" "s1c" "s1hint" "s2c" permutation s1b s2b3 s1l s2l s1ul s1u s1c s1hint s2c
permutation "s1b" "s2b3" "s1l" "s1u" "s1ul" "s2l" "s1c" "s1hint" "s2c" permutation s1b s2b3 s1l s1u s1ul s2l s1c s1hint s2c
...@@ -31,31 +31,31 @@ teardown ...@@ -31,31 +31,31 @@ teardown
DROP TABLE foo; DROP TABLE foo;
} }
session "s1" session s1
# obtain lock on the tuple, traversing its update chain # 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; } step s1l { SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; }
session "s2" session s2
setup { SELECT pg_advisory_lock(0); } setup { SELECT pg_advisory_lock(0); }
step "s2b" { BEGIN; } step s2b { BEGIN; }
step "s2u" { UPDATE foo SET value = 2 WHERE key = 1; } step s2u { UPDATE foo SET value = 2 WHERE key = 1; }
step "s2_blocker1" { DELETE FROM foo; } step s2_blocker1 { DELETE FROM foo; }
step "s2_blocker2" { UPDATE foo SET key = 2 WHERE key = 1; } step s2_blocker2 { UPDATE foo SET key = 2 WHERE key = 1; }
step "s2_blocker3" { 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); } step s2_unlock { SELECT pg_advisory_unlock(0); }
step "s2c" { COMMIT; } step s2c { COMMIT; }
step "s2r" { ROLLBACK; } step s2r { ROLLBACK; }
permutation "s2b" "s1l" "s2u" "s2_blocker1" "s2_unlock" "s2c" permutation s2b s1l s2u s2_blocker1 s2_unlock s2c
permutation "s2b" "s1l" "s2u" "s2_blocker2" "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_blocker3 s2_unlock s2c
permutation "s2b" "s1l" "s2u" "s2_blocker1" "s2_unlock" "s2r" permutation s2b s1l s2u s2_blocker1 s2_unlock s2r
permutation "s2b" "s1l" "s2u" "s2_blocker2" "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_blocker3 s2_unlock s2r
permutation "s2b" "s1l" "s2u" "s2_blocker1" "s2c" "s2_unlock" permutation s2b s1l s2u s2_blocker1 s2c s2_unlock
permutation "s2b" "s1l" "s2u" "s2_blocker2" "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_blocker3 s2c s2_unlock
permutation "s2b" "s1l" "s2u" "s2_blocker1" "s2r" "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_blocker2 s2r s2_unlock
permutation "s2b" "s1l" "s2u" "s2_blocker3" "s2r" "s2_unlock" permutation s2b s1l s2u s2_blocker3 s2r s2_unlock
...@@ -20,20 +20,20 @@ teardown ...@@ -20,20 +20,20 @@ teardown
DROP TABLE foo; DROP TABLE foo;
} }
session "s1" session s1
step "s1b" { BEGIN ISOLATION LEVEL REPEATABLE READ; } step s1b { BEGIN ISOLATION LEVEL REPEATABLE READ; }
step "s1s" { SELECT * FROM foo; } # obtain snapshot step s1s { SELECT * FROM foo; } # obtain snapshot
step "s1l" { SELECT * FROM foo FOR KEY SHARE; } # obtain lock step s1l { SELECT * FROM foo FOR KEY SHARE; } # obtain lock
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
step "s2b" { BEGIN; } step s2b { BEGIN; }
step "s2u" { UPDATE foo SET value = 2 WHERE key = 1; } step s2u { UPDATE foo SET value = 2 WHERE key = 1; }
step "s2c" { COMMIT; } step s2c { COMMIT; }
step "s2d1" { 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 s2d2 { UPDATE foo SET key = 3 WHERE key = 1; }
step "s2d3" { UPDATE foo SET value = 3 WHERE key = 1; } step s2d3 { UPDATE foo SET value = 3 WHERE key = 1; }
permutation "s1b" "s2b" "s1s" "s2u" "s1l" "s2c" "s2d1" "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 s2d2 s1c
permutation "s1b" "s2b" "s1s" "s2u" "s1l" "s2c" "s2d3" "s1c" permutation s1b s2b s1s s2u s1l s2c s2d3 s1c
...@@ -22,17 +22,17 @@ teardown ...@@ -22,17 +22,17 @@ teardown
DROP FUNCTION unlck(); DROP FUNCTION unlck();
} }
session "s1" session s1
step "s1i" { step s1i {
CREATE INDEX CONCURRENTLY mcic_one_pkey ON mcic_one (id) CREATE INDEX CONCURRENTLY mcic_one_pkey ON mcic_one (id)
WHERE lck_shr(281457); WHERE lck_shr(281457);
} }
teardown { SELECT unlck(); } teardown { SELECT unlck(); }
session "s2" session s2
step "s2l" { SELECT pg_advisory_lock(281457); } step s2l { SELECT pg_advisory_lock(281457); }
step "s2i" { step s2i {
CREATE INDEX CONCURRENTLY mcic_two_pkey ON mcic_two (id) CREATE INDEX CONCURRENTLY mcic_two_pkey ON mcic_two (id)
WHERE unlck(); WHERE unlck();
} }
...@@ -40,4 +40,4 @@ step "s2i" { ...@@ -40,4 +40,4 @@ step "s2i" {
# (*) marker ensures that s2i is reported as "waiting", even if it # (*) marker ensures that s2i is reported as "waiting", even if it
# completes very quickly # completes very quickly
permutation "s2l" "s1i" "s2i"(*) permutation s2l s1i s2i(*)
...@@ -19,29 +19,29 @@ teardown ...@@ -19,29 +19,29 @@ teardown
DROP TABLE t; DROP TABLE t;
} }
session "s1" session s1
setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } setup { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "rx1" { SELECT * FROM t WHERE id = 1000000; } step rx1 { SELECT * FROM t WHERE id = 1000000; }
# delay until after T3 commits # delay until after T3 commits
step "wz1" { UPDATE t SET txt = 'a' WHERE id = 1; } step wz1 { UPDATE t SET txt = 'a' WHERE id = 1; }
step "c1" { COMMIT; } step c1 { COMMIT; }
session "s2" session s2
setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } setup { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "wx2" { UPDATE t SET txt = 'b' WHERE id = 1000000; } step wx2 { UPDATE t SET txt = 'b' WHERE id = 1000000; }
step "c2" { COMMIT; } step c2 { COMMIT; }
session "s3" session s3
setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } setup { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "wx3" { UPDATE t SET txt = 'c' WHERE id = 1000000; } step wx3 { UPDATE t SET txt = 'c' WHERE id = 1000000; }
step "ry3" { SELECT * FROM t WHERE id = 500000; } step ry3 { SELECT * FROM t WHERE id = 500000; }
# delay until after T4 commits # delay until after T4 commits
step "c3" { COMMIT; } step c3 { COMMIT; }
session "s4" session s4
setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } setup { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "wy4" { UPDATE t SET txt = 'd' WHERE id = 500000; } step wy4 { UPDATE t SET txt = 'd' WHERE id = 500000; }
step "rz4" { SELECT * FROM t WHERE id = 1; } step rz4 { SELECT * FROM t WHERE id = 1; }
step "c4" { COMMIT; } step c4 { COMMIT; }
permutation "rx1" "wx2" "c2" "wx3" "ry3" "wy4" "rz4" "c4" "c3" "wz1" "c1" permutation rx1 wx2 c2 wx3 ry3 wy4 rz4 c4 c3 wz1 c1
...@@ -15,21 +15,21 @@ teardown ...@@ -15,21 +15,21 @@ teardown
DROP TABLE justthis; DROP TABLE justthis;
} }
session "s1" session s1
setup { BEGIN; } setup { BEGIN; }
step "s1lock" { SELECT * FROM justthis FOR SHARE; } step s1lock { SELECT * FROM justthis FOR SHARE; }
step "s1svpt" { SAVEPOINT foo; } step s1svpt { SAVEPOINT foo; }
step "s1lock2" { SELECT * FROM justthis FOR SHARE; } step s1lock2 { SELECT * FROM justthis FOR SHARE; }
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
setup { BEGIN; } setup { BEGIN; }
step "s2lock" { SELECT * FROM justthis FOR SHARE; } # ensure it's a multi step s2lock { SELECT * FROM justthis FOR SHARE; } # ensure it's a multi
step "s2c" { COMMIT; } step s2c { COMMIT; }
session "s3" session s3
setup { BEGIN; } setup { BEGIN; }
step "s3lock" { SELECT * FROM justthis FOR UPDATE; } step s3lock { SELECT * FROM justthis FOR UPDATE; }
step "s3c" { COMMIT; } step s3c { COMMIT; }
permutation "s1lock" "s2lock" "s1svpt" "s3lock" "s1lock2" "s2c" "s1c" "s3c" permutation s1lock s2lock s1svpt s3lock s1lock2 s2c s1c s3c
...@@ -14,31 +14,31 @@ teardown ...@@ -14,31 +14,31 @@ teardown
DROP TABLE dont_forget; DROP TABLE dont_forget;
} }
session "s1" session s1
setup { BEGIN; } setup { BEGIN; }
step "s1_show" { SELECT current_setting('default_transaction_isolation') <> 'read committed'; } step s1_show { SELECT current_setting('default_transaction_isolation') <> 'read committed'; }
step "s1_lock" { SELECT * FROM dont_forget FOR KEY SHARE; } step s1_lock { SELECT * FROM dont_forget FOR KEY SHARE; }
step "s1_commit" { COMMIT; } step s1_commit { COMMIT; }
session "s2" session s2
setup { BEGIN; } setup { BEGIN; }
step "s2_update" { UPDATE dont_forget SET value = 2; } step s2_update { UPDATE dont_forget SET value = 2; }
step "s2_abort" { ROLLBACK; } step s2_abort { ROLLBACK; }
step "s2_commit" { COMMIT; } step s2_commit { COMMIT; }
session "s3" session s3
# try cases with both a non-conflicting lock with s1's and a conflicting one # try cases with both a non-conflicting lock with s1's and a conflicting one
step "s3_forkeyshr" { SELECT * FROM dont_forget FOR KEY SHARE; } step s3_forkeyshr { SELECT * FROM dont_forget FOR KEY SHARE; }
step "s3_fornokeyupd" { SELECT * FROM dont_forget FOR NO KEY UPDATE; } step s3_fornokeyupd { SELECT * FROM dont_forget FOR NO KEY UPDATE; }
step "s3_forupd" { SELECT * FROM dont_forget FOR UPDATE; } step s3_forupd { SELECT * FROM dont_forget FOR UPDATE; }
permutation "s1_show" "s1_commit" "s2_commit" permutation s1_show s1_commit s2_commit
permutation "s1_lock" "s2_update" "s2_abort" "s3_forkeyshr" "s1_commit" permutation s1_lock s2_update s2_abort s3_forkeyshr s1_commit
permutation "s1_lock" "s2_update" "s2_commit" "s3_forkeyshr" "s1_commit" permutation s1_lock s2_update s2_commit s3_forkeyshr s1_commit
permutation "s1_lock" "s2_update" "s1_commit" "s3_forkeyshr" "s2_commit" permutation s1_lock s2_update s1_commit s3_forkeyshr s2_commit
permutation "s1_lock" "s2_update" "s2_abort" "s3_fornokeyupd" "s1_commit" permutation s1_lock s2_update s2_abort s3_fornokeyupd s1_commit
permutation "s1_lock" "s2_update" "s2_commit" "s3_fornokeyupd" "s1_commit" permutation s1_lock s2_update s2_commit s3_fornokeyupd s1_commit
permutation "s1_lock" "s2_update" "s1_commit" "s3_fornokeyupd" "s2_commit" permutation s1_lock s2_update s1_commit s3_fornokeyupd s2_commit
permutation "s1_lock" "s2_update" "s2_abort" "s3_forupd" "s1_commit" permutation s1_lock s2_update s2_abort s3_forupd s1_commit
permutation "s1_lock" "s2_update" "s2_commit" "s3_forupd" "s1_commit" permutation s1_lock s2_update s2_commit s3_forupd s1_commit
permutation "s1_lock" "s2_update" "s1_commit" "s3_forupd" "s2_commit" permutation s1_lock s2_update s1_commit s3_forupd s2_commit
...@@ -14,24 +14,24 @@ teardown ...@@ -14,24 +14,24 @@ teardown
DROP TABLE foo; DROP TABLE foo;
} }
session "s1" session s1
setup { BEGIN; } setup { BEGIN; }
step "s1a" { SELECT * FROM foo FOR SHARE NOWAIT; } step s1a { SELECT * FROM foo FOR SHARE NOWAIT; }
step "s1b" { COMMIT; } step s1b { COMMIT; }
session "s2" session s2
setup { BEGIN; } setup { BEGIN; }
step "s2a" { SELECT * FROM foo FOR SHARE NOWAIT; } step s2a { SELECT * FROM foo FOR SHARE NOWAIT; }
step "s2b" { SELECT * FROM foo FOR UPDATE NOWAIT; } step s2b { SELECT * FROM foo FOR UPDATE NOWAIT; }
step "s2c" { COMMIT; } step s2c { COMMIT; }
# s1 and s2 both get SHARE lock, creating a multixact lock, then s2 # s1 and s2 both get SHARE lock, creating a multixact lock, then s2
# tries to upgrade to UPDATE but aborts because it cannot acquire a # tries to upgrade to UPDATE but aborts because it cannot acquire a
# multi-xact lock # multi-xact lock
permutation "s1a" "s2a" "s2b" "s1b" "s2c" permutation s1a s2a s2b s1b s2c
# the same but with the SHARE locks acquired in a different order, so # the same but with the SHARE locks acquired in a different order, so
# s2 again aborts because it can't acquired a multi-xact lock # s2 again aborts because it can't acquired a multi-xact lock
permutation "s2a" "s1a" "s2b" "s1b" "s2c" permutation s2a s1a s2b s1b s2c
# s2 acquires SHARE then UPDATE, then s1 tries to acquire SHARE but # s2 acquires SHARE then UPDATE, then s1 tries to acquire SHARE but
# can't so aborts because it can't acquire a regular lock # can't so aborts because it can't acquire a regular lock
permutation "s2a" "s2b" "s1a" "s1b" "s2c" permutation s2a s2b s1a s1b s2c
...@@ -14,20 +14,20 @@ teardown ...@@ -14,20 +14,20 @@ teardown
DROP TABLE foo; DROP TABLE foo;
} }
session "s1" session s1
setup { BEGIN; } setup { BEGIN; }
step "s1a" { SELECT * FROM foo FOR UPDATE; } step s1a { SELECT * FROM foo FOR UPDATE; }
step "s1b" { COMMIT; } step s1b { COMMIT; }
session "s2" session s2
setup { BEGIN; } setup { BEGIN; }
step "s2a" { SELECT * FROM foo FOR UPDATE; } step s2a { SELECT * FROM foo FOR UPDATE; }
step "s2b" { COMMIT; } step s2b { COMMIT; }
session "s3" session s3
setup { BEGIN; } setup { BEGIN; }
step "s3a" { SELECT * FROM foo FOR UPDATE NOWAIT; } step s3a { SELECT * FROM foo FOR UPDATE NOWAIT; }
step "s3b" { COMMIT; } step s3b { COMMIT; }
# s3 skips to second record due to tuple lock held by s2 # s3 skips to second record due to tuple lock held by s2
permutation "s1a" "s2a" "s3a" "s1b" "s2b" "s3b" permutation s1a s2a s3a s1b s2b s3b
...@@ -14,22 +14,22 @@ teardown ...@@ -14,22 +14,22 @@ teardown
DROP TABLE foo; DROP TABLE foo;
} }
session "s1" session s1
setup { BEGIN; } setup { BEGIN; }
step "s1a" { SELECT * FROM foo WHERE pg_advisory_lock(0) IS NOT NULL FOR UPDATE NOWAIT; } step s1a { SELECT * FROM foo WHERE pg_advisory_lock(0) IS NOT NULL FOR UPDATE NOWAIT; }
step "s1b" { COMMIT; } step s1b { COMMIT; }
session "s2" session s2
step "s2a" { SELECT pg_advisory_lock(0); } step s2a { SELECT pg_advisory_lock(0); }
step "s2b" { UPDATE foo SET data = data; } step s2b { UPDATE foo SET data = data; }
step "s2c" { BEGIN; } step s2c { BEGIN; }
step "s2d" { UPDATE foo SET data = data; } step s2d { UPDATE foo SET data = data; }
step "s2e" { SELECT pg_advisory_unlock(0); } step s2e { SELECT pg_advisory_unlock(0); }
step "s2f" { COMMIT; } step s2f { COMMIT; }
# s1 takes a snapshot but then waits on an advisory lock, then s2 # s1 takes a snapshot but then waits on an advisory lock, then s2
# updates the row in one transaction, then again in another without # updates the row in one transaction, then again in another without
# committing, before allowing s1 to proceed to try to lock a row; # committing, before allowing s1 to proceed to try to lock a row;
# because it has a snapshot that sees the older version, we reach the # because it has a snapshot that sees the older version, we reach the
# waiting code in EvalPlanQualFetch which ereports when in NOWAIT mode. # waiting code in EvalPlanQualFetch which ereports when in NOWAIT mode.
permutation "s2a" "s1a" "s2b" "s2c" "s2d" "s2e" "s1b" "s2f" permutation s2a s1a s2b s2c s2d s2e s1b s2f
...@@ -18,11 +18,11 @@ teardown ...@@ -18,11 +18,11 @@ teardown
DROP TABLE test_nowait; DROP TABLE test_nowait;
} }
session "sl1" session sl1
step "sl1_prep" { step sl1_prep {
PREPARE sl1_run AS SELECT id FROM test_nowait WHERE pg_advisory_lock(0) is not null FOR UPDATE NOWAIT; PREPARE sl1_run AS SELECT id FROM test_nowait WHERE pg_advisory_lock(0) is not null FOR UPDATE NOWAIT;
} }
step "sl1_exec" { step sl1_exec {
BEGIN ISOLATION LEVEL READ COMMITTED; BEGIN ISOLATION LEVEL READ COMMITTED;
EXECUTE sl1_run; EXECUTE sl1_run;
SELECT xmin, xmax, ctid, * FROM test_nowait; SELECT xmin, xmax, ctid, * FROM test_nowait;
...@@ -31,22 +31,22 @@ teardown { COMMIT; } ...@@ -31,22 +31,22 @@ teardown { COMMIT; }
# A session that's used for an UPDATE of the rows to be locked, for when we're testing ctid # A session that's used for an UPDATE of the rows to be locked, for when we're testing ctid
# chain following. # chain following.
session "upd" session upd
step "upd_getlock" { step upd_getlock {
SELECT pg_advisory_lock(0); SELECT pg_advisory_lock(0);
} }
step "upd_doupdate" { step upd_doupdate {
BEGIN ISOLATION LEVEL READ COMMITTED; BEGIN ISOLATION LEVEL READ COMMITTED;
UPDATE test_nowait SET value = value WHERE id % 2 = 0; UPDATE test_nowait SET value = value WHERE id % 2 = 0;
COMMIT; COMMIT;
} }
step "upd_releaselock" { step upd_releaselock {
SELECT pg_advisory_unlock(0); SELECT pg_advisory_unlock(0);
} }
# A session that acquires locks that sl1 is supposed to avoid blocking on # A session that acquires locks that sl1 is supposed to avoid blocking on
session "lk1" session lk1
step "lk1_doforshare" { step lk1_doforshare {
BEGIN ISOLATION LEVEL READ COMMITTED; BEGIN ISOLATION LEVEL READ COMMITTED;
SELECT id FROM test_nowait WHERE id % 2 = 0 FOR SHARE; SELECT id FROM test_nowait WHERE id % 2 = 0 FOR SHARE;
} }
...@@ -54,4 +54,4 @@ teardown { ...@@ -54,4 +54,4 @@ teardown {
COMMIT; COMMIT;
} }
permutation "sl1_prep" "upd_getlock" "sl1_exec" "upd_doupdate" "lk1_doforshare" "upd_releaselock" permutation sl1_prep upd_getlock sl1_exec upd_doupdate lk1_doforshare upd_releaselock
...@@ -14,12 +14,12 @@ teardown ...@@ -14,12 +14,12 @@ teardown
DROP TABLE foo; DROP TABLE foo;
} }
session "s1" session s1
setup { BEGIN; } setup { BEGIN; }
step "s1a" { SELECT * FROM foo FOR UPDATE NOWAIT; } step s1a { SELECT * FROM foo FOR UPDATE NOWAIT; }
step "s1b" { COMMIT; } step s1b { COMMIT; }
session "s2" session s2
setup { BEGIN; } setup { BEGIN; }
step "s2a" { SELECT * FROM foo FOR UPDATE NOWAIT; } step s2a { SELECT * FROM foo FOR UPDATE NOWAIT; }
step "s2b" { COMMIT; } step s2b { COMMIT; }
...@@ -19,14 +19,14 @@ teardown ...@@ -19,14 +19,14 @@ teardown
DROP TABLE test_t; DROP TABLE test_t;
} }
session "s1" session s1
setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } setup { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "rxy1" { select * from test_t where val2 = 1; } step rxy1 { select * from test_t where val2 = 1; }
step "wx1" { update test_t set val2 = 2 where val2 = 1 and id = 10; } step wx1 { update test_t set val2 = 2 where val2 = 1 and id = 10; }
step "c1" { COMMIT; } step c1 { COMMIT; }
session "s2" session s2
setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } setup { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "wy2" { update test_t set val2 = 2 where val2 = 1 and id = 9; } step wy2 { update test_t set val2 = 2 where val2 = 1 and id = 9; }
step "rxy2" { select * from test_t where val2 = 1; } step rxy2 { select * from test_t where val2 = 1; }
step "c2" { COMMIT; } step c2 { COMMIT; }
...@@ -15,29 +15,29 @@ setup { ...@@ -15,29 +15,29 @@ setup {
insert into tpart_2 values (110,'xxx'), (120, 'yyy'), (150, 'zzz'); insert into tpart_2 values (110,'xxx'), (120, 'yyy'), (150, 'zzz');
} }
session "s1" session s1
step "s1b" { begin; } step s1b { begin; }
step "s1a" { alter table tpart attach partition tpart_2 for values from (100) to (200); } step s1a { alter table tpart attach partition tpart_2 for values from (100) to (200); }
step "s1c" { commit; } step s1c { commit; }
session "s2" session s2
step "s2b" { begin; } step s2b { begin; }
step "s2i" { insert into tpart values (110,'xxx'), (120, 'yyy'), (150, 'zzz'); } step s2i { insert into tpart values (110,'xxx'), (120, 'yyy'), (150, 'zzz'); }
step "s2i2" { insert into tpart_default (i, j) values (110, 'xxx'), (120, 'yyy'), (150, 'zzz'); } step s2i2 { insert into tpart_default (i, j) values (110, 'xxx'), (120, 'yyy'), (150, 'zzz'); }
step "s2c" { commit; } step s2c { commit; }
step "s2s" { select tableoid::regclass, * from tpart; } step s2s { select tableoid::regclass, * from tpart; }
teardown { drop table tpart; } teardown { drop table tpart; }
# insert into tpart by s2 which routes to tpart_default due to not seeing # insert into tpart by s2 which routes to tpart_default due to not seeing
# concurrently added tpart_2 should fail, because the partition constraint # concurrently added tpart_2 should fail, because the partition constraint
# of tpart_default would have changed due to tpart_2 having been added # of tpart_default would have changed due to tpart_2 having been added
permutation "s1b" "s1a" "s2b" "s2i" "s1c" "s2c" "s2s" permutation s1b s1a s2b s2i s1c s2c s2s
# similar to above, but now insert into sub-partitioned tpart_default # similar to above, but now insert into sub-partitioned tpart_default
permutation "s1b" "s1a" "s2b" "s2i2" "s1c" "s2c" "s2s" permutation s1b s1a s2b s2i2 s1c s2c s2s
# reverse: now the insert into tpart_default by s2 occurs first followed by # reverse: now the insert into tpart_default by s2 occurs first followed by
# attach in s1, which should fail when it scans the leaf default partition # attach in s1, which should fail when it scans the leaf default partition
# find the violating rows # find the violating rows
permutation "s1b" "s2b" "s2i" "s1a" "s2c" "s1c" "s2s" permutation s1b s2b s2i s1a s2c s1c s2s
...@@ -46,41 +46,41 @@ teardown ...@@ -46,41 +46,41 @@ teardown
DROP TABLE bar, foo_range_parted; DROP TABLE bar, foo_range_parted;
} }
session "s1" session s1
step "s1b" { BEGIN ISOLATION LEVEL READ COMMITTED; } step s1b { BEGIN ISOLATION LEVEL READ COMMITTED; }
step "s1u" { UPDATE foo SET a=2 WHERE a=1; } step s1u { UPDATE foo SET a=2 WHERE a=1; }
step "s1u2" { UPDATE footrg SET b='EFG' WHERE a=1; } step s1u2 { UPDATE footrg SET b='EFG' WHERE a=1; }
step "s1u3pc" { UPDATE foo_range_parted SET a=11 WHERE a=7; } step s1u3pc { UPDATE foo_range_parted SET a=11 WHERE a=7; }
step "s1u3npc" { UPDATE foo_range_parted SET b='XYZ' WHERE a=7; } step s1u3npc { UPDATE foo_range_parted SET b='XYZ' WHERE a=7; }
step "s1c" { COMMIT; } step s1c { COMMIT; }
step "s1r" { ROLLBACK; } step s1r { ROLLBACK; }
session "s2" session s2
step "s2b" { BEGIN ISOLATION LEVEL READ COMMITTED; } step s2b { BEGIN ISOLATION LEVEL READ COMMITTED; }
step "s2u" { UPDATE foo SET b='EFG' WHERE a=1; } step s2u { UPDATE foo SET b='EFG' WHERE a=1; }
step "s2u2" { UPDATE footrg SET b='XYZ' WHERE a=1; } step s2u2 { UPDATE footrg SET b='XYZ' WHERE a=1; }
step "s2i" { INSERT INTO bar VALUES(7); } step s2i { INSERT INTO bar VALUES(7); }
step "s2d" { DELETE FROM foo WHERE a=1; } step s2d { DELETE FROM foo WHERE a=1; }
step "s2c" { COMMIT; } step s2c { COMMIT; }
# Concurrency error from ExecUpdate and ExecDelete. # Concurrency error from ExecUpdate and ExecDelete.
permutation "s1b" "s2b" "s1u" "s1c" "s2d" "s2c" permutation s1b s2b s1u s1c s2d s2c
permutation "s1b" "s2b" "s1u" "s2d" "s1c" "s2c" permutation s1b s2b s1u s2d s1c s2c
permutation "s1b" "s2b" "s1u" "s2u" "s1c" "s2c" permutation s1b s2b s1u s2u s1c s2c
permutation "s1b" "s2b" "s2d" "s1u" "s2c" "s1c" permutation s1b s2b s2d s1u s2c s1c
# Concurrency error from GetTupleForTrigger # Concurrency error from GetTupleForTrigger
permutation "s1b" "s2b" "s1u2" "s1c" "s2u2" "s2c" permutation s1b s2b s1u2 s1c s2u2 s2c
permutation "s1b" "s2b" "s1u2" "s2u2" "s1c" "s2c" permutation s1b s2b s1u2 s2u2 s1c s2c
permutation "s1b" "s2b" "s2u2" "s1u2" "s2c" "s1c" permutation s1b s2b s2u2 s1u2 s2c s1c
# Concurrency error from ExecLockRows # Concurrency error from ExecLockRows
# test waiting for moved row itself # test waiting for moved row itself
permutation "s1b" "s2b" "s1u3pc" "s2i" "s1c" "s2c" permutation s1b s2b s1u3pc s2i s1c s2c
permutation "s1b" "s2b" "s1u3pc" "s2i" "s1r" "s2c" permutation s1b s2b s1u3pc s2i s1r s2c
# test waiting for in-partition update, followed by cross-partition move # test waiting for in-partition update, followed by cross-partition move
permutation "s1b" "s2b" "s1u3npc" "s1u3pc" "s2i" "s1c" "s2c" permutation s1b s2b s1u3npc s1u3pc s2i s1c s2c
permutation "s1b" "s2b" "s1u3npc" "s1u3pc" "s2i" "s1r" "s2c" permutation s1b s2b s1u3npc s1u3pc s2i s1r s2c
# test waiting for in-partition update, followed by cross-partition move # test waiting for in-partition update, followed by cross-partition move
permutation "s1b" "s2b" "s1u3npc" "s1u3pc" "s1u3pc" "s2i" "s1c" "s2c" permutation s1b s2b s1u3npc s1u3pc s1u3pc s2i s1c s2c
permutation "s1b" "s2b" "s1u3npc" "s1u3pc" "s1u3pc" "s2i" "s1r" "s2c" permutation s1b s2b s1u3npc s1u3pc s1u3pc s2i s1r s2c
...@@ -23,23 +23,23 @@ teardown ...@@ -23,23 +23,23 @@ teardown
DROP TABLE foo; DROP TABLE foo;
} }
session "s1" session s1
setup { BEGIN ISOLATION LEVEL READ COMMITTED; } setup { BEGIN ISOLATION LEVEL READ COMMITTED; }
step "s1u" { UPDATE foo SET a=2, b=b || ' -> moved by session-1' WHERE a=1; } step s1u { UPDATE foo SET a=2, b=b || ' -> moved by session-1' WHERE a=1; }
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
setup { BEGIN ISOLATION LEVEL READ COMMITTED; } setup { BEGIN ISOLATION LEVEL READ COMMITTED; }
step "s2donothing" { INSERT INTO foo VALUES(1, 'session-2 donothing') ON CONFLICT DO NOTHING; } step s2donothing { INSERT INTO foo VALUES(1, 'session-2 donothing') ON CONFLICT DO NOTHING; }
step "s2c" { COMMIT; } step s2c { COMMIT; }
session "s3" session s3
setup { BEGIN ISOLATION LEVEL READ COMMITTED; } setup { BEGIN ISOLATION LEVEL READ COMMITTED; }
step "s3donothing" { INSERT INTO foo VALUES(2, 'session-3 donothing') ON CONFLICT DO NOTHING; } step s3donothing { INSERT INTO foo VALUES(2, 'session-3 donothing') ON CONFLICT DO NOTHING; }
step "s3select" { SELECT * FROM foo ORDER BY a; } step s3select { SELECT * FROM foo ORDER BY a; }
step "s3c" { COMMIT; } step s3c { COMMIT; }
# Regular case where one session block-waits on another to determine if it # Regular case where one session block-waits on another to determine if it
# should proceed with an insert or do nothing. # should proceed with an insert or do nothing.
permutation "s1u" "s2donothing" "s3donothing" "s1c" "s2c" "s3select" "s3c" permutation s1u s2donothing s3donothing s1c s2c s3select s3c
permutation "s2donothing" "s1u" "s3donothing" "s1c" "s2c" "s3select" "s3c" permutation s2donothing s1u s3donothing s1c s2c s3select s3c
...@@ -16,29 +16,29 @@ teardown ...@@ -16,29 +16,29 @@ teardown
DROP TABLE foo; DROP TABLE foo;
} }
session "s1" session s1
setup { BEGIN ISOLATION LEVEL READ COMMITTED; } setup { BEGIN ISOLATION LEVEL READ COMMITTED; }
step "s1u" { UPDATE foo SET a=2, b=b || ' -> moved by session-1' WHERE a=1; } step s1u { UPDATE foo SET a=2, b=b || ' -> moved by session-1' WHERE a=1; }
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
step "s2beginrr" { BEGIN ISOLATION LEVEL REPEATABLE READ; } step s2beginrr { BEGIN ISOLATION LEVEL REPEATABLE READ; }
step "s2begins" { BEGIN ISOLATION LEVEL SERIALIZABLE; } step s2begins { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "s2donothing" { INSERT INTO foo VALUES(1, 'session-2 donothing') ON CONFLICT DO NOTHING; } step s2donothing { INSERT INTO foo VALUES(1, 'session-2 donothing') ON CONFLICT DO NOTHING; }
step "s2c" { COMMIT; } step s2c { COMMIT; }
step "s2select" { SELECT * FROM foo ORDER BY a; } step s2select { SELECT * FROM foo ORDER BY a; }
session "s3" session s3
step "s3beginrr" { BEGIN ISOLATION LEVEL REPEATABLE READ; } step s3beginrr { BEGIN ISOLATION LEVEL REPEATABLE READ; }
step "s3begins" { BEGIN ISOLATION LEVEL SERIALIZABLE; } step s3begins { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "s3donothing" { INSERT INTO foo VALUES(2, 'session-3 donothing'), (2, 'session-3 donothing2') ON CONFLICT DO NOTHING; } step s3donothing { INSERT INTO foo VALUES(2, 'session-3 donothing'), (2, 'session-3 donothing2') ON CONFLICT DO NOTHING; }
step "s3c" { COMMIT; } step s3c { COMMIT; }
permutation "s2beginrr" "s3beginrr" "s1u" "s2donothing" "s1c" "s2c" "s3donothing" "s3c" "s2select" permutation s2beginrr s3beginrr s1u s2donothing s1c s2c s3donothing s3c s2select
permutation "s2beginrr" "s3beginrr" "s1u" "s3donothing" "s1c" "s3c" "s2donothing" "s2c" "s2select" permutation s2beginrr s3beginrr s1u s3donothing s1c s3c s2donothing s2c s2select
permutation "s2beginrr" "s3beginrr" "s1u" "s2donothing" "s3donothing" "s1c" "s2c" "s3c" "s2select" permutation s2beginrr s3beginrr s1u s2donothing s3donothing s1c s2c s3c s2select
permutation "s2beginrr" "s3beginrr" "s1u" "s3donothing" "s2donothing" "s1c" "s3c" "s2c" "s2select" permutation s2beginrr s3beginrr s1u s3donothing s2donothing s1c s3c s2c s2select
permutation "s2begins" "s3begins" "s1u" "s2donothing" "s1c" "s2c" "s3donothing" "s3c" "s2select" permutation s2begins s3begins s1u s2donothing s1c s2c s3donothing s3c s2select
permutation "s2begins" "s3begins" "s1u" "s3donothing" "s1c" "s3c" "s2donothing" "s2c" "s2select" permutation s2begins s3begins s1u s3donothing s1c s3c s2donothing s2c s2select
permutation "s2begins" "s3begins" "s1u" "s2donothing" "s3donothing" "s1c" "s2c" "s3c" "s2select" permutation s2begins s3begins s1u s2donothing s3donothing s1c s2c s3c s2select
permutation "s2begins" "s3begins" "s1u" "s3donothing" "s2donothing" "s1c" "s3c" "s2c" "s2select" permutation s2begins s3begins s1u s3donothing s2donothing s1c s3c s2c s2select
...@@ -44,33 +44,33 @@ teardown ...@@ -44,33 +44,33 @@ teardown
DROP TABLE triglog; DROP TABLE triglog;
} }
session "s1" session s1
step "s1b" { BEGIN ISOLATION LEVEL READ COMMITTED; } step s1b { BEGIN ISOLATION LEVEL READ COMMITTED; }
step "s1u" { UPDATE foo SET a = a + 1, b = b || ' update1' WHERE b like '%ABC%'; } step s1u { UPDATE foo SET a = a + 1, b = b || ' update1' WHERE b like '%ABC%'; }
step "s1ut" { UPDATE footrg SET a = a + 1, b = b || ' update1' WHERE b like '%ABC%'; } step s1ut { UPDATE footrg SET a = a + 1, b = b || ' update1' WHERE b like '%ABC%'; }
step "s1s" { SELECT tableoid::regclass, * FROM foo ORDER BY a; } step s1s { SELECT tableoid::regclass, * FROM foo ORDER BY a; }
step "s1st" { SELECT tableoid::regclass, * FROM footrg ORDER BY a; } step s1st { SELECT tableoid::regclass, * FROM footrg ORDER BY a; }
step "s1stl" { SELECT * FROM triglog ORDER BY a; } step s1stl { SELECT * FROM triglog ORDER BY a; }
step "s1c" { COMMIT; } step s1c { COMMIT; }
session "s2" session s2
step "s2b" { BEGIN ISOLATION LEVEL READ COMMITTED; } step s2b { BEGIN ISOLATION LEVEL READ COMMITTED; }
step "s2u1" { UPDATE foo SET b = b || ' update2' WHERE a = 1; } step s2u1 { UPDATE foo SET b = b || ' update2' WHERE a = 1; }
step "s2u2" { UPDATE foo SET b = 'EFG' WHERE a = 1; } step s2u2 { UPDATE foo SET b = 'EFG' WHERE a = 1; }
step "s2ut1" { UPDATE footrg SET b = b || ' update2' WHERE a = 1; } step s2ut1 { UPDATE footrg SET b = b || ' update2' WHERE a = 1; }
step "s2ut2" { UPDATE footrg SET b = 'EFG' WHERE a = 1; } step s2ut2 { UPDATE footrg SET b = 'EFG' WHERE a = 1; }
step "s2c" { COMMIT; } step s2c { COMMIT; }
# Session s1 is moving a row into another partition, but is waiting for # Session s1 is moving a row into another partition, but is waiting for
# another session s2 that is updating the original row. The row that ends up # another session s2 that is updating the original row. The row that ends up
# in the new partition should contain the changes made by session s2. # in the new partition should contain the changes made by session s2.
permutation "s1b" "s2b" "s2u1" "s1u" "s2c" "s1c" "s1s" permutation s1b s2b s2u1 s1u s2c s1c s1s
# Same as above, except, session s1 is waiting in GetTupleForTrigger(). # Same as above, except, session s1 is waiting in GetTupleForTrigger().
permutation "s1b" "s2b" "s2ut1" "s1ut" "s2c" "s1c" "s1st" "s1stl" permutation s1b s2b s2ut1 s1ut s2c s1c s1st s1stl
# Below two cases are similar to the above two; except that the session s1 # Below two cases are similar to the above two; except that the session s1
# fails EvalPlanQual() test, so partition key update does not happen. # fails EvalPlanQual() test, so partition key update does not happen.
permutation "s1b" "s2b" "s2u2" "s1u" "s2c" "s1c" "s1s" permutation s1b s2b s2u2 s1u s2c s1c s1s
permutation "s1b" "s2b" "s2ut2" "s1ut" "s2c" "s1c" "s1st" "s1stl" permutation s1b s2b s2ut2 s1ut s2c s1c s1st s1stl
...@@ -22,7 +22,7 @@ teardown ...@@ -22,7 +22,7 @@ teardown
DROP TYPE test2; DROP TYPE test2;
} }
session "s1" session s1
setup setup
{ {
...@@ -30,7 +30,7 @@ setup ...@@ -30,7 +30,7 @@ setup
} }
# assign_simple_var() # assign_simple_var()
step "assign1" step assign1
{ {
do $$ do $$
declare declare
...@@ -46,7 +46,7 @@ $$; ...@@ -46,7 +46,7 @@ $$;
} }
# assign_simple_var() # assign_simple_var()
step "assign2" step assign2
{ {
do $$ do $$
declare declare
...@@ -62,7 +62,7 @@ $$; ...@@ -62,7 +62,7 @@ $$;
} }
# expanded_record_set_field() # expanded_record_set_field()
step "assign3" step assign3
{ {
do $$ do $$
declare declare
...@@ -79,7 +79,7 @@ $$; ...@@ -79,7 +79,7 @@ $$;
} }
# expanded_record_set_fields() # expanded_record_set_fields()
step "assign4" step assign4
{ {
do $$ do $$
declare declare
...@@ -95,7 +95,7 @@ $$; ...@@ -95,7 +95,7 @@ $$;
} }
# expanded_record_set_tuple() # expanded_record_set_tuple()
step "assign5" step assign5
{ {
do $$ do $$
declare declare
...@@ -113,7 +113,7 @@ $$; ...@@ -113,7 +113,7 @@ $$;
} }
# FOR loop must not hold any fetched-but-not-detoasted values across commit # FOR loop must not hold any fetched-but-not-detoasted values across commit
step "assign6" step assign6
{ {
do $$ do $$
declare declare
...@@ -151,28 +151,28 @@ do $$ ...@@ -151,28 +151,28 @@ do $$
$$; $$;
} }
session "s2" session s2
setup setup
{ {
SELECT pg_advisory_unlock_all(); SELECT pg_advisory_unlock_all();
} }
step "lock" step lock
{ {
SELECT pg_advisory_lock(1); SELECT pg_advisory_lock(1);
} }
step "vacuum" step vacuum
{ {
VACUUM test1; VACUUM test1;
} }
step "unlock" step unlock
{ {
SELECT pg_advisory_unlock(1); SELECT pg_advisory_unlock(1);
} }
permutation "lock" "assign1" "vacuum" "unlock" permutation lock assign1 vacuum unlock
permutation "lock" "assign2" "vacuum" "unlock" permutation lock assign2 vacuum unlock
permutation "lock" "assign3" "vacuum" "unlock" permutation lock assign3 vacuum unlock
permutation "lock" "assign4" "vacuum" "unlock" permutation lock assign4 vacuum unlock
permutation "lock" "assign5" "vacuum" "unlock" permutation lock assign5 vacuum unlock
permutation "lock" "assign6" "vacuum" "unlock" permutation lock assign6 vacuum unlock
permutation "fetch-after-commit" permutation "fetch-after-commit"
...@@ -24,92 +24,92 @@ teardown ...@@ -24,92 +24,92 @@ teardown
drop table other_tbl; drop table other_tbl;
} }
session "s1" session s1
setup setup
{ {
begin isolation level serializable; begin isolation level serializable;
set enable_seqscan=off; set enable_seqscan=off;
} }
step "ra1" { select * from gin_tbl where p @> array[1] limit 1; } step ra1 { select * from gin_tbl where p @> array[1] limit 1; }
step "rb1" { select count(*) from gin_tbl where p @> array[2]; } step rb1 { select count(*) from gin_tbl where p @> array[2]; }
step "rc1" { select count(*) from gin_tbl where p @> array[800]; } step rc1 { select count(*) from gin_tbl where p @> array[800]; }
step "rd1" { select count(*) from gin_tbl where p @> array[2000]; } step rd1 { select count(*) from gin_tbl where p @> array[2000]; }
step "wo1" { insert into other_tbl values (1); } step wo1 { insert into other_tbl values (1); }
step "c1" { commit; } step c1 { commit; }
session "s2" session s2
setup setup
{ {
begin isolation level serializable; begin isolation level serializable;
set enable_seqscan=off; set enable_seqscan=off;
} }
step "ro2" { select count(*) from other_tbl; } step ro2 { select count(*) from other_tbl; }
step "wa2" { insert into gin_tbl values (array[1]); } step wa2 { insert into gin_tbl values (array[1]); }
step "wb2" { insert into gin_tbl values (array[2]); } step wb2 { insert into gin_tbl values (array[2]); }
step "wc2" { insert into gin_tbl values (array[800]); } step wc2 { insert into gin_tbl values (array[800]); }
step "wd2" { insert into gin_tbl values (array[2000]); } step wd2 { insert into gin_tbl values (array[2000]); }
step "c2" { commit; } step c2 { commit; }
session "s3" session s3
step "fu" { alter index ginidx set (fastupdate = on); } step fu { alter index ginidx set (fastupdate = on); }
# An index scan (from one transaction) and an index insert (from another # An index scan (from one transaction) and an index insert (from another
# transaction) try to access the same part of the index. So, there is a # transaction) try to access the same part of the index. So, there is a
# r-w conflict. # r-w conflict.
permutation "ra1" "ro2" "wo1" "c1" "wa2" "c2" permutation ra1 ro2 wo1 c1 wa2 c2
permutation "ro2" "ra1" "wo1" "c1" "wa2" "c2" permutation ro2 ra1 wo1 c1 wa2 c2
permutation "ro2" "ra1" "wo1" "wa2" "c1" "c2" permutation ro2 ra1 wo1 wa2 c1 c2
permutation "ra1" "ro2" "wa2" "wo1" "c1" "c2" permutation ra1 ro2 wa2 wo1 c1 c2
permutation "rb1" "ro2" "wo1" "c1" "wb2" "c2" permutation rb1 ro2 wo1 c1 wb2 c2
permutation "ro2" "rb1" "wo1" "c1" "wb2" "c2" permutation ro2 rb1 wo1 c1 wb2 c2
permutation "ro2" "rb1" "wo1" "wb2" "c1" "c2" permutation ro2 rb1 wo1 wb2 c1 c2
permutation "rb1" "ro2" "wb2" "wo1" "c1" "c2" permutation rb1 ro2 wb2 wo1 c1 c2
permutation "rc1" "ro2" "wo1" "c1" "wc2" "c2" permutation rc1 ro2 wo1 c1 wc2 c2
permutation "ro2" "rc1" "wo1" "c1" "wc2" "c2" permutation ro2 rc1 wo1 c1 wc2 c2
permutation "ro2" "rc1" "wo1" "wc2" "c1" "c2" permutation ro2 rc1 wo1 wc2 c1 c2
permutation "rc1" "ro2" "wc2" "wo1" "c1" "c2" permutation rc1 ro2 wc2 wo1 c1 c2
# An index scan (from one transaction) and an index insert (from another # An index scan (from one transaction) and an index insert (from another
# transaction) try to access different parts of the index. So, there is no # transaction) try to access different parts of the index. So, there is no
# r-w conflict. # r-w conflict.
permutation "ra1" "ro2" "wo1" "c1" "wb2" "c2" permutation ra1 ro2 wo1 c1 wb2 c2
permutation "ro2" "ra1" "wo1" "c1" "wc2" "c2" permutation ro2 ra1 wo1 c1 wc2 c2
permutation "ro2" "rb1" "wo1" "wa2" "c1" "c2" permutation ro2 rb1 wo1 wa2 c1 c2
permutation "rc1" "ro2" "wa2" "wo1" "c1" "c2" permutation rc1 ro2 wa2 wo1 c1 c2
permutation "rb1" "ro2" "wo1" "c1" "wa2" "c2" permutation rb1 ro2 wo1 c1 wa2 c2
permutation "ro2" "rb1" "wo1" "c1" "wc2" "c2" permutation ro2 rb1 wo1 c1 wc2 c2
permutation "ro2" "ra1" "wo1" "wb2" "c1" "c2" permutation ro2 ra1 wo1 wb2 c1 c2
permutation "rc1" "ro2" "wb2" "wo1" "c1" "c2" permutation rc1 ro2 wb2 wo1 c1 c2
permutation "rc1" "ro2" "wo1" "c1" "wa2" "c2" permutation rc1 ro2 wo1 c1 wa2 c2
permutation "ro2" "rc1" "wo1" "c1" "wb2" "c2" permutation ro2 rc1 wo1 c1 wb2 c2
permutation "ro2" "ra1" "wo1" "wc2" "c1" "c2" permutation ro2 ra1 wo1 wc2 c1 c2
permutation "rb1" "ro2" "wc2" "wo1" "c1" "c2" permutation rb1 ro2 wc2 wo1 c1 c2
# With fastupdate = on all index is under predicate lock. So we can't # With fastupdate = on all index is under predicate lock. So we can't
# distinguish particular keys. # distinguish particular keys.
permutation "fu" "ra1" "ro2" "wo1" "c1" "wa2" "c2" permutation fu ra1 ro2 wo1 c1 wa2 c2
permutation "fu" "ra1" "ro2" "wo1" "c1" "wb2" "c2" permutation fu ra1 ro2 wo1 c1 wb2 c2
# Check fastupdate turned on concurrently. # Check fastupdate turned on concurrently.
permutation "ra1" "ro2" "wo1" "c1" "fu" "wa2" "c2" permutation ra1 ro2 wo1 c1 fu wa2 c2
# Tests for conflicts with previously non-existing key # Tests for conflicts with previously non-existing key
permutation "rd1" "ro2" "wo1" "c1" "wd2" "c2" permutation rd1 ro2 wo1 c1 wd2 c2
permutation "ro2" "rd1" "wo1" "c1" "wd2" "c2" permutation ro2 rd1 wo1 c1 wd2 c2
permutation "ro2" "rd1" "wo1" "wd2" "c1" "c2" permutation ro2 rd1 wo1 wd2 c1 c2
permutation "rd1" "ro2" "wd2" "wo1" "c1" "c2" permutation rd1 ro2 wd2 wo1 c1 c2
...@@ -21,7 +21,7 @@ teardown ...@@ -21,7 +21,7 @@ teardown
drop table gist_point_tbl; drop table gist_point_tbl;
} }
session "s1" session s1
setup setup
{ {
begin isolation level serializable; begin isolation level serializable;
...@@ -30,16 +30,16 @@ setup ...@@ -30,16 +30,16 @@ setup
set enable_indexonlyscan=on; set enable_indexonlyscan=on;
} }
step "rxy1" { select sum(p[0]) from gist_point_tbl where p << point(2500, 2500); } step rxy1 { select sum(p[0]) from gist_point_tbl where p << point(2500, 2500); }
step "wx1" { insert into gist_point_tbl (id, p) step wx1 { insert into gist_point_tbl (id, p)
select g, point(g*500, g*500) from generate_series(15, 20) g; } select g, point(g*500, g*500) from generate_series(15, 20) g; }
step "rxy3" { select sum(p[0]) from gist_point_tbl where p >> point(6000,6000); } step rxy3 { select sum(p[0]) from gist_point_tbl where p >> point(6000,6000); }
step "wx3" { insert into gist_point_tbl (id, p) step wx3 { insert into gist_point_tbl (id, p)
select g, point(g*500, g*500) from generate_series(12, 18) g; } select g, point(g*500, g*500) from generate_series(12, 18) g; }
step "c1" { commit; } step c1 { commit; }
session "s2" session s2
setup setup
{ {
begin isolation level serializable; begin isolation level serializable;
...@@ -48,70 +48,70 @@ setup ...@@ -48,70 +48,70 @@ setup
set enable_indexonlyscan=on; set enable_indexonlyscan=on;
} }
step "rxy2" { select sum(p[0]) from gist_point_tbl where p >> point(7500,7500); } step rxy2 { select sum(p[0]) from gist_point_tbl where p >> point(7500,7500); }
step "wy2" { insert into gist_point_tbl (id, p) step wy2 { insert into gist_point_tbl (id, p)
select g, point(g*500, g*500) from generate_series(1, 5) g; } select g, point(g*500, g*500) from generate_series(1, 5) g; }
step "rxy4" { select sum(p[0]) from gist_point_tbl where p << point(1000,1000); } step rxy4 { select sum(p[0]) from gist_point_tbl where p << point(1000,1000); }
step "wy4" { insert into gist_point_tbl (id, p) step wy4 { insert into gist_point_tbl (id, p)
select g, point(g*50, g*50) from generate_series(1, 20) g; } select g, point(g*50, g*50) from generate_series(1, 20) g; }
step "c2" { commit; } step c2 { commit; }
# An index scan (from one transaction) and an index insert (from another # An index scan (from one transaction) and an index insert (from another
# transaction) try to access the same part of the index but one transaction # transaction) try to access the same part of the index but one transaction
# commits before other transaction begins so no r-w conflict. # commits before other transaction begins so no r-w conflict.
permutation "rxy1" "wx1" "c1" "rxy2" "wy2" "c2" permutation rxy1 wx1 c1 rxy2 wy2 c2
permutation "rxy2" "wy2" "c2" "rxy1" "wx1" "c1" permutation rxy2 wy2 c2 rxy1 wx1 c1
# An index scan (from one transaction) and an index insert (from another # An index scan (from one transaction) and an index insert (from another
# transaction) try to access different parts of the index and also one # transaction) try to access different parts of the index and also one
# transaction commits before other transaction begins, so no r-w conflict. # transaction commits before other transaction begins, so no r-w conflict.
permutation "rxy3" "wx3" "c1" "rxy4" "wy4" "c2" permutation rxy3 wx3 c1 rxy4 wy4 c2
permutation "rxy4" "wy4" "c2" "rxy3" "wx3" "c1" permutation rxy4 wy4 c2 rxy3 wx3 c1
# An index scan (from one transaction) and an index insert (from another # An index scan (from one transaction) and an index insert (from another
# transaction) try to access the same part of the index and one transaction # transaction) try to access the same part of the index and one transaction
# begins before other transaction commits so there is a r-w conflict. # begins before other transaction commits so there is a r-w conflict.
permutation "rxy1" "wx1" "rxy2" "c1" "wy2" "c2" permutation rxy1 wx1 rxy2 c1 wy2 c2
permutation "rxy1" "wx1" "rxy2" "wy2" "c1" "c2" permutation rxy1 wx1 rxy2 wy2 c1 c2
permutation "rxy1" "wx1" "rxy2" "wy2" "c2" "c1" permutation rxy1 wx1 rxy2 wy2 c2 c1
permutation "rxy1" "rxy2" "wx1" "c1" "wy2" "c2" permutation rxy1 rxy2 wx1 c1 wy2 c2
permutation "rxy1" "rxy2" "wx1" "wy2" "c1" "c2" permutation rxy1 rxy2 wx1 wy2 c1 c2
permutation "rxy1" "rxy2" "wx1" "wy2" "c2" "c1" permutation rxy1 rxy2 wx1 wy2 c2 c1
permutation "rxy1" "rxy2" "wy2" "wx1" "c1" "c2" permutation rxy1 rxy2 wy2 wx1 c1 c2
permutation "rxy1" "rxy2" "wy2" "wx1" "c2" "c1" permutation rxy1 rxy2 wy2 wx1 c2 c1
permutation "rxy1" "rxy2" "wy2" "c2" "wx1" "c1" permutation rxy1 rxy2 wy2 c2 wx1 c1
permutation "rxy2" "rxy1" "wx1" "c1" "wy2" "c2" permutation rxy2 rxy1 wx1 c1 wy2 c2
permutation "rxy2" "rxy1" "wx1" "wy2" "c1" "c2" permutation rxy2 rxy1 wx1 wy2 c1 c2
permutation "rxy2" "rxy1" "wx1" "wy2" "c2" "c1" permutation rxy2 rxy1 wx1 wy2 c2 c1
permutation "rxy2" "rxy1" "wy2" "wx1" "c1" "c2" permutation rxy2 rxy1 wy2 wx1 c1 c2
permutation "rxy2" "rxy1" "wy2" "wx1" "c2" "c1" permutation rxy2 rxy1 wy2 wx1 c2 c1
permutation "rxy2" "rxy1" "wy2" "c2" "wx1" "c1" permutation rxy2 rxy1 wy2 c2 wx1 c1
permutation "rxy2" "wy2" "rxy1" "wx1" "c1" "c2" permutation rxy2 wy2 rxy1 wx1 c1 c2
permutation "rxy2" "wy2" "rxy1" "wx1" "c2" "c1" permutation rxy2 wy2 rxy1 wx1 c2 c1
permutation "rxy2" "wy2" "rxy1" "c2" "wx1" "c1" permutation rxy2 wy2 rxy1 c2 wx1 c1
# An index scan (from one transaction) and an index insert (from another # An index scan (from one transaction) and an index insert (from another
# transaction) try to access different parts of the index so no r-w conflict. # transaction) try to access different parts of the index so no r-w conflict.
permutation "rxy3" "wx3" "rxy4" "c1" "wy4" "c2" permutation rxy3 wx3 rxy4 c1 wy4 c2
permutation "rxy3" "wx3" "rxy4" "wy4" "c1" "c2" permutation rxy3 wx3 rxy4 wy4 c1 c2
permutation "rxy3" "wx3" "rxy4" "wy4" "c2" "c1" permutation rxy3 wx3 rxy4 wy4 c2 c1
permutation "rxy3" "rxy4" "wx3" "c1" "wy4" "c2" permutation rxy3 rxy4 wx3 c1 wy4 c2
permutation "rxy3" "rxy4" "wx3" "wy4" "c1" "c2" permutation rxy3 rxy4 wx3 wy4 c1 c2
permutation "rxy3" "rxy4" "wx3" "wy4" "c2" "c1" permutation rxy3 rxy4 wx3 wy4 c2 c1
permutation "rxy3" "rxy4" "wy4" "wx3" "c1" "c2" permutation rxy3 rxy4 wy4 wx3 c1 c2
permutation "rxy3" "rxy4" "wy4" "wx3" "c2" "c1" permutation rxy3 rxy4 wy4 wx3 c2 c1
permutation "rxy3" "rxy4" "wy4" "c2" "wx3" "c1" permutation rxy3 rxy4 wy4 c2 wx3 c1
permutation "rxy4" "rxy3" "wx3" "c1" "wy4" "c2" permutation rxy4 rxy3 wx3 c1 wy4 c2
permutation "rxy4" "rxy3" "wx3" "wy4" "c1" "c2" permutation rxy4 rxy3 wx3 wy4 c1 c2
permutation "rxy4" "rxy3" "wx3" "wy4" "c2" "c1" permutation rxy4 rxy3 wx3 wy4 c2 c1
permutation "rxy4" "rxy3" "wy4" "wx3" "c1" "c2" permutation rxy4 rxy3 wy4 wx3 c1 c2
permutation "rxy4" "rxy3" "wy4" "wx3" "c2" "c1" permutation rxy4 rxy3 wy4 wx3 c2 c1
permutation "rxy4" "rxy3" "wy4" "c2" "wx3" "c1" permutation rxy4 rxy3 wy4 c2 wx3 c1
permutation "rxy4" "wy4" "rxy3" "wx3" "c1" "c2" permutation rxy4 wy4 rxy3 wx3 c1 c2
permutation "rxy4" "wy4" "rxy3" "wx3" "c2" "c1" permutation rxy4 wy4 rxy3 wx3 c2 c1
permutation "rxy4" "wy4" "rxy3" "c2" "wx3" "c1" permutation rxy4 wy4 rxy3 c2 wx3 c1
...@@ -22,16 +22,16 @@ teardown ...@@ -22,16 +22,16 @@ teardown
DROP TABLE test; DROP TABLE test;
} }
session "s1" session s1
step "b1" { BEGIN ISOLATION LEVEL SERIALIZABLE; } step b1 { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "r1" { SELECT * FROM test WHERE i IN (5, 7) } step r1 { SELECT * FROM test WHERE i IN (5, 7) }
step "w1" { UPDATE test SET t = 'pear_xact1' WHERE i = 7 } step w1 { UPDATE test SET t = 'pear_xact1' WHERE i = 7 }
step "c1" { COMMIT; } step c1 { COMMIT; }
session "s2" session s2
step "b2" { BEGIN ISOLATION LEVEL SERIALIZABLE; } step b2 { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "r2" { SELECT * FROM test WHERE i IN (5, 7) } step r2 { SELECT * FROM test WHERE i IN (5, 7) }
step "w2" { UPDATE test SET t = 'apple_xact2' WHERE i = 5 } step w2 { UPDATE test SET t = 'apple_xact2' WHERE i = 5 }
step "c2" { COMMIT; } step c2 { COMMIT; }
permutation "b1" "b2" "r1" "r2" "w1" "w2" "c1" "c2" permutation b1 b2 r1 r2 w1 w2 c1 c2
...@@ -12,26 +12,26 @@ teardown ...@@ -12,26 +12,26 @@ teardown
# Sessions for CREATE INDEX CONCURRENTLY test # Sessions for CREATE INDEX CONCURRENTLY test
session "s1" session s1
step "w1" { BEGIN; INSERT INTO cic_test VALUES (1); } step w1 { BEGIN; INSERT INTO cic_test VALUES (1); }
step "p1" { PREPARE TRANSACTION 's1'; } step p1 { PREPARE TRANSACTION 's1'; }
step "c1" { COMMIT PREPARED 's1'; } step c1 { COMMIT PREPARED 's1'; }
session "s2" session s2
# The isolation tester never recognizes that a lock of s1 blocks s2, because a # The isolation tester never recognizes that a lock of s1 blocks s2, because a
# prepared transaction's locks have no pid associated. While there's a slight # prepared transaction's locks have no pid associated. While there's a slight
# chance of timeout while waiting for an autovacuum-held lock, that wouldn't # chance of timeout while waiting for an autovacuum-held lock, that wouldn't
# change the output. Hence, no timeout is too short. # change the output. Hence, no timeout is too short.
setup { SET lock_timeout = 10; } setup { SET lock_timeout = 10; }
step "cic2" step cic2
{ {
CREATE INDEX CONCURRENTLY on cic_test(a); CREATE INDEX CONCURRENTLY on cic_test(a);
} }
step "r2" step r2
{ {
SET enable_seqscan to off; SET enable_seqscan to off;
SET enable_bitmapscan to off; SET enable_bitmapscan to off;
SELECT * FROM cic_test WHERE a = 1; SELECT * FROM cic_test WHERE a = 1;
} }
permutation "w1" "p1" "cic2" "c1" "r2" permutation w1 p1 cic2 c1 r2
...@@ -17,14 +17,14 @@ teardown ...@@ -17,14 +17,14 @@ teardown
DROP TABLE person, project; DROP TABLE person, project;
} }
session "s1" session s1
setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } setup { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "rx1" { SELECT count(*) FROM person WHERE person_id = 1 AND is_project_manager; } step rx1 { SELECT count(*) FROM person WHERE person_id = 1 AND is_project_manager; }
step "wy1" { INSERT INTO project VALUES (101, 'Build Great Wall', 1); } step wy1 { INSERT INTO project VALUES (101, 'Build Great Wall', 1); }
step "c1" { COMMIT; } step c1 { COMMIT; }
session "s2" session s2
setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } setup { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "ry2" { SELECT count(*) FROM project WHERE project_manager = 1; } step ry2 { SELECT count(*) FROM project WHERE project_manager = 1; }
step "wx2" { UPDATE person SET is_project_manager = false WHERE person_id = 1; } step wx2 { UPDATE person SET is_project_manager = false WHERE person_id = 1; }
step "c2" { COMMIT; } step c2 { COMMIT; }
This diff is collapsed.
This diff is collapsed.
...@@ -19,12 +19,12 @@ teardown ...@@ -19,12 +19,12 @@ teardown
DROP TABLE test; DROP TABLE test;
} }
session "s1" session s1
setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } setup { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "rwx1" { UPDATE test SET t = 'apple' WHERE t = 'pear'; } step rwx1 { UPDATE test SET t = 'apple' WHERE t = 'pear'; }
step "c1" { COMMIT; } step c1 { COMMIT; }
session "s2" session s2
setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } setup { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step "rwx2" { UPDATE test SET t = 'pear' WHERE t = 'apple'} step rwx2 { UPDATE test SET t = 'pear' WHERE t = 'apple'}
step "c2" { COMMIT; } step c2 { COMMIT; }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment