this to clean up in preparation for the next permutation, e.g dropping
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
session is executed in its own connection. A session part consists
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.
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.
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
order). Note that the list of steps in a manually specified
"permutation" line doesn't actually have to be a permutation of the
or leave others out. Also, each step name can be annotated with some
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
specified in the spec file, or automatically generated), the isolation
%type <permutationstep> permutation_step
%type <blocker> blocker
-%token <str> sqlblock string_literal
+%token <str> sqlblock identifier
%token <integer> INTEGER
%token NOTICES PERMUTATION SESSION SETUP STEP TEARDOWN TEST
;
session:
- SESSION string_literal opt_setup step_list opt_teardown
+ SESSION identifier opt_setup step_list opt_teardown
{
$$ = pg_malloc(sizeof(Session));
$$->name = $2;
step:
- STEP string_literal sqlblock
+ STEP identifier sqlblock
{
$$ = pg_malloc(sizeof(Step));
$$->name = $2;
;
permutation_step:
- string_literal
+ identifier
{
$$ = pg_malloc(sizeof(PermutationStep));
$$->name = $1;
$$->nblockers = 0;
$$->step = NULL;
}
- | string_literal '(' blocker_list ')'
+ | identifier '(' blocker_list ')'
{
$$ = pg_malloc(sizeof(PermutationStep));
$$->name = $1;
;
blocker:
- string_literal
+ identifier
{
$$ = pg_malloc(sizeof(PermutationStepBlocker));
$$->stepname = $1;
$$->step = NULL;
$$->target_notices = -1;
}
- | string_literal NOTICES INTEGER
+ | identifier NOTICES INTEGER
{
$$ = pg_malloc(sizeof(PermutationStepBlocker));
$$->stepname = $1;
DROP TABLE foo;
}
-session "s1"
+session s1
setup { BEGIN; }
-step "s1s" { SAVEPOINT f; }
-step "s1u" { UPDATE foo SET key = 2; } # obtain KEY REVOKE
-step "s1r" { ROLLBACK TO f; } # lose KEY REVOKE
-step "s1l" { SELECT * FROM foo FOR KEY SHARE; }
-step "s1c" { COMMIT; }
+step s1s { SAVEPOINT f; }
+step s1u { UPDATE foo SET key = 2; } # obtain KEY REVOKE
+step s1r { ROLLBACK TO f; } # lose KEY REVOKE
+step s1l { SELECT * FROM foo FOR KEY SHARE; }
+step s1c { COMMIT; }
-session "s2"
+session s2
setup { BEGIN; }
-step "s2l" { SELECT * FROM foo FOR KEY SHARE; }
-step "s2c" { COMMIT; }
+step s2l { SELECT * FROM foo FOR KEY SHARE; }
+step s2c { COMMIT; }
-permutation "s1s" "s1u" "s1r" "s1l" "s1c" "s2l" "s2c"
-permutation "s1s" "s1u" "s1r" "s1l" "s2l" "s1c" "s2c"
-permutation "s1s" "s1u" "s1r" "s1l" "s2l" "s2c" "s1c"
-permutation "s1s" "s1u" "s1r" "s2l" "s1l" "s1c" "s2c"
-permutation "s1s" "s1u" "s1r" "s2l" "s1l" "s2c" "s1c"
-permutation "s1s" "s1u" "s1r" "s2l" "s2c" "s1l" "s1c"
-permutation "s1s" "s1u" "s2l" "s1r" "s1l" "s1c" "s2c"
-permutation "s1s" "s1u" "s2l" "s1r" "s1l" "s2c" "s1c"
-permutation "s1s" "s1u" "s2l" "s1r" "s2c" "s1l" "s1c"
-permutation "s1s" "s2l" "s1u" "s2c" "s1r" "s1l" "s1c"
-permutation "s1s" "s2l" "s2c" "s1u" "s1r" "s1l" "s1c"
-permutation "s2l" "s1s" "s1u" "s2c" "s1r" "s1l" "s1c"
-permutation "s2l" "s1s" "s2c" "s1u" "s1r" "s1l" "s1c"
-permutation "s2l" "s2c" "s1s" "s1u" "s1r" "s1l" "s1c"
+permutation s1s s1u s1r s1l s1c s2l s2c
+permutation s1s s1u s1r s1l s2l s1c s2c
+permutation s1s s1u s1r s1l s2l s2c s1c
+permutation s1s s1u s1r s2l s1l s1c s2c
+permutation s1s s1u s1r s2l s1l s2c s1c
+permutation s1s s1u s1r s2l s2c s1l s1c
+permutation s1s s1u s2l s1r s1l s1c s2c
+permutation s1s s1u s2l s1r s1l s2c s1c
+permutation s1s s1u s2l s1r s2c s1l s1c
+permutation s1s s2l s1u s2c s1r s1l s1c
+permutation s1s s2l s2c s1u s1r s1l s1c
+permutation s2l s1s s1u s2c s1r s1l s1c
+permutation s2l s1s s2c s1u s1r s1l s1c
+permutation s2l s2c s1s s1u s1r s1l s1c
DROP TABLE a, b;
}
-session "s1"
-step "s1" { BEGIN; }
-step "at1" { ALTER TABLE b ADD CONSTRAINT bfk FOREIGN KEY (a_id) REFERENCES a (i) NOT VALID; }
-step "sc1" { COMMIT; }
-step "s2" { BEGIN; }
-step "at2" { ALTER TABLE b VALIDATE CONSTRAINT bfk; }
-step "sc2" { COMMIT; }
+session s1
+step s1 { BEGIN; }
+step at1 { ALTER TABLE b ADD CONSTRAINT bfk FOREIGN KEY (a_id) REFERENCES a (i) NOT VALID; }
+step sc1 { COMMIT; }
+step s2 { BEGIN; }
+step at2 { ALTER TABLE b VALIDATE CONSTRAINT bfk; }
+step sc2 { COMMIT; }
-session "s2"
+session s2
setup { BEGIN; }
-step "rx1" { SELECT * FROM b WHERE a_id = 1 LIMIT 1; }
-step "wx" { INSERT INTO b VALUES (0); }
-step "rx3" { SELECT * FROM b WHERE a_id = 3 LIMIT 3; }
-step "c2" { COMMIT; }
+step rx1 { SELECT * FROM b WHERE a_id = 1 LIMIT 1; }
+step wx { INSERT INTO b VALUES (0); }
+step rx3 { SELECT * FROM b WHERE a_id = 3 LIMIT 3; }
+step c2 { COMMIT; }
-permutation "s1" "at1" "sc1" "s2" "at2" "sc2" "rx1" "wx" "rx3" "c2"
-permutation "s1" "at1" "sc1" "s2" "at2" "rx1" "sc2" "wx" "rx3" "c2"
-permutation "s1" "at1" "sc1" "s2" "at2" "rx1" "wx" "sc2" "rx3" "c2"
-permutation "s1" "at1" "sc1" "s2" "at2" "rx1" "wx" "rx3" "sc2" "c2"
-permutation "s1" "at1" "sc1" "s2" "at2" "rx1" "wx" "rx3" "c2" "sc2"
-permutation "s1" "at1" "sc1" "s2" "rx1" "at2" "sc2" "wx" "rx3" "c2"
-permutation "s1" "at1" "sc1" "s2" "rx1" "at2" "wx" "sc2" "rx3" "c2"
-permutation "s1" "at1" "sc1" "s2" "rx1" "at2" "wx" "rx3" "sc2" "c2"
-permutation "s1" "at1" "sc1" "s2" "rx1" "at2" "wx" "rx3" "c2" "sc2"
-permutation "s1" "at1" "sc1" "s2" "rx1" "wx" "at2" "sc2" "rx3" "c2"
-permutation "s1" "at1" "sc1" "s2" "rx1" "wx" "at2" "rx3" "sc2" "c2"
-permutation "s1" "at1" "sc1" "s2" "rx1" "wx" "at2" "rx3" "c2" "sc2"
-permutation "s1" "at1" "sc1" "s2" "rx1" "wx" "rx3" "at2" "sc2" "c2"
-permutation "s1" "at1" "sc1" "s2" "rx1" "wx" "rx3" "at2" "c2" "sc2"
-permutation "s1" "at1" "sc1" "s2" "rx1" "wx" "rx3" "c2" "at2" "sc2"
-permutation "s1" "at1" "sc1" "rx1" "s2" "at2" "sc2" "wx" "rx3" "c2"
-permutation "s1" "at1" "sc1" "rx1" "s2" "at2" "wx" "sc2" "rx3" "c2"
-permutation "s1" "at1" "sc1" "rx1" "s2" "at2" "wx" "rx3" "sc2" "c2"
-permutation "s1" "at1" "sc1" "rx1" "s2" "at2" "wx" "rx3" "c2" "sc2"
-permutation "s1" "at1" "sc1" "rx1" "s2" "wx" "at2" "sc2" "rx3" "c2"
-permutation "s1" "at1" "sc1" "rx1" "s2" "wx" "at2" "rx3" "sc2" "c2"
-permutation "s1" "at1" "sc1" "rx1" "s2" "wx" "at2" "rx3" "c2" "sc2"
-permutation "s1" "at1" "sc1" "rx1" "s2" "wx" "rx3" "at2" "sc2" "c2"
-permutation "s1" "at1" "sc1" "rx1" "s2" "wx" "rx3" "at2" "c2" "sc2"
-permutation "s1" "at1" "sc1" "rx1" "s2" "wx" "rx3" "c2" "at2" "sc2"
-permutation "s1" "at1" "sc1" "rx1" "wx" "s2" "at2" "sc2" "rx3" "c2"
-permutation "s1" "at1" "sc1" "rx1" "wx" "s2" "at2" "rx3" "sc2" "c2"
-permutation "s1" "at1" "sc1" "rx1" "wx" "s2" "at2" "rx3" "c2" "sc2"
-permutation "s1" "at1" "sc1" "rx1" "wx" "s2" "rx3" "at2" "sc2" "c2"
-permutation "s1" "at1" "sc1" "rx1" "wx" "s2" "rx3" "at2" "c2" "sc2"
-permutation "s1" "at1" "sc1" "rx1" "wx" "s2" "rx3" "c2" "at2" "sc2"
-permutation "s1" "at1" "sc1" "rx1" "wx" "rx3" "s2" "at2" "sc2" "c2"
-permutation "s1" "at1" "sc1" "rx1" "wx" "rx3" "s2" "at2" "c2" "sc2"
-permutation "s1" "at1" "sc1" "rx1" "wx" "rx3" "s2" "c2" "at2" "sc2"
-permutation "s1" "at1" "sc1" "rx1" "wx" "rx3" "c2" "s2" "at2" "sc2"
-permutation "s1" "at1" "rx1" "sc1" "s2" "at2" "sc2" "wx" "rx3" "c2"
-permutation "s1" "at1" "rx1" "sc1" "s2" "at2" "wx" "sc2" "rx3" "c2"
-permutation "s1" "at1" "rx1" "sc1" "s2" "at2" "wx" "rx3" "sc2" "c2"
-permutation "s1" "at1" "rx1" "sc1" "s2" "at2" "wx" "rx3" "c2" "sc2"
-permutation "s1" "at1" "rx1" "sc1" "s2" "wx" "at2" "sc2" "rx3" "c2"
-permutation "s1" "at1" "rx1" "sc1" "s2" "wx" "at2" "rx3" "sc2" "c2"
-permutation "s1" "at1" "rx1" "sc1" "s2" "wx" "at2" "rx3" "c2" "sc2"
-permutation "s1" "at1" "rx1" "sc1" "s2" "wx" "rx3" "at2" "sc2" "c2"
-permutation "s1" "at1" "rx1" "sc1" "s2" "wx" "rx3" "at2" "c2" "sc2"
-permutation "s1" "at1" "rx1" "sc1" "s2" "wx" "rx3" "c2" "at2" "sc2"
-permutation "s1" "at1" "rx1" "sc1" "wx" "s2" "at2" "sc2" "rx3" "c2"
-permutation "s1" "at1" "rx1" "sc1" "wx" "s2" "at2" "rx3" "sc2" "c2"
-permutation "s1" "at1" "rx1" "sc1" "wx" "s2" "at2" "rx3" "c2" "sc2"
-permutation "s1" "at1" "rx1" "sc1" "wx" "s2" "rx3" "at2" "sc2" "c2"
-permutation "s1" "at1" "rx1" "sc1" "wx" "s2" "rx3" "at2" "c2" "sc2"
-permutation "s1" "at1" "rx1" "sc1" "wx" "s2" "rx3" "c2" "at2" "sc2"
-permutation "s1" "at1" "rx1" "sc1" "wx" "rx3" "s2" "at2" "sc2" "c2"
-permutation "s1" "at1" "rx1" "sc1" "wx" "rx3" "s2" "at2" "c2" "sc2"
-permutation "s1" "at1" "rx1" "sc1" "wx" "rx3" "s2" "c2" "at2" "sc2"
-permutation "s1" "at1" "rx1" "sc1" "wx" "rx3" "c2" "s2" "at2" "sc2"
-permutation "s1" "at1" "rx1" "wx" "sc1" "s2" "at2" "sc2" "rx3" "c2"
-permutation "s1" "at1" "rx1" "wx" "sc1" "s2" "at2" "rx3" "sc2" "c2"
-permutation "s1" "at1" "rx1" "wx" "sc1" "s2" "at2" "rx3" "c2" "sc2"
-permutation "s1" "at1" "rx1" "wx" "sc1" "s2" "rx3" "at2" "sc2" "c2"
-permutation "s1" "at1" "rx1" "wx" "sc1" "s2" "rx3" "at2" "c2" "sc2"
-permutation "s1" "at1" "rx1" "wx" "sc1" "s2" "rx3" "c2" "at2" "sc2"
-permutation "s1" "at1" "rx1" "wx" "sc1" "rx3" "s2" "at2" "sc2" "c2"
-permutation "s1" "at1" "rx1" "wx" "sc1" "rx3" "s2" "at2" "c2" "sc2"
-permutation "s1" "at1" "rx1" "wx" "sc1" "rx3" "s2" "c2" "at2" "sc2"
-permutation "s1" "at1" "rx1" "wx" "sc1" "rx3" "c2" "s2" "at2" "sc2"
-permutation "s1" "rx1" "at1" "sc1" "s2" "at2" "sc2" "wx" "rx3" "c2"
-permutation "s1" "rx1" "at1" "sc1" "s2" "at2" "wx" "sc2" "rx3" "c2"
-permutation "s1" "rx1" "at1" "sc1" "s2" "at2" "wx" "rx3" "sc2" "c2"
-permutation "s1" "rx1" "at1" "sc1" "s2" "at2" "wx" "rx3" "c2" "sc2"
-permutation "s1" "rx1" "at1" "sc1" "s2" "wx" "at2" "sc2" "rx3" "c2"
-permutation "s1" "rx1" "at1" "sc1" "s2" "wx" "at2" "rx3" "sc2" "c2"
-permutation "s1" "rx1" "at1" "sc1" "s2" "wx" "at2" "rx3" "c2" "sc2"
-permutation "s1" "rx1" "at1" "sc1" "s2" "wx" "rx3" "at2" "sc2" "c2"
-permutation "s1" "rx1" "at1" "sc1" "s2" "wx" "rx3" "at2" "c2" "sc2"
-permutation "s1" "rx1" "at1" "sc1" "s2" "wx" "rx3" "c2" "at2" "sc2"
-permutation "s1" "rx1" "at1" "sc1" "wx" "s2" "at2" "sc2" "rx3" "c2"
-permutation "s1" "rx1" "at1" "sc1" "wx" "s2" "at2" "rx3" "sc2" "c2"
-permutation "s1" "rx1" "at1" "sc1" "wx" "s2" "at2" "rx3" "c2" "sc2"
-permutation "s1" "rx1" "at1" "sc1" "wx" "s2" "rx3" "at2" "sc2" "c2"
-permutation "s1" "rx1" "at1" "sc1" "wx" "s2" "rx3" "at2" "c2" "sc2"
-permutation "s1" "rx1" "at1" "sc1" "wx" "s2" "rx3" "c2" "at2" "sc2"
-permutation "s1" "rx1" "at1" "sc1" "wx" "rx3" "s2" "at2" "sc2" "c2"
-permutation "s1" "rx1" "at1" "sc1" "wx" "rx3" "s2" "at2" "c2" "sc2"
-permutation "s1" "rx1" "at1" "sc1" "wx" "rx3" "s2" "c2" "at2" "sc2"
-permutation "s1" "rx1" "at1" "sc1" "wx" "rx3" "c2" "s2" "at2" "sc2"
-permutation "s1" "rx1" "at1" "wx" "sc1" "s2" "at2" "sc2" "rx3" "c2"
-permutation "s1" "rx1" "at1" "wx" "sc1" "s2" "at2" "rx3" "sc2" "c2"
-permutation "s1" "rx1" "at1" "wx" "sc1" "s2" "at2" "rx3" "c2" "sc2"
-permutation "s1" "rx1" "at1" "wx" "sc1" "s2" "rx3" "at2" "sc2" "c2"
-permutation "s1" "rx1" "at1" "wx" "sc1" "s2" "rx3" "at2" "c2" "sc2"
-permutation "s1" "rx1" "at1" "wx" "sc1" "s2" "rx3" "c2" "at2" "sc2"
-permutation "s1" "rx1" "at1" "wx" "sc1" "rx3" "s2" "at2" "sc2" "c2"
-permutation "s1" "rx1" "at1" "wx" "sc1" "rx3" "s2" "at2" "c2" "sc2"
-permutation "s1" "rx1" "at1" "wx" "sc1" "rx3" "s2" "c2" "at2" "sc2"
-permutation "s1" "rx1" "at1" "wx" "sc1" "rx3" "c2" "s2" "at2" "sc2"
-permutation "s1" "rx1" "wx" "at1" "rx3" "c2" "sc1" "s2" "at2" "sc2"
-permutation "s1" "rx1" "wx" "rx3" "at1" "c2" "sc1" "s2" "at2" "sc2"
-permutation "s1" "rx1" "wx" "rx3" "c2" "at1" "sc1" "s2" "at2" "sc2"
-permutation "rx1" "s1" "at1" "sc1" "s2" "at2" "sc2" "wx" "rx3" "c2"
-permutation "rx1" "s1" "at1" "sc1" "s2" "at2" "wx" "sc2" "rx3" "c2"
-permutation "rx1" "s1" "at1" "sc1" "s2" "at2" "wx" "rx3" "sc2" "c2"
-permutation "rx1" "s1" "at1" "sc1" "s2" "at2" "wx" "rx3" "c2" "sc2"
-permutation "rx1" "s1" "at1" "sc1" "s2" "wx" "at2" "sc2" "rx3" "c2"
-permutation "rx1" "s1" "at1" "sc1" "s2" "wx" "at2" "rx3" "sc2" "c2"
-permutation "rx1" "s1" "at1" "sc1" "s2" "wx" "at2" "rx3" "c2" "sc2"
-permutation "rx1" "s1" "at1" "sc1" "s2" "wx" "rx3" "at2" "sc2" "c2"
-permutation "rx1" "s1" "at1" "sc1" "s2" "wx" "rx3" "at2" "c2" "sc2"
-permutation "rx1" "s1" "at1" "sc1" "s2" "wx" "rx3" "c2" "at2" "sc2"
-permutation "rx1" "s1" "at1" "sc1" "wx" "s2" "at2" "sc2" "rx3" "c2"
-permutation "rx1" "s1" "at1" "sc1" "wx" "s2" "at2" "rx3" "sc2" "c2"
-permutation "rx1" "s1" "at1" "sc1" "wx" "s2" "at2" "rx3" "c2" "sc2"
-permutation "rx1" "s1" "at1" "sc1" "wx" "s2" "rx3" "at2" "sc2" "c2"
-permutation "rx1" "s1" "at1" "sc1" "wx" "s2" "rx3" "at2" "c2" "sc2"
-permutation "rx1" "s1" "at1" "sc1" "wx" "s2" "rx3" "c2" "at2" "sc2"
-permutation "rx1" "s1" "at1" "sc1" "wx" "rx3" "s2" "at2" "sc2" "c2"
-permutation "rx1" "s1" "at1" "sc1" "wx" "rx3" "s2" "at2" "c2" "sc2"
-permutation "rx1" "s1" "at1" "sc1" "wx" "rx3" "s2" "c2" "at2" "sc2"
-permutation "rx1" "s1" "at1" "sc1" "wx" "rx3" "c2" "s2" "at2" "sc2"
-permutation "rx1" "s1" "at1" "wx" "sc1" "s2" "at2" "sc2" "rx3" "c2"
-permutation "rx1" "s1" "at1" "wx" "sc1" "s2" "at2" "rx3" "sc2" "c2"
-permutation "rx1" "s1" "at1" "wx" "sc1" "s2" "at2" "rx3" "c2" "sc2"
-permutation "rx1" "s1" "at1" "wx" "sc1" "s2" "rx3" "at2" "sc2" "c2"
-permutation "rx1" "s1" "at1" "wx" "sc1" "s2" "rx3" "at2" "c2" "sc2"
-permutation "rx1" "s1" "at1" "wx" "sc1" "s2" "rx3" "c2" "at2" "sc2"
-permutation "rx1" "s1" "at1" "wx" "sc1" "rx3" "s2" "at2" "sc2" "c2"
-permutation "rx1" "s1" "at1" "wx" "sc1" "rx3" "s2" "at2" "c2" "sc2"
-permutation "rx1" "s1" "at1" "wx" "sc1" "rx3" "s2" "c2" "at2" "sc2"
-permutation "rx1" "s1" "at1" "wx" "sc1" "rx3" "c2" "s2" "at2" "sc2"
-permutation "rx1" "s1" "wx" "at1" "rx3" "c2" "sc1" "s2" "at2" "sc2"
-permutation "rx1" "s1" "wx" "rx3" "at1" "c2" "sc1" "s2" "at2" "sc2"
-permutation "rx1" "s1" "wx" "rx3" "c2" "at1" "sc1" "s2" "at2" "sc2"
-permutation "rx1" "wx" "s1" "at1" "rx3" "c2" "sc1" "s2" "at2" "sc2"
-permutation "rx1" "wx" "s1" "rx3" "at1" "c2" "sc1" "s2" "at2" "sc2"
-permutation "rx1" "wx" "s1" "rx3" "c2" "at1" "sc1" "s2" "at2" "sc2"
-permutation "rx1" "wx" "rx3" "s1" "at1" "c2" "sc1" "s2" "at2" "sc2"
-permutation "rx1" "wx" "rx3" "s1" "c2" "at1" "sc1" "s2" "at2" "sc2"
-permutation "rx1" "wx" "rx3" "c2" "s1" "at1" "sc1" "s2" "at2" "sc2"
+permutation s1 at1 sc1 s2 at2 sc2 rx1 wx rx3 c2
+permutation s1 at1 sc1 s2 at2 rx1 sc2 wx rx3 c2
+permutation s1 at1 sc1 s2 at2 rx1 wx sc2 rx3 c2
+permutation s1 at1 sc1 s2 at2 rx1 wx rx3 sc2 c2
+permutation s1 at1 sc1 s2 at2 rx1 wx rx3 c2 sc2
+permutation s1 at1 sc1 s2 rx1 at2 sc2 wx rx3 c2
+permutation s1 at1 sc1 s2 rx1 at2 wx sc2 rx3 c2
+permutation s1 at1 sc1 s2 rx1 at2 wx rx3 sc2 c2
+permutation s1 at1 sc1 s2 rx1 at2 wx rx3 c2 sc2
+permutation s1 at1 sc1 s2 rx1 wx at2 sc2 rx3 c2
+permutation s1 at1 sc1 s2 rx1 wx at2 rx3 sc2 c2
+permutation s1 at1 sc1 s2 rx1 wx at2 rx3 c2 sc2
+permutation s1 at1 sc1 s2 rx1 wx rx3 at2 sc2 c2
+permutation s1 at1 sc1 s2 rx1 wx rx3 at2 c2 sc2
+permutation s1 at1 sc1 s2 rx1 wx rx3 c2 at2 sc2
+permutation s1 at1 sc1 rx1 s2 at2 sc2 wx rx3 c2
+permutation s1 at1 sc1 rx1 s2 at2 wx sc2 rx3 c2
+permutation s1 at1 sc1 rx1 s2 at2 wx rx3 sc2 c2
+permutation s1 at1 sc1 rx1 s2 at2 wx rx3 c2 sc2
+permutation s1 at1 sc1 rx1 s2 wx at2 sc2 rx3 c2
+permutation s1 at1 sc1 rx1 s2 wx at2 rx3 sc2 c2
+permutation s1 at1 sc1 rx1 s2 wx at2 rx3 c2 sc2
+permutation s1 at1 sc1 rx1 s2 wx rx3 at2 sc2 c2
+permutation s1 at1 sc1 rx1 s2 wx rx3 at2 c2 sc2
+permutation s1 at1 sc1 rx1 s2 wx rx3 c2 at2 sc2
+permutation s1 at1 sc1 rx1 wx s2 at2 sc2 rx3 c2
+permutation s1 at1 sc1 rx1 wx s2 at2 rx3 sc2 c2
+permutation s1 at1 sc1 rx1 wx s2 at2 rx3 c2 sc2
+permutation s1 at1 sc1 rx1 wx s2 rx3 at2 sc2 c2
+permutation s1 at1 sc1 rx1 wx s2 rx3 at2 c2 sc2
+permutation s1 at1 sc1 rx1 wx s2 rx3 c2 at2 sc2
+permutation s1 at1 sc1 rx1 wx rx3 s2 at2 sc2 c2
+permutation s1 at1 sc1 rx1 wx rx3 s2 at2 c2 sc2
+permutation s1 at1 sc1 rx1 wx rx3 s2 c2 at2 sc2
+permutation s1 at1 sc1 rx1 wx rx3 c2 s2 at2 sc2
+permutation s1 at1 rx1 sc1 s2 at2 sc2 wx rx3 c2
+permutation s1 at1 rx1 sc1 s2 at2 wx sc2 rx3 c2
+permutation s1 at1 rx1 sc1 s2 at2 wx rx3 sc2 c2
+permutation s1 at1 rx1 sc1 s2 at2 wx rx3 c2 sc2
+permutation s1 at1 rx1 sc1 s2 wx at2 sc2 rx3 c2
+permutation s1 at1 rx1 sc1 s2 wx at2 rx3 sc2 c2
+permutation s1 at1 rx1 sc1 s2 wx at2 rx3 c2 sc2
+permutation s1 at1 rx1 sc1 s2 wx rx3 at2 sc2 c2
+permutation s1 at1 rx1 sc1 s2 wx rx3 at2 c2 sc2
+permutation s1 at1 rx1 sc1 s2 wx rx3 c2 at2 sc2
+permutation s1 at1 rx1 sc1 wx s2 at2 sc2 rx3 c2
+permutation s1 at1 rx1 sc1 wx s2 at2 rx3 sc2 c2
+permutation s1 at1 rx1 sc1 wx s2 at2 rx3 c2 sc2
+permutation s1 at1 rx1 sc1 wx s2 rx3 at2 sc2 c2
+permutation s1 at1 rx1 sc1 wx s2 rx3 at2 c2 sc2
+permutation s1 at1 rx1 sc1 wx s2 rx3 c2 at2 sc2
+permutation s1 at1 rx1 sc1 wx rx3 s2 at2 sc2 c2
+permutation s1 at1 rx1 sc1 wx rx3 s2 at2 c2 sc2
+permutation s1 at1 rx1 sc1 wx rx3 s2 c2 at2 sc2
+permutation s1 at1 rx1 sc1 wx rx3 c2 s2 at2 sc2
+permutation s1 at1 rx1 wx sc1 s2 at2 sc2 rx3 c2
+permutation s1 at1 rx1 wx sc1 s2 at2 rx3 sc2 c2
+permutation s1 at1 rx1 wx sc1 s2 at2 rx3 c2 sc2
+permutation s1 at1 rx1 wx sc1 s2 rx3 at2 sc2 c2
+permutation s1 at1 rx1 wx sc1 s2 rx3 at2 c2 sc2
+permutation s1 at1 rx1 wx sc1 s2 rx3 c2 at2 sc2
+permutation s1 at1 rx1 wx sc1 rx3 s2 at2 sc2 c2
+permutation s1 at1 rx1 wx sc1 rx3 s2 at2 c2 sc2
+permutation s1 at1 rx1 wx sc1 rx3 s2 c2 at2 sc2
+permutation s1 at1 rx1 wx sc1 rx3 c2 s2 at2 sc2
+permutation s1 rx1 at1 sc1 s2 at2 sc2 wx rx3 c2
+permutation s1 rx1 at1 sc1 s2 at2 wx sc2 rx3 c2
+permutation s1 rx1 at1 sc1 s2 at2 wx rx3 sc2 c2
+permutation s1 rx1 at1 sc1 s2 at2 wx rx3 c2 sc2
+permutation s1 rx1 at1 sc1 s2 wx at2 sc2 rx3 c2
+permutation s1 rx1 at1 sc1 s2 wx at2 rx3 sc2 c2
+permutation s1 rx1 at1 sc1 s2 wx at2 rx3 c2 sc2
+permutation s1 rx1 at1 sc1 s2 wx rx3 at2 sc2 c2
+permutation s1 rx1 at1 sc1 s2 wx rx3 at2 c2 sc2
+permutation s1 rx1 at1 sc1 s2 wx rx3 c2 at2 sc2
+permutation s1 rx1 at1 sc1 wx s2 at2 sc2 rx3 c2
+permutation s1 rx1 at1 sc1 wx s2 at2 rx3 sc2 c2
+permutation s1 rx1 at1 sc1 wx s2 at2 rx3 c2 sc2
+permutation s1 rx1 at1 sc1 wx s2 rx3 at2 sc2 c2
+permutation s1 rx1 at1 sc1 wx s2 rx3 at2 c2 sc2
+permutation s1 rx1 at1 sc1 wx s2 rx3 c2 at2 sc2
+permutation s1 rx1 at1 sc1 wx rx3 s2 at2 sc2 c2
+permutation s1 rx1 at1 sc1 wx rx3 s2 at2 c2 sc2
+permutation s1 rx1 at1 sc1 wx rx3 s2 c2 at2 sc2
+permutation s1 rx1 at1 sc1 wx rx3 c2 s2 at2 sc2
+permutation s1 rx1 at1 wx sc1 s2 at2 sc2 rx3 c2
+permutation s1 rx1 at1 wx sc1 s2 at2 rx3 sc2 c2
+permutation s1 rx1 at1 wx sc1 s2 at2 rx3 c2 sc2
+permutation s1 rx1 at1 wx sc1 s2 rx3 at2 sc2 c2
+permutation s1 rx1 at1 wx sc1 s2 rx3 at2 c2 sc2
+permutation s1 rx1 at1 wx sc1 s2 rx3 c2 at2 sc2
+permutation s1 rx1 at1 wx sc1 rx3 s2 at2 sc2 c2
+permutation s1 rx1 at1 wx sc1 rx3 s2 at2 c2 sc2
+permutation s1 rx1 at1 wx sc1 rx3 s2 c2 at2 sc2
+permutation s1 rx1 at1 wx sc1 rx3 c2 s2 at2 sc2
+permutation s1 rx1 wx at1 rx3 c2 sc1 s2 at2 sc2
+permutation s1 rx1 wx rx3 at1 c2 sc1 s2 at2 sc2
+permutation s1 rx1 wx rx3 c2 at1 sc1 s2 at2 sc2
+permutation rx1 s1 at1 sc1 s2 at2 sc2 wx rx3 c2
+permutation rx1 s1 at1 sc1 s2 at2 wx sc2 rx3 c2
+permutation rx1 s1 at1 sc1 s2 at2 wx rx3 sc2 c2
+permutation rx1 s1 at1 sc1 s2 at2 wx rx3 c2 sc2
+permutation rx1 s1 at1 sc1 s2 wx at2 sc2 rx3 c2
+permutation rx1 s1 at1 sc1 s2 wx at2 rx3 sc2 c2
+permutation rx1 s1 at1 sc1 s2 wx at2 rx3 c2 sc2
+permutation rx1 s1 at1 sc1 s2 wx rx3 at2 sc2 c2
+permutation rx1 s1 at1 sc1 s2 wx rx3 at2 c2 sc2
+permutation rx1 s1 at1 sc1 s2 wx rx3 c2 at2 sc2
+permutation rx1 s1 at1 sc1 wx s2 at2 sc2 rx3 c2
+permutation rx1 s1 at1 sc1 wx s2 at2 rx3 sc2 c2
+permutation rx1 s1 at1 sc1 wx s2 at2 rx3 c2 sc2
+permutation rx1 s1 at1 sc1 wx s2 rx3 at2 sc2 c2
+permutation rx1 s1 at1 sc1 wx s2 rx3 at2 c2 sc2
+permutation rx1 s1 at1 sc1 wx s2 rx3 c2 at2 sc2
+permutation rx1 s1 at1 sc1 wx rx3 s2 at2 sc2 c2
+permutation rx1 s1 at1 sc1 wx rx3 s2 at2 c2 sc2
+permutation rx1 s1 at1 sc1 wx rx3 s2 c2 at2 sc2
+permutation rx1 s1 at1 sc1 wx rx3 c2 s2 at2 sc2
+permutation rx1 s1 at1 wx sc1 s2 at2 sc2 rx3 c2
+permutation rx1 s1 at1 wx sc1 s2 at2 rx3 sc2 c2
+permutation rx1 s1 at1 wx sc1 s2 at2 rx3 c2 sc2
+permutation rx1 s1 at1 wx sc1 s2 rx3 at2 sc2 c2
+permutation rx1 s1 at1 wx sc1 s2 rx3 at2 c2 sc2
+permutation rx1 s1 at1 wx sc1 s2 rx3 c2 at2 sc2
+permutation rx1 s1 at1 wx sc1 rx3 s2 at2 sc2 c2
+permutation rx1 s1 at1 wx sc1 rx3 s2 at2 c2 sc2
+permutation rx1 s1 at1 wx sc1 rx3 s2 c2 at2 sc2
+permutation rx1 s1 at1 wx sc1 rx3 c2 s2 at2 sc2
+permutation rx1 s1 wx at1 rx3 c2 sc1 s2 at2 sc2
+permutation rx1 s1 wx rx3 at1 c2 sc1 s2 at2 sc2
+permutation rx1 s1 wx rx3 c2 at1 sc1 s2 at2 sc2
+permutation rx1 wx s1 at1 rx3 c2 sc1 s2 at2 sc2
+permutation rx1 wx s1 rx3 at1 c2 sc1 s2 at2 sc2
+permutation rx1 wx s1 rx3 c2 at1 sc1 s2 at2 sc2
+permutation rx1 wx rx3 s1 at1 c2 sc1 s2 at2 sc2
+permutation rx1 wx rx3 s1 c2 at1 sc1 s2 at2 sc2
+permutation rx1 wx rx3 c2 s1 at1 sc1 s2 at2 sc2
DROP TABLE a, b;
}
-session "s1"
-step "s1a" { BEGIN; }
-step "s1b" { ALTER TABLE b ADD CONSTRAINT bfk FOREIGN KEY (a_id) REFERENCES a (i) NOT VALID; }
-step "s1c" { COMMIT; }
+session s1
+step s1a { BEGIN; }
+step s1b { ALTER TABLE b ADD CONSTRAINT bfk FOREIGN KEY (a_id) REFERENCES a (i) NOT VALID; }
+step s1c { COMMIT; }
-session "s2"
-step "s2a" { BEGIN; }
-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 "s2d" { INSERT INTO b VALUES (0); }
-step "s2e" { INSERT INTO a VALUES (4); }
-step "s2f" { COMMIT; }
+session s2
+step s2a { BEGIN; }
+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 s2d { INSERT INTO b VALUES (0); }
+step s2e { INSERT INTO a VALUES (4); }
+step s2f { COMMIT; }
-permutation "s1a" "s1b" "s1c" "s2a" "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" "s2c" "s1c" "s2d" "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" "s2b" "s1c" "s2c" "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" "s2b" "s1b" "s1c" "s2c" "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" "s2c" "s1b" "s1c" "s2d" "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" "s2e" "s1b" "s2f" "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" "s2b" "s1c" "s2c" "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" "s2b" "s1b" "s1c" "s2c" "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" "s2c" "s1b" "s1c" "s2d" "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" "s2e" "s1b" "s2f" "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" "s2c" "s1c" "s2d" "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" "s2d" "s1c" "s2e" "s2f"
-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" "s2f" "s1b" "s1c"
-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" "s2d" "s1b" "s2e" "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" "s2d" "s1a" "s1b" "s2e" "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" "s2e" "s1a" "s1b" "s2f" "s1c"
-permutation "s2a" "s2b" "s2c" "s2d" "s2e" "s1a" "s2f" "s1b" "s1c"
-permutation "s2a" "s2b" "s2c" "s2d" "s2e" "s2f" "s1a" "s1b" "s1c"
+permutation s1a s1b s1c s2a 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 s2c s1c s2d 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 s2b s1c s2c 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 s2b s1b s1c s2c 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 s2c s1b s1c s2d 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 s2e s1b s2f 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 s2b s1c s2c 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 s2b s1b s1c s2c 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 s2c s1b s1c s2d 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 s2e s1b s2f 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 s2c s1c s2d 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 s2d s1c s2e s2f
+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 s2f s1b s1c
+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 s2d s1b s2e 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 s2d s1a s1b s2e 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 s2e s1a s1b s2f s1c
+permutation s2a s2b s2c s2d s2e s1a s2f s1b s1c
+permutation s2a s2b s2c s2d s2e s2f s1a s1b s1c
DROP FUNCTION f();
}
-session "s1"
-step "s1a" { BEGIN; }
-step "s1b" { ALTER TABLE a DISABLE TRIGGER t; }
-step "s1c" { ALTER TABLE a ENABLE TRIGGER t; }
-step "s1d" { COMMIT; }
+session s1
+step s1a { BEGIN; }
+step s1b { ALTER TABLE a DISABLE TRIGGER t; }
+step s1c { ALTER TABLE a ENABLE TRIGGER t; }
+step s1d { COMMIT; }
-session "s2"
-step "s2a" { BEGIN; }
-step "s2b" { SELECT * FROM a WHERE i = 1 LIMIT 1 FOR UPDATE; }
-step "s2c" { INSERT INTO a VALUES (0); }
-step "s2d" { COMMIT; }
+session s2
+step s2a { BEGIN; }
+step s2b { SELECT * FROM a WHERE i = 1 LIMIT 1 FOR UPDATE; }
+step s2c { INSERT INTO a VALUES (0); }
+step s2d { COMMIT; }
-permutation "s1a" "s1b" "s1c" "s1d" "s2a" "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" "s2c" "s1d" "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" "s2c" "s1d" "s2d"
-permutation "s1a" "s1b" "s2a" "s2b" "s1c" "s1d" "s2c" "s2d"
-permutation "s1a" "s1b" "s2a" "s2b" "s1c" "s2c" "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" "s2b" "s1d" "s2c" "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" "s2c" "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" "s2c" "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" "s2d" "s1d"
-permutation "s1a" "s2a" "s2b" "s2c" "s1b" "s2d" "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" "s2b" "s1d" "s2c" "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" "s2c" "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" "s2c" "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" "s2d" "s1d"
-permutation "s2a" "s1a" "s2b" "s2c" "s1b" "s2d" "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" "s2c" "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" "s2d" "s1d"
-permutation "s2a" "s2b" "s1a" "s2c" "s1b" "s2d" "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" "s2d" "s1d"
-permutation "s2a" "s2b" "s2c" "s1a" "s1b" "s2d" "s1c" "s1d"
-permutation "s2a" "s2b" "s2c" "s1a" "s2d" "s1b" "s1c" "s1d"
-permutation "s2a" "s2b" "s2c" "s2d" "s1a" "s1b" "s1c" "s1d"
+permutation s1a s1b s1c s1d s2a 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 s2c s1d 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 s2c s1d s2d
+permutation s1a s1b s2a s2b s1c s1d s2c s2d
+permutation s1a s1b s2a s2b s1c s2c 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 s2b s1d s2c 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 s2c 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 s2c 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 s2d s1d
+permutation s1a s2a s2b s2c s1b s2d 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 s2b s1d s2c 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 s2c 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 s2c 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 s2d s1d
+permutation s2a s1a s2b s2c s1b s2d 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 s2c 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 s2d s1d
+permutation s2a s2b s1a s2c s1b s2d 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 s2d s1d
+permutation s2a s2b s2c s1a s1b s2d s1c s1d
+permutation s2a s2b s2c s1a s2d s1b s1c s1d
+permutation s2a s2b s2c s2d s1a s1b s1c s1d
DROP TABLE IF EXISTS c1, c2, p;
}
-session "s1"
-step "s1b" { BEGIN; }
-step "s1delc1" { ALTER TABLE c1 NO INHERIT p; }
-step "s1modc1a" { ALTER TABLE c1 ALTER COLUMN a TYPE float; }
-step "s1addc2" { ALTER TABLE c2 INHERIT p; }
-step "s1dropc1" { DROP TABLE c1; }
-step "s1c" { COMMIT; }
+session s1
+step s1b { BEGIN; }
+step s1delc1 { ALTER TABLE c1 NO INHERIT p; }
+step s1modc1a { ALTER TABLE c1 ALTER COLUMN a TYPE float; }
+step s1addc2 { ALTER TABLE c2 INHERIT p; }
+step s1dropc1 { DROP TABLE c1; }
+step s1c { COMMIT; }
-session "s2"
-step "s2sel" { SELECT SUM(a) FROM p; }
+session s2
+step s2sel { SELECT SUM(a) FROM p; }
# NO INHERIT will not be visible to concurrent select,
# 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
-permutation "s1b" "s1delc1" "s1addc2" "s2sel" "s1c" "s2sel"
+permutation s1b s1delc1 s1addc2 s2sel s1c s2sel
# 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
-permutation "s1b" "s1delc1" "s1modc1a" "s2sel" "s1c" "s2sel"
+permutation s1b s1delc1 s1modc1a s2sel s1c s2sel
# Note we assume that each step is delivered to the backend as a single Query
# message so it will run as one transaction.
-session "notifier"
-step "listenc" { LISTEN c1; LISTEN c2; }
-step "notify1" { NOTIFY c1; }
-step "notify2" { NOTIFY c2, 'payload'; }
-step "notify3" { NOTIFY c3, 'payload3'; } # not listening to c3
-step "notifyf" { SELECT pg_notify('c2', NULL); }
-step "notifyd1" { NOTIFY c2, 'payload'; NOTIFY c1; NOTIFY "c2", 'payload'; }
-step "notifyd2" { NOTIFY c1; NOTIFY c1; NOTIFY c1, 'p1'; NOTIFY c1, 'p2'; }
-step "notifys1" {
+session notifier
+step listenc { LISTEN c1; LISTEN c2; }
+step notify1 { NOTIFY c1; }
+step notify2 { NOTIFY c2, 'payload'; }
+step notify3 { NOTIFY c3, 'payload3'; } # not listening to c3
+step notifyf { SELECT pg_notify('c2', NULL); }
+step notifyd1 { NOTIFY c2, 'payload'; NOTIFY c1; NOTIFY "c2", 'payload'; }
+step notifyd2 { NOTIFY c1; NOTIFY c1; NOTIFY c1, 'p1'; NOTIFY c1, 'p2'; }
+step notifys1 {
BEGIN;
NOTIFY c1, 'payload'; NOTIFY "c2", 'payload';
NOTIFY c1, 'payload'; NOTIFY "c2", 'payload';
ROLLBACK TO SAVEPOINT s2;
COMMIT;
}
-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 usage { SELECT pg_notification_queue_usage() > 0 AS nonzero; }
+step bignotify { SELECT count(pg_notify('c1', s::text)) FROM generate_series(1, 1000) s; }
teardown { UNLISTEN *; }
# The listener session is used for cross-backend notify checks.
-session "listener"
-step "llisten" { LISTEN c1; LISTEN c2; }
-step "lcheck" { SELECT 1 AS x; }
-step "lbegin" { BEGIN; }
-step "lbegins" { BEGIN ISOLATION LEVEL SERIALIZABLE; }
-step "lcommit" { COMMIT; }
+session listener
+step llisten { LISTEN c1; LISTEN c2; }
+step lcheck { SELECT 1 AS x; }
+step lbegin { BEGIN; }
+step lbegins { BEGIN ISOLATION LEVEL SERIALIZABLE; }
+step lcommit { COMMIT; }
teardown { UNLISTEN *; }
# In some tests we need a second listener, just to block the queue.
-session "listener2"
-step "l2listen" { LISTEN c1; }
-step "l2begin" { BEGIN; }
-step "l2commit" { COMMIT; }
-step "l2stop" { UNLISTEN *; }
+session listener2
+step l2listen { LISTEN c1; }
+step l2begin { BEGIN; }
+step l2commit { COMMIT; }
+step l2stop { UNLISTEN *; }
# Trivial cases.
-permutation "listenc" "notify1" "notify2" "notify3" "notifyf"
+permutation listenc notify1 notify2 notify3 notifyf
# 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
# listener session to check for notifies. In principle we could just wait
# for delivery, but that would require extra support in isolationtester
# 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.
-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,
# 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,
# after submitting notifications while another connection is listening for
# commit the listener's transaction, so that it never reports these events.
# Hence, this should be the last test in this script.
-permutation "llisten" "lbegin" "usage" "bignotify" "usage"
+permutation llisten lbegin usage bignotify usage
DROP TABLE room_reservation;
}
-session "s1"
+session s1
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 "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 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 c1 { COMMIT; }
-session "s2"
+session s2
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 "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 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 c2 { COMMIT; }
DROP FUNCTION f();
}
-session "s1"
-step "s1a" { BEGIN; }
-step "s1b" { CREATE TRIGGER t AFTER UPDATE ON a EXECUTE PROCEDURE f(); }
-step "s1c" { COMMIT; }
+session s1
+step s1a { BEGIN; }
+step s1b { CREATE TRIGGER t AFTER UPDATE ON a EXECUTE PROCEDURE f(); }
+step s1c { COMMIT; }
-session "s2"
-step "s2a" { BEGIN; }
-step "s2b" { SELECT * FROM a WHERE i = 1 FOR UPDATE; }
-step "s2c" { UPDATE a SET i = 4 WHERE i = 3; }
-step "s2d" { COMMIT; }
+session s2
+step s2a { BEGIN; }
+step s2b { SELECT * FROM a WHERE i = 1 FOR UPDATE; }
+step s2c { UPDATE a SET i = 4 WHERE i = 3; }
+step s2d { COMMIT; }
-permutation "s1a" "s1b" "s1c" "s2a" "s2b" "s2c" "s2d"
-permutation "s1a" "s1b" "s2a" "s1c" "s2b" "s2c" "s2d"
-permutation "s1a" "s1b" "s2a" "s2b" "s1c" "s2c" "s2d"
-permutation "s1a" "s1b" "s2a" "s2b" "s2c" "s1c" "s2d"
-permutation "s1a" "s2a" "s1b" "s1c" "s2b" "s2c" "s2d"
-permutation "s1a" "s2a" "s1b" "s2b" "s1c" "s2c" "s2d"
-permutation "s1a" "s2a" "s1b" "s2b" "s2c" "s1c" "s2d"
-permutation "s1a" "s2a" "s2b" "s1b" "s1c" "s2c" "s2d"
-permutation "s1a" "s2a" "s2b" "s1b" "s2c" "s1c" "s2d"
-permutation "s1a" "s2a" "s2b" "s2c" "s1b" "s2d" "s1c"
-permutation "s1a" "s2a" "s2b" "s2c" "s2d" "s1b" "s1c"
-permutation "s2a" "s1a" "s1b" "s1c" "s2b" "s2c" "s2d"
-permutation "s2a" "s1a" "s1b" "s2b" "s1c" "s2c" "s2d"
-permutation "s2a" "s1a" "s1b" "s2b" "s2c" "s1c" "s2d"
-permutation "s2a" "s1a" "s2b" "s1b" "s1c" "s2c" "s2d"
-permutation "s2a" "s1a" "s2b" "s1b" "s2c" "s1c" "s2d"
-permutation "s2a" "s1a" "s2b" "s2c" "s1b" "s2d" "s1c"
-permutation "s2a" "s1a" "s2b" "s2c" "s2d" "s1b" "s1c"
-permutation "s2a" "s2b" "s1a" "s1b" "s1c" "s2c" "s2d"
-permutation "s2a" "s2b" "s1a" "s1b" "s2c" "s1c" "s2d"
-permutation "s2a" "s2b" "s1a" "s2c" "s1b" "s2d" "s1c"
-permutation "s2a" "s2b" "s1a" "s2c" "s2d" "s1b" "s1c"
-permutation "s2a" "s2b" "s2c" "s1a" "s1b" "s2d" "s1c"
-permutation "s2a" "s2b" "s2c" "s1a" "s2d" "s1b" "s1c"
-permutation "s2a" "s2b" "s2c" "s2d" "s1a" "s1b" "s1c"
+permutation s1a s1b s1c s2a s2b s2c s2d
+permutation s1a s1b s2a s1c s2b s2c s2d
+permutation s1a s1b s2a s2b s1c s2c s2d
+permutation s1a s1b s2a s2b s2c s1c s2d
+permutation s1a s2a s1b s1c s2b s2c s2d
+permutation s1a s2a s1b s2b s1c s2c s2d
+permutation s1a s2a s1b s2b s2c s1c s2d
+permutation s1a s2a s2b s1b s1c s2c s2d
+permutation s1a s2a s2b s1b s2c s1c s2d
+permutation s1a s2a s2b s2c s1b s2d s1c
+permutation s1a s2a s2b s2c s2d s1b s1c
+permutation s2a s1a s1b s1c s2b s2c s2d
+permutation s2a s1a s1b s2b s1c s2c s2d
+permutation s2a s1a s1b s2b s2c s1c s2d
+permutation s2a s1a s2b s1b s1c s2c s2d
+permutation s2a s1a s2b s1b s2c s1c s2d
+permutation s2a s1a s2b s2c s1b s2d s1c
+permutation s2a s1a s2b s2c s2d s1b s1c
+permutation s2a s2b s1a s1b s1c s2c s2d
+permutation s2a s2b s1a s1b s2c s1c s2d
+permutation s2a s2b s1a s2c s1b s2d s1c
+permutation s2a s2b s1a s2c s2d s1b s1c
+permutation s2a s2b s2c s1a s1b s2d s1c
+permutation s2a s2b s2c s1a s2d s1b s1c
+permutation s2a s2b s2c s2d s1a s1b s1c
DROP TABLE a1, a2, a3, a4, a5, a6, a7, a8;
}
-session "s1"
+session s1
setup { BEGIN; SET deadlock_timeout = '100s'; }
-step "s1a1" { LOCK TABLE a1; }
-step "s1a2" { LOCK TABLE a2; }
-step "s1c" { COMMIT; }
+step s1a1 { LOCK TABLE a1; }
+step s1a2 { LOCK TABLE a2; }
+step s1c { COMMIT; }
-session "s2"
+session s2
setup { BEGIN; SET deadlock_timeout = '100s'; }
-step "s2a2" { LOCK TABLE a2; }
-step "s2a3" { LOCK TABLE a3; }
-step "s2c" { COMMIT; }
+step s2a2 { LOCK TABLE a2; }
+step s2a3 { LOCK TABLE a3; }
+step s2c { COMMIT; }
-session "s3"
+session s3
setup { BEGIN; SET deadlock_timeout = '100s'; }
-step "s3a3" { LOCK TABLE a3; }
-step "s3a4" { LOCK TABLE a4; }
-step "s3c" { COMMIT; }
+step s3a3 { LOCK TABLE a3; }
+step s3a4 { LOCK TABLE a4; }
+step s3c { COMMIT; }
-session "s4"
+session s4
setup { BEGIN; SET deadlock_timeout = '100s'; }
-step "s4a4" { LOCK TABLE a4; }
-step "s4a5" { LOCK TABLE a5; }
-step "s4c" { COMMIT; }
+step s4a4 { LOCK TABLE a4; }
+step s4a5 { LOCK TABLE a5; }
+step s4c { COMMIT; }
-session "s5"
+session s5
setup { BEGIN; SET deadlock_timeout = '100s'; }
-step "s5a5" { LOCK TABLE a5; }
-step "s5a6" { LOCK TABLE a6; }
-step "s5c" { COMMIT; }
+step s5a5 { LOCK TABLE a5; }
+step s5a6 { LOCK TABLE a6; }
+step s5c { COMMIT; }
-session "s6"
+session s6
setup { BEGIN; SET deadlock_timeout = '100s'; }
-step "s6a6" { LOCK TABLE a6; }
-step "s6a7" { LOCK TABLE a7; }
-step "s6c" { COMMIT; }
+step s6a6 { LOCK TABLE a6; }
+step s6a7 { LOCK TABLE a7; }
+step s6c { COMMIT; }
-session "s7"
+session s7
setup { BEGIN; SET deadlock_timeout = '100s'; }
-step "s7a7" { LOCK TABLE a7; }
-step "s7a8" { LOCK TABLE a8; }
-step "s7c" { COMMIT; }
+step s7a7 { LOCK TABLE a7; }
+step s7a8 { LOCK TABLE a8; }
+step s7c { COMMIT; }
-session "s8"
+session s8
setup { BEGIN; SET deadlock_timeout = '10ms'; }
-step "s8a8" { LOCK TABLE a8; }
-step "s8a1" { LOCK TABLE a1; }
-step "s8c" { COMMIT; }
+step s8a8 { LOCK TABLE a8; }
+step s8a1 { LOCK TABLE a1; }
+step s8c { COMMIT; }
# Note: when s8a1 detects the deadlock and fails, s7a8 is released, making
# it timing-dependent which query completion is received first by the tester.
# dummy blocking mark to s8a1 to ensure it will be reported as "waiting"
# 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
DROP TABLE a1;
}
-session "s1"
+session s1
setup { BEGIN; }
-step "s1as" { LOCK TABLE a1 IN ACCESS SHARE MODE; }
-step "s1ae" { LOCK TABLE a1 IN ACCESS EXCLUSIVE MODE; }
-step "s1c" { COMMIT; }
+step s1as { LOCK TABLE a1 IN ACCESS SHARE MODE; }
+step s1ae { LOCK TABLE a1 IN ACCESS EXCLUSIVE MODE; }
+step s1c { COMMIT; }
-session "s2"
+session s2
setup { BEGIN; }
-step "s2as" { LOCK TABLE a1 IN ACCESS SHARE MODE; }
-step "s2ae" { LOCK TABLE a1 IN ACCESS EXCLUSIVE MODE; }
-step "s2c" { COMMIT; }
+step s2as { LOCK TABLE a1 IN ACCESS SHARE MODE; }
+step s2ae { LOCK TABLE a1 IN ACCESS EXCLUSIVE MODE; }
+step s2c { COMMIT; }
-permutation "s1as" "s2as" "s1ae" "s2ae" "s1c" "s2c"
+permutation s1as s2as s1ae s2ae s1c s2c
DROP TABLE a1, a2;
}
-session "s1"
+session s1
setup { BEGIN; SET deadlock_timeout = '10ms'; }
-step "s1a" { LOCK TABLE a1 IN SHARE UPDATE EXCLUSIVE MODE; }
-step "s1b" { LOCK TABLE a2 IN SHARE UPDATE EXCLUSIVE MODE; }
-step "s1c" { COMMIT; }
+step s1a { LOCK TABLE a1 IN SHARE UPDATE EXCLUSIVE MODE; }
+step s1b { LOCK TABLE a2 IN SHARE UPDATE EXCLUSIVE MODE; }
+step s1c { COMMIT; }
-session "s2"
+session s2
setup { BEGIN; SET deadlock_timeout = '100s'; }
-step "s2a" { LOCK TABLE a2 IN ACCESS SHARE MODE; }
-step "s2b" { LOCK TABLE a1 IN SHARE UPDATE EXCLUSIVE MODE; }
-step "s2c" { COMMIT; }
+step s2a { LOCK TABLE a2 IN ACCESS SHARE MODE; }
+step s2b { LOCK TABLE a1 IN SHARE UPDATE EXCLUSIVE MODE; }
+step s2c { COMMIT; }
-session "s3"
+session s3
setup { BEGIN; SET deadlock_timeout = '100s'; }
-step "s3a" { LOCK TABLE a2 IN ACCESS EXCLUSIVE MODE; }
-step "s3c" { COMMIT; }
+step s3a { LOCK TABLE a2 IN ACCESS EXCLUSIVE MODE; }
+step s3c { COMMIT; }
-session "s4"
+session s4
setup { BEGIN; SET deadlock_timeout = '100s'; }
-step "s4a" { LOCK TABLE a2 IN ACCESS EXCLUSIVE MODE; }
-step "s4c" { COMMIT; }
+step s4a { LOCK TABLE a2 IN ACCESS EXCLUSIVE MODE; }
+step s4c { COMMIT; }
# The expected output for this test assumes that isolationtester will
# detect step s1b as waiting before the deadlock detector runs and
# releases s1 from its blocked state. To ensure that happens even in
# 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
DROP TABLE a1, a2;
}
-session "d1"
+session d1
setup { BEGIN; SET deadlock_timeout = '10s'; }
-step "d1a1" { LOCK TABLE a1 IN ACCESS SHARE MODE; }
-step "d1a2" { LOCK TABLE a2 IN ACCESS SHARE MODE; }
-step "d1c" { COMMIT; }
+step d1a1 { LOCK TABLE a1 IN ACCESS SHARE MODE; }
+step d1a2 { LOCK TABLE a2 IN ACCESS SHARE MODE; }
+step d1c { COMMIT; }
-session "d2"
+session d2
setup { BEGIN; SET deadlock_timeout = '10ms'; }
-step "d2a2" { LOCK TABLE a2 IN ACCESS SHARE MODE; }
-step "d2a1" { LOCK TABLE a1 IN ACCESS SHARE MODE; }
-step "d2c" { COMMIT; }
+step d2a2 { LOCK TABLE a2 IN ACCESS SHARE MODE; }
+step d2a1 { LOCK TABLE a1 IN ACCESS SHARE MODE; }
+step d2c { COMMIT; }
-session "e1"
+session e1
setup { BEGIN; SET deadlock_timeout = '10s'; }
-step "e1l" { LOCK TABLE a1 IN ACCESS EXCLUSIVE MODE; }
-step "e1c" { COMMIT; }
+step e1l { LOCK TABLE a1 IN ACCESS EXCLUSIVE MODE; }
+step e1c { COMMIT; }
-session "e2"
+session e2
setup { BEGIN; SET deadlock_timeout = '10s'; }
-step "e2l" { LOCK TABLE a2 IN ACCESS EXCLUSIVE MODE; }
-step "e2c" { COMMIT; }
+step e2l { LOCK TABLE a2 IN ACCESS EXCLUSIVE MODE; }
+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
DROP TABLE foo;
}
-session "s1"
+session s1
setup { BEGIN; }
-step "s1l" { SELECT * FROM foo FOR KEY SHARE; }
-step "s1svp" { SAVEPOINT f; }
-step "s1d" { SELECT * FROM foo FOR NO KEY UPDATE; }
-step "s1r" { ROLLBACK TO f; }
-step "s1c" { COMMIT; }
+step s1l { SELECT * FROM foo FOR KEY SHARE; }
+step s1svp { SAVEPOINT f; }
+step s1d { SELECT * FROM foo FOR NO KEY UPDATE; }
+step s1r { ROLLBACK TO f; }
+step s1c { COMMIT; }
-session "s2"
+session s2
setup { BEGIN; }
-step "s2l" { SELECT * FROM foo FOR UPDATE; }
-step "s2l2" { SELECT * FROM foo FOR NO KEY UPDATE; }
-step "s2c" { COMMIT; }
+step s2l { SELECT * FROM foo FOR UPDATE; }
+step s2l2 { SELECT * FROM foo FOR NO KEY UPDATE; }
+step s2c { COMMIT; }
-permutation "s1l" "s1svp" "s1d" "s1r" "s2l" "s1c" "s2c"
-permutation "s1l" "s1svp" "s1d" "s2l" "s1r" "s1c" "s2c"
-permutation "s1l" "s1svp" "s1d" "s1r" "s2l2" "s1c" "s2c"
-permutation "s1l" "s1svp" "s1d" "s2l2" "s1r" "s1c" "s2c"
+permutation s1l s1svp s1d s1r s2l s1c s2c
+permutation s1l s1svp s1d s2l s1r s1c s2c
+permutation s1l s1svp s1d s1r s2l2 s1c s2c
+permutation s1l s1svp s1d s2l2 s1r s1c s2c
DROP TABLE foo;
}
-session "s1"
+session s1
setup { BEGIN; }
-step "s1l" { SELECT * FROM foo FOR KEY SHARE; }
-step "s1svp" { SAVEPOINT f; }
-step "s1d" { DELETE FROM foo; }
-step "s1r" { ROLLBACK TO f; }
-step "s1c" { COMMIT; }
+step s1l { SELECT * FROM foo FOR KEY SHARE; }
+step s1svp { SAVEPOINT f; }
+step s1d { DELETE FROM foo; }
+step s1r { ROLLBACK TO f; }
+step s1c { COMMIT; }
-session "s2"
+session s2
setup { BEGIN; }
-step "s2l" { SELECT * FROM foo FOR UPDATE; }
-step "s2c" { COMMIT; }
+step s2l { SELECT * FROM foo FOR UPDATE; }
+step s2c { COMMIT; }
-permutation "s1l" "s1svp" "s1d" "s1r" "s1c" "s2l" "s2c"
-permutation "s1l" "s1svp" "s1d" "s1r" "s2l" "s1c" "s2c"
-permutation "s1l" "s1svp" "s1d" "s2l" "s1r" "s1c" "s2c"
-permutation "s1l" "s1svp" "s2l" "s1d" "s1r" "s1c" "s2c"
-permutation "s1l" "s2l" "s1svp" "s1d" "s1r" "s1c" "s2c"
-permutation "s2l" "s1l" "s2c" "s1svp" "s1d" "s1r" "s1c"
-permutation "s2l" "s2c" "s1l" "s1svp" "s1d" "s1r" "s1c"
+permutation s1l s1svp s1d s1r s1c s2l s2c
+permutation s1l s1svp s1d s1r s2l s1c s2c
+permutation s1l s1svp s1d s2l s1r s1c s2c
+permutation s1l s1svp s2l s1d s1r s1c s2c
+permutation s1l s2l s1svp s1d s1r s1c s2c
+permutation s2l s1l s2c s1svp s1d s1r s1c
+permutation s2l s2c s1l s1svp s1d s1r s1c
DROP TABLE test_dc;
}
-session "s1"
-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 "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 "begin" { BEGIN; }
-step "explaini" { EXPLAIN (COSTS OFF) EXECUTE getrow_idx; }
-step "explains" { EXPLAIN (COSTS OFF) EXECUTE getrow_seq; }
-step "selecti" { EXECUTE getrow_idx; }
-step "selects" { EXECUTE getrow_seq; }
-step "end" { COMMIT; }
+session s1
+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 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 begin { BEGIN; }
+step explaini { EXPLAIN (COSTS OFF) EXECUTE getrow_idx; }
+step explains { EXPLAIN (COSTS OFF) EXECUTE getrow_seq; }
+step selecti { EXECUTE getrow_idx; }
+step selects { EXECUTE getrow_seq; }
+step end { COMMIT; }
-session "s2"
+session s2
setup { BEGIN; }
-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 "end2" { COMMIT; }
+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 end2 { COMMIT; }
-session "s3"
-step "drop" { DROP INDEX CONCURRENTLY test_dc_data; }
+session s3
+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
}
-session "s0"
-step "s0_rep" { SELECT * FROM trigtest ORDER BY key, data }
+session s0
+step s0_rep { SELECT * FROM trigtest ORDER BY key, data }
-session "s1"
+session s1
#setup { }
-step "s1_b_rc" { BEGIN ISOLATION LEVEL READ COMMITTED; SELECT 1; }
-step "s1_b_rr" { BEGIN ISOLATION LEVEL REPEATABLE READ; SELECT 1; }
-step "s1_c" { COMMIT; }
-step "s1_r" { ROLLBACK; }
-step "s1_trig_rep_b_i" { CREATE TRIGGER rep_b_i BEFORE INSERT ON trigtest FOR EACH ROW EXECUTE PROCEDURE trig_report(); }
-step "s1_trig_rep_a_i" { CREATE TRIGGER rep_a_i AFTER INSERT ON trigtest FOR EACH ROW EXECUTE PROCEDURE trig_report(); }
-step "s1_trig_rep_b_u" { CREATE TRIGGER rep_b_u BEFORE UPDATE ON trigtest FOR EACH ROW EXECUTE PROCEDURE trig_report(); }
-step "s1_trig_rep_a_u" { CREATE TRIGGER rep_a_u AFTER UPDATE ON trigtest FOR EACH ROW EXECUTE PROCEDURE trig_report(); }
-step "s1_trig_rep_b_d" { CREATE TRIGGER rep_b_d BEFORE DELETE ON trigtest FOR EACH ROW EXECUTE PROCEDURE trig_report(); }
-step "s1_trig_rep_a_d" { CREATE TRIGGER rep_a_d AFTER DELETE ON trigtest FOR EACH ROW EXECUTE PROCEDURE trig_report(); }
-step "s1_ins_a" { INSERT INTO trigtest VALUES ('key-a', 'val-a-s1') RETURNING *; }
-step "s1_ins_b" { INSERT INTO trigtest VALUES ('key-b', 'val-b-s1') RETURNING *; }
-step "s1_ins_c" { INSERT INTO trigtest VALUES ('key-c', 'val-c-s1') RETURNING *; }
-step "s1_del_a" {
+step s1_b_rc { BEGIN ISOLATION LEVEL READ COMMITTED; SELECT 1; }
+step s1_b_rr { BEGIN ISOLATION LEVEL REPEATABLE READ; SELECT 1; }
+step s1_c { COMMIT; }
+step s1_r { ROLLBACK; }
+step s1_trig_rep_b_i { CREATE TRIGGER rep_b_i BEFORE INSERT ON trigtest FOR EACH ROW EXECUTE PROCEDURE trig_report(); }
+step s1_trig_rep_a_i { CREATE TRIGGER rep_a_i AFTER INSERT ON trigtest FOR EACH ROW EXECUTE PROCEDURE trig_report(); }
+step s1_trig_rep_b_u { CREATE TRIGGER rep_b_u BEFORE UPDATE ON trigtest FOR EACH ROW EXECUTE PROCEDURE trig_report(); }
+step s1_trig_rep_a_u { CREATE TRIGGER rep_a_u AFTER UPDATE ON trigtest FOR EACH ROW EXECUTE PROCEDURE trig_report(); }
+step s1_trig_rep_b_d { CREATE TRIGGER rep_b_d BEFORE DELETE ON trigtest FOR EACH ROW EXECUTE PROCEDURE trig_report(); }
+step s1_trig_rep_a_d { CREATE TRIGGER rep_a_d AFTER DELETE ON trigtest FOR EACH ROW EXECUTE PROCEDURE trig_report(); }
+step s1_ins_a { INSERT INTO trigtest VALUES ('key-a', 'val-a-s1') RETURNING *; }
+step s1_ins_b { INSERT INTO trigtest VALUES ('key-b', 'val-b-s1') RETURNING *; }
+step s1_ins_c { INSERT INTO trigtest VALUES ('key-c', 'val-c-s1') RETURNING *; }
+step s1_del_a {
DELETE FROM trigtest
WHERE
noisy_oper('upd', key, '=', 'key-a') AND
noisy_oper('upk', data, '<>', 'mismatch')
RETURNING *
}
-step "s1_del_b" {
+step s1_del_b {
DELETE FROM trigtest
WHERE
noisy_oper('upd', key, '=', 'key-b') AND
noisy_oper('upk', data, '<>', 'mismatch')
RETURNING *
}
-step "s1_upd_a_data" {
+step s1_upd_a_data {
UPDATE trigtest SET data = data || '-ups1'
WHERE
noisy_oper('upd', key, '=', 'key-a') AND
noisy_oper('upk', data, '<>', 'mismatch')
RETURNING *;
}
-step "s1_upd_b_data" {
+step s1_upd_b_data {
UPDATE trigtest SET data = data || '-ups1'
WHERE
noisy_oper('upd', key, '=', 'key-b') AND
noisy_oper('upk', data, '<>', 'mismatch')
RETURNING *;
}
-step "s1_upd_a_tob" {
+step s1_upd_a_tob {
UPDATE trigtest SET key = 'key-b', data = data || '-tobs1'
WHERE
noisy_oper('upk', key, '=', 'key-a') AND
RETURNING *;
}
-session "s2"
+session s2
#setup { }
-step "s2_b_rc" { BEGIN ISOLATION LEVEL READ COMMITTED; SELECT 1; }
-step "s2_b_rr" { BEGIN ISOLATION LEVEL REPEATABLE READ; SELECT 1; }
-step "s2_c" { COMMIT; }
-#step "s2_r" { ROLLBACK; }
-step "s2_ins_a" { INSERT INTO trigtest VALUES ('key-a', 'val-a-s2') RETURNING *; }
-step "s2_del_a" {
+step s2_b_rc { BEGIN ISOLATION LEVEL READ COMMITTED; SELECT 1; }
+step s2_b_rr { BEGIN ISOLATION LEVEL REPEATABLE READ; SELECT 1; }
+step s2_c { COMMIT; }
+#step s2_r { ROLLBACK; }
+step s2_ins_a { INSERT INTO trigtest VALUES ('key-a', 'val-a-s2') RETURNING *; }
+step s2_del_a {
DELETE FROM trigtest
WHERE
noisy_oper('upd', key, '=', 'key-a') AND
noisy_oper('upk', data, '<>', 'mismatch')
RETURNING *
}
-step "s2_upd_a_data" {
+step s2_upd_a_data {
UPDATE trigtest SET data = data || '-ups2'
WHERE
noisy_oper('upd', key, '=', 'key-a') AND
noisy_oper('upk', data, '<>', 'mismatch')
RETURNING *;
}
-step "s2_upd_b_data" {
+step s2_upd_b_data {
UPDATE trigtest SET data = data || '-ups2'
WHERE
noisy_oper('upd', key, '=', 'key-b') AND
noisy_oper('upk', data, '<>', 'mismatch')
RETURNING *;
}
-step "s2_upd_all_data" {
+step s2_upd_all_data {
UPDATE trigtest SET data = data || '-ups2'
WHERE
noisy_oper('upd', key, '<>', 'mismatch') AND
noisy_oper('upk', data, '<>', 'mismatch')
RETURNING *;
}
-step "s2_upsert_a_data" {
+step s2_upsert_a_data {
INSERT INTO trigtest VALUES ('key-a', 'val-a-upss2')
ON CONFLICT (key)
DO UPDATE SET data = trigtest.data || '-upserts2'
RETURNING *;
}
-#session "s3"
+#session s3
#setup { }
-#step "s3_b_rc" { BEGIN ISOLATION LEVEL READ COMMITTED; SELECT 1; }
-#step "s3_c" { COMMIT; }
-#step "s3_r" { ROLLBACK; }
-#step "s3_del_a" {
+#step s3_b_rc { BEGIN ISOLATION LEVEL READ COMMITTED; SELECT 1; }
+#step s3_c { COMMIT; }
+#step s3_r { ROLLBACK; }
+#step s3_del_a {
# DELETE FROM trigtest
# WHERE
# noisy_oper('upd', key, '=', 'key-a') AND
# noisy_oper('upk', data, '<>', 'mismatch')
# RETURNING *
#}
-#step "s3_upd_a_data" {
+#step s3_upd_a_data {
# UPDATE trigtest SET data = data || '-ups3'
# WHERE
# noisy_oper('upd', key, '=', 'key-a') AND
### base case verifying that triggers see performed modifications
# s1 updates, s1 commits, s2 updates
-permutation "s1_trig_rep_b_u" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_data" "s1_c" "s2_upd_a_data" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_u s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_upd_a_data s1_c s2_upd_a_data s2_c
+ s0_rep
# s1 updates, s1 rolls back, s2 updates
-permutation "s1_trig_rep_b_u" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_data" "s1_r" "s2_upd_a_data" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_u s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_upd_a_data s1_r s2_upd_a_data s2_c
+ s0_rep
# s1 updates, s1 commits back, s2 deletes
-permutation "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_data" "s1_c" "s2_del_a" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_upd_a_data s1_c s2_del_a s2_c
+ s0_rep
# s1 updates, s1 rolls back back, s2 deletes
-permutation "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_data" "s1_r" "s2_del_a" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_upd_a_data s1_r s2_del_a s2_c
+ s0_rep
### Verify EPQ is performed if necessary, and skipped if transaction rolled back
# s1 updates, s2 updates, s1 commits, EPQ
-permutation "s1_trig_rep_b_u" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_data" "s2_upd_a_data" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_u s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_upd_a_data s2_upd_a_data s1_c s2_c
+ s0_rep
# s1 updates, s2 updates, s1 rolls back, no EPQ
-permutation "s1_trig_rep_b_u" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_data" "s2_upd_a_data" "s1_r" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_u s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_upd_a_data s2_upd_a_data s1_r s2_c
+ s0_rep
# s1 updates, s2 deletes, s1 commits, EPQ
-permutation "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_data" "s2_upd_a_data" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_upd_a_data s2_upd_a_data s1_c s2_c
+ s0_rep
# s1 updates, s2 deletes, s1 rolls back, no EPQ
-permutation "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_data" "s2_upd_a_data" "s1_r" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_upd_a_data s2_upd_a_data s1_r s2_c
+ s0_rep
# s1 deletes, s2 updates, s1 commits, EPQ
-permutation "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_del_a" "s2_upd_a_data" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_del_a s2_upd_a_data s1_c s2_c
+ s0_rep
# s1 deletes, s2 updates, s1 rolls back, no EPQ
-permutation "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_del_a" "s2_upd_a_data" "s1_r" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_del_a s2_upd_a_data s1_r s2_c
+ s0_rep
# s1 inserts, s2 inserts, s1 commits, s2 inserts, unique conflict
-permutation "s1_trig_rep_b_i" "s1_trig_rep_b_d" "s1_trig_rep_a_i" "s1_trig_rep_a_d"
- "s1_b_rc" "s2_b_rc"
- "s1_ins_a" "s2_ins_a" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_i s1_trig_rep_b_d s1_trig_rep_a_i s1_trig_rep_a_d
+ s1_b_rc s2_b_rc
+ s1_ins_a s2_ins_a s1_c s2_c
+ s0_rep
# s1 inserts, s2 inserts, s1 rolls back, s2 inserts, no unique conflict
-permutation "s1_trig_rep_b_i" "s1_trig_rep_b_d" "s1_trig_rep_a_i" "s1_trig_rep_a_d"
- "s1_b_rc" "s2_b_rc"
- "s1_ins_a" "s2_ins_a" "s1_r" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_i s1_trig_rep_b_d s1_trig_rep_a_i s1_trig_rep_a_d
+ s1_b_rc s2_b_rc
+ s1_ins_a s2_ins_a s1_r s2_c
+ s0_rep
# s1 updates, s2 upserts, s1 commits, EPQ
-permutation "s1_trig_rep_b_i" "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_i" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_data" "s2_upsert_a_data" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_i s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_i s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_upd_a_data s2_upsert_a_data s1_c s2_c
+ s0_rep
# s1 updates, s2 upserts, s1 rolls back, no EPQ
-permutation "s1_trig_rep_b_i" "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_i" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_data" "s2_upsert_a_data" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_i s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_i s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_upd_a_data s2_upsert_a_data s1_c s2_c
+ s0_rep
# s1 inserts, s2 upserts, s1 commits
-permutation "s1_trig_rep_b_i" "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_i" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_b_rc" "s2_b_rc"
- "s1_ins_a" "s2_upsert_a_data" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_i s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_i s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_b_rc s2_b_rc
+ s1_ins_a s2_upsert_a_data s1_c s2_c
+ s0_rep
# s1 inserts, s2 upserts, s1 rolls back
-permutation "s1_trig_rep_b_i" "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_i" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_b_rc" "s2_b_rc"
- "s1_ins_a" "s2_upsert_a_data" "s1_r" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_i s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_i s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_b_rc s2_b_rc
+ s1_ins_a s2_upsert_a_data s1_r s2_c
+ s0_rep
# s1 inserts, s2 upserts, s1 updates, s1 commits, EPQ
-permutation "s1_trig_rep_b_i" "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_i" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_b_rc" "s2_b_rc"
- "s1_ins_a" "s1_upd_a_data" "s2_upsert_a_data" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_i s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_i s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_b_rc s2_b_rc
+ s1_ins_a s1_upd_a_data s2_upsert_a_data s1_c s2_c
+ s0_rep
# s1 inserts, s2 upserts, s1 updates, s1 rolls back, no EPQ
-permutation "s1_trig_rep_b_i" "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_i" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_b_rc" "s2_b_rc"
- "s1_ins_a" "s1_upd_a_data" "s2_upsert_a_data" "s1_r" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_i s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_i s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_b_rc s2_b_rc
+ s1_ins_a s1_upd_a_data s2_upsert_a_data s1_r s2_c
+ s0_rep
### Verify EPQ is performed if necessary, and skipped if transaction rolled back,
### just without before triggers (for comparison, no additional row locks)
# s1 updates, s2 updates, s1 commits, EPQ
-permutation "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_data" "s2_upd_a_data" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_upd_a_data s2_upd_a_data s1_c s2_c
+ s0_rep
# s1 updates, s2 updates, s1 rolls back, no EPQ
-permutation "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_data" "s2_upd_a_data" "s1_r" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_upd_a_data s2_upd_a_data s1_r s2_c
+ s0_rep
# s1 updates, s2 deletes, s1 commits, EPQ
-permutation "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_data" "s2_del_a" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_upd_a_data s2_del_a s1_c s2_c
+ s0_rep
# s1 updates, s2 deletes, s1 rolls back, no EPQ
-permutation "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_data" "s2_del_a" "s1_r" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_upd_a_data s2_del_a s1_r s2_c
+ s0_rep
# s1 deletes, s2 updates, s1 commits, EPQ
-permutation "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_del_a" "s2_upd_a_data" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_del_a s2_upd_a_data s1_c s2_c
+ s0_rep
# s1 deletes, s2 updates, s1 rolls back, no EPQ
-permutation "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_del_a" "s2_upd_a_data" "s1_r" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_del_a s2_upd_a_data s1_r s2_c
+ s0_rep
# s1 deletes, s2 deletes, s1 commits, EPQ
-permutation "s1_trig_rep_a_d"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_del_a" "s2_del_a" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_a_d
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_del_a s2_del_a s1_c s2_c
+ s0_rep
# s1 deletes, s2 deletes, s1 rolls back, no EPQ
-permutation "s1_trig_rep_a_d"
- "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_del_a" "s2_del_a" "s1_r" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_a_d
+ s1_ins_a s1_ins_b s1_b_rc s2_b_rc
+ s1_del_a s2_del_a s1_r s2_c
+ s0_rep
### Verify that an update affecting a row that has been
### updated/deleted to not match the where clause anymore works
### correctly
# s1 updates to different key, s2 updates old key, s1 commits, EPQ failure should lead to no update
-permutation "s1_trig_rep_b_u" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_c" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_tob" "s2_upd_a_data" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_u s1_trig_rep_a_u
+ s1_ins_a s1_ins_c s1_b_rc s2_b_rc
+ s1_upd_a_tob s2_upd_a_data s1_c s2_c
+ s0_rep
# s1 updates to different key, s2 updates old key, s1 rolls back, no EPQ failure
-permutation "s1_trig_rep_b_u" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_c" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_tob" "s2_upd_a_data" "s1_r" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_u s1_trig_rep_a_u
+ s1_ins_a s1_ins_c s1_b_rc s2_b_rc
+ s1_upd_a_tob s2_upd_a_data s1_r s2_c
+ s0_rep
# s1 updates to different key, s2 updates new key, s1 commits, s2 will
# not see tuple with new key and not block
-permutation "s1_trig_rep_b_u" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_c" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_tob" "s2_upd_b_data" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_u s1_trig_rep_a_u
+ s1_ins_a s1_ins_c s1_b_rc s2_b_rc
+ s1_upd_a_tob s2_upd_b_data s1_c s2_c
+ s0_rep
# s1 updates to different key, s2 updates all keys, s1 commits, s2,
# will not see tuple with old key, but block on old, and then follow
# the chain
-permutation "s1_trig_rep_b_u" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_c" "s1_b_rc" "s2_b_rc"
- "s1_upd_a_tob" "s2_upd_all_data" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_u s1_trig_rep_a_u
+ s1_ins_a s1_ins_c s1_b_rc s2_b_rc
+ s1_upd_a_tob s2_upd_all_data s1_c s2_c
+ s0_rep
# s1 deletes, s2 updates, s1 committs, EPQ failure should lead to no update
-permutation "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_c" "s1_b_rc" "s2_b_rc"
- "s1_del_a" "s2_upd_a_data" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_ins_a s1_ins_c s1_b_rc s2_b_rc
+ s1_del_a s2_upd_a_data s1_c s2_c
+ s0_rep
# s1 deletes, s2 updates, s1 rolls back, no EPQ failure
-permutation "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_c" "s1_b_rc" "s2_b_rc"
- "s1_del_a" "s2_upd_a_data" "s1_r" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_ins_a s1_ins_c s1_b_rc s2_b_rc
+ s1_del_a s2_upd_a_data s1_r s2_c
+ s0_rep
# s1 deletes, s2 deletes, s1 committs, EPQ failure should lead to no delete
-permutation "s1_trig_rep_b_d" "s1_trig_rep_a_d"
- "s1_ins_a" "s1_ins_c" "s1_b_rc" "s2_b_rc"
- "s1_del_a" "s2_del_a" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_d s1_trig_rep_a_d
+ s1_ins_a s1_ins_c s1_b_rc s2_b_rc
+ s1_del_a s2_del_a s1_c s2_c
+ s0_rep
# s1 deletes, s2 deletes, s1 rolls back, no EPQ failure
-permutation "s1_trig_rep_b_d" "s1_trig_rep_a_d"
- "s1_ins_a" "s1_ins_c" "s1_b_rc" "s2_b_rc"
- "s1_del_a" "s2_del_a" "s1_r" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_d s1_trig_rep_a_d
+ s1_ins_a s1_ins_c s1_b_rc s2_b_rc
+ s1_del_a s2_del_a s1_r s2_c
+ s0_rep
### Verify EPQ with more than two participants works
## XXX: Disable tests, there is some potential for instability here that's not yet fully understood
## s1 updates, s2 updates, s3 updates, s1 commits, s2 EPQ, s2 commits, s3 EPQ
-#permutation "s1_trig_rep_b_u" "s1_trig_rep_a_u"
-# "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc" "s3_b_rc"
-# "s1_upd_a_data" "s2_upd_a_data" "s3_upd_a_data" "s1_c" "s2_c" "s3_c"
-# "s0_rep"
+#permutation s1_trig_rep_b_u s1_trig_rep_a_u
+# s1_ins_a s1_ins_b s1_b_rc s2_b_rc s3_b_rc
+# s1_upd_a_data s2_upd_a_data s3_upd_a_data s1_c s2_c s3_c
+# s0_rep
## s1 updates, s2 updates, s3 updates, s1 commits, s2 EPQ, s2 rolls back, s3 EPQ
-#permutation "s1_trig_rep_b_u" "s1_trig_rep_a_u"
-# "s1_ins_a" "s1_ins_b" "s1_b_rc" "s2_b_rc" "s3_b_rc"
-# "s1_upd_a_data" "s2_upd_a_data" "s3_upd_a_data" "s1_c" "s2_r" "s3_c"
-# "s0_rep"
+#permutation s1_trig_rep_b_u s1_trig_rep_a_u
+# s1_ins_a s1_ins_b s1_b_rc s2_b_rc s3_b_rc
+# s1_upd_a_data s2_upd_a_data s3_upd_a_data s1_c s2_r s3_c
+# s0_rep
## s1 updates, s3 updates, s2 upserts, s1 updates, s1 commits, s3 EPQ, s3 deletes, s3 commits, s2 inserts without EPQ recheck
-#permutation "s1_trig_rep_b_i" "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_i" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
-# "s1_ins_a" "s1_b_rc" "s2_b_rc" "s3_b_rc"
-# "s1_upd_a_data" "s3_upd_a_data" "s2_upsert_a_data" "s1_upd_a_data" "s1_c" "s3_del_a" "s3_c" "s2_c"
-# "s0_rep"
+#permutation s1_trig_rep_b_i s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_i s1_trig_rep_a_d s1_trig_rep_a_u
+# s1_ins_a s1_b_rc s2_b_rc s3_b_rc
+# s1_upd_a_data s3_upd_a_data s2_upsert_a_data s1_upd_a_data s1_c s3_del_a s3_c s2_c
+# s0_rep
## s1 updates, s3 updates, s2 upserts, s1 updates, s1 commits, s3 EPQ, s3 deletes, s3 rolls back, s2 EPQ
-#permutation "s1_trig_rep_b_i" "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_i" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
-# "s1_ins_a" "s1_b_rc" "s2_b_rc" "s3_b_rc"
-# "s1_upd_a_data" "s3_upd_a_data" "s2_upsert_a_data" "s1_upd_a_data" "s1_c" "s3_del_a" "s3_r" "s2_c"
-# "s0_rep"
+#permutation s1_trig_rep_b_i s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_i s1_trig_rep_a_d s1_trig_rep_a_u
+# s1_ins_a s1_b_rc s2_b_rc s3_b_rc
+# s1_upd_a_data s3_upd_a_data s2_upsert_a_data s1_upd_a_data s1_c s3_del_a s3_r s2_c
+# s0_rep
### Document that EPQ doesn't "leap" onto a tuple that would match after blocking
# s1 inserts a, s1 updates b, s2 updates b, s1 deletes b, s1 updates a to b, s1 commits, s2 EPQ finds tuple deleted
-permutation "s1_trig_rep_b_i" "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_i" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_ins_b" "s1_b_rc" "s2_b_rc"
- "s1_ins_a" "s1_upd_b_data" "s2_upd_b_data" "s1_del_b" "s1_upd_a_tob" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_i s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_i s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_ins_b s1_b_rc s2_b_rc
+ s1_ins_a s1_upd_b_data s2_upd_b_data s1_del_b s1_upd_a_tob s1_c s2_c
+ s0_rep
### Triggers for EPQ detect serialization failures
# s1 updates, s2 updates, s1 commits, serialization failure
-permutation "s1_trig_rep_b_u" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rr" "s2_b_rr"
- "s1_upd_a_data" "s2_upd_a_data" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_u s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rr s2_b_rr
+ s1_upd_a_data s2_upd_a_data s1_c s2_c
+ s0_rep
# s1 updates, s2 updates, s1 rolls back, s2 succeeds
-permutation "s1_trig_rep_b_u" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rr" "s2_b_rr"
- "s1_upd_a_data" "s2_upd_a_data" "s1_r" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_u s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rr s2_b_rr
+ s1_upd_a_data s2_upd_a_data s1_r s2_c
+ s0_rep
# s1 deletes, s2 updates, s1 commits, serialization failure
-permutation "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rr" "s2_b_rr"
- "s1_del_a" "s2_upd_a_data" "s1_c" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rr s2_b_rr
+ s1_del_a s2_upd_a_data s1_c s2_c
+ s0_rep
# s1 deletes, s2 updates, s1 rolls back, s2 succeeds
-permutation "s1_trig_rep_b_d" "s1_trig_rep_b_u" "s1_trig_rep_a_d" "s1_trig_rep_a_u"
- "s1_ins_a" "s1_ins_b" "s1_b_rr" "s2_b_rr"
- "s1_del_a" "s2_upd_a_data" "s1_r" "s2_c"
- "s0_rep"
+permutation s1_trig_rep_b_d s1_trig_rep_b_u s1_trig_rep_a_d s1_trig_rep_a_u
+ s1_ins_a s1_ins_b s1_b_rr s2_b_rr
+ s1_del_a s2_upd_a_data s1_r s2_c
+ s0_rep
DROP TABLE parttbl;
}
-session "s1"
+session s1
setup { BEGIN ISOLATION LEVEL READ COMMITTED; }
# wx1 then wx2 checks the basic case of re-fetching up-to-date values
-step "wx1" { UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking'; }
+step wx1 { UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking'; }
# wy1 then wy2 checks the case where quals pass then fail
-step "wy1" { UPDATE accounts SET balance = balance + 500 WHERE accountid = 'checking'; }
+step wy1 { UPDATE accounts SET balance = balance + 500 WHERE accountid = 'checking'; }
# upsert tests are to check writable-CTE cases
-step "upsert1" {
+step upsert1 {
WITH upsert AS
(UPDATE accounts SET balance = balance + 500
WHERE accountid = 'savings'
# when the first updated tuple was in a non-first child table.
# writep2/returningp1 tests a memory allocation issue
-step "readp1" { SELECT tableoid::regclass, ctid, * FROM p WHERE b IN (0, 1) AND c = 0 FOR UPDATE; }
-step "writep1" { UPDATE p SET b = -1 WHERE a = 1 AND b = 1 AND c = 0; }
-step "writep2" { UPDATE p SET b = -b WHERE a = 1 AND c = 0; }
-step "c1" { COMMIT; }
+step readp1 { SELECT tableoid::regclass, ctid, * FROM p WHERE b IN (0, 1) AND c = 0 FOR UPDATE; }
+step writep1 { UPDATE p SET b = -1 WHERE a = 1 AND b = 1 AND c = 0; }
+step writep2 { UPDATE p SET b = -b WHERE a = 1 AND c = 0; }
+step c1 { COMMIT; }
# these tests are meant to exercise EvalPlanQualFetchRowMarks,
# ie, handling non-locked tables in an EvalPlanQual recheck
-step "partiallock" {
+step partiallock {
SELECT * FROM accounts a1, accounts a2
WHERE a1.accountid = a2.accountid
FOR UPDATE OF a1;
}
-step "lockwithvalues" {
+step lockwithvalues {
SELECT * FROM accounts a1, (values('checking'),('savings')) v(id)
WHERE a1.accountid = v.id
FOR UPDATE OF a1;
# these tests exercise EvalPlanQual with a SubLink sub-select (which should be
# unaffected by any EPQ recheck behavior in the outer query); cf bug #14034
-step "updateforss" {
+step updateforss {
UPDATE table_a SET value = 'newTableAValue' WHERE id = 1;
UPDATE table_b SET value = 'newTableBValue' WHERE id = 1;
}
# these tests exercise EvalPlanQual with conditional InitPlans which
# have not been executed prior to the EPQ
-step "updateforcip" {
+step updateforcip {
UPDATE table_a SET value = NULL WHERE id = 1;
}
# these tests exercise mark/restore during EPQ recheck, cf bug #15032
-step "selectjoinforupdate" {
+step selectjoinforupdate {
set enable_nestloop to 0;
set enable_hashjoin to 0;
set enable_seqscan to 0;
# test for EPQ on a partitioned result table
-step "simplepartupdate" {
+step simplepartupdate {
update parttbl set a = a;
}
-session "s2"
+session s2
setup { BEGIN ISOLATION LEVEL READ COMMITTED; }
-step "wx2" { UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking'; }
-step "wy2" { UPDATE accounts SET balance = balance + 1000 WHERE accountid = 'checking' AND balance < 1000; }
-step "upsert2" {
+step wx2 { UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking'; }
+step wy2 { UPDATE accounts SET balance = balance + 1000 WHERE accountid = 'checking' AND balance < 1000; }
+step upsert2 {
WITH upsert AS
(UPDATE accounts SET balance = balance + 1234
WHERE accountid = 'savings'
INSERT INTO accounts SELECT 'savings', 1234
WHERE NOT EXISTS (SELECT 1 FROM upsert);
}
-step "readp2" { SELECT tableoid::regclass, ctid, * FROM p WHERE b IN (0, 1) AND c = 0 FOR UPDATE; }
-step "returningp1" {
+step readp2 { SELECT tableoid::regclass, ctid, * FROM p WHERE b IN (0, 1) AND c = 0 FOR UPDATE; }
+step returningp1 {
WITH u AS ( UPDATE p SET b = b WHERE a > 0 RETURNING * )
SELECT * FROM u;
}
-step "readforss" {
+step readforss {
SELECT ta.id AS ta_id, ta.value AS ta_value,
(SELECT ROW(tb.id, tb.value)
FROM table_b tb WHERE ta.id = tb.id) AS tb_row
FROM table_a ta
WHERE ta.id = 1 FOR UPDATE OF ta;
}
-step "updateforcip2" {
+step updateforcip2 {
UPDATE table_a SET value = COALESCE(value, (SELECT text 'newValue')) WHERE id = 1;
}
-step "updateforcip3" {
+step updateforcip3 {
WITH d(val) AS (SELECT text 'newValue' FROM generate_series(1,1))
UPDATE table_a SET value = COALESCE(value, (SELECT val FROM d)) WHERE id = 1;
}
-step "wrtwcte" { UPDATE table_a SET value = 'tableAValue2' WHERE id = 1; }
-step "wrjt" { UPDATE jointest SET data = 42 WHERE id = 7; }
-step "complexpartupdate" {
+step wrtwcte { UPDATE table_a SET value = 'tableAValue2' WHERE id = 1; }
+step wrjt { UPDATE jointest SET data = 42 WHERE id = 7; }
+step complexpartupdate {
with u as (update parttbl set a = a returning parttbl.*)
update parttbl set a = u.a from u;
}
-step "c2" { COMMIT; }
+step c2 { COMMIT; }
-session "s3"
+session s3
setup { BEGIN ISOLATION LEVEL READ COMMITTED; }
-step "read" { SELECT * FROM accounts ORDER BY accountid; }
-step "read_a" { SELECT * FROM table_a ORDER BY id; }
+step read { SELECT * FROM accounts ORDER BY accountid; }
+step read_a { SELECT * FROM table_a ORDER BY id; }
# this test exercises EvalPlanQual with a CTE, cf bug #14328
-step "readwcte" {
+step readwcte {
WITH
cte1 AS (
SELECT id FROM table_b WHERE value = 'tableBValue'
}
# this test exercises a different CTE misbehavior, cf bug #14870
-step "multireadwcte" {
+step multireadwcte {
WITH updated AS (
UPDATE table_a SET value = 'tableAValue3' WHERE id = 1 RETURNING id
)
teardown { COMMIT; }
-permutation "wx1" "wx2" "c1" "c2" "read"
-permutation "wy1" "wy2" "c1" "c2" "read"
-permutation "upsert1" "upsert2" "c1" "c2" "read"
-permutation "readp1" "writep1" "readp2" "c1" "c2"
-permutation "writep2" "returningp1" "c1" "c2"
-permutation "wx2" "partiallock" "c2" "c1" "read"
-permutation "wx2" "lockwithvalues" "c2" "c1" "read"
-permutation "updateforss" "readforss" "c1" "c2"
-permutation "updateforcip" "updateforcip2" "c1" "c2" "read_a"
-permutation "updateforcip" "updateforcip3" "c1" "c2" "read_a"
-permutation "wrtwcte" "readwcte" "c1" "c2"
-permutation "wrjt" "selectjoinforupdate" "c2" "c1"
-permutation "wrtwcte" "multireadwcte" "c1" "c2"
-
-permutation "simplepartupdate" "complexpartupdate" "c1" "c2"
+permutation wx1 wx2 c1 c2 read
+permutation wy1 wy2 c1 c2 read
+permutation upsert1 upsert2 c1 c2 read
+permutation readp1 writep1 readp2 c1 c2
+permutation writep2 returningp1 c1 c2
+permutation wx2 partiallock c2 c1 read
+permutation wx2 lockwithvalues c2 c1 read
+permutation updateforss readforss c1 c2
+permutation updateforcip updateforcip2 c1 c2 read_a
+permutation updateforcip updateforcip3 c1 c2 read_a
+permutation wrtwcte readwcte c1 c2
+permutation wrjt selectjoinforupdate c2 c1
+permutation wrtwcte multireadwcte c1 c2
+
+permutation simplepartupdate complexpartupdate c1 c2
DROP TABLE foo, bar;
}
-session "s1"
+session s1
setup { BEGIN; }
-step "ins" { INSERT INTO bar VALUES (42); }
-step "com" { COMMIT; }
+step ins { INSERT INTO bar VALUES (42); }
+step com { COMMIT; }
-session "s2"
-step "upd" { UPDATE foo SET b = 'Hello World'; }
+session s2
+step upd { UPDATE foo SET b = 'Hello World'; }
DROP TABLE parent, child;
}
-session "s1"
+session s1
setup { BEGIN; SET deadlock_timeout = '100ms'; }
-step "s1i" { INSERT INTO child VALUES (1, 1); }
-step "s1u" { UPDATE parent SET aux = 'bar'; }
-step "s1c" { COMMIT; }
+step s1i { INSERT INTO child VALUES (1, 1); }
+step s1u { UPDATE parent SET aux = 'bar'; }
+step s1c { COMMIT; }
-session "s2"
+session s2
setup { BEGIN; SET deadlock_timeout = '10s'; }
-step "s2i" { INSERT INTO child VALUES (2, 1); }
-step "s2u" { UPDATE parent SET aux = 'baz'; }
-step "s2c" { COMMIT; }
+step s2i { INSERT INTO child VALUES (2, 1); }
+step s2u { UPDATE parent SET aux = 'baz'; }
+step s2c { COMMIT; }
-permutation "s1i" "s1u" "s1c" "s2i" "s2u" "s2c"
-permutation "s1i" "s1u" "s2i" "s1c" "s2u" "s2c"
-permutation "s1i" "s1u" "s2i" "s2u" "s1c" "s2c"
-permutation "s1i" "s2i" "s1u" "s1c" "s2u" "s2c"
-permutation "s1i" "s2i" "s1u" "s2u" "s1c" "s2c"
-permutation "s1i" "s2i" "s2u" "s1u" "s2c" "s1c"
-permutation "s1i" "s2i" "s2u" "s2c" "s1u" "s1c"
-permutation "s2i" "s1i" "s1u" "s1c" "s2u" "s2c"
-permutation "s2i" "s1i" "s1u" "s2u" "s1c" "s2c"
-permutation "s2i" "s1i" "s2u" "s1u" "s2c" "s1c"
-permutation "s2i" "s1i" "s2u" "s2c" "s1u" "s1c"
-permutation "s2i" "s2u" "s1i" "s1u" "s2c" "s1c"
-permutation "s2i" "s2u" "s1i" "s2c" "s1u" "s1c"
-permutation "s2i" "s2u" "s2c" "s1i" "s1u" "s1c"
+permutation s1i s1u s1c s2i s2u s2c
+permutation s1i s1u s2i s1c s2u s2c
+permutation s1i s1u s2i s2u s1c s2c
+permutation s1i s2i s1u s1c s2u s2c
+permutation s1i s2i s1u s2u s1c s2c
+permutation s1i s2i s2u s1u s2c s1c
+permutation s1i s2i s2u s2c s1u s1c
+permutation s2i s1i s1u s1c s2u s2c
+permutation s2i s1i s1u s2u s1c s2c
+permutation s2i s1i s2u s1u s2c s1c
+permutation s2i s1i s2u s2c s1u s1c
+permutation s2i s2u s1i s1u s2c s1c
+permutation s2i s2u s1i s2c s1u s1c
+permutation s2i s2u s2c s1i s1u s1c
DROP TABLE a, b;
}
-session "s1"
+session s1
setup { BEGIN; SET deadlock_timeout = '100ms'; }
-step "s1u1" { UPDATE A SET Col1 = 1 WHERE AID = 1; }
-step "s1u2" { UPDATE B SET Col2 = 1 WHERE BID = 2; }
-step "s1c" { COMMIT; }
+step s1u1 { UPDATE A SET Col1 = 1 WHERE AID = 1; }
+step s1u2 { UPDATE B SET Col2 = 1 WHERE BID = 2; }
+step s1c { COMMIT; }
-session "s2"
+session s2
setup { BEGIN; SET deadlock_timeout = '10s'; }
-step "s2u1" { UPDATE B SET Col2 = 1 WHERE BID = 2; }
-step "s2u2" { UPDATE B SET Col2 = 1 WHERE BID = 2; }
-step "s2c" { COMMIT; }
+step s2u1 { UPDATE B SET Col2 = 1 WHERE BID = 2; }
+step s2u2 { UPDATE B SET Col2 = 1 WHERE BID = 2; }
+step s2c { COMMIT; }
-permutation "s1u1" "s1u2" "s1c" "s2u1" "s2u2" "s2c"
-permutation "s1u1" "s1u2" "s2u1" "s1c" "s2u2" "s2c"
-permutation "s1u1" "s2u1" "s1u2" "s2u2" "s2c" "s1c"
-permutation "s1u1" "s2u1" "s2u2" "s1u2" "s2c" "s1c"
-permutation "s1u1" "s2u1" "s2u2" "s2c" "s1u2" "s1c"
-permutation "s2u1" "s1u1" "s1u2" "s2u2" "s2c" "s1c"
-permutation "s2u1" "s1u1" "s2u2" "s1u2" "s2c" "s1c"
-permutation "s2u1" "s1u1" "s2u2" "s2c" "s1u2" "s1c"
-permutation "s2u1" "s2u2" "s1u1" "s1u2" "s2c" "s1c"
-permutation "s2u1" "s2u2" "s1u1" "s2c" "s1u2" "s1c"
-permutation "s2u1" "s2u2" "s2c" "s1u1" "s1u2" "s1c"
+permutation s1u1 s1u2 s1c s2u1 s2u2 s2c
+permutation s1u1 s1u2 s2u1 s1c s2u2 s2c
+permutation s1u1 s2u1 s1u2 s2u2 s2c s1c
+permutation s1u1 s2u1 s2u2 s1u2 s2c s1c
+permutation s1u1 s2u1 s2u2 s2c s1u2 s1c
+permutation s2u1 s1u1 s1u2 s2u2 s2c s1c
+permutation s2u1 s1u1 s2u2 s1u2 s2c s1c
+permutation s2u1 s1u1 s2u2 s2c s1u2 s1c
+permutation s2u1 s2u2 s1u1 s1u2 s2c s1c
+permutation s2u1 s2u2 s1u1 s2c s1u2 s1c
+permutation s2u1 s2u2 s2c s1u1 s1u2 s1c
DROP TABLE tab_freeze;
}
-session "s1"
-step "s1_begin" { BEGIN; }
-step "s1_update" { UPDATE tab_freeze SET x = x + 1 WHERE id = 3; }
-step "s1_commit" { COMMIT; }
-step "s1_selectone" {
+session s1
+step s1_begin { BEGIN; }
+step s1_update { UPDATE tab_freeze SET x = x + 1 WHERE id = 3; }
+step s1_commit { COMMIT; }
+step s1_selectone {
BEGIN;
SET LOCAL enable_seqscan = false;
SET LOCAL enable_bitmapscan = false;
SELECT * FROM tab_freeze WHERE id = 3;
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"
-step "s2_begin" { BEGIN; }
-step "s2_key_share" { SELECT id FROM tab_freeze WHERE id = 3 FOR KEY SHARE; }
-step "s2_commit" { COMMIT; }
-step "s2_vacuum" { VACUUM FREEZE tab_freeze; }
+session s2
+step s2_begin { BEGIN; }
+step s2_key_share { SELECT id FROM tab_freeze WHERE id = 3 FOR KEY SHARE; }
+step s2_commit { COMMIT; }
+step s2_vacuum { VACUUM FREEZE tab_freeze; }
-session "s3"
-step "s3_begin" { BEGIN; }
-step "s3_key_share" { SELECT id FROM tab_freeze WHERE id = 3 FOR KEY SHARE; }
-step "s3_commit" { COMMIT; }
+session s3
+step s3_begin { BEGIN; }
+step s3_key_share { SELECT id FROM tab_freeze WHERE id = 3 FOR KEY SHARE; }
+step s3_commit { COMMIT; }
# This permutation verfies that a previous bug
# is not reintroduced. We used to make wrong pruning / freezing
# decision for multixacts, which could lead to a) broken hot chains b)
# dead rows being revived.
-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" # create additional row version that has multis
- "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
- "s1_selectone" # if hot chain is broken, the row can't be found via index scan
- "s3_commit" # commit remaining open xact
- "s2_vacuum" # pruning / freezing in broken hot chains would unset xmax, reviving rows
- "s1_selectall" # show borkedness
+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 # create additional row version that has multis
+ 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
+ s1_selectone # if hot chain is broken, the row can't be found via index scan
+ s3_commit # commit remaining open xact
+ s2_vacuum # pruning / freezing in broken hot chains would unset xmax, reviving rows
+ s1_selectall # show borkedness
DROP TABLE taby;
}
-session "s1"
+session s1
setup
{
BEGIN ISOLATION LEVEL SERIALIZABLE;
SET LOCAL random_page_cost = 0.1;
SET LOCAL cpu_tuple_cost = 0.03;
}
-step "rxwy1" { DELETE FROM taby WHERE id = (SELECT min(id) FROM tabx); }
-step "c1" { COMMIT; }
+step rxwy1 { DELETE FROM taby WHERE id = (SELECT min(id) FROM tabx); }
+step c1 { COMMIT; }
-session "s2"
+session s2
setup
{
BEGIN ISOLATION LEVEL SERIALIZABLE;
SET LOCAL random_page_cost = 0.1;
SET LOCAL cpu_tuple_cost = 0.03;
}
-step "rywx2" { DELETE FROM tabx WHERE id = (SELECT min(id) FROM taby); }
-step "c2" { COMMIT; }
+step rywx2 { DELETE FROM tabx WHERE id = (SELECT min(id) FROM taby); }
+step c2 { COMMIT; }
# Session 1 executes actions which act directly on both the parent and
# its child. Abbreviation "c" is used for queries working on the child
# and "p" on the parent.
-session "s1"
+session s1
setup
{
CREATE TEMPORARY TABLE inh_temp_child_s1 () INHERITS (inh_parent);
}
-step "s1_begin" { BEGIN; }
-step "s1_truncate_p" { TRUNCATE inh_parent; }
-step "s1_select_p" { SELECT a FROM inh_parent; }
-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_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_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_c" { DELETE FROM inh_parent WHERE a IN (4, 6); }
-step "s1_commit" { COMMIT; }
+step s1_begin { BEGIN; }
+step s1_truncate_p { TRUNCATE inh_parent; }
+step s1_select_p { SELECT a FROM inh_parent; }
+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_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_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_c { DELETE FROM inh_parent WHERE a IN (4, 6); }
+step s1_commit { COMMIT; }
teardown
{
DROP TABLE inh_temp_child_s1;
}
# Session 2 executes actions on the parent which act only on the child.
-session "s2"
+session s2
setup
{
CREATE TEMPORARY TABLE inh_temp_child_s2 () INHERITS (inh_parent);
}
-step "s2_truncate_p" { TRUNCATE inh_parent; }
-step "s2_select_p" { SELECT a FROM inh_parent; }
-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_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_truncate_p { TRUNCATE inh_parent; }
+step s2_select_p { SELECT a FROM inh_parent; }
+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_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); }
teardown
{
DROP TABLE inh_temp_child_s2;
}
# 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
-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 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
# 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" "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 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
# 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" "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 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
# TRUNCATE on a parent tree does not block access to temporary child relation
# 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_c" "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
DROP TABLE ints;
}
-session "s1"
-step "beginrr1" { BEGIN ISOLATION LEVEL REPEATABLE READ; }
-step "begins1" { BEGIN ISOLATION LEVEL SERIALIZABLE; }
-step "donothing1" { INSERT INTO ints(key, val) VALUES(1, 'donothing1') ON CONFLICT DO NOTHING; }
-step "c1" { COMMIT; }
-step "show" { SELECT * FROM ints; }
+session s1
+step beginrr1 { BEGIN ISOLATION LEVEL REPEATABLE READ; }
+step begins1 { BEGIN ISOLATION LEVEL SERIALIZABLE; }
+step donothing1 { INSERT INTO ints(key, val) VALUES(1, 'donothing1') ON CONFLICT DO NOTHING; }
+step c1 { COMMIT; }
+step show { SELECT * FROM ints; }
-session "s2"
-step "beginrr2" { BEGIN ISOLATION LEVEL REPEATABLE READ; }
-step "begins2" { BEGIN ISOLATION LEVEL SERIALIZABLE; }
-step "donothing2" { INSERT INTO ints(key, val) VALUES(1, 'donothing2'), (1, 'donothing3') ON CONFLICT DO NOTHING; }
-step "c2" { COMMIT; }
+session s2
+step beginrr2 { BEGIN ISOLATION LEVEL REPEATABLE READ; }
+step begins2 { BEGIN ISOLATION LEVEL SERIALIZABLE; }
+step donothing2 { INSERT INTO ints(key, val) VALUES(1, 'donothing2'), (1, 'donothing3') ON CONFLICT DO NOTHING; }
+step c2 { COMMIT; }
-permutation "beginrr1" "beginrr2" "donothing1" "c1" "donothing2" "c2" "show"
-permutation "beginrr1" "beginrr2" "donothing2" "c2" "donothing1" "c1" "show"
-permutation "beginrr1" "beginrr2" "donothing1" "donothing2" "c1" "c2" "show"
-permutation "beginrr1" "beginrr2" "donothing2" "donothing1" "c2" "c1" "show"
-permutation "begins1" "begins2" "donothing1" "c1" "donothing2" "c2" "show"
-permutation "begins1" "begins2" "donothing2" "c2" "donothing1" "c1" "show"
-permutation "begins1" "begins2" "donothing1" "donothing2" "c1" "c2" "show"
-permutation "begins1" "begins2" "donothing2" "donothing1" "c2" "c1" "show"
+permutation beginrr1 beginrr2 donothing1 c1 donothing2 c2 show
+permutation beginrr1 beginrr2 donothing2 c2 donothing1 c1 show
+permutation beginrr1 beginrr2 donothing1 donothing2 c1 c2 show
+permutation beginrr1 beginrr2 donothing2 donothing1 c2 c1 show
+permutation begins1 begins2 donothing1 c1 donothing2 c2 show
+permutation begins1 begins2 donothing2 c2 donothing1 c1 show
+permutation begins1 begins2 donothing1 donothing2 c1 c2 show
+permutation begins1 begins2 donothing2 donothing1 c2 c1 show
DROP TABLE ints;
}
-session "s1"
+session s1
setup
{
BEGIN ISOLATION LEVEL READ COMMITTED;
}
-step "donothing1" { INSERT INTO ints(key, val) VALUES(1, 'donothing1') ON CONFLICT DO NOTHING; }
-step "c1" { COMMIT; }
-step "a1" { ABORT; }
+step donothing1 { INSERT INTO ints(key, val) VALUES(1, 'donothing1') ON CONFLICT DO NOTHING; }
+step c1 { COMMIT; }
+step a1 { ABORT; }
-session "s2"
+session s2
setup
{
BEGIN ISOLATION LEVEL READ COMMITTED;
}
-step "donothing2" { INSERT INTO ints(key, val) VALUES(1, 'donothing2') ON CONFLICT DO NOTHING; }
-step "select2" { SELECT * FROM ints; }
-step "c2" { COMMIT; }
+step donothing2 { INSERT INTO ints(key, val) VALUES(1, 'donothing2') ON CONFLICT DO NOTHING; }
+step select2 { SELECT * FROM ints; }
+step c2 { COMMIT; }
# Regular case where one session block-waits on another to determine if it
# should proceed with an insert or do nothing.
-permutation "donothing1" "donothing2" "c1" "select2" "c2"
-permutation "donothing1" "donothing2" "a1" "select2" "c2"
+permutation donothing1 donothing2 c1 select2 c2
+permutation donothing1 donothing2 a1 select2 c2
DROP TABLE upsert;
}
-session "s1"
+session s1
setup
{
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 "c1" { COMMIT; }
-step "a1" { ABORT; }
+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 a1 { ABORT; }
-session "s2"
+session s2
setup
{
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 "select2" { SELECT * FROM upsert; }
-step "c2" { COMMIT; }
+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 c2 { COMMIT; }
# 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
# a column constrained by a unique index, as the example illustrates.
-permutation "insert1" "insert2" "c1" "select2" "c2"
-permutation "insert1" "insert2" "a1" "select2" "c2"
+permutation insert1 insert2 c1 select2 c2
+permutation insert1 insert2 a1 select2 c2
DROP TABLE colors;
}
-session "s1"
+session s1
setup
{
BEGIN ISOLATION LEVEL READ COMMITTED;
}
-step "insert1" {
+step insert1 {
WITH t AS (
INSERT INTO colors(key, color, is_active)
VALUES(1, 'Brown', true), (2, 'Gray', true)
SET color = EXCLUDED.color
WHERE colors.is_active)
SELECT * FROM colors ORDER BY key;}
-step "select1surprise" { SELECT * FROM colors ORDER BY key; }
-step "c1" { COMMIT; }
+step select1surprise { SELECT * FROM colors ORDER BY key; }
+step c1 { COMMIT; }
-session "s2"
+session s2
setup
{
BEGIN ISOLATION LEVEL READ COMMITTED;
}
-step "update2" { UPDATE colors SET is_active = true WHERE key = 1; }
-step "c2" { COMMIT; }
+step update2 { UPDATE colors SET is_active = true WHERE key = 1; }
+step c2 { COMMIT; }
# Perhaps surprisingly, the session 1 MVCC-snapshot-visible tuple (the tuple
# with the pre-populated color 'Red') is denied the opportunity to prevent the
# 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
# tuple with key value 2, since nothing changed there):
-permutation "update2" "insert1" "c2" "select1surprise" "c1"
+permutation update2 insert1 c2 select1surprise c1
DROP TABLE upsert;
}
-session "s1"
+session s1
setup
{
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 "c1" { COMMIT; }
-step "a1" { ABORT; }
+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 a1 { ABORT; }
-session "s2"
+session s2
setup
{
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 "select2" { SELECT * FROM upsert; }
-step "c2" { COMMIT; }
+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 c2 { COMMIT; }
# 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
# tuple while there is no version of that tuple visible to the updating
# session's snapshot. This is permitted only in READ COMMITTED mode.
-permutation "insert1" "insert2" "c1" "select2" "c2"
-permutation "insert1" "insert2" "a1" "select2" "c2"
+permutation insert1 insert2 c1 select2 c2
+permutation insert1 insert2 a1 select2 c2
DROP TABLE upserttest;
}
-session "controller"
+session controller
setup
{
SET default_transaction_isolation = 'read committed';
}
-step "controller_locks" {SELECT pg_advisory_lock(sess, lock), sess, lock FROM generate_series(1, 2) a(sess), generate_series(1,3) b(lock);}
-step "controller_unlock_1_1" { SELECT pg_advisory_unlock(1, 1); }
-step "controller_unlock_2_1" { SELECT pg_advisory_unlock(2, 1); }
-step "controller_unlock_1_2" { SELECT pg_advisory_unlock(1, 2); }
-step "controller_unlock_2_2" { SELECT pg_advisory_unlock(2, 2); }
-step "controller_unlock_1_3" { SELECT pg_advisory_unlock(1, 3); }
-step "controller_unlock_2_3" { SELECT pg_advisory_unlock(2, 3); }
-step "controller_show" {SELECT * FROM upserttest; }
+step controller_locks {SELECT pg_advisory_lock(sess, lock), sess, lock FROM generate_series(1, 2) a(sess), generate_series(1,3) b(lock);}
+step controller_unlock_1_1 { SELECT pg_advisory_unlock(1, 1); }
+step controller_unlock_2_1 { SELECT pg_advisory_unlock(2, 1); }
+step controller_unlock_1_2 { SELECT pg_advisory_unlock(1, 2); }
+step controller_unlock_2_2 { SELECT pg_advisory_unlock(2, 2); }
+step controller_unlock_1_3 { SELECT pg_advisory_unlock(1, 3); }
+step controller_unlock_2_3 { SELECT pg_advisory_unlock(2, 3); }
+step controller_show {SELECT * FROM upserttest; }
-session "s1"
+session s1
setup
{
SET default_transaction_isolation = 'read committed';
SET spec.session = 1;
}
-step "s1_begin" { BEGIN; }
-step "s1_upsert" { INSERT INTO upserttest(key, data) VALUES('k1', 'inserted s1') ON CONFLICT (blurt_and_lock(key)) DO UPDATE SET data = upserttest.data || ' with conflict update s1'; }
-step "s1_commit" { COMMIT; }
+step s1_begin { BEGIN; }
+step s1_upsert { INSERT INTO upserttest(key, data) VALUES('k1', 'inserted s1') ON CONFLICT (blurt_and_lock(key)) DO UPDATE SET data = upserttest.data || ' with conflict update s1'; }
+step s1_commit { COMMIT; }
-session "s2"
+session s2
setup
{
SET default_transaction_isolation = 'read committed';
SET spec.session = 2;
}
-step "s2_begin" { BEGIN; }
-step "s2_upsert" { INSERT INTO upserttest(key, data) VALUES('k1', 'inserted s2') ON CONFLICT (blurt_and_lock(key)) DO UPDATE SET data = upserttest.data || ' with conflict update s2'; }
-step "s2_commit" { COMMIT; }
+step s2_begin { BEGIN; }
+step s2_upsert { INSERT INTO upserttest(key, data) VALUES('k1', 'inserted s2') ON CONFLICT (blurt_and_lock(key)) DO UPDATE SET data = upserttest.data || ' with conflict update s2'; }
+step s2_commit { COMMIT; }
# Test that speculative locks are correctly acquired and released, s2
# inserts, s1 updates.
# blurt_and_lock function acquires advisory locks that allow us to
# continue after a) the optimistic conflict probe b) after the
# insertion of the speculative tuple.
- "controller_locks"
- "controller_show"
- "s1_upsert" "s2_upsert"
- "controller_show"
+ controller_locks
+ controller_show
+ s1_upsert s2_upsert
+ controller_show
# Switch both sessions to wait on the other lock next time (the speculative insertion)
- "controller_unlock_1_1" "controller_unlock_2_1"
+ controller_unlock_1_1 controller_unlock_2_1
# Allow both sessions to continue
- "controller_unlock_1_3" "controller_unlock_2_3"
- "controller_show"
+ controller_unlock_1_3 controller_unlock_2_3
+ controller_show
# Allow the second session to finish insertion
- "controller_unlock_2_2"
+ controller_unlock_2_2
# This should now show a successful insertion
- "controller_show"
+ controller_show
# Allow the first session to finish insertion
- "controller_unlock_1_2"
+ controller_unlock_1_2
# This should now show a successful UPSERT
- "controller_show"
+ controller_show
# Test that speculative locks are correctly acquired and released, s2
# inserts, s1 updates.
# blurt_and_lock function acquires advisory locks that allow us to
# continue after a) the optimistic conflict probe b) after the
# insertion of the speculative tuple.
- "controller_locks"
- "controller_show"
- "s1_upsert" "s2_upsert"
- "controller_show"
+ controller_locks
+ controller_show
+ s1_upsert s2_upsert
+ controller_show
# Switch both sessions to wait on the other lock next time (the speculative insertion)
- "controller_unlock_1_1" "controller_unlock_2_1"
+ controller_unlock_1_1 controller_unlock_2_1
# Allow both sessions to continue
- "controller_unlock_1_3" "controller_unlock_2_3"
- "controller_show"
+ controller_unlock_1_3 controller_unlock_2_3
+ controller_show
# Allow the first session to finish insertion
- "controller_unlock_1_2"
+ controller_unlock_1_2
# This should now show a successful insertion
- "controller_show"
+ controller_show
# Allow the second session to finish insertion
- "controller_unlock_2_2"
+ controller_unlock_2_2
# This should now show a successful UPSERT
- "controller_show"
+ controller_show
# Test that speculative locks are correctly acquired and released, s2
# inserts, s1 updates. With the added complication that transactions
# blurt_and_lock function acquires advisory locks that allow us to
# continue after a) the optimistic conflict probe b) after the
# insertion of the speculative tuple.
- "controller_locks"
- "controller_show"
- "s1_begin" "s2_begin"
- "s1_upsert" "s2_upsert"
- "controller_show"
+ controller_locks
+ controller_show
+ s1_begin s2_begin
+ s1_upsert s2_upsert
+ controller_show
# Switch both sessions to wait on the other lock next time (the speculative insertion)
- "controller_unlock_1_1" "controller_unlock_2_1"
+ controller_unlock_1_1 controller_unlock_2_1
# Allow both sessions to continue
- "controller_unlock_1_3" "controller_unlock_2_3"
- "controller_show"
+ controller_unlock_1_3 controller_unlock_2_3
+ controller_show
# Allow the first session to finish insertion
- "controller_unlock_1_2"
+ controller_unlock_1_2
# But the change isn't visible yet, nor should the second session continue
- "controller_show"
+ controller_show
# Allow the second session to finish insertion, but it's blocked
- "controller_unlock_2_2"
- "controller_show"
+ controller_unlock_2_2
+ controller_show
# But committing should unblock
- "s1_commit"
- "controller_show"
- "s2_commit"
- "controller_show"
+ s1_commit
+ controller_show
+ s2_commit
+ controller_show
DROP FUNCTION ctoast_large_val();
}
-session "s1"
+session s1
setup
{
BEGIN ISOLATION LEVEL READ COMMITTED;
SELECT pg_advisory_xact_lock(1);
}
-step "s1commit" { COMMIT; }
+step s1commit { COMMIT; }
-session "s2"
+session s2
setup
{
SET default_transaction_isolation = 'read committed';
}
-step "s2insert" {
+step s2insert {
INSERT INTO ctoast (key, val) VALUES (1, ctoast_large_val()) ON CONFLICT DO NOTHING;
}
-session "s3"
+session s3
setup
{
SET default_transaction_isolation = 'read committed';
}
-step "s3insert" {
+step s3insert {
INSERT INTO ctoast (key, val) VALUES (1, ctoast_large_val()) ON CONFLICT DO NOTHING;
}
-permutation "s2insert" "s3insert" "s1commit"
+permutation s2insert s3insert s1commit
DROP TABLE lcku_table;
}
-session "s1"
-step "s1b" { BEGIN; }
-step "s1l" { SELECT pg_advisory_lock(578902068); }
-step "s1u" { UPDATE lcku_table SET id = 2 WHERE id = 3; }
-step "s1hint" { SELECT * FROM lcku_table; }
-step "s1ul" { SELECT pg_advisory_unlock(578902068); }
-step "s1c" { COMMIT; }
+session s1
+step s1b { BEGIN; }
+step s1l { SELECT pg_advisory_lock(578902068); }
+step s1u { UPDATE lcku_table SET id = 2 WHERE id = 3; }
+step s1hint { SELECT * FROM lcku_table; }
+step s1ul { SELECT pg_advisory_unlock(578902068); }
+step s1c { COMMIT; }
teardown { SELECT pg_advisory_unlock_all(); }
-session "s2"
-step "s2b1" { BEGIN ISOLATION LEVEL READ COMMITTED; }
-step "s2b2" { BEGIN ISOLATION LEVEL REPEATABLE READ; }
-step "s2b3" { BEGIN ISOLATION LEVEL SERIALIZABLE; }
-step "s2l" { SELECT * FROM lcku_table WHERE pg_advisory_lock(578902068) IS NOT NULL FOR KEY SHARE; }
-step "s2c" { COMMIT; }
+session s2
+step s2b1 { BEGIN ISOLATION LEVEL READ COMMITTED; }
+step s2b2 { BEGIN ISOLATION LEVEL REPEATABLE READ; }
+step s2b3 { BEGIN ISOLATION LEVEL SERIALIZABLE; }
+step s2l { SELECT * FROM lcku_table WHERE pg_advisory_lock(578902068) IS NOT NULL FOR KEY SHARE; }
+step s2c { COMMIT; }
teardown { SELECT pg_advisory_unlock_all(); }
-permutation "s1b" "s2b1" "s1l" "s2l" "s1u" "s1c" "s1ul" "s2c"
-permutation "s1b" "s2b1" "s1l" "s1u" "s2l" "s1c" "s1ul" "s2c"
-#permutation "s1b" "s2b1" "s1l" "s2l" "s1ul" "s1u" "s1c" "s2c&q