diff --git a/contrib/test_decoding/specs/oldest_xmin.spec b/contrib/test_decoding/specs/oldest_xmin.spec index da3a8cd512..88bd30f5ff 100644 --- a/contrib/test_decoding/specs/oldest_xmin.spec +++ b/contrib/test_decoding/specs/oldest_xmin.spec @@ -39,4 +39,4 @@ step "s1_commit" { COMMIT; } # composite type is a rare form of DDL which allows T1 to see the tuple which # will be removed (xmax set) before T1 commits. That is, interlocking doesn't # forbid modifying catalog after someone read it (and didn't commit yet). -permutation "s0_begin" "s0_getxid" "s1_begin" "s1_insert" "s0_alter" "s0_commit" "s0_checkpoint" "s0_get_changes" "s0_get_changes""s1_commit" "s0_vacuum" "s0_get_changes" +permutation "s0_begin" "s0_getxid" "s1_begin" "s1_insert" "s0_alter" "s0_commit" "s0_checkpoint" "s0_get_changes" "s0_get_changes" "s1_commit" "s0_vacuum" "s0_get_changes" diff --git a/src/test/isolation/README b/src/test/isolation/README index 9d568e5354..8457a5689f 100644 --- a/src/test/isolation/README +++ b/src/test/isolation/README @@ -80,7 +80,7 @@ teardown { } this to clean up in preparation for the next permutation, e.g dropping any test tables created by setup. This part is optional. -session "" +session There are normally several "session" parts in a spec file. Each session is executed in its own connection. A session part consists @@ -91,17 +91,17 @@ session "" Each step has the syntax - step "" { } + step { } - where is a name identifying this step, and SQL is a SQL statement + where is a name identifying this step, and 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 "" ... +permutation ... 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 @@ -109,7 +109,17 @@ permutation "" ... 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 blocks, however. Use the usual SQL +comment conventions there.) + +There is no way to include a "}" character in an block. For each permutation of the session steps (whether these are manually specified in the spec file, or automatically generated), the isolation diff --git a/src/test/isolation/specparse.y b/src/test/isolation/specparse.y index 04dbb576a7..c25aa1a73f 100644 --- a/src/test/isolation/specparse.y +++ b/src/test/isolation/specparse.y @@ -49,7 +49,7 @@ TestSpec parseresult; /* result of parsing is left here */ %type permutation_step %type blocker -%token sqlblock string_literal +%token sqlblock identifier %token INTEGER %token NOTICES PERMUTATION SESSION SETUP STEP TEARDOWN TEST @@ -117,7 +117,7 @@ session_list: ; session: - SESSION string_literal opt_setup step_list opt_teardown + SESSION identifier opt_setup step_list opt_teardown { $$ = pg_malloc(sizeof(Session)); $$->name = $2; @@ -146,7 +146,7 @@ step_list: step: - STEP string_literal sqlblock + STEP identifier sqlblock { $$ = pg_malloc(sizeof(Step)); $$->name = $2; @@ -211,7 +211,7 @@ permutation_step_list: ; permutation_step: - string_literal + identifier { $$ = pg_malloc(sizeof(PermutationStep)); $$->name = $1; @@ -219,7 +219,7 @@ permutation_step: $$->nblockers = 0; $$->step = NULL; } - | string_literal '(' blocker_list ')' + | identifier '(' blocker_list ')' { $$ = pg_malloc(sizeof(PermutationStep)); $$->name = $1; @@ -246,7 +246,7 @@ blocker_list: ; blocker: - string_literal + identifier { $$ = pg_malloc(sizeof(PermutationStepBlocker)); $$->stepname = $1; @@ -255,7 +255,7 @@ blocker: $$->step = NULL; $$->target_notices = -1; } - | string_literal NOTICES INTEGER + | identifier NOTICES INTEGER { $$ = pg_malloc(sizeof(PermutationStepBlocker)); $$->stepname = $1; diff --git a/src/test/isolation/specs/aborted-keyrevoke.spec b/src/test/isolation/specs/aborted-keyrevoke.spec index 08945d8b31..4f6f9027cc 100644 --- a/src/test/isolation/specs/aborted-keyrevoke.spec +++ b/src/test/isolation/specs/aborted-keyrevoke.spec @@ -17,30 +17,30 @@ teardown 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 diff --git a/src/test/isolation/specs/alter-table-1.spec b/src/test/isolation/specs/alter-table-1.spec index 10e463f6bc..dfd0ce7094 100644 --- a/src/test/isolation/specs/alter-table-1.spec +++ b/src/test/isolation/specs/alter-table-1.spec @@ -16,155 +16,155 @@ teardown 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 diff --git a/src/test/isolation/specs/alter-table-2.spec b/src/test/isolation/specs/alter-table-2.spec index 9b17992d7d..a3e3131e9f 100644 --- a/src/test/isolation/specs/alter-table-2.spec +++ b/src/test/isolation/specs/alter-table-2.spec @@ -16,64 +16,64 @@ teardown 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 diff --git a/src/test/isolation/specs/alter-table-3.spec b/src/test/isolation/specs/alter-table-3.spec index d07e3dde41..f70d9c0792 100644 --- a/src/test/isolation/specs/alter-table-3.spec +++ b/src/test/isolation/specs/alter-table-3.spec @@ -17,63 +17,63 @@ teardown 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 diff --git a/src/test/isolation/specs/alter-table-4.spec b/src/test/isolation/specs/alter-table-4.spec index a9c1a93723..f143b790d9 100644 --- a/src/test/isolation/specs/alter-table-4.spec +++ b/src/test/isolation/specs/alter-table-4.spec @@ -15,23 +15,23 @@ teardown 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 diff --git a/src/test/isolation/specs/async-notify.spec b/src/test/isolation/specs/async-notify.spec index a7b2600d25..0b8cfd9108 100644 --- a/src/test/isolation/specs/async-notify.spec +++ b/src/test/isolation/specs/async-notify.spec @@ -5,15 +5,15 @@ # 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'; @@ -31,47 +31,47 @@ step "notifys1" { 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 @@ -81,4 +81,4 @@ permutation "l2listen" "l2begin" "notify1" "lbegins" "llisten" "lcommit" "l2comm # 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 diff --git a/src/test/isolation/specs/classroom-scheduling.spec b/src/test/isolation/specs/classroom-scheduling.spec index a31565b9cd..770715b149 100644 --- a/src/test/isolation/specs/classroom-scheduling.spec +++ b/src/test/isolation/specs/classroom-scheduling.spec @@ -16,14 +16,14 @@ teardown 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; } diff --git a/src/test/isolation/specs/create-trigger.spec b/src/test/isolation/specs/create-trigger.spec index caac381757..9d4710cbdd 100644 --- a/src/test/isolation/specs/create-trigger.spec +++ b/src/test/isolation/specs/create-trigger.spec @@ -16,39 +16,39 @@ teardown 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 diff --git a/src/test/isolation/specs/deadlock-hard.spec b/src/test/isolation/specs/deadlock-hard.spec index 3316d75e95..60bedca237 100644 --- a/src/test/isolation/specs/deadlock-hard.spec +++ b/src/test/isolation/specs/deadlock-hard.spec @@ -20,53 +20,53 @@ teardown 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. @@ -76,4 +76,4 @@ step "s8c" { COMMIT; } # 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 diff --git a/src/test/isolation/specs/deadlock-parallel.spec b/src/test/isolation/specs/deadlock-parallel.spec index 7ad290c0bd..a050a4963a 100644 --- a/src/test/isolation/specs/deadlock-parallel.spec +++ b/src/test/isolation/specs/deadlock-parallel.spec @@ -53,33 +53,33 @@ teardown drop table bigt; } -session "d1" +session d1 setup { BEGIN isolation level repeatable read; SET force_parallel_mode = off; SET deadlock_timeout = '10s'; } # these locks will be taken in the leader, so they will persist: -step "d1a1" { SELECT lock_share(1,x), lock_excl(3,x) FROM bigt LIMIT 1; } +step d1a1 { SELECT lock_share(1,x), lock_excl(3,x) FROM bigt LIMIT 1; } # this causes all the parallel workers to take locks: -step "d1a2" { SET force_parallel_mode = on; +step d1a2 { SET force_parallel_mode = on; SET parallel_setup_cost = 0; SET parallel_tuple_cost = 0; SET min_parallel_table_scan_size = 0; SET parallel_leader_participation = off; SET max_parallel_workers_per_gather = 3; SELECT sum(lock_share(2,x)) FROM bigt; } -step "d1c" { COMMIT; } +step d1c { COMMIT; } -session "d2" +session d2 setup { BEGIN isolation level repeatable read; SET force_parallel_mode = off; SET deadlock_timeout = '10ms'; } # this lock will be taken in the leader, so it will persist: -step "d2a2" { select lock_share(2,x) FROM bigt LIMIT 1; } +step d2a2 { select lock_share(2,x) FROM bigt LIMIT 1; } # this causes all the parallel workers to take locks; # after which, make the leader take lock 3 to prevent client-driven deadlock -step "d2a1" { SET force_parallel_mode = on; +step d2a1 { SET force_parallel_mode = on; SET parallel_setup_cost = 0; SET parallel_tuple_cost = 0; SET min_parallel_table_scan_size = 0; @@ -90,24 +90,24 @@ step "d2a1" { SET force_parallel_mode = on; RESET parallel_setup_cost; RESET parallel_tuple_cost; SELECT lock_share(3,x) FROM bigt LIMIT 1; } -step "d2c" { COMMIT; } +step d2c { COMMIT; } -session "e1" +session e1 setup { BEGIN isolation level repeatable read; SET force_parallel_mode = on; SET deadlock_timeout = '10s'; } # this lock will be taken in a parallel worker, but we don't need it to persist -step "e1l" { SELECT lock_excl(1,x) FROM bigt LIMIT 1; } -step "e1c" { COMMIT; } +step e1l { SELECT lock_excl(1,x) FROM bigt LIMIT 1; } +step e1c { COMMIT; } -session "e2" +session e2 setup { BEGIN isolation level repeatable read; SET force_parallel_mode = on; SET deadlock_timeout = '10s'; } # this lock will be taken in a parallel worker, but we don't need it to persist -step "e2l" { SELECT lock_excl(2,x) FROM bigt LIMIT 1; } -step "e2c" { COMMIT; } +step e2l { SELECT lock_excl(2,x) FROM bigt LIMIT 1; } +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 diff --git a/src/test/isolation/specs/deadlock-simple.spec b/src/test/isolation/specs/deadlock-simple.spec index b1300ca77c..3086dc7c86 100644 --- a/src/test/isolation/specs/deadlock-simple.spec +++ b/src/test/isolation/specs/deadlock-simple.spec @@ -14,16 +14,16 @@ teardown 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 diff --git a/src/test/isolation/specs/deadlock-soft-2.spec b/src/test/isolation/specs/deadlock-soft-2.spec index 6ff915f606..5b7d3db503 100644 --- a/src/test/isolation/specs/deadlock-soft-2.spec +++ b/src/test/isolation/specs/deadlock-soft-2.spec @@ -13,31 +13,31 @@ teardown 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 diff --git a/src/test/isolation/specs/deadlock-soft.spec b/src/test/isolation/specs/deadlock-soft.spec index 49d16e027c..bc9c6a7d43 100644 --- a/src/test/isolation/specs/deadlock-soft.spec +++ b/src/test/isolation/specs/deadlock-soft.spec @@ -15,26 +15,26 @@ teardown 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 diff --git a/src/test/isolation/specs/delete-abort-savept-2.spec b/src/test/isolation/specs/delete-abort-savept-2.spec index d35c67f670..65bd936dcc 100644 --- a/src/test/isolation/specs/delete-abort-savept-2.spec +++ b/src/test/isolation/specs/delete-abort-savept-2.spec @@ -14,21 +14,21 @@ teardown 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 diff --git a/src/test/isolation/specs/delete-abort-savept.spec b/src/test/isolation/specs/delete-abort-savept.spec index bc32e21682..498ffed32a 100644 --- a/src/test/isolation/specs/delete-abort-savept.spec +++ b/src/test/isolation/specs/delete-abort-savept.spec @@ -15,23 +15,23 @@ teardown 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 diff --git a/src/test/isolation/specs/detach-partition-concurrently-1.spec b/src/test/isolation/specs/detach-partition-concurrently-1.spec index 6ca0adac1d..835fe89540 100644 --- a/src/test/isolation/specs/detach-partition-concurrently-1.spec +++ b/src/test/isolation/specs/detach-partition-concurrently-1.spec @@ -14,56 +14,56 @@ teardown { DROP TABLE IF EXISTS d_listp, d_listp2, d_listp_foobar; } -session "s1" -step "s1b" { BEGIN; } -step "s1brr" { BEGIN ISOLATION LEVEL REPEATABLE READ; } -step "s1s" { SELECT * FROM d_listp; } -step "s1ins" { INSERT INTO d_listp VALUES (1); } -step "s1ins2" { INSERT INTO d_listp VALUES (2); } -step "s1prep" { PREPARE f(int) AS INSERT INTO d_listp VALUES ($1); } -step "s1prep1" { PREPARE f(int) AS INSERT INTO d_listp VALUES (1); } -step "s1prep2" { PREPARE f(int) AS INSERT INTO d_listp VALUES (2); } -step "s1exec1" { EXECUTE f(1); } -step "s1exec2" { EXECUTE f(2); } -step "s1dealloc" { DEALLOCATE f; } -step "s1c" { COMMIT; } +session s1 +step s1b { BEGIN; } +step s1brr { BEGIN ISOLATION LEVEL REPEATABLE READ; } +step s1s { SELECT * FROM d_listp; } +step s1ins { INSERT INTO d_listp VALUES (1); } +step s1ins2 { INSERT INTO d_listp VALUES (2); } +step s1prep { PREPARE f(int) AS INSERT INTO d_listp VALUES ($1); } +step s1prep1 { PREPARE f(int) AS INSERT INTO d_listp VALUES (1); } +step s1prep2 { PREPARE f(int) AS INSERT INTO d_listp VALUES (2); } +step s1exec1 { EXECUTE f(1); } +step s1exec2 { EXECUTE f(2); } +step s1dealloc { DEALLOCATE f; } +step s1c { COMMIT; } -session "s2" -step "s2detach" { ALTER TABLE d_listp DETACH PARTITION d_listp2 CONCURRENTLY; } -step "s2drop" { DROP TABLE d_listp2; } +session s2 +step s2detach { ALTER TABLE d_listp DETACH PARTITION d_listp2 CONCURRENTLY; } +step s2drop { DROP TABLE d_listp2; } -session "s3" -step "s3s" { SELECT * FROM d_listp; } -step "s3i" { SELECT relpartbound IS NULL FROM pg_class where relname = 'd_listp2'; } -step "s3ins2" { INSERT INTO d_listp VALUES (2); } +session s3 +step s3s { SELECT * FROM d_listp; } +step s3i { SELECT relpartbound IS NULL FROM pg_class where relname = 'd_listp2'; } +step s3ins2 { INSERT INTO d_listp VALUES (2); } # The transaction that detaches hangs until it sees any older transaction # terminate, as does anybody else. -permutation "s1b" "s1s" "s2detach" "s1s" "s1c" "s1s" +permutation s1b s1s s2detach s1s s1c s1s # relpartbound remains set until s1 commits # XXX this could be timing dependent :-( -permutation "s1b" "s1s" "s2detach" "s1s" "s3s" "s3i" "s1c" "s3i" "s2drop" "s1s" +permutation s1b s1s s2detach s1s s3s s3i s1c s3i s2drop s1s # In read-committed mode, the partition disappears from view of concurrent # transactions immediately. But if a write lock is held, then the detach # has to wait. -permutation "s1b" "s1s" "s2detach" "s1ins" "s1s" "s1c" -permutation "s1b" "s1s" "s1ins2" "s2detach" "s1ins" "s1s" "s1c" +permutation s1b s1s s2detach s1ins s1s s1c +permutation s1b s1s s1ins2 s2detach s1ins s1s s1c # In repeatable-read mode, the partition remains visible until commit even # if the to-be-detached partition is not locked for write. -permutation "s1brr" "s1s" "s2detach" "s1ins" "s1s" "s1c" -permutation "s1brr" "s1s" "s2detach" "s1s" "s1c" +permutation s1brr s1s s2detach s1ins s1s s1c +permutation s1brr s1s s2detach s1s s1c # Another process trying to acquire a write lock will be blocked behind the # detacher -permutation "s1b" "s1ins2" "s2detach" "s3ins2" "s1c" +permutation s1b s1ins2 s2detach s3ins2 s1c # a prepared query is not blocked -permutation "s1brr" "s1prep" "s1s" "s2detach" "s1s" "s1exec1" "s3s" "s1dealloc" "s1c" -permutation "s1brr" "s1prep" "s1exec2" "s2detach" "s1s" "s1exec2" "s3s" "s1c" "s1dealloc" -permutation "s1brr" "s1prep" "s1s" "s2detach" "s1s" "s1exec2" "s1c" "s1dealloc" -permutation "s1brr" "s1prep" "s2detach" "s1s" "s1exec2" "s1c" "s1dealloc" -permutation "s1brr" "s1prep1" "s2detach" "s1s" "s1exec2" "s1c" "s1dealloc" -permutation "s1brr" "s1prep2" "s2detach" "s1s" "s1exec2" "s1c" "s1dealloc" +permutation s1brr s1prep s1s s2detach s1s s1exec1 s3s s1dealloc s1c +permutation s1brr s1prep s1exec2 s2detach s1s s1exec2 s3s s1c s1dealloc +permutation s1brr s1prep s1s s2detach s1s s1exec2 s1c s1dealloc +permutation s1brr s1prep s2detach s1s s1exec2 s1c s1dealloc +permutation s1brr s1prep1 s2detach s1s s1exec2 s1c s1dealloc +permutation s1brr s1prep2 s2detach s1s s1exec2 s1c s1dealloc diff --git a/src/test/isolation/specs/detach-partition-concurrently-2.spec b/src/test/isolation/specs/detach-partition-concurrently-2.spec index 9281c80a69..fa767eaefe 100644 --- a/src/test/isolation/specs/detach-partition-concurrently-2.spec +++ b/src/test/isolation/specs/detach-partition-concurrently-2.spec @@ -15,27 +15,27 @@ setup teardown { DROP TABLE IF EXISTS d_lp_fk, d_lp_fk_1, d_lp_fk_2, d_lp_fk_r; } -session "s1" -step "s1b" { BEGIN; } -step "s1s" { SELECT * FROM d_lp_fk; } -step "s1c" { COMMIT; } +session s1 +step s1b { BEGIN; } +step s1s { SELECT * FROM d_lp_fk; } +step s1c { COMMIT; } -session "s2" -step "s2d" { ALTER TABLE d_lp_fk DETACH PARTITION d_lp_fk_1 CONCURRENTLY; } +session s2 +step s2d { ALTER TABLE d_lp_fk DETACH PARTITION d_lp_fk_1 CONCURRENTLY; } -session "s3" -step "s3b" { BEGIN; } -step "s3i1" { INSERT INTO d_lp_fk_r VALUES (1); } -step "s3i2" { INSERT INTO d_lp_fk_r VALUES (2); } -step "s3c" { COMMIT; } +session s3 +step s3b { BEGIN; } +step s3i1 { INSERT INTO d_lp_fk_r VALUES (1); } +step s3i2 { INSERT INTO d_lp_fk_r VALUES (2); } +step s3c { COMMIT; } # The transaction that detaches hangs until it sees any older transaction # terminate. -permutation "s1b" "s1s" "s2d" "s3i1" "s1c" -permutation "s1b" "s1s" "s2d" "s3i2" "s3i2" "s1c" +permutation s1b s1s s2d s3i1 s1c +permutation s1b s1s s2d s3i2 s3i2 s1c -permutation "s1b" "s1s" "s3i1" "s2d" "s1c" -permutation "s1b" "s1s" "s3i2" "s2d" "s1c" +permutation s1b s1s s3i1 s2d s1c +permutation s1b s1s s3i2 s2d s1c # what if s3 has an uncommitted insertion? -permutation "s1b" "s1s" "s3b" "s2d" "s3i1" "s1c" "s3c" +permutation s1b s1s s3b s2d s3i1 s1c s3c diff --git a/src/test/isolation/specs/detach-partition-concurrently-3.spec b/src/test/isolation/specs/detach-partition-concurrently-3.spec index 5c8d45fee5..e74c73b93d 100644 --- a/src/test/isolation/specs/detach-partition-concurrently-3.spec +++ b/src/test/isolation/specs/detach-partition-concurrently-3.spec @@ -20,67 +20,67 @@ teardown { DROP TABLE IF EXISTS d3_listp, d3_listp1, d3_listp2, d3_pid; } -session "s1" -step "s1b" { BEGIN; } -step "s1brr" { BEGIN ISOLATION LEVEL REPEATABLE READ; } -step "s1s" { SELECT * FROM d3_listp; } -step "s1spart" { SELECT * FROM d3_listp1; } -step "s1cancel" { SELECT pg_cancel_backend(pid) FROM d3_pid; } -step "s1noop" { } -step "s1c" { COMMIT; } -step "s1alter" { ALTER TABLE d3_listp1 ALTER a DROP NOT NULL; } -step "s1insert" { INSERT INTO d3_listp VALUES (1); } -step "s1insertpart" { INSERT INTO d3_listp1 VALUES (1); } -step "s1drop" { DROP TABLE d3_listp; } -step "s1droppart" { DROP TABLE d3_listp1; } -step "s1trunc" { TRUNCATE TABLE d3_listp; } -step "s1list" { SELECT relname FROM pg_catalog.pg_class +session s1 +step s1b { BEGIN; } +step s1brr { BEGIN ISOLATION LEVEL REPEATABLE READ; } +step s1s { SELECT * FROM d3_listp; } +step s1spart { SELECT * FROM d3_listp1; } +step s1cancel { SELECT pg_cancel_backend(pid) FROM d3_pid; } +step s1noop { } +step s1c { COMMIT; } +step s1alter { ALTER TABLE d3_listp1 ALTER a DROP NOT NULL; } +step s1insert { INSERT INTO d3_listp VALUES (1); } +step s1insertpart { INSERT INTO d3_listp1 VALUES (1); } +step s1drop { DROP TABLE d3_listp; } +step s1droppart { DROP TABLE d3_listp1; } +step s1trunc { TRUNCATE TABLE d3_listp; } +step s1list { SELECT relname FROM pg_catalog.pg_class WHERE relname LIKE 'd3_listp%' ORDER BY 1; } -step "s1describe" { SELECT 'd3_listp' AS root, * FROM pg_partition_tree('d3_listp') +step s1describe { SELECT 'd3_listp' AS root, * FROM pg_partition_tree('d3_listp') UNION ALL SELECT 'd3_listp1', * FROM pg_partition_tree('d3_listp1'); } -session "s2" -step "s2begin" { BEGIN; } -step "s2snitch" { INSERT INTO d3_pid SELECT pg_backend_pid(); } -step "s2detach" { ALTER TABLE d3_listp DETACH PARTITION d3_listp1 CONCURRENTLY; } -step "s2detach2" { ALTER TABLE d3_listp DETACH PARTITION d3_listp2 CONCURRENTLY; } -step "s2detachfinal" { ALTER TABLE d3_listp DETACH PARTITION d3_listp1 FINALIZE; } -step "s2drop" { DROP TABLE d3_listp1; } -step "s2commit" { COMMIT; } +session s2 +step s2begin { BEGIN; } +step s2snitch { INSERT INTO d3_pid SELECT pg_backend_pid(); } +step s2detach { ALTER TABLE d3_listp DETACH PARTITION d3_listp1 CONCURRENTLY; } +step s2detach2 { ALTER TABLE d3_listp DETACH PARTITION d3_listp2 CONCURRENTLY; } +step s2detachfinal { ALTER TABLE d3_listp DETACH PARTITION d3_listp1 FINALIZE; } +step s2drop { DROP TABLE d3_listp1; } +step s2commit { COMMIT; } # Try various things while the partition is in "being detached" state, with # no session waiting. -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s1describe" "s1alter" -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1insert" "s1c" -permutation "s2snitch" "s1brr" "s1s" "s2detach"("s1cancel") "s1cancel" "s1insert" "s1c" "s1spart" -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s1insertpart" +permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s1describe s1alter +permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1insert s1c +permutation s2snitch s1brr s1s s2detach(s1cancel) s1cancel s1insert s1c s1spart +permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s1insertpart # Test partition descriptor caching -permutation "s2snitch" "s1b" "s1s" "s2detach2"("s1cancel") "s1cancel" "s1c" "s1brr" "s1insert" "s1s" "s1insert" "s1c" -permutation "s2snitch" "s1b" "s1s" "s2detach2"("s1cancel") "s1cancel" "s1c" "s1brr" "s1s" "s1insert" "s1s" "s1c" +permutation s2snitch s1b s1s s2detach2(s1cancel) s1cancel s1c s1brr s1insert s1s s1insert s1c +permutation s2snitch s1b s1s s2detach2(s1cancel) s1cancel s1c s1brr s1s s1insert s1s s1c # "drop" here does both tables -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s1drop" "s1list" +permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s1drop s1list # "truncate" only does parent, not partition -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s1trunc" "s1spart" +permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s1trunc s1spart # If a partition pending detach exists, we cannot drop another one -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1noop" "s2detach2" "s1c" -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1noop" "s2detachfinal" "s1c" "s2detach2" -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s1droppart" "s2detach2" +permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1noop s2detach2 s1c +permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1noop s2detachfinal s1c s2detach2 +permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s1droppart s2detach2 # When a partition with incomplete detach is dropped, we grab lock on parent too. -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s2begin" "s2drop" "s1s" "s2commit" +permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s2begin s2drop s1s s2commit # Partially detach, then select and try to complete the detach. Reading # from partition blocks (AEL is required on partition); reading from parent # does not block. -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s1b" "s1spart" "s2detachfinal" "s1c" -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s1b" "s1s" "s2detachfinal" "s1c" +permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s1b s1spart s2detachfinal s1c +permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s1b s1s s2detachfinal s1c # DETACH FINALIZE in a transaction block. No insert/select on the partition # is allowed concurrently with that. -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s1b" "s1spart" "s2detachfinal" "s1c" -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s2begin" "s2detachfinal" "s2commit" -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s2begin" "s2detachfinal" "s1spart" "s2commit" -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1c" "s2begin" "s2detachfinal" "s1insertpart" "s2commit" +permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s1b s1spart s2detachfinal s1c +permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s2begin s2detachfinal s2commit +permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s2begin s2detachfinal s1spart s2commit +permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1c s2begin s2detachfinal s1insertpart s2commit diff --git a/src/test/isolation/specs/detach-partition-concurrently-4.spec b/src/test/isolation/specs/detach-partition-concurrently-4.spec index 208808bc3d..8f998ed39a 100644 --- a/src/test/isolation/specs/detach-partition-concurrently-4.spec +++ b/src/test/isolation/specs/detach-partition-concurrently-4.spec @@ -23,61 +23,61 @@ setup { create table d4_pid (pid int); } -session "s1" -step "s1b" { begin; } -step "s1brr" { begin isolation level repeatable read; } -step "s1s" { select * from d4_primary; } -step "s1cancel" { select pg_cancel_backend(pid) from d4_pid; } -step "s1noop" { } -step "s1insert" { insert into d4_fk values (1); } -step "s1c" { commit; } -step "s1declare" { declare f cursor for select * from d4_primary; } -step "s1declare2" { declare f cursor for select * from d4_fk where a = 2; } -step "s1fetchall" { fetch all from f; } -step "s1fetchone" { fetch 1 from f; } -step "s1updcur" { update d4_fk set a = 1 where current of f; } -step "s1svpt" { savepoint f; } -step "s1rollback" { rollback to f; } +session s1 +step s1b { begin; } +step s1brr { begin isolation level repeatable read; } +step s1s { select * from d4_primary; } +step s1cancel { select pg_cancel_backend(pid) from d4_pid; } +step s1noop { } +step s1insert { insert into d4_fk values (1); } +step s1c { commit; } +step s1declare { declare f cursor for select * from d4_primary; } +step s1declare2 { declare f cursor for select * from d4_fk where a = 2; } +step s1fetchall { fetch all from f; } +step s1fetchone { fetch 1 from f; } +step s1updcur { update d4_fk set a = 1 where current of f; } +step s1svpt { savepoint f; } +step s1rollback { rollback to f; } -session "s2" -step "s2snitch" { insert into d4_pid select pg_backend_pid(); } -step "s2detach" { alter table d4_primary detach partition d4_primary1 concurrently; } +session s2 +step s2snitch { insert into d4_pid select pg_backend_pid(); } +step s2detach { alter table d4_primary detach partition d4_primary1 concurrently; } -session "s3" -step "s3brr" { begin isolation level repeatable read; } -step "s3insert" { insert into d4_fk values (1); } -step "s3commit" { commit; } -step "s3vacfreeze" { vacuum freeze pg_catalog.pg_inherits; } +session s3 +step s3brr { begin isolation level repeatable read; } +step s3insert { insert into d4_fk values (1); } +step s3commit { commit; } +step s3vacfreeze { vacuum freeze pg_catalog.pg_inherits; } # Trying to insert into a partially detached partition is rejected -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1insert" "s1c" -permutation "s2snitch" "s1b" "s1s" "s2detach" "s1insert" "s1c" +permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1insert s1c +permutation s2snitch s1b s1s s2detach s1insert s1c # ... even under REPEATABLE READ mode. -permutation "s2snitch" "s1brr" "s1s" "s2detach"("s1cancel") "s1cancel" "s1insert" "s1c" -permutation "s2snitch" "s1brr" "s1s" "s2detach" "s1insert" "s1c" +permutation s2snitch s1brr s1s s2detach(s1cancel) s1cancel s1insert s1c +permutation s2snitch s1brr s1s s2detach s1insert s1c # If you read the referenced table using a cursor, you can see a row that the # RI query does not see. -permutation "s2snitch" "s1b" "s1declare" "s2detach"("s1cancel") "s1cancel" "s1fetchall" "s1insert" "s1c" -permutation "s2snitch" "s1b" "s1declare" "s2detach" "s1fetchall" "s1insert" "s1c" -permutation "s2snitch" "s1b" "s1declare" "s2detach"("s1cancel") "s1cancel" "s1svpt" "s1insert" "s1rollback" "s1fetchall" "s1c" -permutation "s2snitch" "s1b" "s1declare" "s2detach" "s1svpt" "s1insert" "s1rollback" "s1fetchall" "s1c" -permutation "s2snitch" "s1b" "s2detach"("s1cancel") "s1declare" "s1cancel" "s1fetchall" "s1insert" "s1c" -permutation "s2snitch" "s1b" "s2detach" "s1declare" "s1fetchall" "s1insert" "s1c" -permutation "s2snitch" "s1b" "s2detach"("s1cancel") "s1declare" "s1cancel" "s1svpt" "s1insert" "s1rollback" "s1fetchall" "s1c" -permutation "s2snitch" "s1b" "s2detach" "s1declare" "s1svpt" "s1insert" "s1rollback" "s1fetchall" "s1c" +permutation s2snitch s1b s1declare s2detach(s1cancel) s1cancel s1fetchall s1insert s1c +permutation s2snitch s1b s1declare s2detach s1fetchall s1insert s1c +permutation s2snitch s1b s1declare s2detach(s1cancel) s1cancel s1svpt s1insert s1rollback s1fetchall s1c +permutation s2snitch s1b s1declare s2detach s1svpt s1insert s1rollback s1fetchall s1c +permutation s2snitch s1b s2detach(s1cancel) s1declare s1cancel s1fetchall s1insert s1c +permutation s2snitch s1b s2detach s1declare s1fetchall s1insert s1c +permutation s2snitch s1b s2detach(s1cancel) s1declare s1cancel s1svpt s1insert s1rollback s1fetchall s1c +permutation s2snitch s1b s2detach s1declare s1svpt s1insert s1rollback s1fetchall s1c # Creating the referencing row using a cursor -permutation "s2snitch" "s1brr" "s1declare2" "s1fetchone" "s2detach"("s1cancel") "s1cancel" "s1updcur" "s1c" -permutation "s2snitch" "s1brr" "s1declare2" "s1fetchone" "s2detach" "s1updcur" "s1c" -permutation "s2snitch" "s1brr" "s1declare2" "s1fetchone" "s1updcur" "s2detach" "s1c" +permutation s2snitch s1brr s1declare2 s1fetchone s2detach(s1cancel) s1cancel s1updcur s1c +permutation s2snitch s1brr s1declare2 s1fetchone s2detach s1updcur s1c +permutation s2snitch s1brr s1declare2 s1fetchone s1updcur s2detach s1c # Try reading the table from an independent session. -permutation "s2snitch" "s1b" "s1s" "s2detach" "s3insert" "s1c" -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s3brr" "s3insert" "s3commit" "s1cancel" "s1c" -permutation "s2snitch" "s1b" "s1s" "s2detach" "s3brr" "s3insert" "s3commit" "s1c" +permutation s2snitch s1b s1s s2detach s3insert s1c +permutation s2snitch s1b s1s s2detach(s1cancel) s3brr s3insert s3commit s1cancel s1c +permutation s2snitch s1b s1s s2detach s3brr s3insert s3commit s1c # Try one where we VACUUM FREEZE pg_inherits (to verify that xmin change is # handled correctly). -permutation "s2snitch" "s1brr" "s1s" "s2detach"("s1cancel") "s1cancel" "s1noop" "s3vacfreeze" "s1s" "s1insert" "s1c" -permutation "s2snitch" "s1b" "s1s" "s2detach"("s1cancel") "s1cancel" "s1noop" "s3vacfreeze" "s1s" "s1insert" "s1c" +permutation s2snitch s1brr s1s s2detach(s1cancel) s1cancel s1noop s3vacfreeze s1s s1insert s1c +permutation s2snitch s1b s1s s2detach(s1cancel) s1cancel s1noop s3vacfreeze s1s s1insert s1c diff --git a/src/test/isolation/specs/drop-index-concurrently-1.spec b/src/test/isolation/specs/drop-index-concurrently-1.spec index dd42b70ddf..812b5de226 100644 --- a/src/test/isolation/specs/drop-index-concurrently-1.spec +++ b/src/test/isolation/specs/drop-index-concurrently-1.spec @@ -17,25 +17,25 @@ teardown 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 diff --git a/src/test/isolation/specs/eval-plan-qual-trigger.spec b/src/test/isolation/specs/eval-plan-qual-trigger.spec index d3b55b7d40..b512edd287 100644 --- a/src/test/isolation/specs/eval-plan-qual-trigger.spec +++ b/src/test/isolation/specs/eval-plan-qual-trigger.spec @@ -54,53 +54,53 @@ teardown } -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 @@ -108,42 +108,42 @@ step "s1_upd_a_tob" { 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' @@ -153,19 +153,19 @@ step "s2_upsert_a_data" { 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 @@ -175,236 +175,236 @@ step "s3_upd_a_data" { ### 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 diff --git a/src/test/isolation/specs/eval-plan-qual.spec b/src/test/isolation/specs/eval-plan-qual.spec index 70fa320fc4..4bb959504a 100644 --- a/src/test/isolation/specs/eval-plan-qual.spec +++ b/src/test/isolation/specs/eval-plan-qual.spec @@ -66,25 +66,25 @@ teardown DROP FUNCTION noisy_oper(text, anynonarray, text, anynonarray) } -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' RETURNING balance; } +step wx1 { UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; } # wy1 then wy2 checks the case where quals pass then fail -step "wy1" { UPDATE accounts SET balance = balance + 500 WHERE accountid = 'checking' RETURNING balance; } +step wy1 { UPDATE accounts SET balance = balance + 500 WHERE accountid = 'checking' RETURNING balance; } -step "wxext1" { UPDATE accounts_ext SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; } -step "tocds1" { UPDATE accounts SET accountid = 'cds' WHERE accountid = 'checking'; } -step "tocdsext1" { UPDATE accounts_ext SET accountid = 'cds' WHERE accountid = 'checking'; } +step wxext1 { UPDATE accounts_ext SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; } +step tocds1 { UPDATE accounts SET accountid = 'cds' WHERE accountid = 'checking'; } +step tocdsext1 { UPDATE accounts_ext SET accountid = 'cds' WHERE accountid = 'checking'; } # d1 then wx1 checks that update can deal with the updated row vanishing # wx2 then d1 checks that the delete affects the updated row # wx2, wx2 then d1 checks that the delete checks the quals correctly (balance too high) # wx2, d2, then d1 checks that delete handles a vanishing row correctly -step "d1" { DELETE FROM accounts WHERE accountid = 'checking' AND balance < 1500 RETURNING balance; } +step d1 { DELETE FROM accounts WHERE accountid = 'checking' AND balance < 1500 RETURNING balance; } # upsert tests are to check writable-CTE cases -step "upsert1" { +step upsert1 { WITH upsert AS (UPDATE accounts SET balance = balance + 500 WHERE accountid = 'savings' @@ -99,29 +99,29 @@ step "upsert1" { # writep2/returningp1 tests a memory allocation issue # writep3a/writep3b tests updates touching more than one table -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 "writep3a" { UPDATE p SET b = -b WHERE c = 0; } -step "c1" { COMMIT; } -step "r1" { ROLLBACK; } +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 writep3a { UPDATE p SET b = -b WHERE c = 0; } +step c1 { COMMIT; } +step r1 { ROLLBACK; } # these tests are meant to exercise EvalPlanQualFetchRowMark, # 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 { -- Reference rowmark column that differs in type from targetlist at some attno. -- See CAHU7rYZo_C4ULsAx_LAj8az9zqgrD8WDd4hTegDTMM1LMqrBsg@mail.gmail.com SELECT a1.*, v.id FROM accounts a1, (values('checking'::text, 'nan'::text),('savings', 'nan')) v(id, notnumeric) WHERE a1.accountid = v.id AND v.notnumeric != 'einszwei' FOR UPDATE OF a1; } -step "partiallock_ext" { +step partiallock_ext { SELECT * FROM accounts_ext a1, accounts_ext a2 WHERE a1.accountid = a2.accountid FOR UPDATE OF a1; @@ -130,7 +130,7 @@ step "partiallock_ext" { # 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; } @@ -138,13 +138,13 @@ step "updateforss" { # 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 local enable_nestloop to 0; set local enable_hashjoin to 0; set local enable_seqscan to 0; @@ -155,7 +155,7 @@ step "selectjoinforupdate" { # these tests exercise Result plan nodes participating in EPQ -step "selectresultforupdate" { +step selectresultforupdate { select * from (select 1 as x) ss1 join (select 7 as y) ss2 on true left join table_a a on a.id = x, jointest jt where jt.id = y; @@ -170,28 +170,28 @@ step "selectresultforupdate" { # test for EPQ on a partitioned result table -step "simplepartupdate" { +step simplepartupdate { update parttbl set a = a; } # test scenarios where update may cause row movement -step "simplepartupdate_route1to2" { +step simplepartupdate_route1to2 { update parttbl set a = 2 where c = 1 returning *; } -step "simplepartupdate_noroute" { +step simplepartupdate_noroute { update parttbl set b = 2 where c = 1 returning *; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL READ COMMITTED; } -step "wx2" { UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; } -step "wy2" { UPDATE accounts SET balance = balance + 1000 WHERE accountid = 'checking' AND balance < 1000 RETURNING balance; } -step "d2" { DELETE FROM accounts WHERE accountid = 'checking'; } +step wx2 { UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; } +step wy2 { UPDATE accounts SET balance = balance + 1000 WHERE accountid = 'checking' AND balance < 1000 RETURNING balance; } +step d2 { DELETE FROM accounts WHERE accountid = 'checking'; } -step "upsert2" { +step upsert2 { WITH upsert AS (UPDATE accounts SET balance = balance + 1234 WHERE accountid = 'savings' @@ -199,45 +199,45 @@ step "upsert2" { INSERT INTO accounts SELECT 'savings', 1234 WHERE NOT EXISTS (SELECT 1 FROM upsert); } -step "wx2_ext" { UPDATE accounts_ext SET balance = balance + 450; } -step "readp2" { SELECT tableoid::regclass, ctid, * FROM p WHERE b IN (0, 1) AND c = 0 FOR UPDATE; } -step "returningp1" { +step wx2_ext { UPDATE accounts_ext SET balance = balance + 450; } +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 "writep3b" { UPDATE p SET b = -b WHERE c = 0; } -step "readforss" { +step writep3b { UPDATE p SET b = -b WHERE c = 0; } +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 "complexpartupdate_route_err1" { +step complexpartupdate_route_err1 { with u as (update another_parttbl set a = 1 returning another_parttbl.*) update parttbl p set a = u.a from u where p.a = u.a and p.c = 1 returning p.*; } -step "complexpartupdate_route" { +step complexpartupdate_route { with u as (update another_parttbl set a = 1 returning another_parttbl.*) update parttbl p set a = p.b from u where p.a = u.a and p.c = 1 returning p.*; } -step "complexpartupdate_doesnt_route" { +step complexpartupdate_doesnt_route { with u as (update another_parttbl set a = 1 returning another_parttbl.*) update parttbl p set a = 3 - p.b from u where p.a = u.a and p.c = 1 returning p.*; } @@ -246,13 +246,13 @@ step "complexpartupdate_doesnt_route" { # (updated|deleted). The *fail versions of the tests additionally # perform an update, via a function, in a different command, to test # behaviour relating to that. -step "updwcte" { WITH doup AS (UPDATE accounts SET balance = balance + 1100 WHERE accountid = 'checking' RETURNING *) UPDATE accounts a SET balance = doup.balance + 100 FROM doup RETURNING *; } -step "updwctefail" { WITH doup AS (UPDATE accounts SET balance = balance + 1100 WHERE accountid = 'checking' RETURNING *, update_checking(999)) UPDATE accounts a SET balance = doup.balance + 100 FROM doup RETURNING *; } -step "delwcte" { WITH doup AS (UPDATE accounts SET balance = balance + 1100 WHERE accountid = 'checking' RETURNING *) DELETE FROM accounts a USING doup RETURNING *; } -step "delwctefail" { WITH doup AS (UPDATE accounts SET balance = balance + 1100 WHERE accountid = 'checking' RETURNING *, update_checking(999)) DELETE FROM accounts a USING doup RETURNING *; } +step updwcte { WITH doup AS (UPDATE accounts SET balance = balance + 1100 WHERE accountid = 'checking' RETURNING *) UPDATE accounts a SET balance = doup.balance + 100 FROM doup RETURNING *; } +step updwctefail { WITH doup AS (UPDATE accounts SET balance = balance + 1100 WHERE accountid = 'checking' RETURNING *, update_checking(999)) UPDATE accounts a SET balance = doup.balance + 100 FROM doup RETURNING *; } +step delwcte { WITH doup AS (UPDATE accounts SET balance = balance + 1100 WHERE accountid = 'checking' RETURNING *) DELETE FROM accounts a USING doup RETURNING *; } +step delwctefail { WITH doup AS (UPDATE accounts SET balance = balance + 1100 WHERE accountid = 'checking' RETURNING *, update_checking(999)) DELETE FROM accounts a USING doup RETURNING *; } # Check that nested EPQ works correctly -step "wnested2" { +step wnested2 { UPDATE accounts SET balance = balance - 1200 WHERE noisy_oper('upid', accountid, '=', 'checking') AND noisy_oper('up', balance, '>', 200.0) @@ -265,17 +265,17 @@ step "wnested2" { ); } -step "c2" { COMMIT; } -step "r2" { ROLLBACK; } +step c2 { COMMIT; } +step r2 { ROLLBACK; } -session "s3" +session s3 setup { BEGIN ISOLATION LEVEL READ COMMITTED; } -step "read" { SELECT * FROM accounts ORDER BY accountid; } -step "read_ext" { SELECT * FROM accounts_ext ORDER BY accountid; } -step "read_a" { SELECT * FROM table_a ORDER BY id; } +step read { SELECT * FROM accounts ORDER BY accountid; } +step read_ext { SELECT * FROM accounts_ext 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' @@ -289,7 +289,7 @@ step "readwcte" { } # 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 ) @@ -299,61 +299,61 @@ step "multireadwcte" { teardown { COMMIT; } # test that normal update follows update chains, and reverifies quals -permutation "wx1" "wx2" "c1" "c2" "read" -permutation "wy1" "wy2" "c1" "c2" "read" -permutation "wx1" "wx2" "r1" "c2" "read" -permutation "wy1" "wy2" "r1" "c2" "read" +permutation wx1 wx2 c1 c2 read +permutation wy1 wy2 c1 c2 read +permutation wx1 wx2 r1 c2 read +permutation wy1 wy2 r1 c2 read # test that deletes follow chains, and if necessary reverifies quals -permutation "wx1" "d1" "wx2" "c1" "c2" "read" -permutation "wx2" "d1" "c2" "c1" "read" -permutation "wx2" "wx2" "d1" "c2" "c1" "read" -permutation "wx2" "d2" "d1" "c2" "c1" "read" -permutation "wx1" "d1" "wx2" "r1" "c2" "read" -permutation "wx2" "d1" "r2" "c1" "read" -permutation "wx2" "wx2" "d1" "r2" "c1" "read" -permutation "wx2" "d2" "d1" "r2" "c1" "read" -permutation "d1" "wx2" "c1" "c2" "read" -permutation "d1" "wx2" "r1" "c2" "read" +permutation wx1 d1 wx2 c1 c2 read +permutation wx2 d1 c2 c1 read +permutation wx2 wx2 d1 c2 c1 read +permutation wx2 d2 d1 c2 c1 read +permutation wx1 d1 wx2 r1 c2 read +permutation wx2 d1 r2 c1 read +permutation wx2 wx2 d1 r2 c1 read +permutation wx2 d2 d1 r2 c1 read +permutation d1 wx2 c1 c2 read +permutation d1 wx2 r1 c2 read # Check that nested EPQ works correctly -permutation "wnested2" "c1" "c2" "read" -permutation "wx1" "wxext1" "wnested2" "c1" "c2" "read" -permutation "wx1" "wx1" "wxext1" "wnested2" "c1" "c2" "read" -permutation "wx1" "wx1" "wxext1" "wxext1" "wnested2" "c1" "c2" "read" -permutation "wx1" "wxext1" "wxext1" "wnested2" "c1" "c2" "read" -permutation "wx1" "tocds1" "wnested2" "c1" "c2" "read" -permutation "wx1" "tocdsext1" "wnested2" "c1" "c2" "read" +permutation wnested2 c1 c2 read +permutation wx1 wxext1 wnested2 c1 c2 read +permutation wx1 wx1 wxext1 wnested2 c1 c2 read +permutation wx1 wx1 wxext1 wxext1 wnested2 c1 c2 read +permutation wx1 wxext1 wxext1 wnested2 c1 c2 read +permutation wx1 tocds1 wnested2 c1 c2 read +permutation wx1 tocdsext1 wnested2 c1 c2 read # test that an update to a self-modified row is ignored when # previously updated by the same cid -permutation "wx1" "updwcte" "c1" "c2" "read" +permutation wx1 updwcte c1 c2 read # test that an update to a self-modified row throws error when # previously updated by a different cid -permutation "wx1" "updwctefail" "c1" "c2" "read" +permutation wx1 updwctefail c1 c2 read # test that a delete to a self-modified row is ignored when # previously updated by the same cid -permutation "wx1" "delwcte" "c1" "c2" "read" +permutation wx1 delwcte c1 c2 read # test that a delete to a self-modified row throws error when # previously updated by a different cid -permutation "wx1" "delwctefail" "c1" "c2" "read" +permutation wx1 delwctefail c1 c2 read -permutation "upsert1" "upsert2" "c1" "c2" "read" -permutation "readp1" "writep1" "readp2" "c1" "c2" -permutation "writep2" "returningp1" "c1" "c2" -permutation "writep3a" "writep3b" "c1" "c2" -permutation "wx2" "partiallock" "c2" "c1" "read" -permutation "wx2" "lockwithvalues" "c2" "c1" "read" -permutation "wx2_ext" "partiallock_ext" "c2" "c1" "read_ext" -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 "wrjt" "selectresultforupdate" "c2" "c1" -permutation "wrtwcte" "multireadwcte" "c1" "c2" +permutation upsert1 upsert2 c1 c2 read +permutation readp1 writep1 readp2 c1 c2 +permutation writep2 returningp1 c1 c2 +permutation writep3a writep3b c1 c2 +permutation wx2 partiallock c2 c1 read +permutation wx2 lockwithvalues c2 c1 read +permutation wx2_ext partiallock_ext c2 c1 read_ext +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 wrjt selectresultforupdate c2 c1 +permutation wrtwcte multireadwcte c1 c2 -permutation "simplepartupdate" "complexpartupdate" "c1" "c2" -permutation "simplepartupdate_route1to2" "complexpartupdate_route_err1" "c1" "c2" -permutation "simplepartupdate_noroute" "complexpartupdate_route" "c1" "c2" -permutation "simplepartupdate_noroute" "complexpartupdate_doesnt_route" "c1" "c2" +permutation simplepartupdate complexpartupdate c1 c2 +permutation simplepartupdate_route1to2 complexpartupdate_route_err1 c1 c2 +permutation simplepartupdate_noroute complexpartupdate_route c1 c2 +permutation simplepartupdate_noroute complexpartupdate_doesnt_route c1 c2 diff --git a/src/test/isolation/specs/fk-contention.spec b/src/test/isolation/specs/fk-contention.spec index 8481ae4e33..f11a1d8cef 100644 --- a/src/test/isolation/specs/fk-contention.spec +++ b/src/test/isolation/specs/fk-contention.spec @@ -10,10 +10,10 @@ teardown 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'; } diff --git a/src/test/isolation/specs/fk-deadlock.spec b/src/test/isolation/specs/fk-deadlock.spec index 4f357c62ea..b4970dd06f 100644 --- a/src/test/isolation/specs/fk-deadlock.spec +++ b/src/test/isolation/specs/fk-deadlock.spec @@ -18,29 +18,29 @@ teardown 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 diff --git a/src/test/isolation/specs/fk-deadlock2.spec b/src/test/isolation/specs/fk-deadlock2.spec index a8305246e1..c8e0e4eb19 100644 --- a/src/test/isolation/specs/fk-deadlock2.spec +++ b/src/test/isolation/specs/fk-deadlock2.spec @@ -23,26 +23,26 @@ teardown 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 diff --git a/src/test/isolation/specs/fk-partitioned-1.spec b/src/test/isolation/specs/fk-partitioned-1.spec index 4c760e89b3..f71ee5cb17 100644 --- a/src/test/isolation/specs/fk-partitioned-1.spec +++ b/src/test/isolation/specs/fk-partitioned-1.spec @@ -11,35 +11,35 @@ drop table if exists ppk, pfk, pfk1; insert into pfk1 values (1); } -session "s1" -step "s1b" { begin; } -step "s1d" { delete from ppk1 where a = 1; } -step "s1c" { commit; } +session s1 +step s1b { begin; } +step s1d { delete from ppk1 where a = 1; } +step s1c { commit; } -session "s2" -step "s2b" { begin; } -step "s2a" { alter table pfk attach partition pfk1 for values in (1); } -step "s2c" { commit; } +session s2 +step s2b { begin; } +step s2a { alter table pfk attach partition pfk1 for values in (1); } +step s2c { commit; } teardown { drop table ppk, pfk, pfk1; } -permutation "s1b" "s1d" "s1c" "s2b" "s2a" "s2c" -permutation "s1b" "s1d" "s2b" "s1c" "s2a" "s2c" -permutation "s1b" "s1d" "s2b" "s2a" "s1c" "s2c" -#permutation "s1b" "s1d" "s2b" "s2a" "s2c" "s1c" -permutation "s1b" "s2b" "s1d" "s1c" "s2a" "s2c" -permutation "s1b" "s2b" "s1d" "s2a" "s1c" "s2c" -#permutation "s1b" "s2b" "s1d" "s2a" "s2c" "s1c" -#permutation "s1b" "s2b" "s2a" "s1d" "s1c" "s2c" -permutation "s1b" "s2b" "s2a" "s1d" "s2c" "s1c" -permutation "s1b" "s2b" "s2a" "s2c" "s1d" "s1c" -permutation "s2b" "s1b" "s1d" "s1c" "s2a" "s2c" -permutation "s2b" "s1b" "s1d" "s2a" "s1c" "s2c" -#permutation "s2b" "s1b" "s1d" "s2a" "s2c" "s1c" -#permutation "s2b" "s1b" "s2a" "s1d" "s1c" "s2c" -permutation "s2b" "s1b" "s2a" "s1d" "s2c" "s1c" -permutation "s2b" "s1b" "s2a" "s2c" "s1d" "s1c" -#permutation "s2b" "s2a" "s1b" "s1d" "s1c" "s2c" -permutation "s2b" "s2a" "s1b" "s1d" "s2c" "s1c" -permutation "s2b" "s2a" "s1b" "s2c" "s1d" "s1c" -permutation "s2b" "s2a" "s2c" "s1b" "s1d" "s1c" +permutation s1b s1d s1c s2b s2a s2c +permutation s1b s1d s2b s1c s2a s2c +permutation s1b s1d s2b s2a s1c s2c +#permutation s1b s1d s2b s2a s2c s1c +permutation s1b s2b s1d s1c s2a s2c +permutation s1b s2b s1d s2a s1c s2c +#permutation s1b s2b s1d s2a s2c s1c +#permutation s1b s2b s2a s1d s1c s2c +permutation s1b s2b s2a s1d s2c s1c +permutation s1b s2b s2a s2c s1d s1c +permutation s2b s1b s1d s1c s2a s2c +permutation s2b s1b s1d s2a s1c s2c +#permutation s2b s1b s1d s2a s2c s1c +#permutation s2b s1b s2a s1d s1c s2c +permutation s2b s1b s2a s1d s2c s1c +permutation s2b s1b s2a s2c s1d s1c +#permutation s2b s2a s1b s1d s1c s2c +permutation s2b s2a s1b s1d s2c s1c +permutation s2b s2a s1b s2c s1d s1c +permutation s2b s2a s2c s1b s1d s1c diff --git a/src/test/isolation/specs/fk-partitioned-2.spec b/src/test/isolation/specs/fk-partitioned-2.spec index f1a76e801c..209ad59b3f 100644 --- a/src/test/isolation/specs/fk-partitioned-2.spec +++ b/src/test/isolation/specs/fk-partitioned-2.spec @@ -8,22 +8,22 @@ setup { create table pfk1 partition of pfk for values in (1); } -session "s1" -step "s1b" { begin; } -step "s1d" { delete from ppk where a = 1; } -step "s1c" { commit; } +session s1 +step s1b { begin; } +step s1d { delete from ppk where a = 1; } +step s1c { commit; } -session "s2" -step "s2b" { begin; } -step "s2bs" { begin isolation level serializable; select 1; } -step "s2i" { insert into pfk values (1); } -step "s2c" { commit; } +session s2 +step s2b { begin; } +step s2bs { begin isolation level serializable; select 1; } +step s2i { insert into pfk values (1); } +step s2c { commit; } teardown { drop table ppk, pfk, pfk1; } -permutation "s1b" "s1d" "s2b" "s2i" "s1c" "s2c" -permutation "s1b" "s1d" "s2bs" "s2i" "s1c" "s2c" -permutation "s1b" "s2b" "s1d" "s2i" "s1c" "s2c" -permutation "s1b" "s2bs" "s1d" "s2i" "s1c" "s2c" -permutation "s1b" "s2b" "s2i" "s1d" "s2c" "s1c" -permutation "s1b" "s2bs" "s2i" "s1d" "s2c" "s1c" +permutation s1b s1d s2b s2i s1c s2c +permutation s1b s1d s2bs s2i s1c s2c +permutation s1b s2b s1d s2i s1c s2c +permutation s1b s2bs s1d s2i s1c s2c +permutation s1b s2b s2i s1d s2c s1c +permutation s1b s2bs s2i s1d s2c s1c diff --git a/src/test/isolation/specs/freeze-the-dead.spec b/src/test/isolation/specs/freeze-the-dead.spec index 915bf15b92..6c349048d8 100644 --- a/src/test/isolation/specs/freeze-the-dead.spec +++ b/src/test/isolation/specs/freeze-the-dead.spec @@ -15,29 +15,29 @@ teardown 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 verifies that a previous bug # https://postgr.es/m/E5711E62-8FDF-4DCA-A888-C200BF6B5742@amazon.com @@ -45,12 +45,12 @@ step "s3_commit" { COMMIT; } # 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 diff --git a/src/test/isolation/specs/horizons.spec b/src/test/isolation/specs/horizons.spec index f74035c42f..d5239ff228 100644 --- a/src/test/isolation/specs/horizons.spec +++ b/src/test/isolation/specs/horizons.spec @@ -23,19 +23,19 @@ teardown { DROP FUNCTION explain_json(text); } -session "lifeline" +session lifeline # Start a transaction, force a snapshot to be held -step "ll_start" +step ll_start { BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; SELECT 1; } -step "ll_commit" { COMMIT; } +step ll_commit { COMMIT; } -session "pruner" +session pruner setup { @@ -44,13 +44,13 @@ setup SET enable_bitmapscan = false; } -step "pruner_create_temp" +step pruner_create_temp { CREATE TEMPORARY TABLE horizons_tst (data int unique) WITH (autovacuum_enabled = off); INSERT INTO horizons_tst(data) VALUES(1),(2); } -step "pruner_create_perm" +step pruner_create_perm { CREATE TABLE horizons_tst (data int unique) WITH (autovacuum_enabled = off); INSERT INTO horizons_tst(data) VALUES(1),(2); @@ -58,20 +58,20 @@ step "pruner_create_perm" # Temp tables cannot be dropped in the teardown, so just always do so # as part of the permutation -step "pruner_drop" +step pruner_drop { DROP TABLE horizons_tst; } -step "pruner_delete" +step pruner_delete { DELETE FROM horizons_tst; } -step "pruner_begin" { BEGIN; } -step "pruner_commit" { COMMIT; } +step pruner_begin { BEGIN; } +step pruner_commit { COMMIT; } -step "pruner_vacuum" +step pruner_vacuum { VACUUM horizons_tst; } @@ -79,7 +79,7 @@ step "pruner_vacuum" # Show the heap fetches of an ordered index-only-scan (other plans # have been forbidden above) - that tells us how many non-killed leaf # entries there are. -step "pruner_query" +step pruner_query { SELECT explain_json($$ EXPLAIN (FORMAT json, BUFFERS, ANALYZE) @@ -87,7 +87,7 @@ step "pruner_query" } # Verify that the query plan still is an IOS -step "pruner_query_plan" +step pruner_query_plan { EXPLAIN (COSTS OFF) SELECT * FROM horizons_tst ORDER BY data; } @@ -96,74 +96,74 @@ step "pruner_query_plan" # Show that with a permanent relation deleted rows cannot be pruned # away if there's a concurrent session still seeing the rows. permutation - "pruner_create_perm" - "ll_start" - "pruner_query_plan" + pruner_create_perm + ll_start + pruner_query_plan # Run query that could do pruning twice, first has chance to prune, # second would not perform heap fetches if first query did. - "pruner_query" - "pruner_query" - "pruner_delete" - "pruner_query" - "pruner_query" - "ll_commit" - "pruner_drop" + pruner_query + pruner_query + pruner_delete + pruner_query + pruner_query + ll_commit + pruner_drop # Show that with a temporary relation deleted rows can be pruned away, # even if there's a concurrent session with a snapshot from before the # deletion. That's safe because the session with the older snapshot # cannot access the temporary table. permutation - "pruner_create_temp" - "ll_start" - "pruner_query_plan" - "pruner_query" - "pruner_query" - "pruner_delete" - "pruner_query" - "pruner_query" - "ll_commit" - "pruner_drop" + pruner_create_temp + ll_start + pruner_query_plan + pruner_query + pruner_query + pruner_delete + pruner_query + pruner_query + ll_commit + pruner_drop # Verify that pruning in temporary relations doesn't remove rows still # visible in the current session permutation - "pruner_create_temp" - "ll_start" - "pruner_query" - "pruner_query" - "pruner_begin" - "pruner_delete" - "pruner_query" - "pruner_query" - "ll_commit" - "pruner_commit" - "pruner_drop" + pruner_create_temp + ll_start + pruner_query + pruner_query + pruner_begin + pruner_delete + pruner_query + pruner_query + ll_commit + pruner_commit + pruner_drop # Show that vacuum cannot remove deleted rows still visible to another # session's snapshot, when accessing a permanent table. permutation - "pruner_create_perm" - "ll_start" - "pruner_query" - "pruner_query" - "pruner_delete" - "pruner_vacuum" - "pruner_query" - "pruner_query" - "ll_commit" - "pruner_drop" + pruner_create_perm + ll_start + pruner_query + pruner_query + pruner_delete + pruner_vacuum + pruner_query + pruner_query + ll_commit + pruner_drop # Show that vacuum can remove deleted rows still visible to another # session's snapshot, when accessing a temporary table. permutation - "pruner_create_temp" - "ll_start" - "pruner_query" - "pruner_query" - "pruner_delete" - "pruner_vacuum" - "pruner_query" - "pruner_query" - "ll_commit" - "pruner_drop" + pruner_create_temp + ll_start + pruner_query + pruner_query + pruner_delete + pruner_vacuum + pruner_query + pruner_query + ll_commit + pruner_drop diff --git a/src/test/isolation/specs/index-only-scan.spec b/src/test/isolation/specs/index-only-scan.spec index 417bb02102..4e4171ca80 100644 --- a/src/test/isolation/specs/index-only-scan.spec +++ b/src/test/isolation/specs/index-only-scan.spec @@ -23,7 +23,7 @@ teardown DROP TABLE taby; } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; @@ -31,10 +31,10 @@ setup 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; @@ -42,5 +42,5 @@ setup 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; } diff --git a/src/test/isolation/specs/inherit-temp.spec b/src/test/isolation/specs/inherit-temp.spec index 5cd251d0aa..644f919e84 100644 --- a/src/test/isolation/specs/inherit-temp.spec +++ b/src/test/isolation/specs/inherit-temp.spec @@ -19,60 +19,60 @@ teardown # 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 diff --git a/src/test/isolation/specs/insert-conflict-do-nothing-2.spec b/src/test/isolation/specs/insert-conflict-do-nothing-2.spec index 8a8ec94447..825b7d6490 100644 --- a/src/test/isolation/specs/insert-conflict-do-nothing-2.spec +++ b/src/test/isolation/specs/insert-conflict-do-nothing-2.spec @@ -11,24 +11,24 @@ teardown 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 diff --git a/src/test/isolation/specs/insert-conflict-do-nothing.spec b/src/test/isolation/specs/insert-conflict-do-nothing.spec index 71acc380c7..b0e6a37247 100644 --- a/src/test/isolation/specs/insert-conflict-do-nothing.spec +++ b/src/test/isolation/specs/insert-conflict-do-nothing.spec @@ -16,25 +16,25 @@ teardown 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 diff --git a/src/test/isolation/specs/insert-conflict-do-update-2.spec b/src/test/isolation/specs/insert-conflict-do-update-2.spec index 12f6be8000..8a7c546f43 100644 --- a/src/test/isolation/specs/insert-conflict-do-update-2.spec +++ b/src/test/isolation/specs/insert-conflict-do-update-2.spec @@ -15,26 +15,26 @@ teardown 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 diff --git a/src/test/isolation/specs/insert-conflict-do-update-3.spec b/src/test/isolation/specs/insert-conflict-do-update-3.spec index e282c3beca..df6795467d 100644 --- a/src/test/isolation/specs/insert-conflict-do-update-3.spec +++ b/src/test/isolation/specs/insert-conflict-do-update-3.spec @@ -37,12 +37,12 @@ teardown 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) @@ -50,20 +50,20 @@ step "insert1" { 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 diff --git a/src/test/isolation/specs/insert-conflict-do-update.spec b/src/test/isolation/specs/insert-conflict-do-update.spec index 7c8cb47100..62cdafda98 100644 --- a/src/test/isolation/specs/insert-conflict-do-update.spec +++ b/src/test/isolation/specs/insert-conflict-do-update.spec @@ -13,27 +13,27 @@ teardown 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 diff --git a/src/test/isolation/specs/insert-conflict-specconflict.spec b/src/test/isolation/specs/insert-conflict-specconflict.spec index 3bc2bf0630..55b8bb100f 100644 --- a/src/test/isolation/specs/insert-conflict-specconflict.spec +++ b/src/test/isolation/specs/insert-conflict-specconflict.spec @@ -43,24 +43,24 @@ teardown DROP TABLE upserttest; } -session "controller" +session controller setup { SET default_transaction_isolation = 'read committed'; SET application_name = 'isolation/insert-conflict-specconflict-controller'; } -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_lock_2_4" { SELECT pg_advisory_lock(2, 4); } -step "controller_unlock_2_4" { SELECT pg_advisory_unlock(2, 4); } -step "controller_show" {SELECT * FROM upserttest; } -step "controller_show_count" {SELECT COUNT(*) FROM upserttest; } -step "controller_print_speculative_locks" { +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_lock_2_4 { SELECT pg_advisory_lock(2, 4); } +step controller_unlock_2_4 { SELECT pg_advisory_unlock(2, 4); } +step controller_show {SELECT * FROM upserttest; } +step controller_show_count {SELECT COUNT(*) FROM upserttest; } +step controller_print_speculative_locks { SELECT pa.application_name, locktype, mode, granted FROM pg_locks pl JOIN pg_stat_activity pa USING (pid) WHERE @@ -70,33 +70,33 @@ step "controller_print_speculative_locks" { ORDER BY 1, 2, 3, 4; } -session "s1" +session s1 setup { SET default_transaction_isolation = 'read committed'; SET spec.session = 1; SET application_name = 'isolation/insert-conflict-specconflict-s1'; } -step "s1_begin" { BEGIN; } -step "s1_create_non_unique_index" { CREATE INDEX upserttest_key_idx ON upserttest((blurt_and_lock_4(key))); } -step "s1_confirm_index_order" { SELECT 'upserttest_key_uniq_idx'::regclass::int8 < 'upserttest_key_idx'::regclass::int8; } -step "s1_upsert" { INSERT INTO upserttest(key, data) VALUES('k1', 'inserted s1') ON CONFLICT (blurt_and_lock_123(key)) DO UPDATE SET data = upserttest.data || ' with conflict update s1'; } -step "s1_insert_toast" { INSERT INTO upserttest VALUES('k2', ctoast_large_val()) ON CONFLICT DO NOTHING; } -step "s1_commit" { COMMIT; } -step "s1_noop" { } +step s1_begin { BEGIN; } +step s1_create_non_unique_index { CREATE INDEX upserttest_key_idx ON upserttest((blurt_and_lock_4(key))); } +step s1_confirm_index_order { SELECT 'upserttest_key_uniq_idx'::regclass::int8 < 'upserttest_key_idx'::regclass::int8; } +step s1_upsert { INSERT INTO upserttest(key, data) VALUES('k1', 'inserted s1') ON CONFLICT (blurt_and_lock_123(key)) DO UPDATE SET data = upserttest.data || ' with conflict update s1'; } +step s1_insert_toast { INSERT INTO upserttest VALUES('k2', ctoast_large_val()) ON CONFLICT DO NOTHING; } +step s1_commit { COMMIT; } +step s1_noop { } -session "s2" +session s2 setup { SET default_transaction_isolation = 'read committed'; SET spec.session = 2; SET application_name = 'isolation/insert-conflict-specconflict-s2'; } -step "s2_begin" { BEGIN; } -step "s2_upsert" { INSERT INTO upserttest(key, data) VALUES('k1', 'inserted s2') ON CONFLICT (blurt_and_lock_123(key)) DO UPDATE SET data = upserttest.data || ' with conflict update s2'; } -step "s2_insert_toast" { INSERT INTO upserttest VALUES('k2', ctoast_large_val()) ON CONFLICT DO NOTHING; } -step "s2_commit" { COMMIT; } -step "s2_noop" { } +step s2_begin { BEGIN; } +step s2_upsert { INSERT INTO upserttest(key, data) VALUES('k1', 'inserted s2') ON CONFLICT (blurt_and_lock_123(key)) DO UPDATE SET data = upserttest.data || ' with conflict update s2'; } +step s2_insert_toast { INSERT INTO upserttest VALUES('k2', ctoast_large_val()) ON CONFLICT DO NOTHING; } +step s2_commit { COMMIT; } +step s2_noop { } # Test that speculative locks are correctly acquired and released, s2 # inserts, s1 updates. @@ -105,23 +105,23 @@ permutation # blurt_and_lock_123 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, s1 # inserts, s2 updates. @@ -130,23 +130,23 @@ permutation # blurt_and_lock_123 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 speculatively inserted toast rows do not cause conflicts. # s1 inserts successfully, s2 does not. @@ -155,23 +155,23 @@ permutation # blurt_and_lock_123 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_insert_toast" "s2_insert_toast" - "controller_show" + controller_locks + controller_show + s1_insert_toast s2_insert_toast + 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 that 1 additional tuple was inserted successfully - "controller_show_count" + controller_show_count # Allow the second session to finish insertion and kill the speculatively inserted tuple - "controller_unlock_2_2" + controller_unlock_2_2 # This should show the same number of tuples as before s2 inserted - "controller_show_count" + controller_show_count # Test that speculative locks are correctly acquired and released, s2 # inserts, s1 updates. With the added complication that transactions @@ -181,28 +181,28 @@ permutation # blurt_and_lock_123 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 # Test that speculative wait is performed if a session sees a speculatively # inserted tuple. A speculatively inserted tuple is one which has been inserted @@ -218,45 +218,45 @@ permutation # create the second index here to avoid affecting the other # permutations. - "s1_create_non_unique_index" + s1_create_non_unique_index # confirm that the insertion into the unique index will happen first - "s1_confirm_index_order" - "controller_locks" - "controller_show" - "s2_begin" + s1_confirm_index_order + controller_locks + controller_show + s2_begin # Both sessions wait on advisory locks # (but don't show s2_upsert as complete till we've seen all of s1's notices) - "s1_upsert" "s2_upsert" ("s1_upsert" notices 10) - "controller_show" + s1_upsert s2_upsert (s1_upsert notices 10) + 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 do the optimistic conflict probe and do the # speculative insertion into the table # They will then be waiting on another advisory lock when they attempt to # update the index - "controller_unlock_1_3" "controller_unlock_2_3" - "controller_show" + controller_unlock_1_3 controller_unlock_2_3 + controller_show # take lock to block second session after inserting in unique index but # before completing the speculative insert - "controller_lock_2_4" + controller_lock_2_4 # Allow the second session to move forward - "controller_unlock_2_2" + controller_unlock_2_2 # This should still not show a successful insertion - "controller_show" + controller_show # Allow the first session to continue, it should perform speculative wait - "controller_unlock_1_2" + controller_unlock_1_2 # Should report s1 is waiting on speculative lock - "controller_print_speculative_locks" + controller_print_speculative_locks # Allow s2 to insert into the non-unique index and complete. s1 will # no longer wait on speculative lock, but proceed to wait on the # transaction to finish. The no-op step is needed to ensure that # we don't advance to the reporting step until s2_upsert has completed. - "controller_unlock_2_4" "s2_noop" + controller_unlock_2_4 s2_noop # Should report that s1 is now waiting for s2 to commit - "controller_print_speculative_locks" + controller_print_speculative_locks # Once s2 commits, s1 is finally free to continue to update - "s2_commit" "s1_noop" + s2_commit s1_noop # This should now show a successful UPSERT - "controller_show" + controller_show # Ensure no unexpected locks survive - "controller_print_speculative_locks" + controller_print_speculative_locks diff --git a/src/test/isolation/specs/lock-committed-keyupdate.spec b/src/test/isolation/specs/lock-committed-keyupdate.spec index 3fb424af0e..487f0e0d95 100644 --- a/src/test/isolation/specs/lock-committed-keyupdate.spec +++ b/src/test/isolation/specs/lock-committed-keyupdate.spec @@ -18,49 +18,49 @@ teardown 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" -permutation "s1b" "s2b1" "s1l" "s1u" "s1ul" "s2l" "s1c" "s2c" +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 +permutation s1b s2b1 s1l s1u s1ul s2l s1c s2c -permutation "s1b" "s2b1" "s1l" "s2l" "s1u" "s1c" "s1hint" "s1ul" "s2c" -permutation "s1b" "s2b1" "s1l" "s1u" "s2l" "s1c" "s1hint" "s1ul" "s2c" -#permutation "s1b" "s2b1" "s1l" "s2l" "s1ul" "s1u" "s1c" "s1hint" "s2c" -permutation "s1b" "s2b1" "s1l" "s1u" "s1ul" "s2l" "s1c" "s1hint" "s2c" +permutation s1b s2b1 s1l s2l s1u s1c s1hint s1ul s2c +permutation s1b s2b1 s1l s1u s2l s1c s1hint s1ul s2c +#permutation s1b s2b1 s1l s2l s1ul s1u s1c s1hint s2c +permutation s1b s2b1 s1l s1u s1ul s2l s1c s1hint s2c -permutation "s1b" "s2b2" "s1l" "s2l" "s1u" "s1c" "s1ul" "s2c" -permutation "s1b" "s2b2" "s1l" "s1u" "s2l" "s1c" "s1ul" "s2c" -#permutation "s1b" "s2b2" "s1l" "s2l" "s1ul" "s1u" "s1c" "s2c" -permutation "s1b" "s2b2" "s1l" "s1u" "s1ul" "s2l" "s1c" "s2c" +permutation s1b s2b2 s1l s2l s1u s1c s1ul s2c +permutation s1b s2b2 s1l s1u s2l s1c s1ul s2c +#permutation s1b s2b2 s1l s2l s1ul s1u s1c s2c +permutation s1b s2b2 s1l s1u s1ul s2l s1c s2c -permutation "s1b" "s2b2" "s1l" "s2l" "s1u" "s1c" "s1hint" "s1ul" "s2c" -permutation "s1b" "s2b2" "s1l" "s1u" "s2l" "s1c" "s1hint" "s1ul" "s2c" -#permutation "s1b" "s2b2" "s1l" "s2l" "s1ul" "s1u" "s1c" "s1hint" "s2c" -permutation "s1b" "s2b2" "s1l" "s1u" "s1ul" "s2l" "s1c" "s1hint" "s2c" +permutation s1b s2b2 s1l s2l s1u s1c s1hint s1ul s2c +permutation s1b s2b2 s1l s1u s2l s1c s1hint s1ul s2c +#permutation s1b s2b2 s1l s2l s1ul s1u s1c s1hint s2c +permutation s1b s2b2 s1l s1u s1ul s2l s1c s1hint s2c -permutation "s1b" "s2b3" "s1l" "s2l" "s1u" "s1c" "s1ul" "s2c" -permutation "s1b" "s2b3" "s1l" "s1u" "s2l" "s1c" "s1ul" "s2c" -#permutation "s1b" "s2b3" "s1l" "s2l" "s1ul" "s1u" "s1c" "s2c" -permutation "s1b" "s2b3" "s1l" "s1u" "s1ul" "s2l" "s1c" "s2c" +permutation s1b s2b3 s1l s2l s1u s1c s1ul s2c +permutation s1b s2b3 s1l s1u s2l s1c s1ul s2c +#permutation s1b s2b3 s1l s2l s1ul s1u s1c s2c +permutation s1b s2b3 s1l s1u s1ul s2l s1c s2c -permutation "s1b" "s2b3" "s1l" "s2l" "s1u" "s1c" "s1hint" "s1ul" "s2c" -permutation "s1b" "s2b3" "s1l" "s1u" "s2l" "s1c" "s1hint" "s1ul" "s2c" -#permutation "s1b" "s2b3" "s1l" "s2l" "s1ul" "s1u" "s1c" "s1hint" "s2c" -permutation "s1b" "s2b3" "s1l" "s1u" "s1ul" "s2l" "s1c" "s1hint" "s2c" +permutation s1b s2b3 s1l s2l s1u s1c s1hint s1ul s2c +permutation s1b s2b3 s1l s1u s2l s1c s1hint s1ul s2c +#permutation s1b s2b3 s1l s2l s1ul s1u s1c s1hint s2c +permutation s1b s2b3 s1l s1u s1ul s2l s1c s1hint s2c diff --git a/src/test/isolation/specs/lock-committed-update.spec b/src/test/isolation/specs/lock-committed-update.spec index 0495c11570..74d80d53e6 100644 --- a/src/test/isolation/specs/lock-committed-update.spec +++ b/src/test/isolation/specs/lock-committed-update.spec @@ -14,49 +14,49 @@ teardown DROP TABLE lcu_table; } -session "s1" -step "s1b" { BEGIN; } -step "s1l" { SELECT pg_advisory_lock(380170116); } -step "s1u" { UPDATE lcu_table SET value = 'two' WHERE id = 1; } -step "s1hint" { SELECT * FROM lcu_table; } -step "s1ul" { SELECT pg_advisory_unlock(380170116); } -step "s1c" { COMMIT; } +session s1 +step s1b { BEGIN; } +step s1l { SELECT pg_advisory_lock(380170116); } +step s1u { UPDATE lcu_table SET value = 'two' WHERE id = 1; } +step s1hint { SELECT * FROM lcu_table; } +step s1ul { SELECT pg_advisory_unlock(380170116); } +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 lcu_table WHERE pg_advisory_lock(380170116) 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 lcu_table WHERE pg_advisory_lock(380170116) 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" -permutation "s1b" "s2b1" "s1l" "s1u" "s1ul" "s2l" "s1c" "s2c" +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 +permutation s1b s2b1 s1l s1u s1ul s2l s1c s2c -permutation "s1b" "s2b1" "s1l" "s2l" "s1u" "s1c" "s1hint" "s1ul" "s2c" -permutation "s1b" "s2b1" "s1l" "s1u" "s2l" "s1c" "s1hint" "s1ul" "s2c" -permutation "s1b" "s2b1" "s1l" "s2l" "s1ul" "s1u" "s1c" "s1hint" "s2c" -permutation "s1b" "s2b1" "s1l" "s1u" "s1ul" "s2l" "s1c" "s1hint" "s2c" +permutation s1b s2b1 s1l s2l s1u s1c s1hint s1ul s2c +permutation s1b s2b1 s1l s1u s2l s1c s1hint s1ul s2c +permutation s1b s2b1 s1l s2l s1ul s1u s1c s1hint s2c +permutation s1b s2b1 s1l s1u s1ul s2l s1c s1hint s2c -permutation "s1b" "s2b2" "s1l" "s2l" "s1u" "s1c" "s1ul" "s2c" -permutation "s1b" "s2b2" "s1l" "s1u" "s2l" "s1c" "s1ul" "s2c" -permutation "s1b" "s2b2" "s1l" "s2l" "s1ul" "s1u" "s1c" "s2c" -permutation "s1b" "s2b2" "s1l" "s1u" "s1ul" "s2l" "s1c" "s2c" +permutation s1b s2b2 s1l s2l s1u s1c s1ul s2c +permutation s1b s2b2 s1l s1u s2l s1c s1ul s2c +permutation s1b s2b2 s1l s2l s1ul s1u s1c s2c +permutation s1b s2b2 s1l s1u s1ul s2l s1c s2c -permutation "s1b" "s2b2" "s1l" "s2l" "s1u" "s1c" "s1hint" "s1ul" "s2c" -permutation "s1b" "s2b2" "s1l" "s1u" "s2l" "s1c" "s1hint" "s1ul" "s2c" -permutation "s1b" "s2b2" "s1l" "s2l" "s1ul" "s1u" "s1c" "s1hint" "s2c" -permutation "s1b" "s2b2" "s1l" "s1u" "s1ul" "s2l" "s1c" "s1hint" "s2c" +permutation s1b s2b2 s1l s2l s1u s1c s1hint s1ul s2c +permutation s1b s2b2 s1l s1u s2l s1c s1hint s1ul s2c +permutation s1b s2b2 s1l s2l s1ul s1u s1c s1hint s2c +permutation s1b s2b2 s1l s1u s1ul s2l s1c s1hint s2c -permutation "s1b" "s2b3" "s1l" "s2l" "s1u" "s1c" "s1ul" "s2c" -permutation "s1b" "s2b3" "s1l" "s1u" "s2l" "s1c" "s1ul" "s2c" -permutation "s1b" "s2b3" "s1l" "s2l" "s1ul" "s1u" "s1c" "s2c" -permutation "s1b" "s2b3" "s1l" "s1u" "s1ul" "s2l" "s1c" "s2c" +permutation s1b s2b3 s1l s2l s1u s1c s1ul s2c +permutation s1b s2b3 s1l s1u s2l s1c s1ul s2c +permutation s1b s2b3 s1l s2l s1ul s1u s1c s2c +permutation s1b s2b3 s1l s1u s1ul s2l s1c s2c -permutation "s1b" "s2b3" "s1l" "s2l" "s1u" "s1c" "s1hint" "s1ul" "s2c" -permutation "s1b" "s2b3" "s1l" "s1u" "s2l" "s1c" "s1hint" "s1ul" "s2c" -permutation "s1b" "s2b3" "s1l" "s2l" "s1ul" "s1u" "s1c" "s1hint" "s2c" -permutation "s1b" "s2b3" "s1l" "s1u" "s1ul" "s2l" "s1c" "s1hint" "s2c" +permutation s1b s2b3 s1l s2l s1u s1c s1hint s1ul s2c +permutation s1b s2b3 s1l s1u s2l s1c s1hint s1ul s2c +permutation s1b s2b3 s1l s2l s1ul s1u s1c s1hint s2c +permutation s1b s2b3 s1l s1u s1ul s2l s1c s1hint s2c diff --git a/src/test/isolation/specs/lock-update-delete.spec b/src/test/isolation/specs/lock-update-delete.spec index b7b796fc01..b9dd7d12a9 100644 --- a/src/test/isolation/specs/lock-update-delete.spec +++ b/src/test/isolation/specs/lock-update-delete.spec @@ -31,31 +31,31 @@ teardown DROP TABLE foo; } -session "s1" +session s1 # obtain lock on the tuple, traversing its update chain -step "s1l" { SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; } +step s1l { SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; } -session "s2" +session s2 setup { SELECT pg_advisory_lock(0); } -step "s2b" { BEGIN; } -step "s2u" { UPDATE foo SET value = 2 WHERE key = 1; } -step "s2_blocker1" { DELETE FROM foo; } -step "s2_blocker2" { UPDATE foo SET key = 2 WHERE key = 1; } -step "s2_blocker3" { UPDATE foo SET value = 2 WHERE key = 1; } -step "s2_unlock" { SELECT pg_advisory_unlock(0); } -step "s2c" { COMMIT; } -step "s2r" { ROLLBACK; } +step s2b { BEGIN; } +step s2u { UPDATE foo SET value = 2 WHERE key = 1; } +step s2_blocker1 { DELETE FROM foo; } +step s2_blocker2 { UPDATE foo SET key = 2 WHERE key = 1; } +step s2_blocker3 { UPDATE foo SET value = 2 WHERE key = 1; } +step s2_unlock { SELECT pg_advisory_unlock(0); } +step s2c { COMMIT; } +step s2r { ROLLBACK; } -permutation "s2b" "s1l" "s2u" "s2_blocker1" "s2_unlock" "s2c" -permutation "s2b" "s1l" "s2u" "s2_blocker2" "s2_unlock" "s2c" -permutation "s2b" "s1l" "s2u" "s2_blocker3" "s2_unlock" "s2c" -permutation "s2b" "s1l" "s2u" "s2_blocker1" "s2_unlock" "s2r" -permutation "s2b" "s1l" "s2u" "s2_blocker2" "s2_unlock" "s2r" -permutation "s2b" "s1l" "s2u" "s2_blocker3" "s2_unlock" "s2r" +permutation s2b s1l s2u s2_blocker1 s2_unlock s2c +permutation s2b s1l s2u s2_blocker2 s2_unlock s2c +permutation s2b s1l s2u s2_blocker3 s2_unlock s2c +permutation s2b s1l s2u s2_blocker1 s2_unlock s2r +permutation s2b s1l s2u s2_blocker2 s2_unlock s2r +permutation s2b s1l s2u s2_blocker3 s2_unlock s2r -permutation "s2b" "s1l" "s2u" "s2_blocker1" "s2c" "s2_unlock" -permutation "s2b" "s1l" "s2u" "s2_blocker2" "s2c" "s2_unlock" -permutation "s2b" "s1l" "s2u" "s2_blocker3" "s2c" "s2_unlock" -permutation "s2b" "s1l" "s2u" "s2_blocker1" "s2r" "s2_unlock" -permutation "s2b" "s1l" "s2u" "s2_blocker2" "s2r" "s2_unlock" -permutation "s2b" "s1l" "s2u" "s2_blocker3" "s2r" "s2_unlock" +permutation s2b s1l s2u s2_blocker1 s2c s2_unlock +permutation s2b s1l s2u s2_blocker2 s2c s2_unlock +permutation s2b s1l s2u s2_blocker3 s2c s2_unlock +permutation s2b s1l s2u s2_blocker1 s2r s2_unlock +permutation s2b s1l s2u s2_blocker2 s2r s2_unlock +permutation s2b s1l s2u s2_blocker3 s2r s2_unlock diff --git a/src/test/isolation/specs/lock-update-traversal.spec b/src/test/isolation/specs/lock-update-traversal.spec index 2ffe87d152..9d3d32de42 100644 --- a/src/test/isolation/specs/lock-update-traversal.spec +++ b/src/test/isolation/specs/lock-update-traversal.spec @@ -20,20 +20,20 @@ teardown DROP TABLE foo; } -session "s1" -step "s1b" { BEGIN ISOLATION LEVEL REPEATABLE READ; } -step "s1s" { SELECT * FROM foo; } # obtain snapshot -step "s1l" { SELECT * FROM foo FOR KEY SHARE; } # obtain lock -step "s1c" { COMMIT; } +session s1 +step s1b { BEGIN ISOLATION LEVEL REPEATABLE READ; } +step s1s { SELECT * FROM foo; } # obtain snapshot +step s1l { SELECT * FROM foo FOR KEY SHARE; } # obtain lock +step s1c { COMMIT; } -session "s2" -step "s2b" { BEGIN; } -step "s2u" { UPDATE foo SET value = 2 WHERE key = 1; } -step "s2c" { COMMIT; } -step "s2d1" { DELETE FROM foo WHERE key = 1; } -step "s2d2" { UPDATE foo SET key = 3 WHERE key = 1; } -step "s2d3" { UPDATE foo SET value = 3 WHERE key = 1; } +session s2 +step s2b { BEGIN; } +step s2u { UPDATE foo SET value = 2 WHERE key = 1; } +step s2c { COMMIT; } +step s2d1 { DELETE FROM foo WHERE key = 1; } +step s2d2 { UPDATE foo SET key = 3 WHERE key = 1; } +step s2d3 { UPDATE foo SET value = 3 WHERE key = 1; } -permutation "s1b" "s2b" "s1s" "s2u" "s1l" "s2c" "s2d1" "s1c" -permutation "s1b" "s2b" "s1s" "s2u" "s1l" "s2c" "s2d2" "s1c" -permutation "s1b" "s2b" "s1s" "s2u" "s1l" "s2c" "s2d3" "s1c" +permutation s1b s2b s1s s2u s1l s2c s2d1 s1c +permutation s1b s2b s1s s2u s1l s2c s2d2 s1c +permutation s1b s2b s1s s2u s1l s2c s2d3 s1c diff --git a/src/test/isolation/specs/multiple-cic.spec b/src/test/isolation/specs/multiple-cic.spec index 3ac1d39d86..e34a6b0f9b 100644 --- a/src/test/isolation/specs/multiple-cic.spec +++ b/src/test/isolation/specs/multiple-cic.spec @@ -22,17 +22,17 @@ teardown DROP FUNCTION unlck(); } -session "s1" -step "s1i" { +session s1 +step s1i { CREATE INDEX CONCURRENTLY mcic_one_pkey ON mcic_one (id) WHERE lck_shr(281457); } teardown { SELECT unlck(); } -session "s2" -step "s2l" { SELECT pg_advisory_lock(281457); } -step "s2i" { +session s2 +step s2l { SELECT pg_advisory_lock(281457); } +step s2i { CREATE INDEX CONCURRENTLY mcic_two_pkey ON mcic_two (id) WHERE unlck(); } @@ -40,4 +40,4 @@ step "s2i" { # (*) marker ensures that s2i is reported as "waiting", even if it # completes very quickly -permutation "s2l" "s1i" "s2i"(*) +permutation s2l s1i s2i(*) diff --git a/src/test/isolation/specs/multiple-row-versions.spec b/src/test/isolation/specs/multiple-row-versions.spec index 1bb5b4e8ba..0779ea09b8 100644 --- a/src/test/isolation/specs/multiple-row-versions.spec +++ b/src/test/isolation/specs/multiple-row-versions.spec @@ -19,29 +19,29 @@ teardown DROP TABLE t; } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "rx1" { SELECT * FROM t WHERE id = 1000000; } +step rx1 { SELECT * FROM t WHERE id = 1000000; } # delay until after T3 commits -step "wz1" { UPDATE t SET txt = 'a' WHERE id = 1; } -step "c1" { COMMIT; } +step wz1 { UPDATE t SET txt = 'a' WHERE id = 1; } +step c1 { COMMIT; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "wx2" { UPDATE t SET txt = 'b' WHERE id = 1000000; } -step "c2" { COMMIT; } +step wx2 { UPDATE t SET txt = 'b' WHERE id = 1000000; } +step c2 { COMMIT; } -session "s3" +session s3 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "wx3" { UPDATE t SET txt = 'c' WHERE id = 1000000; } -step "ry3" { SELECT * FROM t WHERE id = 500000; } +step wx3 { UPDATE t SET txt = 'c' WHERE id = 1000000; } +step ry3 { SELECT * FROM t WHERE id = 500000; } # delay until after T4 commits -step "c3" { COMMIT; } +step c3 { COMMIT; } -session "s4" +session s4 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "wy4" { UPDATE t SET txt = 'd' WHERE id = 500000; } -step "rz4" { SELECT * FROM t WHERE id = 1; } -step "c4" { COMMIT; } +step wy4 { UPDATE t SET txt = 'd' WHERE id = 500000; } +step rz4 { SELECT * FROM t WHERE id = 1; } +step c4 { COMMIT; } -permutation "rx1" "wx2" "c2" "wx3" "ry3" "wy4" "rz4" "c4" "c3" "wz1" "c1" +permutation rx1 wx2 c2 wx3 ry3 wy4 rz4 c4 c3 wz1 c1 diff --git a/src/test/isolation/specs/multixact-no-deadlock.spec b/src/test/isolation/specs/multixact-no-deadlock.spec index 205658b897..a8af724e58 100644 --- a/src/test/isolation/specs/multixact-no-deadlock.spec +++ b/src/test/isolation/specs/multixact-no-deadlock.spec @@ -15,21 +15,21 @@ teardown DROP TABLE justthis; } -session "s1" +session s1 setup { BEGIN; } -step "s1lock" { SELECT * FROM justthis FOR SHARE; } -step "s1svpt" { SAVEPOINT foo; } -step "s1lock2" { SELECT * FROM justthis FOR SHARE; } -step "s1c" { COMMIT; } +step s1lock { SELECT * FROM justthis FOR SHARE; } +step s1svpt { SAVEPOINT foo; } +step s1lock2 { SELECT * FROM justthis FOR SHARE; } +step s1c { COMMIT; } -session "s2" +session s2 setup { BEGIN; } -step "s2lock" { SELECT * FROM justthis FOR SHARE; } # ensure it's a multi -step "s2c" { COMMIT; } +step s2lock { SELECT * FROM justthis FOR SHARE; } # ensure it's a multi +step s2c { COMMIT; } -session "s3" +session s3 setup { BEGIN; } -step "s3lock" { SELECT * FROM justthis FOR UPDATE; } -step "s3c" { COMMIT; } +step s3lock { SELECT * FROM justthis FOR UPDATE; } +step s3c { COMMIT; } -permutation "s1lock" "s2lock" "s1svpt" "s3lock" "s1lock2" "s2c" "s1c" "s3c" +permutation s1lock s2lock s1svpt s3lock s1lock2 s2c s1c s3c diff --git a/src/test/isolation/specs/multixact-no-forget.spec b/src/test/isolation/specs/multixact-no-forget.spec index 7fb93c1e34..7f8a38b51b 100644 --- a/src/test/isolation/specs/multixact-no-forget.spec +++ b/src/test/isolation/specs/multixact-no-forget.spec @@ -14,31 +14,31 @@ teardown DROP TABLE dont_forget; } -session "s1" +session s1 setup { BEGIN; } -step "s1_show" { SELECT current_setting('default_transaction_isolation') <> 'read committed'; } -step "s1_lock" { SELECT * FROM dont_forget FOR KEY SHARE; } -step "s1_commit" { COMMIT; } +step s1_show { SELECT current_setting('default_transaction_isolation') <> 'read committed'; } +step s1_lock { SELECT * FROM dont_forget FOR KEY SHARE; } +step s1_commit { COMMIT; } -session "s2" -setup { BEGIN; } -step "s2_update" { UPDATE dont_forget SET value = 2; } -step "s2_abort" { ROLLBACK; } -step "s2_commit" { COMMIT; } +session s2 +setup { BEGIN; } +step s2_update { UPDATE dont_forget SET value = 2; } +step s2_abort { ROLLBACK; } +step s2_commit { COMMIT; } -session "s3" +session s3 # try cases with both a non-conflicting lock with s1's and a conflicting one -step "s3_forkeyshr" { SELECT * FROM dont_forget FOR KEY SHARE; } -step "s3_fornokeyupd" { SELECT * FROM dont_forget FOR NO KEY UPDATE; } -step "s3_forupd" { SELECT * FROM dont_forget FOR UPDATE; } +step s3_forkeyshr { SELECT * FROM dont_forget FOR KEY SHARE; } +step s3_fornokeyupd { SELECT * FROM dont_forget FOR NO KEY UPDATE; } +step s3_forupd { SELECT * FROM dont_forget FOR UPDATE; } -permutation "s1_show" "s1_commit" "s2_commit" -permutation "s1_lock" "s2_update" "s2_abort" "s3_forkeyshr" "s1_commit" -permutation "s1_lock" "s2_update" "s2_commit" "s3_forkeyshr" "s1_commit" -permutation "s1_lock" "s2_update" "s1_commit" "s3_forkeyshr" "s2_commit" -permutation "s1_lock" "s2_update" "s2_abort" "s3_fornokeyupd" "s1_commit" -permutation "s1_lock" "s2_update" "s2_commit" "s3_fornokeyupd" "s1_commit" -permutation "s1_lock" "s2_update" "s1_commit" "s3_fornokeyupd" "s2_commit" -permutation "s1_lock" "s2_update" "s2_abort" "s3_forupd" "s1_commit" -permutation "s1_lock" "s2_update" "s2_commit" "s3_forupd" "s1_commit" -permutation "s1_lock" "s2_update" "s1_commit" "s3_forupd" "s2_commit" +permutation s1_show s1_commit s2_commit +permutation s1_lock s2_update s2_abort s3_forkeyshr s1_commit +permutation s1_lock s2_update s2_commit s3_forkeyshr s1_commit +permutation s1_lock s2_update s1_commit s3_forkeyshr s2_commit +permutation s1_lock s2_update s2_abort s3_fornokeyupd s1_commit +permutation s1_lock s2_update s2_commit s3_fornokeyupd s1_commit +permutation s1_lock s2_update s1_commit s3_fornokeyupd s2_commit +permutation s1_lock s2_update s2_abort s3_forupd s1_commit +permutation s1_lock s2_update s2_commit s3_forupd s1_commit +permutation s1_lock s2_update s1_commit s3_forupd s2_commit diff --git a/src/test/isolation/specs/nowait-2.spec b/src/test/isolation/specs/nowait-2.spec index 69ce5edd81..cf892f2cbe 100644 --- a/src/test/isolation/specs/nowait-2.spec +++ b/src/test/isolation/specs/nowait-2.spec @@ -14,24 +14,24 @@ teardown DROP TABLE foo; } -session "s1" +session s1 setup { BEGIN; } -step "s1a" { SELECT * FROM foo FOR SHARE NOWAIT; } -step "s1b" { COMMIT; } +step s1a { SELECT * FROM foo FOR SHARE NOWAIT; } +step s1b { COMMIT; } -session "s2" +session s2 setup { BEGIN; } -step "s2a" { SELECT * FROM foo FOR SHARE NOWAIT; } -step "s2b" { SELECT * FROM foo FOR UPDATE NOWAIT; } -step "s2c" { COMMIT; } +step s2a { SELECT * FROM foo FOR SHARE NOWAIT; } +step s2b { SELECT * FROM foo FOR UPDATE NOWAIT; } +step s2c { COMMIT; } # s1 and s2 both get SHARE lock, creating a multixact lock, then s2 # tries to upgrade to UPDATE but aborts because it cannot acquire a # multi-xact lock -permutation "s1a" "s2a" "s2b" "s1b" "s2c" +permutation s1a s2a s2b s1b s2c # the same but with the SHARE locks acquired in a different order, so # s2 again aborts because it can't acquired a multi-xact lock -permutation "s2a" "s1a" "s2b" "s1b" "s2c" +permutation s2a s1a s2b s1b s2c # s2 acquires SHARE then UPDATE, then s1 tries to acquire SHARE but # can't so aborts because it can't acquire a regular lock -permutation "s2a" "s2b" "s1a" "s1b" "s2c" +permutation s2a s2b s1a s1b s2c diff --git a/src/test/isolation/specs/nowait-3.spec b/src/test/isolation/specs/nowait-3.spec index 9e6b994fdd..06fb7624c3 100644 --- a/src/test/isolation/specs/nowait-3.spec +++ b/src/test/isolation/specs/nowait-3.spec @@ -14,20 +14,20 @@ teardown DROP TABLE foo; } -session "s1" +session s1 setup { BEGIN; } -step "s1a" { SELECT * FROM foo FOR UPDATE; } -step "s1b" { COMMIT; } +step s1a { SELECT * FROM foo FOR UPDATE; } +step s1b { COMMIT; } -session "s2" +session s2 setup { BEGIN; } -step "s2a" { SELECT * FROM foo FOR UPDATE; } -step "s2b" { COMMIT; } +step s2a { SELECT * FROM foo FOR UPDATE; } +step s2b { COMMIT; } -session "s3" +session s3 setup { BEGIN; } -step "s3a" { SELECT * FROM foo FOR UPDATE NOWAIT; } -step "s3b" { COMMIT; } +step s3a { SELECT * FROM foo FOR UPDATE NOWAIT; } +step s3b { COMMIT; } # s3 skips to second record due to tuple lock held by s2 -permutation "s1a" "s2a" "s3a" "s1b" "s2b" "s3b" +permutation s1a s2a s3a s1b s2b s3b diff --git a/src/test/isolation/specs/nowait-4.spec b/src/test/isolation/specs/nowait-4.spec index 48ac777d78..da80330a62 100644 --- a/src/test/isolation/specs/nowait-4.spec +++ b/src/test/isolation/specs/nowait-4.spec @@ -14,22 +14,22 @@ teardown DROP TABLE foo; } -session "s1" +session s1 setup { BEGIN; } -step "s1a" { SELECT * FROM foo WHERE pg_advisory_lock(0) IS NOT NULL FOR UPDATE NOWAIT; } -step "s1b" { COMMIT; } +step s1a { SELECT * FROM foo WHERE pg_advisory_lock(0) IS NOT NULL FOR UPDATE NOWAIT; } +step s1b { COMMIT; } -session "s2" -step "s2a" { SELECT pg_advisory_lock(0); } -step "s2b" { UPDATE foo SET data = data; } -step "s2c" { BEGIN; } -step "s2d" { UPDATE foo SET data = data; } -step "s2e" { SELECT pg_advisory_unlock(0); } -step "s2f" { COMMIT; } +session s2 +step s2a { SELECT pg_advisory_lock(0); } +step s2b { UPDATE foo SET data = data; } +step s2c { BEGIN; } +step s2d { UPDATE foo SET data = data; } +step s2e { SELECT pg_advisory_unlock(0); } +step s2f { COMMIT; } # s1 takes a snapshot but then waits on an advisory lock, then s2 # updates the row in one transaction, then again in another without # committing, before allowing s1 to proceed to try to lock a row; # because it has a snapshot that sees the older version, we reach the # waiting code in EvalPlanQualFetch which ereports when in NOWAIT mode. -permutation "s2a" "s1a" "s2b" "s2c" "s2d" "s2e" "s1b" "s2f" +permutation s2a s1a s2b s2c s2d s2e s1b s2f diff --git a/src/test/isolation/specs/nowait-5.spec b/src/test/isolation/specs/nowait-5.spec index 75e9462fc1..46108de16d 100644 --- a/src/test/isolation/specs/nowait-5.spec +++ b/src/test/isolation/specs/nowait-5.spec @@ -18,11 +18,11 @@ teardown DROP TABLE test_nowait; } -session "sl1" -step "sl1_prep" { +session sl1 +step sl1_prep { PREPARE sl1_run AS SELECT id FROM test_nowait WHERE pg_advisory_lock(0) is not null FOR UPDATE NOWAIT; } -step "sl1_exec" { +step sl1_exec { BEGIN ISOLATION LEVEL READ COMMITTED; EXECUTE sl1_run; SELECT xmin, xmax, ctid, * FROM test_nowait; @@ -31,22 +31,22 @@ teardown { COMMIT; } # A session that's used for an UPDATE of the rows to be locked, for when we're testing ctid # chain following. -session "upd" -step "upd_getlock" { +session upd +step upd_getlock { SELECT pg_advisory_lock(0); } -step "upd_doupdate" { +step upd_doupdate { BEGIN ISOLATION LEVEL READ COMMITTED; UPDATE test_nowait SET value = value WHERE id % 2 = 0; COMMIT; } -step "upd_releaselock" { +step upd_releaselock { SELECT pg_advisory_unlock(0); } # A session that acquires locks that sl1 is supposed to avoid blocking on -session "lk1" -step "lk1_doforshare" { +session lk1 +step lk1_doforshare { BEGIN ISOLATION LEVEL READ COMMITTED; SELECT id FROM test_nowait WHERE id % 2 = 0 FOR SHARE; } @@ -54,4 +54,4 @@ teardown { COMMIT; } -permutation "sl1_prep" "upd_getlock" "sl1_exec" "upd_doupdate" "lk1_doforshare" "upd_releaselock" +permutation sl1_prep upd_getlock sl1_exec upd_doupdate lk1_doforshare upd_releaselock diff --git a/src/test/isolation/specs/nowait.spec b/src/test/isolation/specs/nowait.spec index 73580cd1b2..a75e54cc67 100644 --- a/src/test/isolation/specs/nowait.spec +++ b/src/test/isolation/specs/nowait.spec @@ -14,12 +14,12 @@ teardown DROP TABLE foo; } -session "s1" +session s1 setup { BEGIN; } -step "s1a" { SELECT * FROM foo FOR UPDATE NOWAIT; } -step "s1b" { COMMIT; } +step s1a { SELECT * FROM foo FOR UPDATE NOWAIT; } +step s1b { COMMIT; } -session "s2" +session s2 setup { BEGIN; } -step "s2a" { SELECT * FROM foo FOR UPDATE NOWAIT; } -step "s2b" { COMMIT; } +step s2a { SELECT * FROM foo FOR UPDATE NOWAIT; } +step s2b { COMMIT; } diff --git a/src/test/isolation/specs/partial-index.spec b/src/test/isolation/specs/partial-index.spec index 74e72645d9..c0338418a8 100644 --- a/src/test/isolation/specs/partial-index.spec +++ b/src/test/isolation/specs/partial-index.spec @@ -19,14 +19,14 @@ teardown DROP TABLE test_t; } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "rxy1" { select * from test_t where val2 = 1; } -step "wx1" { update test_t set val2 = 2 where val2 = 1 and id = 10; } -step "c1" { COMMIT; } +step rxy1 { select * from test_t where val2 = 1; } +step wx1 { update test_t set val2 = 2 where val2 = 1 and id = 10; } +step c1 { COMMIT; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "wy2" { update test_t set val2 = 2 where val2 = 1 and id = 9; } -step "rxy2" { select * from test_t where val2 = 1; } -step "c2" { COMMIT; } +step wy2 { update test_t set val2 = 2 where val2 = 1 and id = 9; } +step rxy2 { select * from test_t where val2 = 1; } +step c2 { COMMIT; } diff --git a/src/test/isolation/specs/partition-concurrent-attach.spec b/src/test/isolation/specs/partition-concurrent-attach.spec index 48c3f83e0c..fcd4dce7ec 100644 --- a/src/test/isolation/specs/partition-concurrent-attach.spec +++ b/src/test/isolation/specs/partition-concurrent-attach.spec @@ -15,29 +15,29 @@ setup { insert into tpart_2 values (110,'xxx'), (120, 'yyy'), (150, 'zzz'); } -session "s1" -step "s1b" { begin; } -step "s1a" { alter table tpart attach partition tpart_2 for values from (100) to (200); } -step "s1c" { commit; } +session s1 +step s1b { begin; } +step s1a { alter table tpart attach partition tpart_2 for values from (100) to (200); } +step s1c { commit; } -session "s2" -step "s2b" { begin; } -step "s2i" { insert into tpart values (110,'xxx'), (120, 'yyy'), (150, 'zzz'); } -step "s2i2" { insert into tpart_default (i, j) values (110, 'xxx'), (120, 'yyy'), (150, 'zzz'); } -step "s2c" { commit; } -step "s2s" { select tableoid::regclass, * from tpart; } +session s2 +step s2b { begin; } +step s2i { insert into tpart values (110,'xxx'), (120, 'yyy'), (150, 'zzz'); } +step s2i2 { insert into tpart_default (i, j) values (110, 'xxx'), (120, 'yyy'), (150, 'zzz'); } +step s2c { commit; } +step s2s { select tableoid::regclass, * from tpart; } teardown { drop table tpart; } # insert into tpart by s2 which routes to tpart_default due to not seeing # concurrently added tpart_2 should fail, because the partition constraint # of tpart_default would have changed due to tpart_2 having been added -permutation "s1b" "s1a" "s2b" "s2i" "s1c" "s2c" "s2s" +permutation s1b s1a s2b s2i s1c s2c s2s # similar to above, but now insert into sub-partitioned tpart_default -permutation "s1b" "s1a" "s2b" "s2i2" "s1c" "s2c" "s2s" +permutation s1b s1a s2b s2i2 s1c s2c s2s # reverse: now the insert into tpart_default by s2 occurs first followed by # attach in s1, which should fail when it scans the leaf default partition # find the violating rows -permutation "s1b" "s2b" "s2i" "s1a" "s2c" "s1c" "s2s" +permutation s1b s2b s2i s1a s2c s1c s2s diff --git a/src/test/isolation/specs/partition-key-update-1.spec b/src/test/isolation/specs/partition-key-update-1.spec index 79db1d0f30..6b5f4228c5 100644 --- a/src/test/isolation/specs/partition-key-update-1.spec +++ b/src/test/isolation/specs/partition-key-update-1.spec @@ -46,41 +46,41 @@ teardown DROP TABLE bar, foo_range_parted; } -session "s1" -step "s1b" { BEGIN ISOLATION LEVEL READ COMMITTED; } -step "s1u" { UPDATE foo SET a=2 WHERE a=1; } -step "s1u2" { UPDATE footrg SET b='EFG' WHERE a=1; } -step "s1u3pc" { UPDATE foo_range_parted SET a=11 WHERE a=7; } -step "s1u3npc" { UPDATE foo_range_parted SET b='XYZ' WHERE a=7; } -step "s1c" { COMMIT; } -step "s1r" { ROLLBACK; } +session s1 +step s1b { BEGIN ISOLATION LEVEL READ COMMITTED; } +step s1u { UPDATE foo SET a=2 WHERE a=1; } +step s1u2 { UPDATE footrg SET b='EFG' WHERE a=1; } +step s1u3pc { UPDATE foo_range_parted SET a=11 WHERE a=7; } +step s1u3npc { UPDATE foo_range_parted SET b='XYZ' WHERE a=7; } +step s1c { COMMIT; } +step s1r { ROLLBACK; } -session "s2" -step "s2b" { BEGIN ISOLATION LEVEL READ COMMITTED; } -step "s2u" { UPDATE foo SET b='EFG' WHERE a=1; } -step "s2u2" { UPDATE footrg SET b='XYZ' WHERE a=1; } -step "s2i" { INSERT INTO bar VALUES(7); } -step "s2d" { DELETE FROM foo WHERE a=1; } -step "s2c" { COMMIT; } +session s2 +step s2b { BEGIN ISOLATION LEVEL READ COMMITTED; } +step s2u { UPDATE foo SET b='EFG' WHERE a=1; } +step s2u2 { UPDATE footrg SET b='XYZ' WHERE a=1; } +step s2i { INSERT INTO bar VALUES(7); } +step s2d { DELETE FROM foo WHERE a=1; } +step s2c { COMMIT; } # Concurrency error from ExecUpdate and ExecDelete. -permutation "s1b" "s2b" "s1u" "s1c" "s2d" "s2c" -permutation "s1b" "s2b" "s1u" "s2d" "s1c" "s2c" -permutation "s1b" "s2b" "s1u" "s2u" "s1c" "s2c" -permutation "s1b" "s2b" "s2d" "s1u" "s2c" "s1c" +permutation s1b s2b s1u s1c s2d s2c +permutation s1b s2b s1u s2d s1c s2c +permutation s1b s2b s1u s2u s1c s2c +permutation s1b s2b s2d s1u s2c s1c # Concurrency error from GetTupleForTrigger -permutation "s1b" "s2b" "s1u2" "s1c" "s2u2" "s2c" -permutation "s1b" "s2b" "s1u2" "s2u2" "s1c" "s2c" -permutation "s1b" "s2b" "s2u2" "s1u2" "s2c" "s1c" +permutation s1b s2b s1u2 s1c s2u2 s2c +permutation s1b s2b s1u2 s2u2 s1c s2c +permutation s1b s2b s2u2 s1u2 s2c s1c # Concurrency error from ExecLockRows # test waiting for moved row itself -permutation "s1b" "s2b" "s1u3pc" "s2i" "s1c" "s2c" -permutation "s1b" "s2b" "s1u3pc" "s2i" "s1r" "s2c" +permutation s1b s2b s1u3pc s2i s1c s2c +permutation s1b s2b s1u3pc s2i s1r s2c # test waiting for in-partition update, followed by cross-partition move -permutation "s1b" "s2b" "s1u3npc" "s1u3pc" "s2i" "s1c" "s2c" -permutation "s1b" "s2b" "s1u3npc" "s1u3pc" "s2i" "s1r" "s2c" +permutation s1b s2b s1u3npc s1u3pc s2i s1c s2c +permutation s1b s2b s1u3npc s1u3pc s2i s1r s2c # test waiting for in-partition update, followed by cross-partition move -permutation "s1b" "s2b" "s1u3npc" "s1u3pc" "s1u3pc" "s2i" "s1c" "s2c" -permutation "s1b" "s2b" "s1u3npc" "s1u3pc" "s1u3pc" "s2i" "s1r" "s2c" +permutation s1b s2b s1u3npc s1u3pc s1u3pc s2i s1c s2c +permutation s1b s2b s1u3npc s1u3pc s1u3pc s2i s1r s2c diff --git a/src/test/isolation/specs/partition-key-update-2.spec b/src/test/isolation/specs/partition-key-update-2.spec index 699e2e727f..d4cd09b488 100644 --- a/src/test/isolation/specs/partition-key-update-2.spec +++ b/src/test/isolation/specs/partition-key-update-2.spec @@ -23,23 +23,23 @@ teardown DROP TABLE foo; } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL READ COMMITTED; } -step "s1u" { UPDATE foo SET a=2, b=b || ' -> moved by session-1' WHERE a=1; } -step "s1c" { COMMIT; } +step s1u { UPDATE foo SET a=2, b=b || ' -> moved by session-1' WHERE a=1; } +step s1c { COMMIT; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL READ COMMITTED; } -step "s2donothing" { INSERT INTO foo VALUES(1, 'session-2 donothing') ON CONFLICT DO NOTHING; } -step "s2c" { COMMIT; } +step s2donothing { INSERT INTO foo VALUES(1, 'session-2 donothing') ON CONFLICT DO NOTHING; } +step s2c { COMMIT; } -session "s3" +session s3 setup { BEGIN ISOLATION LEVEL READ COMMITTED; } -step "s3donothing" { INSERT INTO foo VALUES(2, 'session-3 donothing') ON CONFLICT DO NOTHING; } -step "s3select" { SELECT * FROM foo ORDER BY a; } -step "s3c" { COMMIT; } +step s3donothing { INSERT INTO foo VALUES(2, 'session-3 donothing') ON CONFLICT DO NOTHING; } +step s3select { SELECT * FROM foo ORDER BY a; } +step s3c { COMMIT; } # Regular case where one session block-waits on another to determine if it # should proceed with an insert or do nothing. -permutation "s1u" "s2donothing" "s3donothing" "s1c" "s2c" "s3select" "s3c" -permutation "s2donothing" "s1u" "s3donothing" "s1c" "s2c" "s3select" "s3c" +permutation s1u s2donothing s3donothing s1c s2c s3select s3c +permutation s2donothing s1u s3donothing s1c s2c s3select s3c diff --git a/src/test/isolation/specs/partition-key-update-3.spec b/src/test/isolation/specs/partition-key-update-3.spec index a6efea1381..d2883e34a5 100644 --- a/src/test/isolation/specs/partition-key-update-3.spec +++ b/src/test/isolation/specs/partition-key-update-3.spec @@ -16,29 +16,29 @@ teardown DROP TABLE foo; } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL READ COMMITTED; } -step "s1u" { UPDATE foo SET a=2, b=b || ' -> moved by session-1' WHERE a=1; } -step "s1c" { COMMIT; } +step s1u { UPDATE foo SET a=2, b=b || ' -> moved by session-1' WHERE a=1; } +step s1c { COMMIT; } -session "s2" -step "s2beginrr" { BEGIN ISOLATION LEVEL REPEATABLE READ; } -step "s2begins" { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "s2donothing" { INSERT INTO foo VALUES(1, 'session-2 donothing') ON CONFLICT DO NOTHING; } -step "s2c" { COMMIT; } -step "s2select" { SELECT * FROM foo ORDER BY a; } +session s2 +step s2beginrr { BEGIN ISOLATION LEVEL REPEATABLE READ; } +step s2begins { BEGIN ISOLATION LEVEL SERIALIZABLE; } +step s2donothing { INSERT INTO foo VALUES(1, 'session-2 donothing') ON CONFLICT DO NOTHING; } +step s2c { COMMIT; } +step s2select { SELECT * FROM foo ORDER BY a; } -session "s3" -step "s3beginrr" { BEGIN ISOLATION LEVEL REPEATABLE READ; } -step "s3begins" { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "s3donothing" { INSERT INTO foo VALUES(2, 'session-3 donothing'), (2, 'session-3 donothing2') ON CONFLICT DO NOTHING; } -step "s3c" { COMMIT; } +session s3 +step s3beginrr { BEGIN ISOLATION LEVEL REPEATABLE READ; } +step s3begins { BEGIN ISOLATION LEVEL SERIALIZABLE; } +step s3donothing { INSERT INTO foo VALUES(2, 'session-3 donothing'), (2, 'session-3 donothing2') ON CONFLICT DO NOTHING; } +step s3c { COMMIT; } -permutation "s2beginrr" "s3beginrr" "s1u" "s2donothing" "s1c" "s2c" "s3donothing" "s3c" "s2select" -permutation "s2beginrr" "s3beginrr" "s1u" "s3donothing" "s1c" "s3c" "s2donothing" "s2c" "s2select" -permutation "s2beginrr" "s3beginrr" "s1u" "s2donothing" "s3donothing" "s1c" "s2c" "s3c" "s2select" -permutation "s2beginrr" "s3beginrr" "s1u" "s3donothing" "s2donothing" "s1c" "s3c" "s2c" "s2select" -permutation "s2begins" "s3begins" "s1u" "s2donothing" "s1c" "s2c" "s3donothing" "s3c" "s2select" -permutation "s2begins" "s3begins" "s1u" "s3donothing" "s1c" "s3c" "s2donothing" "s2c" "s2select" -permutation "s2begins" "s3begins" "s1u" "s2donothing" "s3donothing" "s1c" "s2c" "s3c" "s2select" -permutation "s2begins" "s3begins" "s1u" "s3donothing" "s2donothing" "s1c" "s3c" "s2c" "s2select" +permutation s2beginrr s3beginrr s1u s2donothing s1c s2c s3donothing s3c s2select +permutation s2beginrr s3beginrr s1u s3donothing s1c s3c s2donothing s2c s2select +permutation s2beginrr s3beginrr s1u s2donothing s3donothing s1c s2c s3c s2select +permutation s2beginrr s3beginrr s1u s3donothing s2donothing s1c s3c s2c s2select +permutation s2begins s3begins s1u s2donothing s1c s2c s3donothing s3c s2select +permutation s2begins s3begins s1u s3donothing s1c s3c s2donothing s2c s2select +permutation s2begins s3begins s1u s2donothing s3donothing s1c s2c s3c s2select +permutation s2begins s3begins s1u s3donothing s2donothing s1c s3c s2c s2select diff --git a/src/test/isolation/specs/partition-key-update-4.spec b/src/test/isolation/specs/partition-key-update-4.spec index 3d1579b244..6c70816f1e 100644 --- a/src/test/isolation/specs/partition-key-update-4.spec +++ b/src/test/isolation/specs/partition-key-update-4.spec @@ -44,33 +44,33 @@ teardown DROP TABLE triglog; } -session "s1" -step "s1b" { BEGIN ISOLATION LEVEL READ COMMITTED; } -step "s1u" { UPDATE foo SET a = a + 1, b = b || ' update1' WHERE b like '%ABC%'; } -step "s1ut" { UPDATE footrg SET a = a + 1, b = b || ' update1' WHERE b like '%ABC%'; } -step "s1s" { SELECT tableoid::regclass, * FROM foo ORDER BY a; } -step "s1st" { SELECT tableoid::regclass, * FROM footrg ORDER BY a; } -step "s1stl" { SELECT * FROM triglog ORDER BY a; } -step "s1c" { COMMIT; } +session s1 +step s1b { BEGIN ISOLATION LEVEL READ COMMITTED; } +step s1u { UPDATE foo SET a = a + 1, b = b || ' update1' WHERE b like '%ABC%'; } +step s1ut { UPDATE footrg SET a = a + 1, b = b || ' update1' WHERE b like '%ABC%'; } +step s1s { SELECT tableoid::regclass, * FROM foo ORDER BY a; } +step s1st { SELECT tableoid::regclass, * FROM footrg ORDER BY a; } +step s1stl { SELECT * FROM triglog ORDER BY a; } +step s1c { COMMIT; } -session "s2" -step "s2b" { BEGIN ISOLATION LEVEL READ COMMITTED; } -step "s2u1" { UPDATE foo SET b = b || ' update2' WHERE a = 1; } -step "s2u2" { UPDATE foo SET b = 'EFG' WHERE a = 1; } -step "s2ut1" { UPDATE footrg SET b = b || ' update2' WHERE a = 1; } -step "s2ut2" { UPDATE footrg SET b = 'EFG' WHERE a = 1; } -step "s2c" { COMMIT; } +session s2 +step s2b { BEGIN ISOLATION LEVEL READ COMMITTED; } +step s2u1 { UPDATE foo SET b = b || ' update2' WHERE a = 1; } +step s2u2 { UPDATE foo SET b = 'EFG' WHERE a = 1; } +step s2ut1 { UPDATE footrg SET b = b || ' update2' WHERE a = 1; } +step s2ut2 { UPDATE footrg SET b = 'EFG' WHERE a = 1; } +step s2c { COMMIT; } # Session s1 is moving a row into another partition, but is waiting for # another session s2 that is updating the original row. The row that ends up # in the new partition should contain the changes made by session s2. -permutation "s1b" "s2b" "s2u1" "s1u" "s2c" "s1c" "s1s" +permutation s1b s2b s2u1 s1u s2c s1c s1s # Same as above, except, session s1 is waiting in GetTupleForTrigger(). -permutation "s1b" "s2b" "s2ut1" "s1ut" "s2c" "s1c" "s1st" "s1stl" +permutation s1b s2b s2ut1 s1ut s2c s1c s1st s1stl # Below two cases are similar to the above two; except that the session s1 # fails EvalPlanQual() test, so partition key update does not happen. -permutation "s1b" "s2b" "s2u2" "s1u" "s2c" "s1c" "s1s" -permutation "s1b" "s2b" "s2ut2" "s1ut" "s2c" "s1c" "s1st" "s1stl" +permutation s1b s2b s2u2 s1u s2c s1c s1s +permutation s1b s2b s2ut2 s1ut s2c s1c s1st s1stl diff --git a/src/test/isolation/specs/plpgsql-toast.spec b/src/test/isolation/specs/plpgsql-toast.spec index fb40588d4f..bb444fc9de 100644 --- a/src/test/isolation/specs/plpgsql-toast.spec +++ b/src/test/isolation/specs/plpgsql-toast.spec @@ -22,7 +22,7 @@ teardown DROP TYPE test2; } -session "s1" +session s1 setup { @@ -30,7 +30,7 @@ setup } # assign_simple_var() -step "assign1" +step assign1 { do $$ declare @@ -46,7 +46,7 @@ $$; } # assign_simple_var() -step "assign2" +step assign2 { do $$ declare @@ -62,7 +62,7 @@ $$; } # expanded_record_set_field() -step "assign3" +step assign3 { do $$ declare @@ -79,7 +79,7 @@ $$; } # expanded_record_set_fields() -step "assign4" +step assign4 { do $$ declare @@ -95,7 +95,7 @@ $$; } # expanded_record_set_tuple() -step "assign5" +step assign5 { do $$ declare @@ -113,7 +113,7 @@ $$; } # FOR loop must not hold any fetched-but-not-detoasted values across commit -step "assign6" +step assign6 { do $$ declare @@ -151,28 +151,28 @@ do $$ $$; } -session "s2" +session s2 setup { SELECT pg_advisory_unlock_all(); } -step "lock" +step lock { SELECT pg_advisory_lock(1); } -step "vacuum" +step vacuum { VACUUM test1; } -step "unlock" +step unlock { SELECT pg_advisory_unlock(1); } -permutation "lock" "assign1" "vacuum" "unlock" -permutation "lock" "assign2" "vacuum" "unlock" -permutation "lock" "assign3" "vacuum" "unlock" -permutation "lock" "assign4" "vacuum" "unlock" -permutation "lock" "assign5" "vacuum" "unlock" -permutation "lock" "assign6" "vacuum" "unlock" +permutation lock assign1 vacuum unlock +permutation lock assign2 vacuum unlock +permutation lock assign3 vacuum unlock +permutation lock assign4 vacuum unlock +permutation lock assign5 vacuum unlock +permutation lock assign6 vacuum unlock permutation "fetch-after-commit" diff --git a/src/test/isolation/specs/predicate-gin.spec b/src/test/isolation/specs/predicate-gin.spec index 46fc51befd..e279eaa11a 100644 --- a/src/test/isolation/specs/predicate-gin.spec +++ b/src/test/isolation/specs/predicate-gin.spec @@ -24,92 +24,92 @@ teardown drop table other_tbl; } -session "s1" +session s1 setup { begin isolation level serializable; set enable_seqscan=off; } -step "ra1" { select * from gin_tbl where p @> array[1] limit 1; } -step "rb1" { select count(*) from gin_tbl where p @> array[2]; } -step "rc1" { select count(*) from gin_tbl where p @> array[800]; } -step "rd1" { select count(*) from gin_tbl where p @> array[2000]; } +step ra1 { select * from gin_tbl where p @> array[1] limit 1; } +step rb1 { select count(*) from gin_tbl where p @> array[2]; } +step rc1 { select count(*) from gin_tbl where p @> array[800]; } +step rd1 { select count(*) from gin_tbl where p @> array[2000]; } -step "wo1" { insert into other_tbl values (1); } +step wo1 { insert into other_tbl values (1); } -step "c1" { commit; } +step c1 { commit; } -session "s2" +session s2 setup { begin isolation level serializable; set enable_seqscan=off; } -step "ro2" { select count(*) from other_tbl; } +step ro2 { select count(*) from other_tbl; } -step "wa2" { insert into gin_tbl values (array[1]); } -step "wb2" { insert into gin_tbl values (array[2]); } -step "wc2" { insert into gin_tbl values (array[800]); } -step "wd2" { insert into gin_tbl values (array[2000]); } +step wa2 { insert into gin_tbl values (array[1]); } +step wb2 { insert into gin_tbl values (array[2]); } +step wc2 { insert into gin_tbl values (array[800]); } +step wd2 { insert into gin_tbl values (array[2000]); } -step "c2" { commit; } +step c2 { commit; } -session "s3" -step "fu" { alter index ginidx set (fastupdate = on); } +session s3 +step fu { alter index ginidx set (fastupdate = on); } # An index scan (from one transaction) and an index insert (from another # transaction) try to access the same part of the index. So, there is a # r-w conflict. -permutation "ra1" "ro2" "wo1" "c1" "wa2" "c2" -permutation "ro2" "ra1" "wo1" "c1" "wa2" "c2" -permutation "ro2" "ra1" "wo1" "wa2" "c1" "c2" -permutation "ra1" "ro2" "wa2" "wo1" "c1" "c2" +permutation ra1 ro2 wo1 c1 wa2 c2 +permutation ro2 ra1 wo1 c1 wa2 c2 +permutation ro2 ra1 wo1 wa2 c1 c2 +permutation ra1 ro2 wa2 wo1 c1 c2 -permutation "rb1" "ro2" "wo1" "c1" "wb2" "c2" -permutation "ro2" "rb1" "wo1" "c1" "wb2" "c2" -permutation "ro2" "rb1" "wo1" "wb2" "c1" "c2" -permutation "rb1" "ro2" "wb2" "wo1" "c1" "c2" +permutation rb1 ro2 wo1 c1 wb2 c2 +permutation ro2 rb1 wo1 c1 wb2 c2 +permutation ro2 rb1 wo1 wb2 c1 c2 +permutation rb1 ro2 wb2 wo1 c1 c2 -permutation "rc1" "ro2" "wo1" "c1" "wc2" "c2" -permutation "ro2" "rc1" "wo1" "c1" "wc2" "c2" -permutation "ro2" "rc1" "wo1" "wc2" "c1" "c2" -permutation "rc1" "ro2" "wc2" "wo1" "c1" "c2" +permutation rc1 ro2 wo1 c1 wc2 c2 +permutation ro2 rc1 wo1 c1 wc2 c2 +permutation ro2 rc1 wo1 wc2 c1 c2 +permutation rc1 ro2 wc2 wo1 c1 c2 # An index scan (from one transaction) and an index insert (from another # transaction) try to access different parts of the index. So, there is no # r-w conflict. -permutation "ra1" "ro2" "wo1" "c1" "wb2" "c2" -permutation "ro2" "ra1" "wo1" "c1" "wc2" "c2" -permutation "ro2" "rb1" "wo1" "wa2" "c1" "c2" -permutation "rc1" "ro2" "wa2" "wo1" "c1" "c2" +permutation ra1 ro2 wo1 c1 wb2 c2 +permutation ro2 ra1 wo1 c1 wc2 c2 +permutation ro2 rb1 wo1 wa2 c1 c2 +permutation rc1 ro2 wa2 wo1 c1 c2 -permutation "rb1" "ro2" "wo1" "c1" "wa2" "c2" -permutation "ro2" "rb1" "wo1" "c1" "wc2" "c2" -permutation "ro2" "ra1" "wo1" "wb2" "c1" "c2" -permutation "rc1" "ro2" "wb2" "wo1" "c1" "c2" +permutation rb1 ro2 wo1 c1 wa2 c2 +permutation ro2 rb1 wo1 c1 wc2 c2 +permutation ro2 ra1 wo1 wb2 c1 c2 +permutation rc1 ro2 wb2 wo1 c1 c2 -permutation "rc1" "ro2" "wo1" "c1" "wa2" "c2" -permutation "ro2" "rc1" "wo1" "c1" "wb2" "c2" -permutation "ro2" "ra1" "wo1" "wc2" "c1" "c2" -permutation "rb1" "ro2" "wc2" "wo1" "c1" "c2" +permutation rc1 ro2 wo1 c1 wa2 c2 +permutation ro2 rc1 wo1 c1 wb2 c2 +permutation ro2 ra1 wo1 wc2 c1 c2 +permutation rb1 ro2 wc2 wo1 c1 c2 # With fastupdate = on all index is under predicate lock. So we can't # distinguish particular keys. -permutation "fu" "ra1" "ro2" "wo1" "c1" "wa2" "c2" -permutation "fu" "ra1" "ro2" "wo1" "c1" "wb2" "c2" +permutation fu ra1 ro2 wo1 c1 wa2 c2 +permutation fu ra1 ro2 wo1 c1 wb2 c2 # Check fastupdate turned on concurrently. -permutation "ra1" "ro2" "wo1" "c1" "fu" "wa2" "c2" +permutation ra1 ro2 wo1 c1 fu wa2 c2 # Tests for conflicts with previously non-existing key -permutation "rd1" "ro2" "wo1" "c1" "wd2" "c2" -permutation "ro2" "rd1" "wo1" "c1" "wd2" "c2" -permutation "ro2" "rd1" "wo1" "wd2" "c1" "c2" -permutation "rd1" "ro2" "wd2" "wo1" "c1" "c2" +permutation rd1 ro2 wo1 c1 wd2 c2 +permutation ro2 rd1 wo1 c1 wd2 c2 +permutation ro2 rd1 wo1 wd2 c1 c2 +permutation rd1 ro2 wd2 wo1 c1 c2 diff --git a/src/test/isolation/specs/predicate-gist.spec b/src/test/isolation/specs/predicate-gist.spec index 6d6021f5e4..9016c6e46f 100644 --- a/src/test/isolation/specs/predicate-gist.spec +++ b/src/test/isolation/specs/predicate-gist.spec @@ -21,7 +21,7 @@ teardown drop table gist_point_tbl; } -session "s1" +session s1 setup { begin isolation level serializable; @@ -30,16 +30,16 @@ setup set enable_indexonlyscan=on; } -step "rxy1" { select sum(p[0]) from gist_point_tbl where p << point(2500, 2500); } -step "wx1" { insert into gist_point_tbl (id, p) +step rxy1 { select sum(p[0]) from gist_point_tbl where p << point(2500, 2500); } +step wx1 { insert into gist_point_tbl (id, p) select g, point(g*500, g*500) from generate_series(15, 20) g; } -step "rxy3" { select sum(p[0]) from gist_point_tbl where p >> point(6000,6000); } -step "wx3" { insert into gist_point_tbl (id, p) +step rxy3 { select sum(p[0]) from gist_point_tbl where p >> point(6000,6000); } +step wx3 { insert into gist_point_tbl (id, p) select g, point(g*500, g*500) from generate_series(12, 18) g; } -step "c1" { commit; } +step c1 { commit; } -session "s2" +session s2 setup { begin isolation level serializable; @@ -48,70 +48,70 @@ setup set enable_indexonlyscan=on; } -step "rxy2" { select sum(p[0]) from gist_point_tbl where p >> point(7500,7500); } -step "wy2" { insert into gist_point_tbl (id, p) +step rxy2 { select sum(p[0]) from gist_point_tbl where p >> point(7500,7500); } +step wy2 { insert into gist_point_tbl (id, p) select g, point(g*500, g*500) from generate_series(1, 5) g; } -step "rxy4" { select sum(p[0]) from gist_point_tbl where p << point(1000,1000); } -step "wy4" { insert into gist_point_tbl (id, p) +step rxy4 { select sum(p[0]) from gist_point_tbl where p << point(1000,1000); } +step wy4 { insert into gist_point_tbl (id, p) select g, point(g*50, g*50) from generate_series(1, 20) g; } -step "c2" { commit; } +step c2 { commit; } # An index scan (from one transaction) and an index insert (from another # transaction) try to access the same part of the index but one transaction # commits before other transaction begins so no r-w conflict. -permutation "rxy1" "wx1" "c1" "rxy2" "wy2" "c2" -permutation "rxy2" "wy2" "c2" "rxy1" "wx1" "c1" +permutation rxy1 wx1 c1 rxy2 wy2 c2 +permutation rxy2 wy2 c2 rxy1 wx1 c1 # An index scan (from one transaction) and an index insert (from another # transaction) try to access different parts of the index and also one # transaction commits before other transaction begins, so no r-w conflict. -permutation "rxy3" "wx3" "c1" "rxy4" "wy4" "c2" -permutation "rxy4" "wy4" "c2" "rxy3" "wx3" "c1" +permutation rxy3 wx3 c1 rxy4 wy4 c2 +permutation rxy4 wy4 c2 rxy3 wx3 c1 # An index scan (from one transaction) and an index insert (from another # transaction) try to access the same part of the index and one transaction # begins before other transaction commits so there is a r-w conflict. -permutation "rxy1" "wx1" "rxy2" "c1" "wy2" "c2" -permutation "rxy1" "wx1" "rxy2" "wy2" "c1" "c2" -permutation "rxy1" "wx1" "rxy2" "wy2" "c2" "c1" -permutation "rxy1" "rxy2" "wx1" "c1" "wy2" "c2" -permutation "rxy1" "rxy2" "wx1" "wy2" "c1" "c2" -permutation "rxy1" "rxy2" "wx1" "wy2" "c2" "c1" -permutation "rxy1" "rxy2" "wy2" "wx1" "c1" "c2" -permutation "rxy1" "rxy2" "wy2" "wx1" "c2" "c1" -permutation "rxy1" "rxy2" "wy2" "c2" "wx1" "c1" -permutation "rxy2" "rxy1" "wx1" "c1" "wy2" "c2" -permutation "rxy2" "rxy1" "wx1" "wy2" "c1" "c2" -permutation "rxy2" "rxy1" "wx1" "wy2" "c2" "c1" -permutation "rxy2" "rxy1" "wy2" "wx1" "c1" "c2" -permutation "rxy2" "rxy1" "wy2" "wx1" "c2" "c1" -permutation "rxy2" "rxy1" "wy2" "c2" "wx1" "c1" -permutation "rxy2" "wy2" "rxy1" "wx1" "c1" "c2" -permutation "rxy2" "wy2" "rxy1" "wx1" "c2" "c1" -permutation "rxy2" "wy2" "rxy1" "c2" "wx1" "c1" +permutation rxy1 wx1 rxy2 c1 wy2 c2 +permutation rxy1 wx1 rxy2 wy2 c1 c2 +permutation rxy1 wx1 rxy2 wy2 c2 c1 +permutation rxy1 rxy2 wx1 c1 wy2 c2 +permutation rxy1 rxy2 wx1 wy2 c1 c2 +permutation rxy1 rxy2 wx1 wy2 c2 c1 +permutation rxy1 rxy2 wy2 wx1 c1 c2 +permutation rxy1 rxy2 wy2 wx1 c2 c1 +permutation rxy1 rxy2 wy2 c2 wx1 c1 +permutation rxy2 rxy1 wx1 c1 wy2 c2 +permutation rxy2 rxy1 wx1 wy2 c1 c2 +permutation rxy2 rxy1 wx1 wy2 c2 c1 +permutation rxy2 rxy1 wy2 wx1 c1 c2 +permutation rxy2 rxy1 wy2 wx1 c2 c1 +permutation rxy2 rxy1 wy2 c2 wx1 c1 +permutation rxy2 wy2 rxy1 wx1 c1 c2 +permutation rxy2 wy2 rxy1 wx1 c2 c1 +permutation rxy2 wy2 rxy1 c2 wx1 c1 # An index scan (from one transaction) and an index insert (from another # transaction) try to access different parts of the index so no r-w conflict. -permutation "rxy3" "wx3" "rxy4" "c1" "wy4" "c2" -permutation "rxy3" "wx3" "rxy4" "wy4" "c1" "c2" -permutation "rxy3" "wx3" "rxy4" "wy4" "c2" "c1" -permutation "rxy3" "rxy4" "wx3" "c1" "wy4" "c2" -permutation "rxy3" "rxy4" "wx3" "wy4" "c1" "c2" -permutation "rxy3" "rxy4" "wx3" "wy4" "c2" "c1" -permutation "rxy3" "rxy4" "wy4" "wx3" "c1" "c2" -permutation "rxy3" "rxy4" "wy4" "wx3" "c2" "c1" -permutation "rxy3" "rxy4" "wy4" "c2" "wx3" "c1" -permutation "rxy4" "rxy3" "wx3" "c1" "wy4" "c2" -permutation "rxy4" "rxy3" "wx3" "wy4" "c1" "c2" -permutation "rxy4" "rxy3" "wx3" "wy4" "c2" "c1" -permutation "rxy4" "rxy3" "wy4" "wx3" "c1" "c2" -permutation "rxy4" "rxy3" "wy4" "wx3" "c2" "c1" -permutation "rxy4" "rxy3" "wy4" "c2" "wx3" "c1" -permutation "rxy4" "wy4" "rxy3" "wx3" "c1" "c2" -permutation "rxy4" "wy4" "rxy3" "wx3" "c2" "c1" -permutation "rxy4" "wy4" "rxy3" "c2" "wx3" "c1" +permutation rxy3 wx3 rxy4 c1 wy4 c2 +permutation rxy3 wx3 rxy4 wy4 c1 c2 +permutation rxy3 wx3 rxy4 wy4 c2 c1 +permutation rxy3 rxy4 wx3 c1 wy4 c2 +permutation rxy3 rxy4 wx3 wy4 c1 c2 +permutation rxy3 rxy4 wx3 wy4 c2 c1 +permutation rxy3 rxy4 wy4 wx3 c1 c2 +permutation rxy3 rxy4 wy4 wx3 c2 c1 +permutation rxy3 rxy4 wy4 c2 wx3 c1 +permutation rxy4 rxy3 wx3 c1 wy4 c2 +permutation rxy4 rxy3 wx3 wy4 c1 c2 +permutation rxy4 rxy3 wx3 wy4 c2 c1 +permutation rxy4 rxy3 wy4 wx3 c1 c2 +permutation rxy4 rxy3 wy4 wx3 c2 c1 +permutation rxy4 rxy3 wy4 c2 wx3 c1 +permutation rxy4 wy4 rxy3 wx3 c1 c2 +permutation rxy4 wy4 rxy3 wx3 c2 c1 +permutation rxy4 wy4 rxy3 c2 wx3 c1 diff --git a/src/test/isolation/specs/predicate-hash.spec b/src/test/isolation/specs/predicate-hash.spec index 852c1ca29d..7ca193b108 100644 --- a/src/test/isolation/specs/predicate-hash.spec +++ b/src/test/isolation/specs/predicate-hash.spec @@ -27,7 +27,7 @@ teardown drop table hash_tbl; } -session "s1" +session s1 setup { begin isolation level serializable; @@ -35,16 +35,16 @@ setup set enable_bitmapscan=off; set enable_indexonlyscan=on; } -step "rxy1" { select sum(p) from hash_tbl where p=20; } -step "wx1" { insert into hash_tbl (id, p) +step rxy1 { select sum(p) from hash_tbl where p=20; } +step wx1 { insert into hash_tbl (id, p) select g, 30 from generate_series(41, 50) g; } -step "rxy3" { select sum(p) from hash_tbl where p=20; } -step "wx3" { insert into hash_tbl (id, p) +step rxy3 { select sum(p) from hash_tbl where p=20; } +step wx3 { insert into hash_tbl (id, p) select g, 50 from generate_series(41, 50) g; } -step "c1" { commit; } +step c1 { commit; } -session "s2" +session s2 setup { begin isolation level serializable; @@ -52,71 +52,71 @@ setup set enable_bitmapscan=off; set enable_indexonlyscan=on; } -step "rxy2" { select sum(p) from hash_tbl where p=30; } -step "wy2" { insert into hash_tbl (id, p) +step rxy2 { select sum(p) from hash_tbl where p=30; } +step wy2 { insert into hash_tbl (id, p) select g, 20 from generate_series(51, 60) g; } -step "rxy4" { select sum(p) from hash_tbl where p=30; } -step "wy4" { insert into hash_tbl (id, p) +step rxy4 { select sum(p) from hash_tbl where p=30; } +step wy4 { insert into hash_tbl (id, p) select g, 60 from generate_series(51, 60) g; } -step "c2" { commit; } +step c2 { commit; } # An index scan (from one transaction) and an index insert (from another # transaction) try to access the same bucket of the index but one transaction # commits before other transaction begins so no r-w conflict. -permutation "rxy1" "wx1" "c1" "rxy2" "wy2" "c2" -permutation "rxy2" "wy2" "c2" "rxy1" "wx1" "c1" +permutation rxy1 wx1 c1 rxy2 wy2 c2 +permutation rxy2 wy2 c2 rxy1 wx1 c1 # An index scan (from one transaction) and an index insert (from another # transaction) try to access different buckets of the index and also one # transaction commits before other transaction begins, so no r-w conflict. -permutation "rxy3" "wx3" "c1" "rxy4" "wy4" "c2" -permutation "rxy4" "wy4" "c2" "rxy3" "wx3" "c1" +permutation rxy3 wx3 c1 rxy4 wy4 c2 +permutation rxy4 wy4 c2 rxy3 wx3 c1 # An index scan (from one transaction) and an index insert (from another # transaction) try to access the same bucket of the index and one transaction # begins before other transaction commits so there is a r-w conflict. -permutation "rxy1" "wx1" "rxy2" "c1" "wy2" "c2" -permutation "rxy1" "wx1" "rxy2" "wy2" "c1" "c2" -permutation "rxy1" "wx1" "rxy2" "wy2" "c2" "c1" -permutation "rxy1" "rxy2" "wx1" "c1" "wy2" "c2" -permutation "rxy1" "rxy2" "wx1" "wy2" "c1" "c2" -permutation "rxy1" "rxy2" "wx1" "wy2" "c2" "c1" -permutation "rxy1" "rxy2" "wy2" "wx1" "c1" "c2" -permutation "rxy1" "rxy2" "wy2" "wx1" "c2" "c1" -permutation "rxy1" "rxy2" "wy2" "c2" "wx1" "c1" -permutation "rxy2" "rxy1" "wx1" "c1" "wy2" "c2" -permutation "rxy2" "rxy1" "wx1" "wy2" "c1" "c2" -permutation "rxy2" "rxy1" "wx1" "wy2" "c2" "c1" -permutation "rxy2" "rxy1" "wy2" "wx1" "c1" "c2" -permutation "rxy2" "rxy1" "wy2" "wx1" "c2" "c1" -permutation "rxy2" "rxy1" "wy2" "c2" "wx1" "c1" -permutation "rxy2" "wy2" "rxy1" "wx1" "c1" "c2" -permutation "rxy2" "wy2" "rxy1" "wx1" "c2" "c1" -permutation "rxy2" "wy2" "rxy1" "c2" "wx1" "c1" +permutation rxy1 wx1 rxy2 c1 wy2 c2 +permutation rxy1 wx1 rxy2 wy2 c1 c2 +permutation rxy1 wx1 rxy2 wy2 c2 c1 +permutation rxy1 rxy2 wx1 c1 wy2 c2 +permutation rxy1 rxy2 wx1 wy2 c1 c2 +permutation rxy1 rxy2 wx1 wy2 c2 c1 +permutation rxy1 rxy2 wy2 wx1 c1 c2 +permutation rxy1 rxy2 wy2 wx1 c2 c1 +permutation rxy1 rxy2 wy2 c2 wx1 c1 +permutation rxy2 rxy1 wx1 c1 wy2 c2 +permutation rxy2 rxy1 wx1 wy2 c1 c2 +permutation rxy2 rxy1 wx1 wy2 c2 c1 +permutation rxy2 rxy1 wy2 wx1 c1 c2 +permutation rxy2 rxy1 wy2 wx1 c2 c1 +permutation rxy2 rxy1 wy2 c2 wx1 c1 +permutation rxy2 wy2 rxy1 wx1 c1 c2 +permutation rxy2 wy2 rxy1 wx1 c2 c1 +permutation rxy2 wy2 rxy1 c2 wx1 c1 # An index scan (from one transaction) and an index insert (from another # transaction) try to access different buckets of the index so no r-w conflict. -permutation "rxy3" "wx3" "rxy4" "c1" "wy4" "c2" -permutation "rxy3" "wx3" "rxy4" "wy4" "c1" "c2" -permutation "rxy3" "wx3" "rxy4" "wy4" "c2" "c1" -permutation "rxy3" "rxy4" "wx3" "c1" "wy4" "c2" -permutation "rxy3" "rxy4" "wx3" "wy4" "c1" "c2" -permutation "rxy3" "rxy4" "wx3" "wy4" "c2" "c1" -permutation "rxy3" "rxy4" "wy4" "wx3" "c1" "c2" -permutation "rxy3" "rxy4" "wy4" "wx3" "c2" "c1" -permutation "rxy3" "rxy4" "wy4" "c2" "wx3" "c1" -permutation "rxy4" "rxy3" "wx3" "c1" "wy4" "c2" -permutation "rxy4" "rxy3" "wx3" "wy4" "c1" "c2" -permutation "rxy4" "rxy3" "wx3" "wy4" "c2" "c1" -permutation "rxy4" "rxy3" "wy4" "wx3" "c1" "c2" -permutation "rxy4" "rxy3" "wy4" "wx3" "c2" "c1" -permutation "rxy4" "rxy3" "wy4" "c2" "wx3" "c1" -permutation "rxy4" "wy4" "rxy3" "wx3" "c1" "c2" -permutation "rxy4" "wy4" "rxy3" "wx3" "c2" "c1" -permutation "rxy4" "wy4" "rxy3" "c2" "wx3" "c1" +permutation rxy3 wx3 rxy4 c1 wy4 c2 +permutation rxy3 wx3 rxy4 wy4 c1 c2 +permutation rxy3 wx3 rxy4 wy4 c2 c1 +permutation rxy3 rxy4 wx3 c1 wy4 c2 +permutation rxy3 rxy4 wx3 wy4 c1 c2 +permutation rxy3 rxy4 wx3 wy4 c2 c1 +permutation rxy3 rxy4 wy4 wx3 c1 c2 +permutation rxy3 rxy4 wy4 wx3 c2 c1 +permutation rxy3 rxy4 wy4 c2 wx3 c1 +permutation rxy4 rxy3 wx3 c1 wy4 c2 +permutation rxy4 rxy3 wx3 wy4 c1 c2 +permutation rxy4 rxy3 wx3 wy4 c2 c1 +permutation rxy4 rxy3 wy4 wx3 c1 c2 +permutation rxy4 rxy3 wy4 wx3 c2 c1 +permutation rxy4 rxy3 wy4 c2 wx3 c1 +permutation rxy4 wy4 rxy3 wx3 c1 c2 +permutation rxy4 wy4 rxy3 wx3 c2 c1 +permutation rxy4 wy4 rxy3 c2 wx3 c1 diff --git a/src/test/isolation/specs/predicate-lock-hot-tuple.spec b/src/test/isolation/specs/predicate-lock-hot-tuple.spec index d16fb60533..5b8aecc4ed 100644 --- a/src/test/isolation/specs/predicate-lock-hot-tuple.spec +++ b/src/test/isolation/specs/predicate-lock-hot-tuple.spec @@ -22,16 +22,16 @@ teardown DROP TABLE test; } -session "s1" -step "b1" { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "r1" { SELECT * FROM test WHERE i IN (5, 7) } -step "w1" { UPDATE test SET t = 'pear_xact1' WHERE i = 7 } -step "c1" { COMMIT; } +session s1 +step b1 { BEGIN ISOLATION LEVEL SERIALIZABLE; } +step r1 { SELECT * FROM test WHERE i IN (5, 7) } +step w1 { UPDATE test SET t = 'pear_xact1' WHERE i = 7 } +step c1 { COMMIT; } -session "s2" -step "b2" { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "r2" { SELECT * FROM test WHERE i IN (5, 7) } -step "w2" { UPDATE test SET t = 'apple_xact2' WHERE i = 5 } -step "c2" { COMMIT; } +session s2 +step b2 { BEGIN ISOLATION LEVEL SERIALIZABLE; } +step r2 { SELECT * FROM test WHERE i IN (5, 7) } +step w2 { UPDATE test SET t = 'apple_xact2' WHERE i = 5 } +step c2 { COMMIT; } -permutation "b1" "b2" "r1" "r2" "w1" "w2" "c1" "c2" +permutation b1 b2 r1 r2 w1 w2 c1 c2 diff --git a/src/test/isolation/specs/prepared-transactions-cic.spec b/src/test/isolation/specs/prepared-transactions-cic.spec index c39eaf5ad0..626b1b686a 100644 --- a/src/test/isolation/specs/prepared-transactions-cic.spec +++ b/src/test/isolation/specs/prepared-transactions-cic.spec @@ -12,26 +12,26 @@ teardown # Sessions for CREATE INDEX CONCURRENTLY test -session "s1" -step "w1" { BEGIN; INSERT INTO cic_test VALUES (1); } -step "p1" { PREPARE TRANSACTION 's1'; } -step "c1" { COMMIT PREPARED 's1'; } +session s1 +step w1 { BEGIN; INSERT INTO cic_test VALUES (1); } +step p1 { PREPARE TRANSACTION 's1'; } +step c1 { COMMIT PREPARED 's1'; } -session "s2" +session s2 # The isolation tester never recognizes that a lock of s1 blocks s2, because a # prepared transaction's locks have no pid associated. While there's a slight # chance of timeout while waiting for an autovacuum-held lock, that wouldn't # change the output. Hence, no timeout is too short. setup { SET lock_timeout = 10; } -step "cic2" +step cic2 { CREATE INDEX CONCURRENTLY on cic_test(a); } -step "r2" +step r2 { SET enable_seqscan to off; SET enable_bitmapscan to off; SELECT * FROM cic_test WHERE a = 1; } -permutation "w1" "p1" "cic2" "c1" "r2" +permutation w1 p1 cic2 c1 r2 diff --git a/src/test/isolation/specs/prepared-transactions.spec b/src/test/isolation/specs/prepared-transactions.spec index bb9e154e6e..78b9d2c84e 100644 --- a/src/test/isolation/specs/prepared-transactions.spec +++ b/src/test/isolation/specs/prepared-transactions.spec @@ -32,30 +32,30 @@ teardown } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; INSERT INTO test1 VALUES (1); } -step "r1" { SELECT * FROM test2; } -step "p1" { PREPARE TRANSACTION 's1'; } -step "c1" { COMMIT PREPARED 's1'; } +step r1 { SELECT * FROM test2; } +step p1 { PREPARE TRANSACTION 's1'; } +step c1 { COMMIT PREPARED 's1'; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; SELECT * FROM force_snapshot; } -step "r2" { SELECT * FROM test3; } -step "w2" { INSERT INTO test2 VALUES (2); } -step "p2" { PREPARE TRANSACTION 's2'; } -step "c2" { COMMIT PREPARED 's2'; } +step r2 { SELECT * FROM test3; } +step w2 { INSERT INTO test2 VALUES (2); } +step p2 { PREPARE TRANSACTION 's2'; } +step c2 { COMMIT PREPARED 's2'; } -session "s3" +session s3 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; SELECT * FROM force_snapshot; } -step "w3" { INSERT INTO test3 VALUES (3); } -step "p3" { PREPARE TRANSACTION 's3'; } -step "c3" { COMMIT PREPARED 's3'; } +step w3 { INSERT INTO test3 VALUES (3); } +step p3 { PREPARE TRANSACTION 's3'; } +step c3 { COMMIT PREPARED 's3'; } # When run at the end of the permutations below, this SELECT statement # should never return any tuples, because at least one of the three # transactions involved should be aborted. -session "s4" -step "check" { SELECT * FROM test1,test2,test3; } +session s4 +step check { SELECT * FROM test1,test2,test3; } # We run on all permutations of the statements above subject to the # following constraints: @@ -73,1435 +73,1435 @@ step "check" { SELECT * FROM test1,test2,test3; } # This eliminates some redundant combinations. For example, it doesn't # matter if w2 happens before w3 as long as both come before the # conflicting reads. -permutation "r1" "r2" "w2" "w3" "p1" "p2" "p3" "c3" "c1" "c2" "check" -permutation "r1" "r2" "w2" "w3" "p1" "p2" "p3" "c3" "c2" "c1" "check" -permutation "r1" "r2" "w2" "w3" "p1" "p3" "p2" "c3" "c1" "c2" "check" -permutation "r1" "r2" "w2" "w3" "p1" "p3" "p2" "c3" "c2" "c1" "check" -permutation "r1" "r2" "w2" "w3" "p1" "p3" "c3" "p2" "c1" "c2" "check" -permutation "r1" "r2" "w2" "w3" "p1" "p3" "c3" "p2" "c2" "c1" "check" -permutation "r1" "r2" "w2" "w3" "p1" "p3" "c3" "c1" "p2" "c2" "check" -permutation "r1" "r2" "w2" "w3" "p2" "p1" "p3" "c3" "c1" "c2" "check" -permutation "r1" "r2" "w2" "w3" "p2" "p1" "p3" "c3" "c2" "c1" "check" -permutation "r1" "r2" "w2" "w3" "p2" "p3" "p1" "c3" "c1" "c2" "check" -permutation "r1" "r2" "w2" "w3" "p2" "p3" "p1" "c3" "c2" "c1" "check" -permutation "r1" "r2" "w2" "w3" "p2" "p3" "c3" "p1" "c1" "c2" "check" -permutation "r1" "r2" "w2" "w3" "p2" "p3" "c3" "p1" "c2" "c1" "check" -permutation "r1" "r2" "w2" "w3" "p2" "p3" "c3" "c2" "p1" "c1" "check" -permutation "r1" "r2" "w2" "w3" "p3" "p1" "p2" "c3" "c1" "c2" "check" -permutation "r1" "r2" "w2" "w3" "p3" "p1" "p2" "c3" "c2" "c1" "check" -permutation "r1" "r2" "w2" "w3" "p3" "p1" "c3" "p2" "c1" "c2" "check" -permutation "r1" "r2" "w2" "w3" "p3" "p1" "c3" "p2" "c2" "c1" "check" -permutation "r1" "r2" "w2" "w3" "p3" "p1" "c3" "c1" "p2" "c2" "check" -permutation "r1" "r2" "w2" "w3" "p3" "p2" "p1" "c3" "c1" "c2" "check" -permutation "r1" "r2" "w2" "w3" "p3" "p2" "p1" "c3" "c2" "c1" "check" -permutation "r1" "r2" "w2" "w3" "p3" "p2" "c3" "p1" "c1" "c2" "check" -permutation "r1" "r2" "w2" "w3" "p3" "p2" "c3" "p1" "c2" "c1" "check" -permutation "r1" "r2" "w2" "w3" "p3" "p2" "c3" "c2" "p1" "c1" "check" -permutation "r1" "r2" "w2" "w3" "p3" "c3" "p1" "p2" "c1" "c2" "check" -permutation "r1" "r2" "w2" "w3" "p3" "c3" "p1" "p2" "c2" "c1" "check" -permutation "r1" "r2" "w2" "w3" "p3" "c3" "p1" "c1" "p2" "c2" "check" -permutation "r1" "r2" "w2" "w3" "p3" "c3" "p2" "p1" "c1" "c2" "check" -permutation "r1" "r2" "w2" "w3" "p3" "c3" "p2" "p1" "c2" "c1" "check" -permutation "r1" "r2" "w2" "w3" "p3" "c3" "p2" "c2" "p1" "c1" "check" -permutation "r1" "r2" "w2" "p1" "w3" "p2" "p3" "c3" "c1" "c2" "check" -permutation "r1" "r2" "w2" "p1" "w3" "p2" "p3" "c3" "c2" "c1" "check" -permutation "r1" "r2" "w2" "p1" "w3" "p3" "p2" "c3" "c1" "c2" "check" -permutation "r1" "r2" "w2" "p1" "w3" "p3" "p2" "c3" "c2" "c1" "check" -permutation "r1" "r2" "w2" "p1" "w3" "p3" "c3" "p2" "c1" "c2" "check" -permutation "r1" "r2" "w2" "p1" "w3" "p3" "c3" "p2" "c2" "c1" "check" -permutation "r1" "r2" "w2" "p1" "w3" "p3" "c3" "c1" "p2" "c2" "check" -permutation "r1" "r2" "w2" "p1" "p2" "w3" "p3" "c3" "c1" "c2" "check" -permutation "r1" "r2" "w2" "p1" "p2" "w3" "p3" "c3" "c2" "c1" "check" -permutation "r1" "r2" "w2" "p2" "w3" "p1" "p3" "c3" "c1" "c2" "check" -permutation "r1" "r2" "w2" "p2" "w3" "p1" "p3" "c3" "c2" "c1" "check" -permutation "r1" "r2" "w2" "p2" "w3" "p3" "p1" "c3" "c1" "c2" "check" -permutation "r1" "r2" "w2" "p2" "w3" "p3" "p1" "c3" "c2" "c1" "check" -permutation "r1" "r2" "w2" "p2" "w3" "p3" "c3" "p1" "c1" "c2" "check" -permutation "r1" "r2" "w2" "p2" "w3" "p3" "c3" "p1" "c2" "c1" "check" -permutation "r1" "r2" "w2" "p2" "w3" "p3" "c3" "c2" "p1" "c1" "check" -permutation "r1" "r2" "w2" "p2" "p1" "w3" "p3" "c3" "c1" "c2" "check" -permutation "r1" "r2" "w2" "p2" "p1" "w3" "p3" "c3" "c2" "c1" "check" -permutation "r1" "r2" "p1" "w2" "w3" "p2" "p3" "c3" "c1" "c2" "check" -permutation "r1" "r2" "p1" "w2" "w3" "p2" "p3" "c3" "c2" "c1" "check" -permutation "r1" "r2" "p1" "w2" "w3" "p3" "p2" "c3" "c1" "c2" "check" -permutation "r1" "r2" "p1" "w2" "w3" "p3" "p2" "c3" "c2" "c1" "check" -permutation "r1" "r2" "p1" "w2" "w3" "p3" "c3" "p2" "c1" "c2" "check" -permutation "r1" "r2" "p1" "w2" "w3" "p3" "c3" "p2" "c2" "c1" "check" -permutation "r1" "r2" "p1" "w2" "w3" "p3" "c3" "c1" "p2" "c2" "check" -permutation "r1" "r2" "p1" "w2" "p2" "w3" "p3" "c3" "c1" "c2" "check" -permutation "r1" "r2" "p1" "w2" "p2" "w3" "p3" "c3" "c2" "c1" "check" -permutation "r1" "w2" "w3" "r2" "p1" "p2" "p3" "c3" "c1" "c2" "check" -permutation "r1" "w2" "w3" "r2" "p1" "p2" "p3" "c3" "c2" "c1" "check" -permutation "r1" "w2" "w3" "r2" "p1" "p3" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w2" "w3" "r2" "p1" "p3" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w2" "w3" "r2" "p1" "p3" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w2" "w3" "r2" "p1" "p3" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w2" "w3" "r2" "p1" "p3" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w2" "w3" "r2" "p2" "p1" "p3" "c3" "c1" "c2" "check" -permutation "r1" "w2" "w3" "r2" "p2" "p1" "p3" "c3" "c2" "c1" "check" -permutation "r1" "w2" "w3" "r2" "p2" "p3" "p1" "c3" "c1" "c2" "check" -permutation "r1" "w2" "w3" "r2" "p2" "p3" "p1" "c3" "c2" "c1" "check" -permutation "r1" "w2" "w3" "r2" "p2" "p3" "c3" "p1" "c1" "c2" "check" -permutation "r1" "w2" "w3" "r2" "p2" "p3" "c3" "p1" "c2" "c1" "check" -permutation "r1" "w2" "w3" "r2" "p2" "p3" "c3" "c2" "p1" "c1" "check" -permutation "r1" "w2" "w3" "r2" "p3" "p1" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w2" "w3" "r2" "p3" "p1" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w2" "w3" "r2" "p3" "p1" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w2" "w3" "r2" "p3" "p1" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w2" "w3" "r2" "p3" "p1" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w2" "w3" "r2" "p3" "p2" "p1" "c3" "c1" "c2" "check" -permutation "r1" "w2" "w3" "r2" "p3" "p2" "p1" "c3" "c2" "c1" "check" -permutation "r1" "w2" "w3" "r2" "p3" "p2" "c3" "p1" "c1" "c2" "check" -permutation "r1" "w2" "w3" "r2" "p3" "p2" "c3" "p1" "c2" "c1" "check" -permutation "r1" "w2" "w3" "r2" "p3" "p2" "c3" "c2" "p1" "c1" "check" -permutation "r1" "w2" "w3" "r2" "p3" "c3" "p1" "p2" "c1" "c2" "check" -permutation "r1" "w2" "w3" "r2" "p3" "c3" "p1" "p2" "c2" "c1" "check" -permutation "r1" "w2" "w3" "r2" "p3" "c3" "p1" "c1" "p2" "c2" "check" -permutation "r1" "w2" "w3" "r2" "p3" "c3" "p2" "p1" "c1" "c2" "check" -permutation "r1" "w2" "w3" "r2" "p3" "c3" "p2" "p1" "c2" "c1" "check" -permutation "r1" "w2" "w3" "r2" "p3" "c3" "p2" "c2" "p1" "c1" "check" -permutation "r1" "w2" "w3" "p1" "r2" "p2" "p3" "c3" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p1" "r2" "p2" "p3" "c3" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p1" "r2" "p3" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p1" "r2" "p3" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p1" "r2" "p3" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p1" "r2" "p3" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p1" "r2" "p3" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w2" "w3" "p1" "p3" "r2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p1" "p3" "r2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p1" "p3" "r2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p1" "p3" "r2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p1" "p3" "r2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w2" "w3" "p1" "p3" "c3" "r2" "p2" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p1" "p3" "c3" "r2" "p2" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p1" "p3" "c3" "r2" "c1" "p2" "c2" "check" -permutation "r1" "w2" "w3" "p1" "p3" "c3" "c1" "r2" "p2" "c2" "check" -permutation "r1" "w2" "w3" "p3" "r2" "p1" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p3" "r2" "p1" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p3" "r2" "p1" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p3" "r2" "p1" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p3" "r2" "p1" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w2" "w3" "p3" "r2" "p2" "p1" "c3" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p3" "r2" "p2" "p1" "c3" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p3" "r2" "p2" "c3" "p1" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p3" "r2" "p2" "c3" "p1" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p3" "r2" "p2" "c3" "c2" "p1" "c1" "check" -permutation "r1" "w2" "w3" "p3" "r2" "c3" "p1" "p2" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p3" "r2" "c3" "p1" "p2" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p3" "r2" "c3" "p1" "c1" "p2" "c2" "check" -permutation "r1" "w2" "w3" "p3" "r2" "c3" "p2" "p1" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p3" "r2" "c3" "p2" "p1" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p3" "r2" "c3" "p2" "c2" "p1" "c1" "check" -permutation "r1" "w2" "w3" "p3" "p1" "r2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p3" "p1" "r2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p3" "p1" "r2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p3" "p1" "r2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p3" "p1" "r2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w2" "w3" "p3" "p1" "c3" "r2" "p2" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p3" "p1" "c3" "r2" "p2" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p3" "p1" "c3" "r2" "c1" "p2" "c2" "check" -permutation "r1" "w2" "w3" "p3" "p1" "c3" "c1" "r2" "p2" "c2" "check" -permutation "r1" "w2" "w3" "p3" "c3" "r2" "p1" "p2" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p3" "c3" "r2" "p1" "p2" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p3" "c3" "r2" "p1" "c1" "p2" "c2" "check" -permutation "r1" "w2" "w3" "p3" "c3" "r2" "p2" "p1" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p3" "c3" "r2" "p2" "p1" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p3" "c3" "r2" "p2" "c2" "p1" "c1" "check" -permutation "r1" "w2" "w3" "p3" "c3" "p1" "r2" "p2" "c1" "c2" "check" -permutation "r1" "w2" "w3" "p3" "c3" "p1" "r2" "p2" "c2" "c1" "check" -permutation "r1" "w2" "w3" "p3" "c3" "p1" "r2" "c1" "p2" "c2" "check" -permutation "r1" "w2" "w3" "p3" "c3" "p1" "c1" "r2" "p2" "c2" "check" -permutation "r1" "w2" "p1" "w3" "r2" "p2" "p3" "c3" "c1" "c2" "check" -permutation "r1" "w2" "p1" "w3" "r2" "p2" "p3" "c3" "c2" "c1" "check" -permutation "r1" "w2" "p1" "w3" "r2" "p3" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w2" "p1" "w3" "r2" "p3" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w2" "p1" "w3" "r2" "p3" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w2" "p1" "w3" "r2" "p3" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w2" "p1" "w3" "r2" "p3" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w2" "p1" "w3" "p3" "r2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w2" "p1" "w3" "p3" "r2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w2" "p1" "w3" "p3" "r2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w2" "p1" "w3" "p3" "r2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w2" "p1" "w3" "p3" "r2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w2" "p1" "w3" "p3" "c3" "r2" "p2" "c1" "c2" "check" -permutation "r1" "w2" "p1" "w3" "p3" "c3" "r2" "p2" "c2" "c1" "check" -permutation "r1" "w2" "p1" "w3" "p3" "c3" "r2" "c1" "p2" "c2" "check" -permutation "r1" "w2" "p1" "w3" "p3" "c3" "c1" "r2" "p2" "c2" "check" -permutation "r1" "w3" "r2" "w2" "p1" "p2" "p3" "c3" "c1" "c2" "check" -permutation "r1" "w3" "r2" "w2" "p1" "p2" "p3" "c3" "c2" "c1" "check" -permutation "r1" "w3" "r2" "w2" "p1" "p3" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "r2" "w2" "p1" "p3" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "r2" "w2" "p1" "p3" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "r2" "w2" "p1" "p3" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "r2" "w2" "p1" "p3" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "r2" "w2" "p2" "p1" "p3" "c3" "c1" "c2" "check" -permutation "r1" "w3" "r2" "w2" "p2" "p1" "p3" "c3" "c2" "c1" "check" -permutation "r1" "w3" "r2" "w2" "p2" "p3" "p1" "c3" "c1" "c2" "check" -permutation "r1" "w3" "r2" "w2" "p2" "p3" "p1" "c3" "c2" "c1" "check" -permutation "r1" "w3" "r2" "w2" "p2" "p3" "c3" "p1" "c1" "c2" "check" -permutation "r1" "w3" "r2" "w2" "p2" "p3" "c3" "p1" "c2" "c1" "check" -permutation "r1" "w3" "r2" "w2" "p2" "p3" "c3" "c2" "p1" "c1" "check" -permutation "r1" "w3" "r2" "w2" "p3" "p1" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "r2" "w2" "p3" "p1" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "r2" "w2" "p3" "p1" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "r2" "w2" "p3" "p1" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "r2" "w2" "p3" "p1" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "r2" "w2" "p3" "p2" "p1" "c3" "c1" "c2" "check" -permutation "r1" "w3" "r2" "w2" "p3" "p2" "p1" "c3" "c2" "c1" "check" -permutation "r1" "w3" "r2" "w2" "p3" "p2" "c3" "p1" "c1" "c2" "check" -permutation "r1" "w3" "r2" "w2" "p3" "p2" "c3" "p1" "c2" "c1" "check" -permutation "r1" "w3" "r2" "w2" "p3" "p2" "c3" "c2" "p1" "c1" "check" -permutation "r1" "w3" "r2" "w2" "p3" "c3" "p1" "p2" "c1" "c2" "check" -permutation "r1" "w3" "r2" "w2" "p3" "c3" "p1" "p2" "c2" "c1" "check" -permutation "r1" "w3" "r2" "w2" "p3" "c3" "p1" "c1" "p2" "c2" "check" -permutation "r1" "w3" "r2" "w2" "p3" "c3" "p2" "p1" "c1" "c2" "check" -permutation "r1" "w3" "r2" "w2" "p3" "c3" "p2" "p1" "c2" "c1" "check" -permutation "r1" "w3" "r2" "w2" "p3" "c3" "p2" "c2" "p1" "c1" "check" -permutation "r1" "w3" "r2" "p1" "w2" "p2" "p3" "c3" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p1" "w2" "p2" "p3" "c3" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p1" "w2" "p3" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p1" "w2" "p3" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p1" "w2" "p3" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p1" "w2" "p3" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p1" "w2" "p3" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "r2" "p1" "p3" "w2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p1" "p3" "w2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p1" "p3" "w2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p1" "p3" "w2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p1" "p3" "w2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "r2" "p1" "p3" "c3" "w2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p1" "p3" "c3" "w2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p1" "p3" "c3" "w2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "r2" "p1" "p3" "c3" "c1" "w2" "p2" "c2" "check" -permutation "r1" "w3" "r2" "p3" "w2" "p1" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p3" "w2" "p1" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p3" "w2" "p1" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p3" "w2" "p1" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p3" "w2" "p1" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "r2" "p3" "w2" "p2" "p1" "c3" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p3" "w2" "p2" "p1" "c3" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p3" "w2" "p2" "c3" "p1" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p3" "w2" "p2" "c3" "p1" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p3" "w2" "p2" "c3" "c2" "p1" "c1" "check" -permutation "r1" "w3" "r2" "p3" "w2" "c3" "p1" "p2" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p3" "w2" "c3" "p1" "p2" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p3" "w2" "c3" "p1" "c1" "p2" "c2" "check" -permutation "r1" "w3" "r2" "p3" "w2" "c3" "p2" "p1" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p3" "w2" "c3" "p2" "p1" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p3" "w2" "c3" "p2" "c2" "p1" "c1" "check" -permutation "r1" "w3" "r2" "p3" "p1" "w2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p3" "p1" "w2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p3" "p1" "w2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p3" "p1" "w2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p3" "p1" "w2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "r2" "p3" "p1" "c3" "w2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p3" "p1" "c3" "w2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p3" "p1" "c3" "w2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "r2" "p3" "p1" "c3" "c1" "w2" "p2" "c2" "check" -permutation "r1" "w3" "r2" "p3" "c3" "w2" "p1" "p2" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p3" "c3" "w2" "p1" "p2" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p3" "c3" "w2" "p1" "c1" "p2" "c2" "check" -permutation "r1" "w3" "r2" "p3" "c3" "w2" "p2" "p1" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p3" "c3" "w2" "p2" "p1" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p3" "c3" "w2" "p2" "c2" "p1" "c1" "check" -permutation "r1" "w3" "r2" "p3" "c3" "p1" "w2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "r2" "p3" "c3" "p1" "w2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "r2" "p3" "c3" "p1" "w2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "r2" "p3" "c3" "p1" "c1" "w2" "p2" "c2" "check" -permutation "r1" "w3" "w2" "r2" "p1" "p2" "p3" "c3" "c1" "c2" "check" -permutation "r1" "w3" "w2" "r2" "p1" "p2" "p3" "c3" "c2" "c1" "check" -permutation "r1" "w3" "w2" "r2" "p1" "p3" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "w2" "r2" "p1" "p3" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "w2" "r2" "p1" "p3" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "w2" "r2" "p1" "p3" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "w2" "r2" "p1" "p3" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "w2" "r2" "p2" "p1" "p3" "c3" "c1" "c2" "check" -permutation "r1" "w3" "w2" "r2" "p2" "p1" "p3" "c3" "c2" "c1" "check" -permutation "r1" "w3" "w2" "r2" "p2" "p3" "p1" "c3" "c1" "c2" "check" -permutation "r1" "w3" "w2" "r2" "p2" "p3" "p1" "c3" "c2" "c1" "check" -permutation "r1" "w3" "w2" "r2" "p2" "p3" "c3" "p1" "c1" "c2" "check" -permutation "r1" "w3" "w2" "r2" "p2" "p3" "c3" "p1" "c2" "c1" "check" -permutation "r1" "w3" "w2" "r2" "p2" "p3" "c3" "c2" "p1" "c1" "check" -permutation "r1" "w3" "w2" "r2" "p3" "p1" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "w2" "r2" "p3" "p1" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "w2" "r2" "p3" "p1" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "w2" "r2" "p3" "p1" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "w2" "r2" "p3" "p1" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "w2" "r2" "p3" "p2" "p1" "c3" "c1" "c2" "check" -permutation "r1" "w3" "w2" "r2" "p3" "p2" "p1" "c3" "c2" "c1" "check" -permutation "r1" "w3" "w2" "r2" "p3" "p2" "c3" "p1" "c1" "c2" "check" -permutation "r1" "w3" "w2" "r2" "p3" "p2" "c3" "p1" "c2" "c1" "check" -permutation "r1" "w3" "w2" "r2" "p3" "p2" "c3" "c2" "p1" "c1" "check" -permutation "r1" "w3" "w2" "r2" "p3" "c3" "p1" "p2" "c1" "c2" "check" -permutation "r1" "w3" "w2" "r2" "p3" "c3" "p1" "p2" "c2" "c1" "check" -permutation "r1" "w3" "w2" "r2" "p3" "c3" "p1" "c1" "p2" "c2" "check" -permutation "r1" "w3" "w2" "r2" "p3" "c3" "p2" "p1" "c1" "c2" "check" -permutation "r1" "w3" "w2" "r2" "p3" "c3" "p2" "p1" "c2" "c1" "check" -permutation "r1" "w3" "w2" "r2" "p3" "c3" "p2" "c2" "p1" "c1" "check" -permutation "r1" "w3" "w2" "p1" "r2" "p2" "p3" "c3" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p1" "r2" "p2" "p3" "c3" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p1" "r2" "p3" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p1" "r2" "p3" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p1" "r2" "p3" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p1" "r2" "p3" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p1" "r2" "p3" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "w2" "p1" "p3" "r2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p1" "p3" "r2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p1" "p3" "r2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p1" "p3" "r2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p1" "p3" "r2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "w2" "p1" "p3" "c3" "r2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p1" "p3" "c3" "r2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p1" "p3" "c3" "r2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "w2" "p1" "p3" "c3" "c1" "r2" "p2" "c2" "check" -permutation "r1" "w3" "w2" "p3" "r2" "p1" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p3" "r2" "p1" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p3" "r2" "p1" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p3" "r2" "p1" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p3" "r2" "p1" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "w2" "p3" "r2" "p2" "p1" "c3" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p3" "r2" "p2" "p1" "c3" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p3" "r2" "p2" "c3" "p1" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p3" "r2" "p2" "c3" "p1" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p3" "r2" "p2" "c3" "c2" "p1" "c1" "check" -permutation "r1" "w3" "w2" "p3" "r2" "c3" "p1" "p2" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p3" "r2" "c3" "p1" "p2" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p3" "r2" "c3" "p1" "c1" "p2" "c2" "check" -permutation "r1" "w3" "w2" "p3" "r2" "c3" "p2" "p1" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p3" "r2" "c3" "p2" "p1" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p3" "r2" "c3" "p2" "c2" "p1" "c1" "check" -permutation "r1" "w3" "w2" "p3" "p1" "r2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p3" "p1" "r2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p3" "p1" "r2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p3" "p1" "r2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p3" "p1" "r2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "w2" "p3" "p1" "c3" "r2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p3" "p1" "c3" "r2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p3" "p1" "c3" "r2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "w2" "p3" "p1" "c3" "c1" "r2" "p2" "c2" "check" -permutation "r1" "w3" "w2" "p3" "c3" "r2" "p1" "p2" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p3" "c3" "r2" "p1" "p2" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p3" "c3" "r2" "p1" "c1" "p2" "c2" "check" -permutation "r1" "w3" "w2" "p3" "c3" "r2" "p2" "p1" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p3" "c3" "r2" "p2" "p1" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p3" "c3" "r2" "p2" "c2" "p1" "c1" "check" -permutation "r1" "w3" "w2" "p3" "c3" "p1" "r2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "w2" "p3" "c3" "p1" "r2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "w2" "p3" "c3" "p1" "r2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "w2" "p3" "c3" "p1" "c1" "r2" "p2" "c2" "check" -permutation "r1" "w3" "p1" "r2" "w2" "p2" "p3" "c3" "c1" "c2" "check" -permutation "r1" "w3" "p1" "r2" "w2" "p2" "p3" "c3" "c2" "c1" "check" -permutation "r1" "w3" "p1" "r2" "w2" "p3" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "p1" "r2" "w2" "p3" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "p1" "r2" "w2" "p3" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p1" "r2" "w2" "p3" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p1" "r2" "w2" "p3" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p1" "r2" "p3" "w2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "p1" "r2" "p3" "w2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "p1" "r2" "p3" "w2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p1" "r2" "p3" "w2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p1" "r2" "p3" "w2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p1" "r2" "p3" "c3" "w2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p1" "r2" "p3" "c3" "w2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p1" "r2" "p3" "c3" "w2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p1" "r2" "p3" "c3" "c1" "w2" "p2" "c2" "check" -permutation "r1" "w3" "p1" "w2" "r2" "p2" "p3" "c3" "c1" "c2" "check" -permutation "r1" "w3" "p1" "w2" "r2" "p2" "p3" "c3" "c2" "c1" "check" -permutation "r1" "w3" "p1" "w2" "r2" "p3" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "p1" "w2" "r2" "p3" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "p1" "w2" "r2" "p3" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p1" "w2" "r2" "p3" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p1" "w2" "r2" "p3" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p1" "w2" "p3" "r2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "p1" "w2" "p3" "r2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "p1" "w2" "p3" "r2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p1" "w2" "p3" "r2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p1" "w2" "p3" "r2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p1" "w2" "p3" "c3" "r2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p1" "w2" "p3" "c3" "r2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p1" "w2" "p3" "c3" "r2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p1" "w2" "p3" "c3" "c1" "r2" "p2" "c2" "check" -permutation "r1" "w3" "p1" "p3" "r2" "w2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "p1" "p3" "r2" "w2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "p1" "p3" "r2" "w2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p1" "p3" "r2" "w2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p1" "p3" "r2" "w2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p1" "p3" "r2" "c3" "w2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p1" "p3" "r2" "c3" "w2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p1" "p3" "r2" "c3" "w2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p1" "p3" "r2" "c3" "c1" "w2" "p2" "c2" "check" -permutation "r1" "w3" "p1" "p3" "w2" "r2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "p1" "p3" "w2" "r2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "p1" "p3" "w2" "r2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p1" "p3" "w2" "r2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p1" "p3" "w2" "r2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p1" "p3" "w2" "c3" "r2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p1" "p3" "w2" "c3" "r2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p1" "p3" "w2" "c3" "r2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p1" "p3" "w2" "c3" "c1" "r2" "p2" "c2" "check" -permutation "r1" "w3" "p1" "p3" "c3" "r2" "w2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p1" "p3" "c3" "r2" "w2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p1" "p3" "c3" "r2" "w2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p1" "p3" "c3" "r2" "c1" "w2" "p2" "c2" "check" -permutation "r1" "w3" "p1" "p3" "c3" "w2" "r2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p1" "p3" "c3" "w2" "r2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p1" "p3" "c3" "w2" "r2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p1" "p3" "c3" "w2" "c1" "r2" "p2" "c2" "check" -permutation "r1" "w3" "p1" "p3" "c3" "c1" "r2" "w2" "p2" "c2" "check" -permutation "r1" "w3" "p1" "p3" "c3" "c1" "w2" "r2" "p2" "c2" "check" -permutation "r1" "w3" "p3" "r2" "w2" "p1" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "p3" "r2" "w2" "p1" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "p3" "r2" "w2" "p1" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "r2" "w2" "p1" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "r2" "w2" "p1" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "r2" "w2" "p2" "p1" "c3" "c1" "c2" "check" -permutation "r1" "w3" "p3" "r2" "w2" "p2" "p1" "c3" "c2" "c1" "check" -permutation "r1" "w3" "p3" "r2" "w2" "p2" "c3" "p1" "c1" "c2" "check" -permutation "r1" "w3" "p3" "r2" "w2" "p2" "c3" "p1" "c2" "c1" "check" -permutation "r1" "w3" "p3" "r2" "w2" "p2" "c3" "c2" "p1" "c1" "check" -permutation "r1" "w3" "p3" "r2" "w2" "c3" "p1" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "r2" "w2" "c3" "p1" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "r2" "w2" "c3" "p1" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "r2" "w2" "c3" "p2" "p1" "c1" "c2" "check" -permutation "r1" "w3" "p3" "r2" "w2" "c3" "p2" "p1" "c2" "c1" "check" -permutation "r1" "w3" "p3" "r2" "w2" "c3" "p2" "c2" "p1" "c1" "check" -permutation "r1" "w3" "p3" "r2" "p1" "w2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "p3" "r2" "p1" "w2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "p3" "r2" "p1" "w2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "r2" "p1" "w2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "r2" "p1" "w2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "r2" "p1" "c3" "w2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "r2" "p1" "c3" "w2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "r2" "p1" "c3" "w2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "r2" "p1" "c3" "c1" "w2" "p2" "c2" "check" -permutation "r1" "w3" "p3" "r2" "c3" "w2" "p1" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "r2" "c3" "w2" "p1" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "r2" "c3" "w2" "p1" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "r2" "c3" "w2" "p2" "p1" "c1" "c2" "check" -permutation "r1" "w3" "p3" "r2" "c3" "w2" "p2" "p1" "c2" "c1" "check" -permutation "r1" "w3" "p3" "r2" "c3" "w2" "p2" "c2" "p1" "c1" "check" -permutation "r1" "w3" "p3" "r2" "c3" "p1" "w2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "r2" "c3" "p1" "w2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "r2" "c3" "p1" "w2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "r2" "c3" "p1" "c1" "w2" "p2" "c2" "check" -permutation "r1" "w3" "p3" "w2" "r2" "p1" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "p3" "w2" "r2" "p1" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "p3" "w2" "r2" "p1" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "w2" "r2" "p1" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "w2" "r2" "p1" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "w2" "r2" "p2" "p1" "c3" "c1" "c2" "check" -permutation "r1" "w3" "p3" "w2" "r2" "p2" "p1" "c3" "c2" "c1" "check" -permutation "r1" "w3" "p3" "w2" "r2" "p2" "c3" "p1" "c1" "c2" "check" -permutation "r1" "w3" "p3" "w2" "r2" "p2" "c3" "p1" "c2" "c1" "check" -permutation "r1" "w3" "p3" "w2" "r2" "p2" "c3" "c2" "p1" "c1" "check" -permutation "r1" "w3" "p3" "w2" "r2" "c3" "p1" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "w2" "r2" "c3" "p1" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "w2" "r2" "c3" "p1" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "w2" "r2" "c3" "p2" "p1" "c1" "c2" "check" -permutation "r1" "w3" "p3" "w2" "r2" "c3" "p2" "p1" "c2" "c1" "check" -permutation "r1" "w3" "p3" "w2" "r2" "c3" "p2" "c2" "p1" "c1" "check" -permutation "r1" "w3" "p3" "w2" "p1" "r2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "p3" "w2" "p1" "r2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "p3" "w2" "p1" "r2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "w2" "p1" "r2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "w2" "p1" "r2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "w2" "p1" "c3" "r2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "w2" "p1" "c3" "r2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "w2" "p1" "c3" "r2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "w2" "p1" "c3" "c1" "r2" "p2" "c2" "check" -permutation "r1" "w3" "p3" "w2" "c3" "r2" "p1" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "w2" "c3" "r2" "p1" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "w2" "c3" "r2" "p1" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "w2" "c3" "r2" "p2" "p1" "c1" "c2" "check" -permutation "r1" "w3" "p3" "w2" "c3" "r2" "p2" "p1" "c2" "c1" "check" -permutation "r1" "w3" "p3" "w2" "c3" "r2" "p2" "c2" "p1" "c1" "check" -permutation "r1" "w3" "p3" "w2" "c3" "p1" "r2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "w2" "c3" "p1" "r2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "w2" "c3" "p1" "r2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "w2" "c3" "p1" "c1" "r2" "p2" "c2" "check" -permutation "r1" "w3" "p3" "p1" "r2" "w2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "p3" "p1" "r2" "w2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "p3" "p1" "r2" "w2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "p1" "r2" "w2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "p1" "r2" "w2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "p1" "r2" "c3" "w2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "p1" "r2" "c3" "w2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "p1" "r2" "c3" "w2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "p1" "r2" "c3" "c1" "w2" "p2" "c2" "check" -permutation "r1" "w3" "p3" "p1" "w2" "r2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "w3" "p3" "p1" "w2" "r2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "w3" "p3" "p1" "w2" "r2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "p1" "w2" "r2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "p1" "w2" "r2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "p1" "w2" "c3" "r2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "p1" "w2" "c3" "r2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "p1" "w2" "c3" "r2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "p1" "w2" "c3" "c1" "r2" "p2" "c2" "check" -permutation "r1" "w3" "p3" "p1" "c3" "r2" "w2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "p1" "c3" "r2" "w2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "p1" "c3" "r2" "w2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "p1" "c3" "r2" "c1" "w2" "p2" "c2" "check" -permutation "r1" "w3" "p3" "p1" "c3" "w2" "r2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "p1" "c3" "w2" "r2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "p1" "c3" "w2" "r2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "p1" "c3" "w2" "c1" "r2" "p2" "c2" "check" -permutation "r1" "w3" "p3" "p1" "c3" "c1" "r2" "w2" "p2" "c2" "check" -permutation "r1" "w3" "p3" "p1" "c3" "c1" "w2" "r2" "p2" "c2" "check" -permutation "r1" "w3" "p3" "c3" "r2" "w2" "p1" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "c3" "r2" "w2" "p1" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "c3" "r2" "w2" "p1" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "c3" "r2" "w2" "p2" "p1" "c1" "c2" "check" -permutation "r1" "w3" "p3" "c3" "r2" "w2" "p2" "p1" "c2" "c1" "check" -permutation "r1" "w3" "p3" "c3" "r2" "w2" "p2" "c2" "p1" "c1" "check" -permutation "r1" "w3" "p3" "c3" "r2" "p1" "w2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "c3" "r2" "p1" "w2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "c3" "r2" "p1" "w2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "c3" "r2" "p1" "c1" "w2" "p2" "c2" "check" -permutation "r1" "w3" "p3" "c3" "w2" "r2" "p1" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "c3" "w2" "r2" "p1" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "c3" "w2" "r2" "p1" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "c3" "w2" "r2" "p2" "p1" "c1" "c2" "check" -permutation "r1" "w3" "p3" "c3" "w2" "r2" "p2" "p1" "c2" "c1" "check" -permutation "r1" "w3" "p3" "c3" "w2" "r2" "p2" "c2" "p1" "c1" "check" -permutation "r1" "w3" "p3" "c3" "w2" "p1" "r2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "c3" "w2" "p1" "r2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "c3" "w2" "p1" "r2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "c3" "w2" "p1" "c1" "r2" "p2" "c2" "check" -permutation "r1" "w3" "p3" "c3" "p1" "r2" "w2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "c3" "p1" "r2" "w2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "c3" "p1" "r2" "w2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "c3" "p1" "r2" "c1" "w2" "p2" "c2" "check" -permutation "r1" "w3" "p3" "c3" "p1" "w2" "r2" "p2" "c1" "c2" "check" -permutation "r1" "w3" "p3" "c3" "p1" "w2" "r2" "p2" "c2" "c1" "check" -permutation "r1" "w3" "p3" "c3" "p1" "w2" "r2" "c1" "p2" "c2" "check" -permutation "r1" "w3" "p3" "c3" "p1" "w2" "c1" "r2" "p2" "c2" "check" -permutation "r1" "w3" "p3" "c3" "p1" "c1" "r2" "w2" "p2" "c2" "check" -permutation "r1" "w3" "p3" "c3" "p1" "c1" "w2" "r2" "p2" "c2" "check" -permutation "r1" "p1" "r2" "w2" "w3" "p2" "p3" "c3" "c1" "c2" "check" -permutation "r1" "p1" "r2" "w2" "w3" "p2" "p3" "c3" "c2" "c1" "check" -permutation "r1" "p1" "r2" "w2" "w3" "p3" "p2" "c3" "c1" "c2" "check" -permutation "r1" "p1" "r2" "w2" "w3" "p3" "p2" "c3" "c2" "c1" "check" -permutation "r1" "p1" "r2" "w2" "w3" "p3" "c3" "p2" "c1" "c2" "check" -permutation "r1" "p1" "r2" "w2" "w3" "p3" "c3" "p2" "c2" "c1" "check" -permutation "r1" "p1" "r2" "w2" "w3" "p3" "c3" "c1" "p2" "c2" "check" -permutation "r1" "p1" "r2" "w2" "p2" "w3" "p3" "c3" "c1" "c2" "check" -permutation "r1" "p1" "r2" "w2" "p2" "w3" "p3" "c3" "c2" "c1" "check" -permutation "r1" "p1" "w2" "w3" "r2" "p2" "p3" "c3" "c1" "c2" "check" -permutation "r1" "p1" "w2" "w3" "r2" "p2" "p3" "c3" "c2" "c1" "check" -permutation "r1" "p1" "w2" "w3" "r2" "p3" "p2" "c3" "c1" "c2" "check" -permutation "r1" "p1" "w2" "w3" "r2" "p3" "p2" "c3" "c2" "c1" "check" -permutation "r1" "p1" "w2" "w3" "r2" "p3" "c3" "p2" "c1" "c2" "check" -permutation "r1" "p1" "w2" "w3" "r2" "p3" "c3" "p2" "c2" "c1" "check" -permutation "r1" "p1" "w2" "w3" "r2" "p3" "c3" "c1" "p2" "c2" "check" -permutation "r1" "p1" "w2" "w3" "p3" "r2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "p1" "w2" "w3" "p3" "r2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "p1" "w2" "w3" "p3" "r2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "p1" "w2" "w3" "p3" "r2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "p1" "w2" "w3" "p3" "r2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "p1" "w2" "w3" "p3" "c3" "r2" "p2" "c1" "c2" "check" -permutation "r1" "p1" "w2" "w3" "p3" "c3" "r2" "p2" "c2" "c1" "check" -permutation "r1" "p1" "w2" "w3" "p3" "c3" "r2" "c1" "p2" "c2" "check" -permutation "r1" "p1" "w2" "w3" "p3" "c3" "c1" "r2" "p2" "c2" "check" -permutation "r1" "p1" "w3" "r2" "w2" "p2" "p3" "c3" "c1" "c2" "check" -permutation "r1" "p1" "w3" "r2" "w2" "p2" "p3" "c3" "c2" "c1" "check" -permutation "r1" "p1" "w3" "r2" "w2" "p3" "p2" "c3" "c1" "c2" "check" -permutation "r1" "p1" "w3" "r2" "w2" "p3" "p2" "c3" "c2" "c1" "check" -permutation "r1" "p1" "w3" "r2" "w2" "p3" "c3" "p2" "c1" "c2" "check" -permutation "r1" "p1" "w3" "r2" "w2" "p3" "c3" "p2" "c2" "c1" "check" -permutation "r1" "p1" "w3" "r2" "w2" "p3" "c3" "c1" "p2" "c2" "check" -permutation "r1" "p1" "w3" "r2" "p3" "w2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "p1" "w3" "r2" "p3" "w2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "p1" "w3" "r2" "p3" "w2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "p1" "w3" "r2" "p3" "w2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "p1" "w3" "r2" "p3" "w2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "p1" "w3" "r2" "p3" "c3" "w2" "p2" "c1" "c2" "check" -permutation "r1" "p1" "w3" "r2" "p3" "c3" "w2" "p2" "c2" "c1" "check" -permutation "r1" "p1" "w3" "r2" "p3" "c3" "w2" "c1" "p2" "c2" "check" -permutation "r1" "p1" "w3" "r2" "p3" "c3" "c1" "w2" "p2" "c2" "check" -permutation "r1" "p1" "w3" "w2" "r2" "p2" "p3" "c3" "c1" "c2" "check" -permutation "r1" "p1" "w3" "w2" "r2" "p2" "p3" "c3" "c2" "c1" "check" -permutation "r1" "p1" "w3" "w2" "r2" "p3" "p2" "c3" "c1" "c2" "check" -permutation "r1" "p1" "w3" "w2" "r2" "p3" "p2" "c3" "c2" "c1" "check" -permutation "r1" "p1" "w3" "w2" "r2" "p3" "c3" "p2" "c1" "c2" "check" -permutation "r1" "p1" "w3" "w2" "r2" "p3" "c3" "p2" "c2" "c1" "check" -permutation "r1" "p1" "w3" "w2" "r2" "p3" "c3" "c1" "p2" "c2" "check" -permutation "r1" "p1" "w3" "w2" "p3" "r2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "p1" "w3" "w2" "p3" "r2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "p1" "w3" "w2" "p3" "r2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "p1" "w3" "w2" "p3" "r2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "p1" "w3" "w2" "p3" "r2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "p1" "w3" "w2" "p3" "c3" "r2" "p2" "c1" "c2" "check" -permutation "r1" "p1" "w3" "w2" "p3" "c3" "r2" "p2" "c2" "c1" "check" -permutation "r1" "p1" "w3" "w2" "p3" "c3" "r2" "c1" "p2" "c2" "check" -permutation "r1" "p1" "w3" "w2" "p3" "c3" "c1" "r2" "p2" "c2" "check" -permutation "r1" "p1" "w3" "p3" "r2" "w2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "p1" "w3" "p3" "r2" "w2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "p1" "w3" "p3" "r2" "w2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "p1" "w3" "p3" "r2" "w2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "p1" "w3" "p3" "r2" "w2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "p1" "w3" "p3" "r2" "c3" "w2" "p2" "c1" "c2" "check" -permutation "r1" "p1" "w3" "p3" "r2" "c3" "w2" "p2" "c2" "c1" "check" -permutation "r1" "p1" "w3" "p3" "r2" "c3" "w2" "c1" "p2" "c2" "check" -permutation "r1" "p1" "w3" "p3" "r2" "c3" "c1" "w2" "p2" "c2" "check" -permutation "r1" "p1" "w3" "p3" "w2" "r2" "p2" "c3" "c1" "c2" "check" -permutation "r1" "p1" "w3" "p3" "w2" "r2" "p2" "c3" "c2" "c1" "check" -permutation "r1" "p1" "w3" "p3" "w2" "r2" "c3" "p2" "c1" "c2" "check" -permutation "r1" "p1" "w3" "p3" "w2" "r2" "c3" "p2" "c2" "c1" "check" -permutation "r1" "p1" "w3" "p3" "w2" "r2" "c3" "c1" "p2" "c2" "check" -permutation "r1" "p1" "w3" "p3" "w2" "c3" "r2" "p2" "c1" "c2" "check" -permutation "r1" "p1" "w3" "p3" "w2" "c3" "r2" "p2" "c2" "c1" "check" -permutation "r1" "p1" "w3" "p3" "w2" "c3" "r2" "c1" "p2" "c2" "check" -permutation "r1" "p1" "w3" "p3" "w2" "c3" "c1" "r2" "p2" "c2" "check" -permutation "r1" "p1" "w3" "p3" "c3" "r2" "w2" "p2" "c1" "c2" "check" -permutation "r1" "p1" "w3" "p3" "c3" "r2" "w2" "p2" "c2" "c1" "check" -permutation "r1" "p1" "w3" "p3" "c3" "r2" "w2" "c1" "p2" "c2" "check" -permutation "r1" "p1" "w3" "p3" "c3" "r2" "c1" "w2" "p2" "c2" "check" -permutation "r1" "p1" "w3" "p3" "c3" "w2" "r2" "p2" "c1" "c2" "check" -permutation "r1" "p1" "w3" "p3" "c3" "w2" "r2" "p2" "c2" "c1" "check" -permutation "r1" "p1" "w3" "p3" "c3" "w2" "r2" "c1" "p2" "c2" "check" -permutation "r1" "p1" "w3" "p3" "c3" "w2" "c1" "r2" "p2" "c2" "check" -permutation "r1" "p1" "w3" "p3" "c3" "c1" "r2" "w2" "p2" "c2" "check" -permutation "r1" "p1" "w3" "p3" "c3" "c1" "w2" "r2" "p2" "c2" "check" -permutation "w2" "r1" "r2" "w3" "p1" "p2" "p3" "c3" "c1" "c2" "check" -permutation "w2" "r1" "r2" "w3" "p1" "p2" "p3" "c3" "c2" "c1" "check" -permutation "w2" "r1" "r2" "w3" "p1" "p3" "p2" "c3" "c1" "c2" "check" -permutation "w2" "r1" "r2" "w3" "p1" "p3" "p2" "c3" "c2" "c1" "check" -permutation "w2" "r1" "r2" "w3" "p1" "p3" "c3" "p2" "c1" "c2" "check" -permutation "w2" "r1" "r2" "w3" "p1" "p3" "c3" "p2" "c2" "c1" "check" -permutation "w2" "r1" "r2" "w3" "p1" "p3" "c3" "c1" "p2" "c2" "check" -permutation "w2" "r1" "r2" "w3" "p2" "p1" "p3" "c3" "c1" "c2" "check" -permutation "w2" "r1" "r2" "w3" "p2" "p1" "p3" "c3" "c2" "c1" "check" -permutation "w2" "r1" "r2" "w3" "p2" "p3" "p1" "c3" "c1" "c2" "check" -permutation "w2" "r1" "r2" "w3" "p2" "p3" "p1" "c3" "c2" "c1" "check" -permutation "w2" "r1" "r2" "w3" "p2" "p3" "c3" "p1" "c1" "c2" "check" -permutation "w2" "r1" "r2" "w3" "p2" "p3" "c3" "p1" "c2" "c1" "check" -permutation "w2" "r1" "r2" "w3" "p2" "p3" "c3" "c2" "p1" "c1" "check" -permutation "w2" "r1" "r2" "w3" "p3" "p1" "p2" "c3" "c1" "c2" "check" -permutation "w2" "r1" "r2" "w3" "p3" "p1" "p2" "c3" "c2" "c1" "check" -permutation "w2" "r1" "r2" "w3" "p3" "p1" "c3" "p2" "c1" "c2" "check" -permutation "w2" "r1" "r2" "w3" "p3" "p1" "c3" "p2" "c2" "c1" "check" -permutation "w2" "r1" "r2" "w3" "p3" "p1" "c3" "c1" "p2" "c2" "check" -permutation "w2" "r1" "r2" "w3" "p3" "p2" "p1" "c3" "c1" "c2" "check" -permutation "w2" "r1" "r2" "w3" "p3" "p2" "p1" "c3" "c2" "c1" "check" -permutation "w2" "r1" "r2" "w3" "p3" "p2" "c3" "p1" "c1" "c2" "check" -permutation "w2" "r1" "r2" "w3" "p3" "p2" "c3" "p1" "c2" "c1" "check" -permutation "w2" "r1" "r2" "w3" "p3" "p2" "c3" "c2" "p1" "c1" "check" -permutation "w2" "r1" "r2" "w3" "p3" "c3" "p1" "p2" "c1" "c2" "check" -permutation "w2" "r1" "r2" "w3" "p3" "c3" "p1" "p2" "c2" "c1" "check" -permutation "w2" "r1" "r2" "w3" "p3" "c3" "p1" "c1" "p2" "c2" "check" -permutation "w2" "r1" "r2" "w3" "p3" "c3" "p2" "p1" "c1" "c2" "check" -permutation "w2" "r1" "r2" "w3" "p3" "c3" "p2" "p1" "c2" "c1" "check" -permutation "w2" "r1" "r2" "w3" "p3" "c3" "p2" "c2" "p1" "c1" "check" -permutation "w2" "r1" "r2" "p1" "w3" "p2" "p3" "c3" "c1" "c2" "check" -permutation "w2" "r1" "r2" "p1" "w3" "p2" "p3" "c3" "c2" "c1" "check" -permutation "w2" "r1" "r2" "p1" "w3" "p3" "p2" "c3" "c1" "c2" "check" -permutation "w2" "r1" "r2" "p1" "w3" "p3" "p2" "c3" "c2" "c1" "check" -permutation "w2" "r1" "r2" "p1" "w3" "p3" "c3" "p2" "c1" "c2" "check" -permutation "w2" "r1" "r2" "p1" "w3" "p3" "c3" "p2" "c2" "c1" "check" -permutation "w2" "r1" "r2" "p1" "w3" "p3" "c3" "c1" "p2" "c2" "check" -permutation "w2" "r1" "r2" "p1" "p2" "w3" "p3" "c3" "c1" "c2" "check" -permutation "w2" "r1" "r2" "p1" "p2" "w3" "p3" "c3" "c2" "c1" "check" -permutation "w2" "r1" "r2" "p2" "w3" "p1" "p3" "c3" "c1" "c2" "check" -permutation "w2" "r1" "r2" "p2" "w3" "p1" "p3" "c3" "c2" "c1" "check" -permutation "w2" "r1" "r2" "p2" "w3" "p3" "p1" "c3" "c1" "c2" "check" -permutation "w2" "r1" "r2" "p2" "w3" "p3" "p1" "c3" "c2" "c1" "check" -permutation "w2" "r1" "r2" "p2" "w3" "p3" "c3" "p1" "c1" "c2" "check" -permutation "w2" "r1" "r2" "p2" "w3" "p3" "c3" "p1" "c2" "c1" "check" -permutation "w2" "r1" "r2" "p2" "w3" "p3" "c3" "c2" "p1" "c1" "check" -permutation "w2" "r1" "r2" "p2" "p1" "w3" "p3" "c3" "c1" "c2" "check" -permutation "w2" "r1" "r2" "p2" "p1" "w3" "p3" "c3" "c2" "c1" "check" -permutation "w2" "r1" "w3" "r2" "p1" "p2" "p3" "c3" "c1" "c2" "check" -permutation "w2" "r1" "w3" "r2" "p1" "p2" "p3" "c3" "c2" "c1" "check" -permutation "w2" "r1" "w3" "r2" "p1" "p3" "p2" "c3" "c1" "c2" "check" -permutation "w2" "r1" "w3" "r2" "p1" "p3" "p2" "c3" "c2" "c1" "check" -permutation "w2" "r1" "w3" "r2" "p1" "p3" "c3" "p2" "c1" "c2" "check" -permutation "w2" "r1" "w3" "r2" "p1" "p3" "c3" "p2" "c2" "c1" "check" -permutation "w2" "r1" "w3" "r2" "p1" "p3" "c3" "c1" "p2" "c2" "check" -permutation "w2" "r1" "w3" "r2" "p2" "p1" "p3" "c3" "c1" "c2" "check" -permutation "w2" "r1" "w3" "r2" "p2" "p1" "p3" "c3" "c2" "c1" "check" -permutation "w2" "r1" "w3" "r2" "p2" "p3" "p1" "c3" "c1" "c2" "check" -permutation "w2" "r1" "w3" "r2" "p2" "p3" "p1" "c3" "c2" "c1" "check" -permutation "w2" "r1" "w3" "r2" "p2" "p3" "c3" "p1" "c1" "c2" "check" -permutation "w2" "r1" "w3" "r2" "p2" "p3" "c3" "p1" "c2" "c1" "check" -permutation "w2" "r1" "w3" "r2" "p2" "p3" "c3" "c2" "p1" "c1" "check" -permutation "w2" "r1" "w3" "r2" "p3" "p1" "p2" "c3" "c1" "c2" "check" -permutation "w2" "r1" "w3" "r2" "p3" "p1" "p2" "c3" "c2" "c1" "check" -permutation "w2" "r1" "w3" "r2" "p3" "p1" "c3" "p2" "c1" "c2" "check" -permutation "w2" "r1" "w3" "r2" "p3" "p1" "c3" "p2" "c2" "c1" "check" -permutation "w2" "r1" "w3" "r2" "p3" "p1" "c3" "c1" "p2" "c2" "check" -permutation "w2" "r1" "w3" "r2" "p3" "p2" "p1" "c3" "c1" "c2" "check" -permutation "w2" "r1" "w3" "r2" "p3" "p2" "p1" "c3" "c2" "c1" "check" -permutation "w2" "r1" "w3" "r2" "p3" "p2" "c3" "p1" "c1" "c2" "check" -permutation "w2" "r1" "w3" "r2" "p3" "p2" "c3" "p1" "c2" "c1" "check" -permutation "w2" "r1" "w3" "r2" "p3" "p2" "c3" "c2" "p1" "c1" "check" -permutation "w2" "r1" "w3" "r2" "p3" "c3" "p1" "p2" "c1" "c2" "check" -permutation "w2" "r1" "w3" "r2" "p3" "c3" "p1" "p2" "c2" "c1" "check" -permutation "w2" "r1" "w3" "r2" "p3" "c3" "p1" "c1" "p2" "c2" "check" -permutation "w2" "r1" "w3" "r2" "p3" "c3" "p2" "p1" "c1" "c2" "check" -permutation "w2" "r1" "w3" "r2" "p3" "c3" "p2" "p1" "c2" "c1" "check" -permutation "w2" "r1" "w3" "r2" "p3" "c3" "p2" "c2" "p1" "c1" "check" -permutation "w2" "r1" "w3" "p1" "r2" "p2" "p3" "c3" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p1" "r2" "p2" "p3" "c3" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p1" "r2" "p3" "p2" "c3" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p1" "r2" "p3" "p2" "c3" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p1" "r2" "p3" "c3" "p2" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p1" "r2" "p3" "c3" "p2" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p1" "r2" "p3" "c3" "c1" "p2" "c2" "check" -permutation "w2" "r1" "w3" "p1" "p3" "r2" "p2" "c3" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p1" "p3" "r2" "p2" "c3" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p1" "p3" "r2" "c3" "p2" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p1" "p3" "r2" "c3" "p2" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p1" "p3" "r2" "c3" "c1" "p2" "c2" "check" -permutation "w2" "r1" "w3" "p1" "p3" "c3" "r2" "p2" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p1" "p3" "c3" "r2" "p2" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p1" "p3" "c3" "r2" "c1" "p2" "c2" "check" -permutation "w2" "r1" "w3" "p1" "p3" "c3" "c1" "r2" "p2" "c2" "check" -permutation "w2" "r1" "w3" "p3" "r2" "p1" "p2" "c3" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p3" "r2" "p1" "p2" "c3" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p3" "r2" "p1" "c3" "p2" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p3" "r2" "p1" "c3" "p2" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p3" "r2" "p1" "c3" "c1" "p2" "c2" "check" -permutation "w2" "r1" "w3" "p3" "r2" "p2" "p1" "c3" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p3" "r2" "p2" "p1" "c3" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p3" "r2" "p2" "c3" "p1" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p3" "r2" "p2" "c3" "p1" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p3" "r2" "p2" "c3" "c2" "p1" "c1" "check" -permutation "w2" "r1" "w3" "p3" "r2" "c3" "p1" "p2" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p3" "r2" "c3" "p1" "p2" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p3" "r2" "c3" "p1" "c1" "p2" "c2" "check" -permutation "w2" "r1" "w3" "p3" "r2" "c3" "p2" "p1" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p3" "r2" "c3" "p2" "p1" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p3" "r2" "c3" "p2" "c2" "p1" "c1" "check" -permutation "w2" "r1" "w3" "p3" "p1" "r2" "p2" "c3" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p3" "p1" "r2" "p2" "c3" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p3" "p1" "r2" "c3" "p2" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p3" "p1" "r2" "c3" "p2" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p3" "p1" "r2" "c3" "c1" "p2" "c2" "check" -permutation "w2" "r1" "w3" "p3" "p1" "c3" "r2" "p2" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p3" "p1" "c3" "r2" "p2" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p3" "p1" "c3" "r2" "c1" "p2" "c2" "check" -permutation "w2" "r1" "w3" "p3" "p1" "c3" "c1" "r2" "p2" "c2" "check" -permutation "w2" "r1" "w3" "p3" "c3" "r2" "p1" "p2" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p3" "c3" "r2" "p1" "p2" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p3" "c3" "r2" "p1" "c1" "p2" "c2" "check" -permutation "w2" "r1" "w3" "p3" "c3" "r2" "p2" "p1" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p3" "c3" "r2" "p2" "p1" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p3" "c3" "r2" "p2" "c2" "p1" "c1" "check" -permutation "w2" "r1" "w3" "p3" "c3" "p1" "r2" "p2" "c1" "c2" "check" -permutation "w2" "r1" "w3" "p3" "c3" "p1" "r2" "p2" "c2" "c1" "check" -permutation "w2" "r1" "w3" "p3" "c3" "p1" "r2" "c1" "p2" "c2" "check" -permutation "w2" "r1" "w3" "p3" "c3" "p1" "c1" "r2" "p2" "c2" "check" -permutation "w2" "r1" "p1" "r2" "w3" "p2" "p3" "c3" "c1" "c2" "check" -permutation "w2" "r1" "p1" "r2" "w3" "p2" "p3" "c3" "c2" "c1" "check" -permutation "w2" "r1" "p1" "r2" "w3" "p3" "p2" "c3" "c1" "c2" "check" -permutation "w2" "r1" "p1" "r2" "w3" "p3" "p2" "c3" "c2" "c1" "check" -permutation "w2" "r1" "p1" "r2" "w3" "p3" "c3" "p2" "c1" "c2" "check" -permutation "w2" "r1" "p1" "r2" "w3" "p3" "c3" "p2" "c2" "c1" "check" -permutation "w2" "r1" "p1" "r2" "w3" "p3" "c3" "c1" "p2" "c2" "check" -permutation "w2" "r1" "p1" "r2" "p2" "w3" "p3" "c3" "c1" "c2" "check" -permutation "w2" "r1" "p1" "r2" "p2" "w3" "p3" "c3" "c2" "c1" "check" -permutation "w2" "r1" "p1" "w3" "r2" "p2" "p3" "c3" "c1" "c2" "check" -permutation "w2" "r1" "p1" "w3" "r2" "p2" "p3" "c3" "c2" "c1" "check" -permutation "w2" "r1" "p1" "w3" "r2" "p3" "p2" "c3" "c1" "c2" "check" -permutation "w2" "r1" "p1" "w3" "r2" "p3" "p2" "c3" "c2" "c1" "check" -permutation "w2" "r1" "p1" "w3" "r2" "p3" "c3" "p2" "c1" "c2" "check" -permutation "w2" "r1" "p1" "w3" "r2" "p3" "c3" "p2" "c2" "c1" "check" -permutation "w2" "r1" "p1" "w3" "r2" "p3" "c3" "c1" "p2" "c2" "check" -permutation "w2" "r1" "p1" "w3" "p3" "r2" "p2" "c3" "c1" "c2" "check" -permutation "w2" "r1" "p1" "w3" "p3" "r2" "p2" "c3" "c2" "c1" "check" -permutation "w2" "r1" "p1" "w3" "p3" "r2" "c3" "p2" "c1" "c2" "check" -permutation "w2" "r1" "p1" "w3" "p3" "r2" "c3" "p2" "c2" "c1" "check" -permutation "w2" "r1" "p1" "w3" "p3" "r2" "c3" "c1" "p2" "c2" "check" -permutation "w2" "r1" "p1" "w3" "p3" "c3" "r2" "p2" "c1" "c2" "check" -permutation "w2" "r1" "p1" "w3" "p3" "c3" "r2" "p2" "c2" "c1" "check" -permutation "w2" "r1" "p1" "w3" "p3" "c3" "r2" "c1" "p2" "c2" "check" -permutation "w2" "r1" "p1" "w3" "p3" "c3" "c1" "r2" "p2" "c2" "check" -permutation "w3" "r1" "r2" "w2" "p1" "p2" "p3" "c3" "c1" "c2" "check" -permutation "w3" "r1" "r2" "w2" "p1" "p2" "p3" "c3" "c2" "c1" "check" -permutation "w3" "r1" "r2" "w2" "p1" "p3" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "r2" "w2" "p1" "p3" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "r2" "w2" "p1" "p3" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "r2" "w2" "p1" "p3" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "r2" "w2" "p1" "p3" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "r2" "w2" "p2" "p1" "p3" "c3" "c1" "c2" "check" -permutation "w3" "r1" "r2" "w2" "p2" "p1" "p3" "c3" "c2" "c1" "check" -permutation "w3" "r1" "r2" "w2" "p2" "p3" "p1" "c3" "c1" "c2" "check" -permutation "w3" "r1" "r2" "w2" "p2" "p3" "p1" "c3" "c2" "c1" "check" -permutation "w3" "r1" "r2" "w2" "p2" "p3" "c3" "p1" "c1" "c2" "check" -permutation "w3" "r1" "r2" "w2" "p2" "p3" "c3" "p1" "c2" "c1" "check" -permutation "w3" "r1" "r2" "w2" "p2" "p3" "c3" "c2" "p1" "c1" "check" -permutation "w3" "r1" "r2" "w2" "p3" "p1" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "r2" "w2" "p3" "p1" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "r2" "w2" "p3" "p1" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "r2" "w2" "p3" "p1" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "r2" "w2" "p3" "p1" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "r2" "w2" "p3" "p2" "p1" "c3" "c1" "c2" "check" -permutation "w3" "r1" "r2" "w2" "p3" "p2" "p1" "c3" "c2" "c1" "check" -permutation "w3" "r1" "r2" "w2" "p3" "p2" "c3" "p1" "c1" "c2" "check" -permutation "w3" "r1" "r2" "w2" "p3" "p2" "c3" "p1" "c2" "c1" "check" -permutation "w3" "r1" "r2" "w2" "p3" "p2" "c3" "c2" "p1" "c1" "check" -permutation "w3" "r1" "r2" "w2" "p3" "c3" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r1" "r2" "w2" "p3" "c3" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r1" "r2" "w2" "p3" "c3" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r1" "r2" "w2" "p3" "c3" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r1" "r2" "w2" "p3" "c3" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r1" "r2" "w2" "p3" "c3" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r1" "r2" "p1" "w2" "p2" "p3" "c3" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p1" "w2" "p2" "p3" "c3" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p1" "w2" "p3" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p1" "w2" "p3" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p1" "w2" "p3" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p1" "w2" "p3" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p1" "w2" "p3" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "r2" "p1" "p3" "w2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p1" "p3" "w2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p1" "p3" "w2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p1" "p3" "w2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p1" "p3" "w2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "r2" "p1" "p3" "c3" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p1" "p3" "c3" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p1" "p3" "c3" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "r2" "p1" "p3" "c3" "c1" "w2" "p2" "c2" "check" -permutation "w3" "r1" "r2" "p3" "w2" "p1" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p3" "w2" "p1" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p3" "w2" "p1" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p3" "w2" "p1" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p3" "w2" "p1" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "r2" "p3" "w2" "p2" "p1" "c3" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p3" "w2" "p2" "p1" "c3" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p3" "w2" "p2" "c3" "p1" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p3" "w2" "p2" "c3" "p1" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p3" "w2" "p2" "c3" "c2" "p1" "c1" "check" -permutation "w3" "r1" "r2" "p3" "w2" "c3" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p3" "w2" "c3" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p3" "w2" "c3" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r1" "r2" "p3" "w2" "c3" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p3" "w2" "c3" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p3" "w2" "c3" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r1" "r2" "p3" "p1" "w2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p3" "p1" "w2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p3" "p1" "w2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p3" "p1" "w2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p3" "p1" "w2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "r2" "p3" "p1" "c3" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p3" "p1" "c3" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p3" "p1" "c3" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "r2" "p3" "p1" "c3" "c1" "w2" "p2" "c2" "check" -permutation "w3" "r1" "r2" "p3" "c3" "w2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p3" "c3" "w2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p3" "c3" "w2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r1" "r2" "p3" "c3" "w2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p3" "c3" "w2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p3" "c3" "w2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r1" "r2" "p3" "c3" "p1" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "r2" "p3" "c3" "p1" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "r2" "p3" "c3" "p1" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "r2" "p3" "c3" "p1" "c1" "w2" "p2" "c2" "check" -permutation "w3" "r1" "w2" "r2" "p1" "p2" "p3" "c3" "c1" "c2" "check" -permutation "w3" "r1" "w2" "r2" "p1" "p2" "p3" "c3" "c2" "c1" "check" -permutation "w3" "r1" "w2" "r2" "p1" "p3" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "w2" "r2" "p1" "p3" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "w2" "r2" "p1" "p3" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "w2" "r2" "p1" "p3" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "w2" "r2" "p1" "p3" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "w2" "r2" "p2" "p1" "p3" "c3" "c1" "c2" "check" -permutation "w3" "r1" "w2" "r2" "p2" "p1" "p3" "c3" "c2" "c1" "check" -permutation "w3" "r1" "w2" "r2" "p2" "p3" "p1" "c3" "c1" "c2" "check" -permutation "w3" "r1" "w2" "r2" "p2" "p3" "p1" "c3" "c2" "c1" "check" -permutation "w3" "r1" "w2" "r2" "p2" "p3" "c3" "p1" "c1" "c2" "check" -permutation "w3" "r1" "w2" "r2" "p2" "p3" "c3" "p1" "c2" "c1" "check" -permutation "w3" "r1" "w2" "r2" "p2" "p3" "c3" "c2" "p1" "c1" "check" -permutation "w3" "r1" "w2" "r2" "p3" "p1" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "w2" "r2" "p3" "p1" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "w2" "r2" "p3" "p1" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "w2" "r2" "p3" "p1" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "w2" "r2" "p3" "p1" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "w2" "r2" "p3" "p2" "p1" "c3" "c1" "c2" "check" -permutation "w3" "r1" "w2" "r2" "p3" "p2" "p1" "c3" "c2" "c1" "check" -permutation "w3" "r1" "w2" "r2" "p3" "p2" "c3" "p1" "c1" "c2" "check" -permutation "w3" "r1" "w2" "r2" "p3" "p2" "c3" "p1" "c2" "c1" "check" -permutation "w3" "r1" "w2" "r2" "p3" "p2" "c3" "c2" "p1" "c1" "check" -permutation "w3" "r1" "w2" "r2" "p3" "c3" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r1" "w2" "r2" "p3" "c3" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r1" "w2" "r2" "p3" "c3" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r1" "w2" "r2" "p3" "c3" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r1" "w2" "r2" "p3" "c3" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r1" "w2" "r2" "p3" "c3" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r1" "w2" "p1" "r2" "p2" "p3" "c3" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p1" "r2" "p2" "p3" "c3" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p1" "r2" "p3" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p1" "r2" "p3" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p1" "r2" "p3" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p1" "r2" "p3" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p1" "r2" "p3" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "w2" "p1" "p3" "r2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p1" "p3" "r2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p1" "p3" "r2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p1" "p3" "r2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p1" "p3" "r2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "w2" "p1" "p3" "c3" "r2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p1" "p3" "c3" "r2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p1" "p3" "c3" "r2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "w2" "p1" "p3" "c3" "c1" "r2" "p2" "c2" "check" -permutation "w3" "r1" "w2" "p3" "r2" "p1" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p3" "r2" "p1" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p3" "r2" "p1" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p3" "r2" "p1" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p3" "r2" "p1" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "w2" "p3" "r2" "p2" "p1" "c3" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p3" "r2" "p2" "p1" "c3" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p3" "r2" "p2" "c3" "p1" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p3" "r2" "p2" "c3" "p1" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p3" "r2" "p2" "c3" "c2" "p1" "c1" "check" -permutation "w3" "r1" "w2" "p3" "r2" "c3" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p3" "r2" "c3" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p3" "r2" "c3" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r1" "w2" "p3" "r2" "c3" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p3" "r2" "c3" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p3" "r2" "c3" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r1" "w2" "p3" "p1" "r2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p3" "p1" "r2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p3" "p1" "r2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p3" "p1" "r2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p3" "p1" "r2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "w2" "p3" "p1" "c3" "r2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p3" "p1" "c3" "r2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p3" "p1" "c3" "r2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "w2" "p3" "p1" "c3" "c1" "r2" "p2" "c2" "check" -permutation "w3" "r1" "w2" "p3" "c3" "r2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p3" "c3" "r2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p3" "c3" "r2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r1" "w2" "p3" "c3" "r2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p3" "c3" "r2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p3" "c3" "r2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r1" "w2" "p3" "c3" "p1" "r2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "w2" "p3" "c3" "p1" "r2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "w2" "p3" "c3" "p1" "r2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "w2" "p3" "c3" "p1" "c1" "r2" "p2" "c2" "check" -permutation "w3" "r1" "p1" "r2" "w2" "p2" "p3" "c3" "c1" "c2" "check" -permutation "w3" "r1" "p1" "r2" "w2" "p2" "p3" "c3" "c2" "c1" "check" -permutation "w3" "r1" "p1" "r2" "w2" "p3" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "p1" "r2" "w2" "p3" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "p1" "r2" "w2" "p3" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p1" "r2" "w2" "p3" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p1" "r2" "w2" "p3" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p1" "r2" "p3" "w2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "p1" "r2" "p3" "w2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "p1" "r2" "p3" "w2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p1" "r2" "p3" "w2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p1" "r2" "p3" "w2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p1" "r2" "p3" "c3" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p1" "r2" "p3" "c3" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p1" "r2" "p3" "c3" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p1" "r2" "p3" "c3" "c1" "w2" "p2" "c2" "check" -permutation "w3" "r1" "p1" "w2" "r2" "p2" "p3" "c3" "c1" "c2" "check" -permutation "w3" "r1" "p1" "w2" "r2" "p2" "p3" "c3" "c2" "c1" "check" -permutation "w3" "r1" "p1" "w2" "r2" "p3" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "p1" "w2" "r2" "p3" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "p1" "w2" "r2" "p3" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p1" "w2" "r2" "p3" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p1" "w2" "r2" "p3" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p1" "w2" "p3" "r2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "p1" "w2" "p3" "r2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "p1" "w2" "p3" "r2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p1" "w2" "p3" "r2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p1" "w2" "p3" "r2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p1" "w2" "p3" "c3" "r2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p1" "w2" "p3" "c3" "r2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p1" "w2" "p3" "c3" "r2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p1" "w2" "p3" "c3" "c1" "r2" "p2" "c2" "check" -permutation "w3" "r1" "p1" "p3" "r2" "w2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "p1" "p3" "r2" "w2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "p1" "p3" "r2" "w2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p1" "p3" "r2" "w2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p1" "p3" "r2" "w2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p1" "p3" "r2" "c3" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p1" "p3" "r2" "c3" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p1" "p3" "r2" "c3" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p1" "p3" "r2" "c3" "c1" "w2" "p2" "c2" "check" -permutation "w3" "r1" "p1" "p3" "w2" "r2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "p1" "p3" "w2" "r2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "p1" "p3" "w2" "r2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p1" "p3" "w2" "r2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p1" "p3" "w2" "r2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p1" "p3" "w2" "c3" "r2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p1" "p3" "w2" "c3" "r2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p1" "p3" "w2" "c3" "r2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p1" "p3" "w2" "c3" "c1" "r2" "p2" "c2" "check" -permutation "w3" "r1" "p1" "p3" "c3" "r2" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p1" "p3" "c3" "r2" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p1" "p3" "c3" "r2" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p1" "p3" "c3" "r2" "c1" "w2" "p2" "c2" "check" -permutation "w3" "r1" "p1" "p3" "c3" "w2" "r2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p1" "p3" "c3" "w2" "r2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p1" "p3" "c3" "w2" "r2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p1" "p3" "c3" "w2" "c1" "r2" "p2" "c2" "check" -permutation "w3" "r1" "p1" "p3" "c3" "c1" "r2" "w2" "p2" "c2" "check" -permutation "w3" "r1" "p1" "p3" "c3" "c1" "w2" "r2" "p2" "c2" "check" -permutation "w3" "r1" "p3" "r2" "w2" "p1" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "p3" "r2" "w2" "p1" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "p3" "r2" "w2" "p1" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "r2" "w2" "p1" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "r2" "w2" "p1" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "r2" "w2" "p2" "p1" "c3" "c1" "c2" "check" -permutation "w3" "r1" "p3" "r2" "w2" "p2" "p1" "c3" "c2" "c1" "check" -permutation "w3" "r1" "p3" "r2" "w2" "p2" "c3" "p1" "c1" "c2" "check" -permutation "w3" "r1" "p3" "r2" "w2" "p2" "c3" "p1" "c2" "c1" "check" -permutation "w3" "r1" "p3" "r2" "w2" "p2" "c3" "c2" "p1" "c1" "check" -permutation "w3" "r1" "p3" "r2" "w2" "c3" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "r2" "w2" "c3" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "r2" "w2" "c3" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "r2" "w2" "c3" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r1" "p3" "r2" "w2" "c3" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r1" "p3" "r2" "w2" "c3" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r1" "p3" "r2" "p1" "w2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "p3" "r2" "p1" "w2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "p3" "r2" "p1" "w2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "r2" "p1" "w2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "r2" "p1" "w2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "r2" "p1" "c3" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "r2" "p1" "c3" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "r2" "p1" "c3" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "r2" "p1" "c3" "c1" "w2" "p2" "c2" "check" -permutation "w3" "r1" "p3" "r2" "c3" "w2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "r2" "c3" "w2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "r2" "c3" "w2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "r2" "c3" "w2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r1" "p3" "r2" "c3" "w2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r1" "p3" "r2" "c3" "w2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r1" "p3" "r2" "c3" "p1" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "r2" "c3" "p1" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "r2" "c3" "p1" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "r2" "c3" "p1" "c1" "w2" "p2" "c2" "check" -permutation "w3" "r1" "p3" "w2" "r2" "p1" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "p3" "w2" "r2" "p1" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "p3" "w2" "r2" "p1" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "w2" "r2" "p1" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "w2" "r2" "p1" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "w2" "r2" "p2" "p1" "c3" "c1" "c2" "check" -permutation "w3" "r1" "p3" "w2" "r2" "p2" "p1" "c3" "c2" "c1" "check" -permutation "w3" "r1" "p3" "w2" "r2" "p2" "c3" "p1" "c1" "c2" "check" -permutation "w3" "r1" "p3" "w2" "r2" "p2" "c3" "p1" "c2" "c1" "check" -permutation "w3" "r1" "p3" "w2" "r2" "p2" "c3" "c2" "p1" "c1" "check" -permutation "w3" "r1" "p3" "w2" "r2" "c3" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "w2" "r2" "c3" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "w2" "r2" "c3" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "w2" "r2" "c3" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r1" "p3" "w2" "r2" "c3" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r1" "p3" "w2" "r2" "c3" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r1" "p3" "w2" "p1" "r2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "p3" "w2" "p1" "r2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "p3" "w2" "p1" "r2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "w2" "p1" "r2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "w2" "p1" "r2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "w2" "p1" "c3" "r2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "w2" "p1" "c3" "r2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "w2" "p1" "c3" "r2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "w2" "p1" "c3" "c1" "r2" "p2" "c2" "check" -permutation "w3" "r1" "p3" "w2" "c3" "r2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "w2" "c3" "r2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "w2" "c3" "r2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "w2" "c3" "r2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r1" "p3" "w2" "c3" "r2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r1" "p3" "w2" "c3" "r2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r1" "p3" "w2" "c3" "p1" "r2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "w2" "c3" "p1" "r2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "w2" "c3" "p1" "r2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "w2" "c3" "p1" "c1" "r2" "p2" "c2" "check" -permutation "w3" "r1" "p3" "p1" "r2" "w2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "p3" "p1" "r2" "w2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "p3" "p1" "r2" "w2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "p1" "r2" "w2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "p1" "r2" "w2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "p1" "r2" "c3" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "p1" "r2" "c3" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "p1" "r2" "c3" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "p1" "r2" "c3" "c1" "w2" "p2" "c2" "check" -permutation "w3" "r1" "p3" "p1" "w2" "r2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r1" "p3" "p1" "w2" "r2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r1" "p3" "p1" "w2" "r2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "p1" "w2" "r2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "p1" "w2" "r2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "p1" "w2" "c3" "r2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "p1" "w2" "c3" "r2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "p1" "w2" "c3" "r2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "p1" "w2" "c3" "c1" "r2" "p2" "c2" "check" -permutation "w3" "r1" "p3" "p1" "c3" "r2" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "p1" "c3" "r2" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "p1" "c3" "r2" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "p1" "c3" "r2" "c1" "w2" "p2" "c2" "check" -permutation "w3" "r1" "p3" "p1" "c3" "w2" "r2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "p1" "c3" "w2" "r2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "p1" "c3" "w2" "r2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "p1" "c3" "w2" "c1" "r2" "p2" "c2" "check" -permutation "w3" "r1" "p3" "p1" "c3" "c1" "r2" "w2" "p2" "c2" "check" -permutation "w3" "r1" "p3" "p1" "c3" "c1" "w2" "r2" "p2" "c2" "check" -permutation "w3" "r1" "p3" "c3" "r2" "w2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "c3" "r2" "w2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "c3" "r2" "w2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "c3" "r2" "w2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r1" "p3" "c3" "r2" "w2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r1" "p3" "c3" "r2" "w2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r1" "p3" "c3" "r2" "p1" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "c3" "r2" "p1" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "c3" "r2" "p1" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "c3" "r2" "p1" "c1" "w2" "p2" "c2" "check" -permutation "w3" "r1" "p3" "c3" "w2" "r2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "c3" "w2" "r2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "c3" "w2" "r2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "c3" "w2" "r2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r1" "p3" "c3" "w2" "r2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r1" "p3" "c3" "w2" "r2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r1" "p3" "c3" "w2" "p1" "r2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "c3" "w2" "p1" "r2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "c3" "w2" "p1" "r2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "c3" "w2" "p1" "c1" "r2" "p2" "c2" "check" -permutation "w3" "r1" "p3" "c3" "p1" "r2" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "c3" "p1" "r2" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "c3" "p1" "r2" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "c3" "p1" "r2" "c1" "w2" "p2" "c2" "check" -permutation "w3" "r1" "p3" "c3" "p1" "w2" "r2" "p2" "c1" "c2" "check" -permutation "w3" "r1" "p3" "c3" "p1" "w2" "r2" "p2" "c2" "c1" "check" -permutation "w3" "r1" "p3" "c3" "p1" "w2" "r2" "c1" "p2" "c2" "check" -permutation "w3" "r1" "p3" "c3" "p1" "w2" "c1" "r2" "p2" "c2" "check" -permutation "w3" "r1" "p3" "c3" "p1" "c1" "r2" "w2" "p2" "c2" "check" -permutation "w3" "r1" "p3" "c3" "p1" "c1" "w2" "r2" "p2" "c2" "check" -permutation "w3" "r2" "r1" "w2" "p1" "p2" "p3" "c3" "c1" "c2" "check" -permutation "w3" "r2" "r1" "w2" "p1" "p2" "p3" "c3" "c2" "c1" "check" -permutation "w3" "r2" "r1" "w2" "p1" "p3" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r2" "r1" "w2" "p1" "p3" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r2" "r1" "w2" "p1" "p3" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r2" "r1" "w2" "p1" "p3" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r2" "r1" "w2" "p1" "p3" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r2" "r1" "w2" "p2" "p1" "p3" "c3" "c1" "c2" "check" -permutation "w3" "r2" "r1" "w2" "p2" "p1" "p3" "c3" "c2" "c1" "check" -permutation "w3" "r2" "r1" "w2" "p2" "p3" "p1" "c3" "c1" "c2" "check" -permutation "w3" "r2" "r1" "w2" "p2" "p3" "p1" "c3" "c2" "c1" "check" -permutation "w3" "r2" "r1" "w2" "p2" "p3" "c3" "p1" "c1" "c2" "check" -permutation "w3" "r2" "r1" "w2" "p2" "p3" "c3" "p1" "c2" "c1" "check" -permutation "w3" "r2" "r1" "w2" "p2" "p3" "c3" "c2" "p1" "c1" "check" -permutation "w3" "r2" "r1" "w2" "p3" "p1" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r2" "r1" "w2" "p3" "p1" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r2" "r1" "w2" "p3" "p1" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r2" "r1" "w2" "p3" "p1" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r2" "r1" "w2" "p3" "p1" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r2" "r1" "w2" "p3" "p2" "p1" "c3" "c1" "c2" "check" -permutation "w3" "r2" "r1" "w2" "p3" "p2" "p1" "c3" "c2" "c1" "check" -permutation "w3" "r2" "r1" "w2" "p3" "p2" "c3" "p1" "c1" "c2" "check" -permutation "w3" "r2" "r1" "w2" "p3" "p2" "c3" "p1" "c2" "c1" "check" -permutation "w3" "r2" "r1" "w2" "p3" "p2" "c3" "c2" "p1" "c1" "check" -permutation "w3" "r2" "r1" "w2" "p3" "c3" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r2" "r1" "w2" "p3" "c3" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r2" "r1" "w2" "p3" "c3" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r2" "r1" "w2" "p3" "c3" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r2" "r1" "w2" "p3" "c3" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r2" "r1" "w2" "p3" "c3" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r2" "r1" "p1" "w2" "p2" "p3" "c3" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p1" "w2" "p2" "p3" "c3" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p1" "w2" "p3" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p1" "w2" "p3" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p1" "w2" "p3" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p1" "w2" "p3" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p1" "w2" "p3" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r2" "r1" "p1" "p3" "w2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p1" "p3" "w2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p1" "p3" "w2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p1" "p3" "w2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p1" "p3" "w2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r2" "r1" "p1" "p3" "c3" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p1" "p3" "c3" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p1" "p3" "c3" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r2" "r1" "p1" "p3" "c3" "c1" "w2" "p2" "c2" "check" -permutation "w3" "r2" "r1" "p3" "w2" "p1" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p3" "w2" "p1" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p3" "w2" "p1" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p3" "w2" "p1" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p3" "w2" "p1" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r2" "r1" "p3" "w2" "p2" "p1" "c3" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p3" "w2" "p2" "p1" "c3" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p3" "w2" "p2" "c3" "p1" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p3" "w2" "p2" "c3" "p1" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p3" "w2" "p2" "c3" "c2" "p1" "c1" "check" -permutation "w3" "r2" "r1" "p3" "w2" "c3" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p3" "w2" "c3" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p3" "w2" "c3" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r2" "r1" "p3" "w2" "c3" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p3" "w2" "c3" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p3" "w2" "c3" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r2" "r1" "p3" "p1" "w2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p3" "p1" "w2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p3" "p1" "w2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p3" "p1" "w2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p3" "p1" "w2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r2" "r1" "p3" "p1" "c3" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p3" "p1" "c3" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p3" "p1" "c3" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r2" "r1" "p3" "p1" "c3" "c1" "w2" "p2" "c2" "check" -permutation "w3" "r2" "r1" "p3" "c3" "w2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p3" "c3" "w2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p3" "c3" "w2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r2" "r1" "p3" "c3" "w2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p3" "c3" "w2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p3" "c3" "w2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r2" "r1" "p3" "c3" "p1" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r2" "r1" "p3" "c3" "p1" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r2" "r1" "p3" "c3" "p1" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r2" "r1" "p3" "c3" "p1" "c1" "w2" "p2" "c2" "check" -permutation "w3" "r2" "p3" "r1" "w2" "p1" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r2" "p3" "r1" "w2" "p1" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r2" "p3" "r1" "w2" "p1" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r2" "p3" "r1" "w2" "p1" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r2" "p3" "r1" "w2" "p1" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r2" "p3" "r1" "w2" "p2" "p1" "c3" "c1" "c2" "check" -permutation "w3" "r2" "p3" "r1" "w2" "p2" "p1" "c3" "c2" "c1" "check" -permutation "w3" "r2" "p3" "r1" "w2" "p2" "c3" "p1" "c1" "c2" "check" -permutation "w3" "r2" "p3" "r1" "w2" "p2" "c3" "p1" "c2" "c1" "check" -permutation "w3" "r2" "p3" "r1" "w2" "p2" "c3" "c2" "p1" "c1" "check" -permutation "w3" "r2" "p3" "r1" "w2" "c3" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r2" "p3" "r1" "w2" "c3" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r2" "p3" "r1" "w2" "c3" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r2" "p3" "r1" "w2" "c3" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r2" "p3" "r1" "w2" "c3" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r2" "p3" "r1" "w2" "c3" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r2" "p3" "r1" "p1" "w2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "r2" "p3" "r1" "p1" "w2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "r2" "p3" "r1" "p1" "w2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "r2" "p3" "r1" "p1" "w2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "r2" "p3" "r1" "p1" "w2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "r2" "p3" "r1" "p1" "c3" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r2" "p3" "r1" "p1" "c3" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r2" "p3" "r1" "p1" "c3" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r2" "p3" "r1" "p1" "c3" "c1" "w2" "p2" "c2" "check" -permutation "w3" "r2" "p3" "r1" "c3" "w2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r2" "p3" "r1" "c3" "w2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r2" "p3" "r1" "c3" "w2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r2" "p3" "r1" "c3" "w2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r2" "p3" "r1" "c3" "w2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r2" "p3" "r1" "c3" "w2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r2" "p3" "r1" "c3" "p1" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r2" "p3" "r1" "c3" "p1" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r2" "p3" "r1" "c3" "p1" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r2" "p3" "r1" "c3" "p1" "c1" "w2" "p2" "c2" "check" -permutation "w3" "r2" "p3" "c3" "r1" "w2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "r2" "p3" "c3" "r1" "w2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "r2" "p3" "c3" "r1" "w2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "r2" "p3" "c3" "r1" "w2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "r2" "p3" "c3" "r1" "w2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "r2" "p3" "c3" "r1" "w2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "r2" "p3" "c3" "r1" "p1" "w2" "p2" "c1" "c2" "check" -permutation "w3" "r2" "p3" "c3" "r1" "p1" "w2" "p2" "c2" "c1" "check" -permutation "w3" "r2" "p3" "c3" "r1" "p1" "w2" "c1" "p2" "c2" "check" -permutation "w3" "r2" "p3" "c3" "r1" "p1" "c1" "w2" "p2" "c2" "check" -permutation "w3" "p3" "r1" "r2" "w2" "p1" "p2" "c3" "c1" "c2" "check" -permutation "w3" "p3" "r1" "r2" "w2" "p1" "p2" "c3" "c2" "c1" "check" -permutation "w3" "p3" "r1" "r2" "w2" "p1" "c3" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "r2" "w2" "p1" "c3" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "r2" "w2" "p1" "c3" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "r2" "w2" "p2" "p1" "c3" "c1" "c2" "check" -permutation "w3" "p3" "r1" "r2" "w2" "p2" "p1" "c3" "c2" "c1" "check" -permutation "w3" "p3" "r1" "r2" "w2" "p2" "c3" "p1" "c1" "c2" "check" -permutation "w3" "p3" "r1" "r2" "w2" "p2" "c3" "p1" "c2" "c1" "check" -permutation "w3" "p3" "r1" "r2" "w2" "p2" "c3" "c2" "p1" "c1" "check" -permutation "w3" "p3" "r1" "r2" "w2" "c3" "p1" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "r2" "w2" "c3" "p1" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "r2" "w2" "c3" "p1" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "r2" "w2" "c3" "p2" "p1" "c1" "c2" "check" -permutation "w3" "p3" "r1" "r2" "w2" "c3" "p2" "p1" "c2" "c1" "check" -permutation "w3" "p3" "r1" "r2" "w2" "c3" "p2" "c2" "p1" "c1" "check" -permutation "w3" "p3" "r1" "r2" "p1" "w2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "p3" "r1" "r2" "p1" "w2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "p3" "r1" "r2" "p1" "w2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "r2" "p1" "w2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "r2" "p1" "w2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "r2" "p1" "c3" "w2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "r2" "p1" "c3" "w2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "r2" "p1" "c3" "w2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "r2" "p1" "c3" "c1" "w2" "p2" "c2" "check" -permutation "w3" "p3" "r1" "r2" "c3" "w2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "r2" "c3" "w2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "r2" "c3" "w2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "r2" "c3" "w2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "p3" "r1" "r2" "c3" "w2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "p3" "r1" "r2" "c3" "w2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "p3" "r1" "r2" "c3" "p1" "w2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "r2" "c3" "p1" "w2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "r2" "c3" "p1" "w2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "r2" "c3" "p1" "c1" "w2" "p2" "c2" "check" -permutation "w3" "p3" "r1" "w2" "r2" "p1" "p2" "c3" "c1" "c2" "check" -permutation "w3" "p3" "r1" "w2" "r2" "p1" "p2" "c3" "c2" "c1" "check" -permutation "w3" "p3" "r1" "w2" "r2" "p1" "c3" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "w2" "r2" "p1" "c3" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "w2" "r2" "p1" "c3" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "w2" "r2" "p2" "p1" "c3" "c1" "c2" "check" -permutation "w3" "p3" "r1" "w2" "r2" "p2" "p1" "c3" "c2" "c1" "check" -permutation "w3" "p3" "r1" "w2" "r2" "p2" "c3" "p1" "c1" "c2" "check" -permutation "w3" "p3" "r1" "w2" "r2" "p2" "c3" "p1" "c2" "c1" "check" -permutation "w3" "p3" "r1" "w2" "r2" "p2" "c3" "c2" "p1" "c1" "check" -permutation "w3" "p3" "r1" "w2" "r2" "c3" "p1" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "w2" "r2" "c3" "p1" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "w2" "r2" "c3" "p1" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "w2" "r2" "c3" "p2" "p1" "c1" "c2" "check" -permutation "w3" "p3" "r1" "w2" "r2" "c3" "p2" "p1" "c2" "c1" "check" -permutation "w3" "p3" "r1" "w2" "r2" "c3" "p2" "c2" "p1" "c1" "check" -permutation "w3" "p3" "r1" "w2" "p1" "r2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "p3" "r1" "w2" "p1" "r2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "p3" "r1" "w2" "p1" "r2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "w2" "p1" "r2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "w2" "p1" "r2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "w2" "p1" "c3" "r2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "w2" "p1" "c3" "r2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "w2" "p1" "c3" "r2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "w2" "p1" "c3" "c1" "r2" "p2" "c2" "check" -permutation "w3" "p3" "r1" "w2" "c3" "r2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "w2" "c3" "r2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "w2" "c3" "r2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "w2" "c3" "r2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "p3" "r1" "w2" "c3" "r2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "p3" "r1" "w2" "c3" "r2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "p3" "r1" "w2" "c3" "p1" "r2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "w2" "c3" "p1" "r2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "w2" "c3" "p1" "r2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "w2" "c3" "p1" "c1" "r2" "p2" "c2" "check" -permutation "w3" "p3" "r1" "p1" "r2" "w2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "p3" "r1" "p1" "r2" "w2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "p3" "r1" "p1" "r2" "w2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "p1" "r2" "w2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "p1" "r2" "w2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "p1" "r2" "c3" "w2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "p1" "r2" "c3" "w2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "p1" "r2" "c3" "w2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "p1" "r2" "c3" "c1" "w2" "p2" "c2" "check" -permutation "w3" "p3" "r1" "p1" "w2" "r2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "p3" "r1" "p1" "w2" "r2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "p3" "r1" "p1" "w2" "r2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "p1" "w2" "r2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "p1" "w2" "r2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "p1" "w2" "c3" "r2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "p1" "w2" "c3" "r2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "p1" "w2" "c3" "r2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "p1" "w2" "c3" "c1" "r2" "p2" "c2" "check" -permutation "w3" "p3" "r1" "p1" "c3" "r2" "w2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "p1" "c3" "r2" "w2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "p1" "c3" "r2" "w2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "p1" "c3" "r2" "c1" "w2" "p2" "c2" "check" -permutation "w3" "p3" "r1" "p1" "c3" "w2" "r2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "p1" "c3" "w2" "r2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "p1" "c3" "w2" "r2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "p1" "c3" "w2" "c1" "r2" "p2" "c2" "check" -permutation "w3" "p3" "r1" "p1" "c3" "c1" "r2" "w2" "p2" "c2" "check" -permutation "w3" "p3" "r1" "p1" "c3" "c1" "w2" "r2" "p2" "c2" "check" -permutation "w3" "p3" "r1" "c3" "r2" "w2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "c3" "r2" "w2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "c3" "r2" "w2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "c3" "r2" "w2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "p3" "r1" "c3" "r2" "w2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "p3" "r1" "c3" "r2" "w2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "p3" "r1" "c3" "r2" "p1" "w2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "c3" "r2" "p1" "w2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "c3" "r2" "p1" "w2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "c3" "r2" "p1" "c1" "w2" "p2" "c2" "check" -permutation "w3" "p3" "r1" "c3" "w2" "r2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "c3" "w2" "r2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "c3" "w2" "r2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "c3" "w2" "r2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "p3" "r1" "c3" "w2" "r2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "p3" "r1" "c3" "w2" "r2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "p3" "r1" "c3" "w2" "p1" "r2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "c3" "w2" "p1" "r2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "c3" "w2" "p1" "r2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "c3" "w2" "p1" "c1" "r2" "p2" "c2" "check" -permutation "w3" "p3" "r1" "c3" "p1" "r2" "w2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "c3" "p1" "r2" "w2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "c3" "p1" "r2" "w2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "c3" "p1" "r2" "c1" "w2" "p2" "c2" "check" -permutation "w3" "p3" "r1" "c3" "p1" "w2" "r2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r1" "c3" "p1" "w2" "r2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r1" "c3" "p1" "w2" "r2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r1" "c3" "p1" "w2" "c1" "r2" "p2" "c2" "check" -permutation "w3" "p3" "r1" "c3" "p1" "c1" "r2" "w2" "p2" "c2" "check" -permutation "w3" "p3" "r1" "c3" "p1" "c1" "w2" "r2" "p2" "c2" "check" -permutation "w3" "p3" "r2" "r1" "w2" "p1" "p2" "c3" "c1" "c2" "check" -permutation "w3" "p3" "r2" "r1" "w2" "p1" "p2" "c3" "c2" "c1" "check" -permutation "w3" "p3" "r2" "r1" "w2" "p1" "c3" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r2" "r1" "w2" "p1" "c3" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r2" "r1" "w2" "p1" "c3" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r2" "r1" "w2" "p2" "p1" "c3" "c1" "c2" "check" -permutation "w3" "p3" "r2" "r1" "w2" "p2" "p1" "c3" "c2" "c1" "check" -permutation "w3" "p3" "r2" "r1" "w2" "p2" "c3" "p1" "c1" "c2" "check" -permutation "w3" "p3" "r2" "r1" "w2" "p2" "c3" "p1" "c2" "c1" "check" -permutation "w3" "p3" "r2" "r1" "w2" "p2" "c3" "c2" "p1" "c1" "check" -permutation "w3" "p3" "r2" "r1" "w2" "c3" "p1" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r2" "r1" "w2" "c3" "p1" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r2" "r1" "w2" "c3" "p1" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r2" "r1" "w2" "c3" "p2" "p1" "c1" "c2" "check" -permutation "w3" "p3" "r2" "r1" "w2" "c3" "p2" "p1" "c2" "c1" "check" -permutation "w3" "p3" "r2" "r1" "w2" "c3" "p2" "c2" "p1" "c1" "check" -permutation "w3" "p3" "r2" "r1" "p1" "w2" "p2" "c3" "c1" "c2" "check" -permutation "w3" "p3" "r2" "r1" "p1" "w2" "p2" "c3" "c2" "c1" "check" -permutation "w3" "p3" "r2" "r1" "p1" "w2" "c3" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r2" "r1" "p1" "w2" "c3" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r2" "r1" "p1" "w2" "c3" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r2" "r1" "p1" "c3" "w2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r2" "r1" "p1" "c3" "w2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r2" "r1" "p1" "c3" "w2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r2" "r1" "p1" "c3" "c1" "w2" "p2" "c2" "check" -permutation "w3" "p3" "r2" "r1" "c3" "w2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r2" "r1" "c3" "w2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r2" "r1" "c3" "w2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r2" "r1" "c3" "w2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "p3" "r2" "r1" "c3" "w2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "p3" "r2" "r1" "c3" "w2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "p3" "r2" "r1" "c3" "p1" "w2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r2" "r1" "c3" "p1" "w2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r2" "r1" "c3" "p1" "w2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r2" "r1" "c3" "p1" "c1" "w2" "p2" "c2" "check" -permutation "w3" "p3" "r2" "c3" "r1" "w2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r2" "c3" "r1" "w2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r2" "c3" "r1" "w2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r2" "c3" "r1" "w2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "p3" "r2" "c3" "r1" "w2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "p3" "r2" "c3" "r1" "w2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "p3" "r2" "c3" "r1" "p1" "w2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "r2" "c3" "r1" "p1" "w2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "r2" "c3" "r1" "p1" "w2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "r2" "c3" "r1" "p1" "c1" "w2" "p2" "c2" "check" -permutation "w3" "p3" "c3" "r1" "r2" "w2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "p3" "c3" "r1" "r2" "w2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "p3" "c3" "r1" "r2" "w2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "p3" "c3" "r1" "r2" "w2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "p3" "c3" "r1" "r2" "w2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "p3" "c3" "r1" "r2" "w2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "p3" "c3" "r1" "r2" "p1" "w2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "c3" "r1" "r2" "p1" "w2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "c3" "r1" "r2" "p1" "w2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "c3" "r1" "r2" "p1" "c1" "w2" "p2" "c2" "check" -permutation "w3" "p3" "c3" "r1" "w2" "r2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "p3" "c3" "r1" "w2" "r2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "p3" "c3" "r1" "w2" "r2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "p3" "c3" "r1" "w2" "r2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "p3" "c3" "r1" "w2" "r2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "p3" "c3" "r1" "w2" "r2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "p3" "c3" "r1" "w2" "p1" "r2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "c3" "r1" "w2" "p1" "r2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "c3" "r1" "w2" "p1" "r2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "c3" "r1" "w2" "p1" "c1" "r2" "p2" "c2" "check" -permutation "w3" "p3" "c3" "r1" "p1" "r2" "w2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "c3" "r1" "p1" "r2" "w2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "c3" "r1" "p1" "r2" "w2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "c3" "r1" "p1" "r2" "c1" "w2" "p2" "c2" "check" -permutation "w3" "p3" "c3" "r1" "p1" "w2" "r2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "c3" "r1" "p1" "w2" "r2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "c3" "r1" "p1" "w2" "r2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "c3" "r1" "p1" "w2" "c1" "r2" "p2" "c2" "check" -permutation "w3" "p3" "c3" "r1" "p1" "c1" "r2" "w2" "p2" "c2" "check" -permutation "w3" "p3" "c3" "r1" "p1" "c1" "w2" "r2" "p2" "c2" "check" -permutation "w3" "p3" "c3" "r2" "r1" "w2" "p1" "p2" "c1" "c2" "check" -permutation "w3" "p3" "c3" "r2" "r1" "w2" "p1" "p2" "c2" "c1" "check" -permutation "w3" "p3" "c3" "r2" "r1" "w2" "p1" "c1" "p2" "c2" "check" -permutation "w3" "p3" "c3" "r2" "r1" "w2" "p2" "p1" "c1" "c2" "check" -permutation "w3" "p3" "c3" "r2" "r1" "w2" "p2" "p1" "c2" "c1" "check" -permutation "w3" "p3" "c3" "r2" "r1" "w2" "p2" "c2" "p1" "c1" "check" -permutation "w3" "p3" "c3" "r2" "r1" "p1" "w2" "p2" "c1" "c2" "check" -permutation "w3" "p3" "c3" "r2" "r1" "p1" "w2" "p2" "c2" "c1" "check" -permutation "w3" "p3" "c3" "r2" "r1" "p1" "w2" "c1" "p2" "c2" "check" -permutation "w3" "p3" "c3" "r2" "r1" "p1" "c1" "w2" "p2" "c2" "check" +permutation r1 r2 w2 w3 p1 p2 p3 c3 c1 c2 check +permutation r1 r2 w2 w3 p1 p2 p3 c3 c2 c1 check +permutation r1 r2 w2 w3 p1 p3 p2 c3 c1 c2 check +permutation r1 r2 w2 w3 p1 p3 p2 c3 c2 c1 check +permutation r1 r2 w2 w3 p1 p3 c3 p2 c1 c2 check +permutation r1 r2 w2 w3 p1 p3 c3 p2 c2 c1 check +permutation r1 r2 w2 w3 p1 p3 c3 c1 p2 c2 check +permutation r1 r2 w2 w3 p2 p1 p3 c3 c1 c2 check +permutation r1 r2 w2 w3 p2 p1 p3 c3 c2 c1 check +permutation r1 r2 w2 w3 p2 p3 p1 c3 c1 c2 check +permutation r1 r2 w2 w3 p2 p3 p1 c3 c2 c1 check +permutation r1 r2 w2 w3 p2 p3 c3 p1 c1 c2 check +permutation r1 r2 w2 w3 p2 p3 c3 p1 c2 c1 check +permutation r1 r2 w2 w3 p2 p3 c3 c2 p1 c1 check +permutation r1 r2 w2 w3 p3 p1 p2 c3 c1 c2 check +permutation r1 r2 w2 w3 p3 p1 p2 c3 c2 c1 check +permutation r1 r2 w2 w3 p3 p1 c3 p2 c1 c2 check +permutation r1 r2 w2 w3 p3 p1 c3 p2 c2 c1 check +permutation r1 r2 w2 w3 p3 p1 c3 c1 p2 c2 check +permutation r1 r2 w2 w3 p3 p2 p1 c3 c1 c2 check +permutation r1 r2 w2 w3 p3 p2 p1 c3 c2 c1 check +permutation r1 r2 w2 w3 p3 p2 c3 p1 c1 c2 check +permutation r1 r2 w2 w3 p3 p2 c3 p1 c2 c1 check +permutation r1 r2 w2 w3 p3 p2 c3 c2 p1 c1 check +permutation r1 r2 w2 w3 p3 c3 p1 p2 c1 c2 check +permutation r1 r2 w2 w3 p3 c3 p1 p2 c2 c1 check +permutation r1 r2 w2 w3 p3 c3 p1 c1 p2 c2 check +permutation r1 r2 w2 w3 p3 c3 p2 p1 c1 c2 check +permutation r1 r2 w2 w3 p3 c3 p2 p1 c2 c1 check +permutation r1 r2 w2 w3 p3 c3 p2 c2 p1 c1 check +permutation r1 r2 w2 p1 w3 p2 p3 c3 c1 c2 check +permutation r1 r2 w2 p1 w3 p2 p3 c3 c2 c1 check +permutation r1 r2 w2 p1 w3 p3 p2 c3 c1 c2 check +permutation r1 r2 w2 p1 w3 p3 p2 c3 c2 c1 check +permutation r1 r2 w2 p1 w3 p3 c3 p2 c1 c2 check +permutation r1 r2 w2 p1 w3 p3 c3 p2 c2 c1 check +permutation r1 r2 w2 p1 w3 p3 c3 c1 p2 c2 check +permutation r1 r2 w2 p1 p2 w3 p3 c3 c1 c2 check +permutation r1 r2 w2 p1 p2 w3 p3 c3 c2 c1 check +permutation r1 r2 w2 p2 w3 p1 p3 c3 c1 c2 check +permutation r1 r2 w2 p2 w3 p1 p3 c3 c2 c1 check +permutation r1 r2 w2 p2 w3 p3 p1 c3 c1 c2 check +permutation r1 r2 w2 p2 w3 p3 p1 c3 c2 c1 check +permutation r1 r2 w2 p2 w3 p3 c3 p1 c1 c2 check +permutation r1 r2 w2 p2 w3 p3 c3 p1 c2 c1 check +permutation r1 r2 w2 p2 w3 p3 c3 c2 p1 c1 check +permutation r1 r2 w2 p2 p1 w3 p3 c3 c1 c2 check +permutation r1 r2 w2 p2 p1 w3 p3 c3 c2 c1 check +permutation r1 r2 p1 w2 w3 p2 p3 c3 c1 c2 check +permutation r1 r2 p1 w2 w3 p2 p3 c3 c2 c1 check +permutation r1 r2 p1 w2 w3 p3 p2 c3 c1 c2 check +permutation r1 r2 p1 w2 w3 p3 p2 c3 c2 c1 check +permutation r1 r2 p1 w2 w3 p3 c3 p2 c1 c2 check +permutation r1 r2 p1 w2 w3 p3 c3 p2 c2 c1 check +permutation r1 r2 p1 w2 w3 p3 c3 c1 p2 c2 check +permutation r1 r2 p1 w2 p2 w3 p3 c3 c1 c2 check +permutation r1 r2 p1 w2 p2 w3 p3 c3 c2 c1 check +permutation r1 w2 w3 r2 p1 p2 p3 c3 c1 c2 check +permutation r1 w2 w3 r2 p1 p2 p3 c3 c2 c1 check +permutation r1 w2 w3 r2 p1 p3 p2 c3 c1 c2 check +permutation r1 w2 w3 r2 p1 p3 p2 c3 c2 c1 check +permutation r1 w2 w3 r2 p1 p3 c3 p2 c1 c2 check +permutation r1 w2 w3 r2 p1 p3 c3 p2 c2 c1 check +permutation r1 w2 w3 r2 p1 p3 c3 c1 p2 c2 check +permutation r1 w2 w3 r2 p2 p1 p3 c3 c1 c2 check +permutation r1 w2 w3 r2 p2 p1 p3 c3 c2 c1 check +permutation r1 w2 w3 r2 p2 p3 p1 c3 c1 c2 check +permutation r1 w2 w3 r2 p2 p3 p1 c3 c2 c1 check +permutation r1 w2 w3 r2 p2 p3 c3 p1 c1 c2 check +permutation r1 w2 w3 r2 p2 p3 c3 p1 c2 c1 check +permutation r1 w2 w3 r2 p2 p3 c3 c2 p1 c1 check +permutation r1 w2 w3 r2 p3 p1 p2 c3 c1 c2 check +permutation r1 w2 w3 r2 p3 p1 p2 c3 c2 c1 check +permutation r1 w2 w3 r2 p3 p1 c3 p2 c1 c2 check +permutation r1 w2 w3 r2 p3 p1 c3 p2 c2 c1 check +permutation r1 w2 w3 r2 p3 p1 c3 c1 p2 c2 check +permutation r1 w2 w3 r2 p3 p2 p1 c3 c1 c2 check +permutation r1 w2 w3 r2 p3 p2 p1 c3 c2 c1 check +permutation r1 w2 w3 r2 p3 p2 c3 p1 c1 c2 check +permutation r1 w2 w3 r2 p3 p2 c3 p1 c2 c1 check +permutation r1 w2 w3 r2 p3 p2 c3 c2 p1 c1 check +permutation r1 w2 w3 r2 p3 c3 p1 p2 c1 c2 check +permutation r1 w2 w3 r2 p3 c3 p1 p2 c2 c1 check +permutation r1 w2 w3 r2 p3 c3 p1 c1 p2 c2 check +permutation r1 w2 w3 r2 p3 c3 p2 p1 c1 c2 check +permutation r1 w2 w3 r2 p3 c3 p2 p1 c2 c1 check +permutation r1 w2 w3 r2 p3 c3 p2 c2 p1 c1 check +permutation r1 w2 w3 p1 r2 p2 p3 c3 c1 c2 check +permutation r1 w2 w3 p1 r2 p2 p3 c3 c2 c1 check +permutation r1 w2 w3 p1 r2 p3 p2 c3 c1 c2 check +permutation r1 w2 w3 p1 r2 p3 p2 c3 c2 c1 check +permutation r1 w2 w3 p1 r2 p3 c3 p2 c1 c2 check +permutation r1 w2 w3 p1 r2 p3 c3 p2 c2 c1 check +permutation r1 w2 w3 p1 r2 p3 c3 c1 p2 c2 check +permutation r1 w2 w3 p1 p3 r2 p2 c3 c1 c2 check +permutation r1 w2 w3 p1 p3 r2 p2 c3 c2 c1 check +permutation r1 w2 w3 p1 p3 r2 c3 p2 c1 c2 check +permutation r1 w2 w3 p1 p3 r2 c3 p2 c2 c1 check +permutation r1 w2 w3 p1 p3 r2 c3 c1 p2 c2 check +permutation r1 w2 w3 p1 p3 c3 r2 p2 c1 c2 check +permutation r1 w2 w3 p1 p3 c3 r2 p2 c2 c1 check +permutation r1 w2 w3 p1 p3 c3 r2 c1 p2 c2 check +permutation r1 w2 w3 p1 p3 c3 c1 r2 p2 c2 check +permutation r1 w2 w3 p3 r2 p1 p2 c3 c1 c2 check +permutation r1 w2 w3 p3 r2 p1 p2 c3 c2 c1 check +permutation r1 w2 w3 p3 r2 p1 c3 p2 c1 c2 check +permutation r1 w2 w3 p3 r2 p1 c3 p2 c2 c1 check +permutation r1 w2 w3 p3 r2 p1 c3 c1 p2 c2 check +permutation r1 w2 w3 p3 r2 p2 p1 c3 c1 c2 check +permutation r1 w2 w3 p3 r2 p2 p1 c3 c2 c1 check +permutation r1 w2 w3 p3 r2 p2 c3 p1 c1 c2 check +permutation r1 w2 w3 p3 r2 p2 c3 p1 c2 c1 check +permutation r1 w2 w3 p3 r2 p2 c3 c2 p1 c1 check +permutation r1 w2 w3 p3 r2 c3 p1 p2 c1 c2 check +permutation r1 w2 w3 p3 r2 c3 p1 p2 c2 c1 check +permutation r1 w2 w3 p3 r2 c3 p1 c1 p2 c2 check +permutation r1 w2 w3 p3 r2 c3 p2 p1 c1 c2 check +permutation r1 w2 w3 p3 r2 c3 p2 p1 c2 c1 check +permutation r1 w2 w3 p3 r2 c3 p2 c2 p1 c1 check +permutation r1 w2 w3 p3 p1 r2 p2 c3 c1 c2 check +permutation r1 w2 w3 p3 p1 r2 p2 c3 c2 c1 check +permutation r1 w2 w3 p3 p1 r2 c3 p2 c1 c2 check +permutation r1 w2 w3 p3 p1 r2 c3 p2 c2 c1 check +permutation r1 w2 w3 p3 p1 r2 c3 c1 p2 c2 check +permutation r1 w2 w3 p3 p1 c3 r2 p2 c1 c2 check +permutation r1 w2 w3 p3 p1 c3 r2 p2 c2 c1 check +permutation r1 w2 w3 p3 p1 c3 r2 c1 p2 c2 check +permutation r1 w2 w3 p3 p1 c3 c1 r2 p2 c2 check +permutation r1 w2 w3 p3 c3 r2 p1 p2 c1 c2 check +permutation r1 w2 w3 p3 c3 r2 p1 p2 c2 c1 check +permutation r1 w2 w3 p3 c3 r2 p1 c1 p2 c2 check +permutation r1 w2 w3 p3 c3 r2 p2 p1 c1 c2 check +permutation r1 w2 w3 p3 c3 r2 p2 p1 c2 c1 check +permutation r1 w2 w3 p3 c3 r2 p2 c2 p1 c1 check +permutation r1 w2 w3 p3 c3 p1 r2 p2 c1 c2 check +permutation r1 w2 w3 p3 c3 p1 r2 p2 c2 c1 check +permutation r1 w2 w3 p3 c3 p1 r2 c1 p2 c2 check +permutation r1 w2 w3 p3 c3 p1 c1 r2 p2 c2 check +permutation r1 w2 p1 w3 r2 p2 p3 c3 c1 c2 check +permutation r1 w2 p1 w3 r2 p2 p3 c3 c2 c1 check +permutation r1 w2 p1 w3 r2 p3 p2 c3 c1 c2 check +permutation r1 w2 p1 w3 r2 p3 p2 c3 c2 c1 check +permutation r1 w2 p1 w3 r2 p3 c3 p2 c1 c2 check +permutation r1 w2 p1 w3 r2 p3 c3 p2 c2 c1 check +permutation r1 w2 p1 w3 r2 p3 c3 c1 p2 c2 check +permutation r1 w2 p1 w3 p3 r2 p2 c3 c1 c2 check +permutation r1 w2 p1 w3 p3 r2 p2 c3 c2 c1 check +permutation r1 w2 p1 w3 p3 r2 c3 p2 c1 c2 check +permutation r1 w2 p1 w3 p3 r2 c3 p2 c2 c1 check +permutation r1 w2 p1 w3 p3 r2 c3 c1 p2 c2 check +permutation r1 w2 p1 w3 p3 c3 r2 p2 c1 c2 check +permutation r1 w2 p1 w3 p3 c3 r2 p2 c2 c1 check +permutation r1 w2 p1 w3 p3 c3 r2 c1 p2 c2 check +permutation r1 w2 p1 w3 p3 c3 c1 r2 p2 c2 check +permutation r1 w3 r2 w2 p1 p2 p3 c3 c1 c2 check +permutation r1 w3 r2 w2 p1 p2 p3 c3 c2 c1 check +permutation r1 w3 r2 w2 p1 p3 p2 c3 c1 c2 check +permutation r1 w3 r2 w2 p1 p3 p2 c3 c2 c1 check +permutation r1 w3 r2 w2 p1 p3 c3 p2 c1 c2 check +permutation r1 w3 r2 w2 p1 p3 c3 p2 c2 c1 check +permutation r1 w3 r2 w2 p1 p3 c3 c1 p2 c2 check +permutation r1 w3 r2 w2 p2 p1 p3 c3 c1 c2 check +permutation r1 w3 r2 w2 p2 p1 p3 c3 c2 c1 check +permutation r1 w3 r2 w2 p2 p3 p1 c3 c1 c2 check +permutation r1 w3 r2 w2 p2 p3 p1 c3 c2 c1 check +permutation r1 w3 r2 w2 p2 p3 c3 p1 c1 c2 check +permutation r1 w3 r2 w2 p2 p3 c3 p1 c2 c1 check +permutation r1 w3 r2 w2 p2 p3 c3 c2 p1 c1 check +permutation r1 w3 r2 w2 p3 p1 p2 c3 c1 c2 check +permutation r1 w3 r2 w2 p3 p1 p2 c3 c2 c1 check +permutation r1 w3 r2 w2 p3 p1 c3 p2 c1 c2 check +permutation r1 w3 r2 w2 p3 p1 c3 p2 c2 c1 check +permutation r1 w3 r2 w2 p3 p1 c3 c1 p2 c2 check +permutation r1 w3 r2 w2 p3 p2 p1 c3 c1 c2 check +permutation r1 w3 r2 w2 p3 p2 p1 c3 c2 c1 check +permutation r1 w3 r2 w2 p3 p2 c3 p1 c1 c2 check +permutation r1 w3 r2 w2 p3 p2 c3 p1 c2 c1 check +permutation r1 w3 r2 w2 p3 p2 c3 c2 p1 c1 check +permutation r1 w3 r2 w2 p3 c3 p1 p2 c1 c2 check +permutation r1 w3 r2 w2 p3 c3 p1 p2 c2 c1 check +permutation r1 w3 r2 w2 p3 c3 p1 c1 p2 c2 check +permutation r1 w3 r2 w2 p3 c3 p2 p1 c1 c2 check +permutation r1 w3 r2 w2 p3 c3 p2 p1 c2 c1 check +permutation r1 w3 r2 w2 p3 c3 p2 c2 p1 c1 check +permutation r1 w3 r2 p1 w2 p2 p3 c3 c1 c2 check +permutation r1 w3 r2 p1 w2 p2 p3 c3 c2 c1 check +permutation r1 w3 r2 p1 w2 p3 p2 c3 c1 c2 check +permutation r1 w3 r2 p1 w2 p3 p2 c3 c2 c1 check +permutation r1 w3 r2 p1 w2 p3 c3 p2 c1 c2 check +permutation r1 w3 r2 p1 w2 p3 c3 p2 c2 c1 check +permutation r1 w3 r2 p1 w2 p3 c3 c1 p2 c2 check +permutation r1 w3 r2 p1 p3 w2 p2 c3 c1 c2 check +permutation r1 w3 r2 p1 p3 w2 p2 c3 c2 c1 check +permutation r1 w3 r2 p1 p3 w2 c3 p2 c1 c2 check +permutation r1 w3 r2 p1 p3 w2 c3 p2 c2 c1 check +permutation r1 w3 r2 p1 p3 w2 c3 c1 p2 c2 check +permutation r1 w3 r2 p1 p3 c3 w2 p2 c1 c2 check +permutation r1 w3 r2 p1 p3 c3 w2 p2 c2 c1 check +permutation r1 w3 r2 p1 p3 c3 w2 c1 p2 c2 check +permutation r1 w3 r2 p1 p3 c3 c1 w2 p2 c2 check +permutation r1 w3 r2 p3 w2 p1 p2 c3 c1 c2 check +permutation r1 w3 r2 p3 w2 p1 p2 c3 c2 c1 check +permutation r1 w3 r2 p3 w2 p1 c3 p2 c1 c2 check +permutation r1 w3 r2 p3 w2 p1 c3 p2 c2 c1 check +permutation r1 w3 r2 p3 w2 p1 c3 c1 p2 c2 check +permutation r1 w3 r2 p3 w2 p2 p1 c3 c1 c2 check +permutation r1 w3 r2 p3 w2 p2 p1 c3 c2 c1 check +permutation r1 w3 r2 p3 w2 p2 c3 p1 c1 c2 check +permutation r1 w3 r2 p3 w2 p2 c3 p1 c2 c1 check +permutation r1 w3 r2 p3 w2 p2 c3 c2 p1 c1 check +permutation r1 w3 r2 p3 w2 c3 p1 p2 c1 c2 check +permutation r1 w3 r2 p3 w2 c3 p1 p2 c2 c1 check +permutation r1 w3 r2 p3 w2 c3 p1 c1 p2 c2 check +permutation r1 w3 r2 p3 w2 c3 p2 p1 c1 c2 check +permutation r1 w3 r2 p3 w2 c3 p2 p1 c2 c1 check +permutation r1 w3 r2 p3 w2 c3 p2 c2 p1 c1 check +permutation r1 w3 r2 p3 p1 w2 p2 c3 c1 c2 check +permutation r1 w3 r2 p3 p1 w2 p2 c3 c2 c1 check +permutation r1 w3 r2 p3 p1 w2 c3 p2 c1 c2 check +permutation r1 w3 r2 p3 p1 w2 c3 p2 c2 c1 check +permutation r1 w3 r2 p3 p1 w2 c3 c1 p2 c2 check +permutation r1 w3 r2 p3 p1 c3 w2 p2 c1 c2 check +permutation r1 w3 r2 p3 p1 c3 w2 p2 c2 c1 check +permutation r1 w3 r2 p3 p1 c3 w2 c1 p2 c2 check +permutation r1 w3 r2 p3 p1 c3 c1 w2 p2 c2 check +permutation r1 w3 r2 p3 c3 w2 p1 p2 c1 c2 check +permutation r1 w3 r2 p3 c3 w2 p1 p2 c2 c1 check +permutation r1 w3 r2 p3 c3 w2 p1 c1 p2 c2 check +permutation r1 w3 r2 p3 c3 w2 p2 p1 c1 c2 check +permutation r1 w3 r2 p3 c3 w2 p2 p1 c2 c1 check +permutation r1 w3 r2 p3 c3 w2 p2 c2 p1 c1 check +permutation r1 w3 r2 p3 c3 p1 w2 p2 c1 c2 check +permutation r1 w3 r2 p3 c3 p1 w2 p2 c2 c1 check +permutation r1 w3 r2 p3 c3 p1 w2 c1 p2 c2 check +permutation r1 w3 r2 p3 c3 p1 c1 w2 p2 c2 check +permutation r1 w3 w2 r2 p1 p2 p3 c3 c1 c2 check +permutation r1 w3 w2 r2 p1 p2 p3 c3 c2 c1 check +permutation r1 w3 w2 r2 p1 p3 p2 c3 c1 c2 check +permutation r1 w3 w2 r2 p1 p3 p2 c3 c2 c1 check +permutation r1 w3 w2 r2 p1 p3 c3 p2 c1 c2 check +permutation r1 w3 w2 r2 p1 p3 c3 p2 c2 c1 check +permutation r1 w3 w2 r2 p1 p3 c3 c1 p2 c2 check +permutation r1 w3 w2 r2 p2 p1 p3 c3 c1 c2 check +permutation r1 w3 w2 r2 p2 p1 p3 c3 c2 c1 check +permutation r1 w3 w2 r2 p2 p3 p1 c3 c1 c2 check +permutation r1 w3 w2 r2 p2 p3 p1 c3 c2 c1 check +permutation r1 w3 w2 r2 p2 p3 c3 p1 c1 c2 check +permutation r1 w3 w2 r2 p2 p3 c3 p1 c2 c1 check +permutation r1 w3 w2 r2 p2 p3 c3 c2 p1 c1 check +permutation r1 w3 w2 r2 p3 p1 p2 c3 c1 c2 check +permutation r1 w3 w2 r2 p3 p1 p2 c3 c2 c1 check +permutation r1 w3 w2 r2 p3 p1 c3 p2 c1 c2 check +permutation r1 w3 w2 r2 p3 p1 c3 p2 c2 c1 check +permutation r1 w3 w2 r2 p3 p1 c3 c1 p2 c2 check +permutation r1 w3 w2 r2 p3 p2 p1 c3 c1 c2 check +permutation r1 w3 w2 r2 p3 p2 p1 c3 c2 c1 check +permutation r1 w3 w2 r2 p3 p2 c3 p1 c1 c2 check +permutation r1 w3 w2 r2 p3 p2 c3 p1 c2 c1 check +permutation r1 w3 w2 r2 p3 p2 c3 c2 p1 c1 check +permutation r1 w3 w2 r2 p3 c3 p1 p2 c1 c2 check +permutation r1 w3 w2 r2 p3 c3 p1 p2 c2 c1 check +permutation r1 w3 w2 r2 p3 c3 p1 c1 p2 c2 check +permutation r1 w3 w2 r2 p3 c3 p2 p1 c1 c2 check +permutation r1 w3 w2 r2 p3 c3 p2 p1 c2 c1 check +permutation r1 w3 w2 r2 p3 c3 p2 c2 p1 c1 check +permutation r1 w3 w2 p1 r2 p2 p3 c3 c1 c2 check +permutation r1 w3 w2 p1 r2 p2 p3 c3 c2 c1 check +permutation r1 w3 w2 p1 r2 p3 p2 c3 c1 c2 check +permutation r1 w3 w2 p1 r2 p3 p2 c3 c2 c1 check +permutation r1 w3 w2 p1 r2 p3 c3 p2 c1 c2 check +permutation r1 w3 w2 p1 r2 p3 c3 p2 c2 c1 check +permutation r1 w3 w2 p1 r2 p3 c3 c1 p2 c2 check +permutation r1 w3 w2 p1 p3 r2 p2 c3 c1 c2 check +permutation r1 w3 w2 p1 p3 r2 p2 c3 c2 c1 check +permutation r1 w3 w2 p1 p3 r2 c3 p2 c1 c2 check +permutation r1 w3 w2 p1 p3 r2 c3 p2 c2 c1 check +permutation r1 w3 w2 p1 p3 r2 c3 c1 p2 c2 check +permutation r1 w3 w2 p1 p3 c3 r2 p2 c1 c2 check +permutation r1 w3 w2 p1 p3 c3 r2 p2 c2 c1 check +permutation r1 w3 w2 p1 p3 c3 r2 c1 p2 c2 check +permutation r1 w3 w2 p1 p3 c3 c1 r2 p2 c2 check +permutation r1 w3 w2 p3 r2 p1 p2 c3 c1 c2 check +permutation r1 w3 w2 p3 r2 p1 p2 c3 c2 c1 check +permutation r1 w3 w2 p3 r2 p1 c3 p2 c1 c2 check +permutation r1 w3 w2 p3 r2 p1 c3 p2 c2 c1 check +permutation r1 w3 w2 p3 r2 p1 c3 c1 p2 c2 check +permutation r1 w3 w2 p3 r2 p2 p1 c3 c1 c2 check +permutation r1 w3 w2 p3 r2 p2 p1 c3 c2 c1 check +permutation r1 w3 w2 p3 r2 p2 c3 p1 c1 c2 check +permutation r1 w3 w2 p3 r2 p2 c3 p1 c2 c1 check +permutation r1 w3 w2 p3 r2 p2 c3 c2 p1 c1 check +permutation r1 w3 w2 p3 r2 c3 p1 p2 c1 c2 check +permutation r1 w3 w2 p3 r2 c3 p1 p2 c2 c1 check +permutation r1 w3 w2 p3 r2 c3 p1 c1 p2 c2 check +permutation r1 w3 w2 p3 r2 c3 p2 p1 c1 c2 check +permutation r1 w3 w2 p3 r2 c3 p2 p1 c2 c1 check +permutation r1 w3 w2 p3 r2 c3 p2 c2 p1 c1 check +permutation r1 w3 w2 p3 p1 r2 p2 c3 c1 c2 check +permutation r1 w3 w2 p3 p1 r2 p2 c3 c2 c1 check +permutation r1 w3 w2 p3 p1 r2 c3 p2 c1 c2 check +permutation r1 w3 w2 p3 p1 r2 c3 p2 c2 c1 check +permutation r1 w3 w2 p3 p1 r2 c3 c1 p2 c2 check +permutation r1 w3 w2 p3 p1 c3 r2 p2 c1 c2 check +permutation r1 w3 w2 p3 p1 c3 r2 p2 c2 c1 check +permutation r1 w3 w2 p3 p1 c3 r2 c1 p2 c2 check +permutation r1 w3 w2 p3 p1 c3 c1 r2 p2 c2 check +permutation r1 w3 w2 p3 c3 r2 p1 p2 c1 c2 check +permutation r1 w3 w2 p3 c3 r2 p1 p2 c2 c1 check +permutation r1 w3 w2 p3 c3 r2 p1 c1 p2 c2 check +permutation r1 w3 w2 p3 c3 r2 p2 p1 c1 c2 check +permutation r1 w3 w2 p3 c3 r2 p2 p1 c2 c1 check +permutation r1 w3 w2 p3 c3 r2 p2 c2 p1 c1 check +permutation r1 w3 w2 p3 c3 p1 r2 p2 c1 c2 check +permutation r1 w3 w2 p3 c3 p1 r2 p2 c2 c1 check +permutation r1 w3 w2 p3 c3 p1 r2 c1 p2 c2 check +permutation r1 w3 w2 p3 c3 p1 c1 r2 p2 c2 check +permutation r1 w3 p1 r2 w2 p2 p3 c3 c1 c2 check +permutation r1 w3 p1 r2 w2 p2 p3 c3 c2 c1 check +permutation r1 w3 p1 r2 w2 p3 p2 c3 c1 c2 check +permutation r1 w3 p1 r2 w2 p3 p2 c3 c2 c1 check +permutation r1 w3 p1 r2 w2 p3 c3 p2 c1 c2 check +permutation r1 w3 p1 r2 w2 p3 c3 p2 c2 c1 check +permutation r1 w3 p1 r2 w2 p3 c3 c1 p2 c2 check +permutation r1 w3 p1 r2 p3 w2 p2 c3 c1 c2 check +permutation r1 w3 p1 r2 p3 w2 p2 c3 c2 c1 check +permutation r1 w3 p1 r2 p3 w2 c3 p2 c1 c2 check +permutation r1 w3 p1 r2 p3 w2 c3 p2 c2 c1 check +permutation r1 w3 p1 r2 p3 w2 c3 c1 p2 c2 check +permutation r1 w3 p1 r2 p3 c3 w2 p2 c1 c2 check +permutation r1 w3 p1 r2 p3 c3 w2 p2 c2 c1 check +permutation r1 w3 p1 r2 p3 c3 w2 c1 p2 c2 check +permutation r1 w3 p1 r2 p3 c3 c1 w2 p2 c2 check +permutation r1 w3 p1 w2 r2 p2 p3 c3 c1 c2 check +permutation r1 w3 p1 w2 r2 p2 p3 c3 c2 c1 check +permutation r1 w3 p1 w2 r2 p3 p2 c3 c1 c2 check +permutation r1 w3 p1 w2 r2 p3 p2 c3 c2 c1 check +permutation r1 w3 p1 w2 r2 p3 c3 p2 c1 c2 check +permutation r1 w3 p1 w2 r2 p3 c3 p2 c2 c1 check +permutation r1 w3 p1 w2 r2 p3 c3 c1 p2 c2 check +permutation r1 w3 p1 w2 p3 r2 p2 c3 c1 c2 check +permutation r1 w3 p1 w2 p3 r2 p2 c3 c2 c1 check +permutation r1 w3 p1 w2 p3 r2 c3 p2 c1 c2 check +permutation r1 w3 p1 w2 p3 r2 c3 p2 c2 c1 check +permutation r1 w3 p1 w2 p3 r2 c3 c1 p2 c2 check +permutation r1 w3 p1 w2 p3 c3 r2 p2 c1 c2 check +permutation r1 w3 p1 w2 p3 c3 r2 p2 c2 c1 check +permutation r1 w3 p1 w2 p3 c3 r2 c1 p2 c2 check +permutation r1 w3 p1 w2 p3 c3 c1 r2 p2 c2 check +permutation r1 w3 p1 p3 r2 w2 p2 c3 c1 c2 check +permutation r1 w3 p1 p3 r2 w2 p2 c3 c2 c1 check +permutation r1 w3 p1 p3 r2 w2 c3 p2 c1 c2 check +permutation r1 w3 p1 p3 r2 w2 c3 p2 c2 c1 check +permutation r1 w3 p1 p3 r2 w2 c3 c1 p2 c2 check +permutation r1 w3 p1 p3 r2 c3 w2 p2 c1 c2 check +permutation r1 w3 p1 p3 r2 c3 w2 p2 c2 c1 check +permutation r1 w3 p1 p3 r2 c3 w2 c1 p2 c2 check +permutation r1 w3 p1 p3 r2 c3 c1 w2 p2 c2 check +permutation r1 w3 p1 p3 w2 r2 p2 c3 c1 c2 check +permutation r1 w3 p1 p3 w2 r2 p2 c3 c2 c1 check +permutation r1 w3 p1 p3 w2 r2 c3 p2 c1 c2 check +permutation r1 w3 p1 p3 w2 r2 c3 p2 c2 c1 check +permutation r1 w3 p1 p3 w2 r2 c3 c1 p2 c2 check +permutation r1 w3 p1 p3 w2 c3 r2 p2 c1 c2 check +permutation r1 w3 p1 p3 w2 c3 r2 p2 c2 c1 check +permutation r1 w3 p1 p3 w2 c3 r2 c1 p2 c2 check +permutation r1 w3 p1 p3 w2 c3 c1 r2 p2 c2 check +permutation r1 w3 p1 p3 c3 r2 w2 p2 c1 c2 check +permutation r1 w3 p1 p3 c3 r2 w2 p2 c2 c1 check +permutation r1 w3 p1 p3 c3 r2 w2 c1 p2 c2 check +permutation r1 w3 p1 p3 c3 r2 c1 w2 p2 c2 check +permutation r1 w3 p1 p3 c3 w2 r2 p2 c1 c2 check +permutation r1 w3 p1 p3 c3 w2 r2 p2 c2 c1 check +permutation r1 w3 p1 p3 c3 w2 r2 c1 p2 c2 check +permutation r1 w3 p1 p3 c3 w2 c1 r2 p2 c2 check +permutation r1 w3 p1 p3 c3 c1 r2 w2 p2 c2 check +permutation r1 w3 p1 p3 c3 c1 w2 r2 p2 c2 check +permutation r1 w3 p3 r2 w2 p1 p2 c3 c1 c2 check +permutation r1 w3 p3 r2 w2 p1 p2 c3 c2 c1 check +permutation r1 w3 p3 r2 w2 p1 c3 p2 c1 c2 check +permutation r1 w3 p3 r2 w2 p1 c3 p2 c2 c1 check +permutation r1 w3 p3 r2 w2 p1 c3 c1 p2 c2 check +permutation r1 w3 p3 r2 w2 p2 p1 c3 c1 c2 check +permutation r1 w3 p3 r2 w2 p2 p1 c3 c2 c1 check +permutation r1 w3 p3 r2 w2 p2 c3 p1 c1 c2 check +permutation r1 w3 p3 r2 w2 p2 c3 p1 c2 c1 check +permutation r1 w3 p3 r2 w2 p2 c3 c2 p1 c1 check +permutation r1 w3 p3 r2 w2 c3 p1 p2 c1 c2 check +permutation r1 w3 p3 r2 w2 c3 p1 p2 c2 c1 check +permutation r1 w3 p3 r2 w2 c3 p1 c1 p2 c2 check +permutation r1 w3 p3 r2 w2 c3 p2 p1 c1 c2 check +permutation r1 w3 p3 r2 w2 c3 p2 p1 c2 c1 check +permutation r1 w3 p3 r2 w2 c3 p2 c2 p1 c1 check +permutation r1 w3 p3 r2 p1 w2 p2 c3 c1 c2 check +permutation r1 w3 p3 r2 p1 w2 p2 c3 c2 c1 check +permutation r1 w3 p3 r2 p1 w2 c3 p2 c1 c2 check +permutation r1 w3 p3 r2 p1 w2 c3 p2 c2 c1 check +permutation r1 w3 p3 r2 p1 w2 c3 c1 p2 c2 check +permutation r1 w3 p3 r2 p1 c3 w2 p2 c1 c2 check +permutation r1 w3 p3 r2 p1 c3 w2 p2 c2 c1 check +permutation r1 w3 p3 r2 p1 c3 w2 c1 p2 c2 check +permutation r1 w3 p3 r2 p1 c3 c1 w2 p2 c2 check +permutation r1 w3 p3 r2 c3 w2 p1 p2 c1 c2 check +permutation r1 w3 p3 r2 c3 w2 p1 p2 c2 c1 check +permutation r1 w3 p3 r2 c3 w2 p1 c1 p2 c2 check +permutation r1 w3 p3 r2 c3 w2 p2 p1 c1 c2 check +permutation r1 w3 p3 r2 c3 w2 p2 p1 c2 c1 check +permutation r1 w3 p3 r2 c3 w2 p2 c2 p1 c1 check +permutation r1 w3 p3 r2 c3 p1 w2 p2 c1 c2 check +permutation r1 w3 p3 r2 c3 p1 w2 p2 c2 c1 check +permutation r1 w3 p3 r2 c3 p1 w2 c1 p2 c2 check +permutation r1 w3 p3 r2 c3 p1 c1 w2 p2 c2 check +permutation r1 w3 p3 w2 r2 p1 p2 c3 c1 c2 check +permutation r1 w3 p3 w2 r2 p1 p2 c3 c2 c1 check +permutation r1 w3 p3 w2 r2 p1 c3 p2 c1 c2 check +permutation r1 w3 p3 w2 r2 p1 c3 p2 c2 c1 check +permutation r1 w3 p3 w2 r2 p1 c3 c1 p2 c2 check +permutation r1 w3 p3 w2 r2 p2 p1 c3 c1 c2 check +permutation r1 w3 p3 w2 r2 p2 p1 c3 c2 c1 check +permutation r1 w3 p3 w2 r2 p2 c3 p1 c1 c2 check +permutation r1 w3 p3 w2 r2 p2 c3 p1 c2 c1 check +permutation r1 w3 p3 w2 r2 p2 c3 c2 p1 c1 check +permutation r1 w3 p3 w2 r2 c3 p1 p2 c1 c2 check +permutation r1 w3 p3 w2 r2 c3 p1 p2 c2 c1 check +permutation r1 w3 p3 w2 r2 c3 p1 c1 p2 c2 check +permutation r1 w3 p3 w2 r2 c3 p2 p1 c1 c2 check +permutation r1 w3 p3 w2 r2 c3 p2 p1 c2 c1 check +permutation r1 w3 p3 w2 r2 c3 p2 c2 p1 c1 check +permutation r1 w3 p3 w2 p1 r2 p2 c3 c1 c2 check +permutation r1 w3 p3 w2 p1 r2 p2 c3 c2 c1 check +permutation r1 w3 p3 w2 p1 r2 c3 p2 c1 c2 check +permutation r1 w3 p3 w2 p1 r2 c3 p2 c2 c1 check +permutation r1 w3 p3 w2 p1 r2 c3 c1 p2 c2 check +permutation r1 w3 p3 w2 p1 c3 r2 p2 c1 c2 check +permutation r1 w3 p3 w2 p1 c3 r2 p2 c2 c1 check +permutation r1 w3 p3 w2 p1 c3 r2 c1 p2 c2 check +permutation r1 w3 p3 w2 p1 c3 c1 r2 p2 c2 check +permutation r1 w3 p3 w2 c3 r2 p1 p2 c1 c2 check +permutation r1 w3 p3 w2 c3 r2 p1 p2 c2 c1 check +permutation r1 w3 p3 w2 c3 r2 p1 c1 p2 c2 check +permutation r1 w3 p3 w2 c3 r2 p2 p1 c1 c2 check +permutation r1 w3 p3 w2 c3 r2 p2 p1 c2 c1 check +permutation r1 w3 p3 w2 c3 r2 p2 c2 p1 c1 check +permutation r1 w3 p3 w2 c3 p1 r2 p2 c1 c2 check +permutation r1 w3 p3 w2 c3 p1 r2 p2 c2 c1 check +permutation r1 w3 p3 w2 c3 p1 r2 c1 p2 c2 check +permutation r1 w3 p3 w2 c3 p1 c1 r2 p2 c2 check +permutation r1 w3 p3 p1 r2 w2 p2 c3 c1 c2 check +permutation r1 w3 p3 p1 r2 w2 p2 c3 c2 c1 check +permutation r1 w3 p3 p1 r2 w2 c3 p2 c1 c2 check +permutation r1 w3 p3 p1 r2 w2 c3 p2 c2 c1 check +permutation r1 w3 p3 p1 r2 w2 c3 c1 p2 c2 check +permutation r1 w3 p3 p1 r2 c3 w2 p2 c1 c2 check +permutation r1 w3 p3 p1 r2 c3 w2 p2 c2 c1 check +permutation r1 w3 p3 p1 r2 c3 w2 c1 p2 c2 check +permutation r1 w3 p3 p1 r2 c3 c1 w2 p2 c2 check +permutation r1 w3 p3 p1 w2 r2 p2 c3 c1 c2 check +permutation r1 w3 p3 p1 w2 r2 p2 c3 c2 c1 check +permutation r1 w3 p3 p1 w2 r2 c3 p2 c1 c2 check +permutation r1 w3 p3 p1 w2 r2 c3 p2 c2 c1 check +permutation r1 w3 p3 p1 w2 r2 c3 c1 p2 c2 check +permutation r1 w3 p3 p1 w2 c3 r2 p2 c1 c2 check +permutation r1 w3 p3 p1 w2 c3 r2 p2 c2 c1 check +permutation r1 w3 p3 p1 w2 c3 r2 c1 p2 c2 check +permutation r1 w3 p3 p1 w2 c3 c1 r2 p2 c2 check +permutation r1 w3 p3 p1 c3 r2 w2 p2 c1 c2 check +permutation r1 w3 p3 p1 c3 r2 w2 p2 c2 c1 check +permutation r1 w3 p3 p1 c3 r2 w2 c1 p2 c2 check +permutation r1 w3 p3 p1 c3 r2 c1 w2 p2 c2 check +permutation r1 w3 p3 p1 c3 w2 r2 p2 c1 c2 check +permutation r1 w3 p3 p1 c3 w2 r2 p2 c2 c1 check +permutation r1 w3 p3 p1 c3 w2 r2 c1 p2 c2 check +permutation r1 w3 p3 p1 c3 w2 c1 r2 p2 c2 check +permutation r1 w3 p3 p1 c3 c1 r2 w2 p2 c2 check +permutation r1 w3 p3 p1 c3 c1 w2 r2 p2 c2 check +permutation r1 w3 p3 c3 r2 w2 p1 p2 c1 c2 check +permutation r1 w3 p3 c3 r2 w2 p1 p2 c2 c1 check +permutation r1 w3 p3 c3 r2 w2 p1 c1 p2 c2 check +permutation r1 w3 p3 c3 r2 w2 p2 p1 c1 c2 check +permutation r1 w3 p3 c3 r2 w2 p2 p1 c2 c1 check +permutation r1 w3 p3 c3 r2 w2 p2 c2 p1 c1 check +permutation r1 w3 p3 c3 r2 p1 w2 p2 c1 c2 check +permutation r1 w3 p3 c3 r2 p1 w2 p2 c2 c1 check +permutation r1 w3 p3 c3 r2 p1 w2 c1 p2 c2 check +permutation r1 w3 p3 c3 r2 p1 c1 w2 p2 c2 check +permutation r1 w3 p3 c3 w2 r2 p1 p2 c1 c2 check +permutation r1 w3 p3 c3 w2 r2 p1 p2 c2 c1 check +permutation r1 w3 p3 c3 w2 r2 p1 c1 p2 c2 check +permutation r1 w3 p3 c3 w2 r2 p2 p1 c1 c2 check +permutation r1 w3 p3 c3 w2 r2 p2 p1 c2 c1 check +permutation r1 w3 p3 c3 w2 r2 p2 c2 p1 c1 check +permutation r1 w3 p3 c3 w2 p1 r2 p2 c1 c2 check +permutation r1 w3 p3 c3 w2 p1 r2 p2 c2 c1 check +permutation r1 w3 p3 c3 w2 p1 r2 c1 p2 c2 check +permutation r1 w3 p3 c3 w2 p1 c1 r2 p2 c2 check +permutation r1 w3 p3 c3 p1 r2 w2 p2 c1 c2 check +permutation r1 w3 p3 c3 p1 r2 w2 p2 c2 c1 check +permutation r1 w3 p3 c3 p1 r2 w2 c1 p2 c2 check +permutation r1 w3 p3 c3 p1 r2 c1 w2 p2 c2 check +permutation r1 w3 p3 c3 p1 w2 r2 p2 c1 c2 check +permutation r1 w3 p3 c3 p1 w2 r2 p2 c2 c1 check +permutation r1 w3 p3 c3 p1 w2 r2 c1 p2 c2 check +permutation r1 w3 p3 c3 p1 w2 c1 r2 p2 c2 check +permutation r1 w3 p3 c3 p1 c1 r2 w2 p2 c2 check +permutation r1 w3 p3 c3 p1 c1 w2 r2 p2 c2 check +permutation r1 p1 r2 w2 w3 p2 p3 c3 c1 c2 check +permutation r1 p1 r2 w2 w3 p2 p3 c3 c2 c1 check +permutation r1 p1 r2 w2 w3 p3 p2 c3 c1 c2 check +permutation r1 p1 r2 w2 w3 p3 p2 c3 c2 c1 check +permutation r1 p1 r2 w2 w3 p3 c3 p2 c1 c2 check +permutation r1 p1 r2 w2 w3 p3 c3 p2 c2 c1 check +permutation r1 p1 r2 w2 w3 p3 c3 c1 p2 c2 check +permutation r1 p1 r2 w2 p2 w3 p3 c3 c1 c2 check +permutation r1 p1 r2 w2 p2 w3 p3 c3 c2 c1 check +permutation r1 p1 w2 w3 r2 p2 p3 c3 c1 c2 check +permutation r1 p1 w2 w3 r2 p2 p3 c3 c2 c1 check +permutation r1 p1 w2 w3 r2 p3 p2 c3 c1 c2 check +permutation r1 p1 w2 w3 r2 p3 p2 c3 c2 c1 check +permutation r1 p1 w2 w3 r2 p3 c3 p2 c1 c2 check +permutation r1 p1 w2 w3 r2 p3 c3 p2 c2 c1 check +permutation r1 p1 w2 w3 r2 p3 c3 c1 p2 c2 check +permutation r1 p1 w2 w3 p3 r2 p2 c3 c1 c2 check +permutation r1 p1 w2 w3 p3 r2 p2 c3 c2 c1 check +permutation r1 p1 w2 w3 p3 r2 c3 p2 c1 c2 check +permutation r1 p1 w2 w3 p3 r2 c3 p2 c2 c1 check +permutation r1 p1 w2 w3 p3 r2 c3 c1 p2 c2 check +permutation r1 p1 w2 w3 p3 c3 r2 p2 c1 c2 check +permutation r1 p1 w2 w3 p3 c3 r2 p2 c2 c1 check +permutation r1 p1 w2 w3 p3 c3 r2 c1 p2 c2 check +permutation r1 p1 w2 w3 p3 c3 c1 r2 p2 c2 check +permutation r1 p1 w3 r2 w2 p2 p3 c3 c1 c2 check +permutation r1 p1 w3 r2 w2 p2 p3 c3 c2 c1 check +permutation r1 p1 w3 r2 w2 p3 p2 c3 c1 c2 check +permutation r1 p1 w3 r2 w2 p3 p2 c3 c2 c1 check +permutation r1 p1 w3 r2 w2 p3 c3 p2 c1 c2 check +permutation r1 p1 w3 r2 w2 p3 c3 p2 c2 c1 check +permutation r1 p1 w3 r2 w2 p3 c3 c1 p2 c2 check +permutation r1 p1 w3 r2 p3 w2 p2 c3 c1 c2 check +permutation r1 p1 w3 r2 p3 w2 p2 c3 c2 c1 check +permutation r1 p1 w3 r2 p3 w2 c3 p2 c1 c2 check +permutation r1 p1 w3 r2 p3 w2 c3 p2 c2 c1 check +permutation r1 p1 w3 r2 p3 w2 c3 c1 p2 c2 check +permutation r1 p1 w3 r2 p3 c3 w2 p2 c1 c2 check +permutation r1 p1 w3 r2 p3 c3 w2 p2 c2 c1 check +permutation r1 p1 w3 r2 p3 c3 w2 c1 p2 c2 check +permutation r1 p1 w3 r2 p3 c3 c1 w2 p2 c2 check +permutation r1 p1 w3 w2 r2 p2 p3 c3 c1 c2 check +permutation r1 p1 w3 w2 r2 p2 p3 c3 c2 c1 check +permutation r1 p1 w3 w2 r2 p3 p2 c3 c1 c2 check +permutation r1 p1 w3 w2 r2 p3 p2 c3 c2 c1 check +permutation r1 p1 w3 w2 r2 p3 c3 p2 c1 c2 check +permutation r1 p1 w3 w2 r2 p3 c3 p2 c2 c1 check +permutation r1 p1 w3 w2 r2 p3 c3 c1 p2 c2 check +permutation r1 p1 w3 w2 p3 r2 p2 c3 c1 c2 check +permutation r1 p1 w3 w2 p3 r2 p2 c3 c2 c1 check +permutation r1 p1 w3 w2 p3 r2 c3 p2 c1 c2 check +permutation r1 p1 w3 w2 p3 r2 c3 p2 c2 c1 check +permutation r1 p1 w3 w2 p3 r2 c3 c1 p2 c2 check +permutation r1 p1 w3 w2 p3 c3 r2 p2 c1 c2 check +permutation r1 p1 w3 w2 p3 c3 r2 p2 c2 c1 check +permutation r1 p1 w3 w2 p3 c3 r2 c1 p2 c2 check +permutation r1 p1 w3 w2 p3 c3 c1 r2 p2 c2 check +permutation r1 p1 w3 p3 r2 w2 p2 c3 c1 c2 check +permutation r1 p1 w3 p3 r2 w2 p2 c3 c2 c1 check +permutation r1 p1 w3 p3 r2 w2 c3 p2 c1 c2 check +permutation r1 p1 w3 p3 r2 w2 c3 p2 c2 c1 check +permutation r1 p1 w3 p3 r2 w2 c3 c1 p2 c2 check +permutation r1 p1 w3 p3 r2 c3 w2 p2 c1 c2 check +permutation r1 p1 w3 p3 r2 c3 w2 p2 c2 c1 check +permutation r1 p1 w3 p3 r2 c3 w2 c1 p2 c2 check +permutation r1 p1 w3 p3 r2 c3 c1 w2 p2 c2 check +permutation r1 p1 w3 p3 w2 r2 p2 c3 c1 c2 check +permutation r1 p1 w3 p3 w2 r2 p2 c3 c2 c1 check +permutation r1 p1 w3 p3 w2 r2 c3 p2 c1 c2 check +permutation r1 p1 w3 p3 w2 r2 c3 p2 c2 c1 check +permutation r1 p1 w3 p3 w2 r2 c3 c1 p2 c2 check +permutation r1 p1 w3 p3 w2 c3 r2 p2 c1 c2 check +permutation r1 p1 w3 p3 w2 c3 r2 p2 c2 c1 check +permutation r1 p1 w3 p3 w2 c3 r2 c1 p2 c2 check +permutation r1 p1 w3 p3 w2 c3 c1 r2 p2 c2 check +permutation r1 p1 w3 p3 c3 r2 w2 p2 c1 c2 check +permutation r1 p1 w3 p3 c3 r2 w2 p2 c2 c1 check +permutation r1 p1 w3 p3 c3 r2 w2 c1 p2 c2 check +permutation r1 p1 w3 p3 c3 r2 c1 w2 p2 c2 check +permutation r1 p1 w3 p3 c3 w2 r2 p2 c1 c2 check +permutation r1 p1 w3 p3 c3 w2 r2 p2 c2 c1 check +permutation r1 p1 w3 p3 c3 w2 r2 c1 p2 c2 check +permutation r1 p1 w3 p3 c3 w2 c1 r2 p2 c2 check +permutation r1 p1 w3 p3 c3 c1 r2 w2 p2 c2 check +permutation r1 p1 w3 p3 c3 c1 w2 r2 p2 c2 check +permutation w2 r1 r2 w3 p1 p2 p3 c3 c1 c2 check +permutation w2 r1 r2 w3 p1 p2 p3 c3 c2 c1 check +permutation w2 r1 r2 w3 p1 p3 p2 c3 c1 c2 check +permutation w2 r1 r2 w3 p1 p3 p2 c3 c2 c1 check +permutation w2 r1 r2 w3 p1 p3 c3 p2 c1 c2 check +permutation w2 r1 r2 w3 p1 p3 c3 p2 c2 c1 check +permutation w2 r1 r2 w3 p1 p3 c3 c1 p2 c2 check +permutation w2 r1 r2 w3 p2 p1 p3 c3 c1 c2 check +permutation w2 r1 r2 w3 p2 p1 p3 c3 c2 c1 check +permutation w2 r1 r2 w3 p2 p3 p1 c3 c1 c2 check +permutation w2 r1 r2 w3 p2 p3 p1 c3 c2 c1 check +permutation w2 r1 r2 w3 p2 p3 c3 p1 c1 c2 check +permutation w2 r1 r2 w3 p2 p3 c3 p1 c2 c1 check +permutation w2 r1 r2 w3 p2 p3 c3 c2 p1 c1 check +permutation w2 r1 r2 w3 p3 p1 p2 c3 c1 c2 check +permutation w2 r1 r2 w3 p3 p1 p2 c3 c2 c1 check +permutation w2 r1 r2 w3 p3 p1 c3 p2 c1 c2 check +permutation w2 r1 r2 w3 p3 p1 c3 p2 c2 c1 check +permutation w2 r1 r2 w3 p3 p1 c3 c1 p2 c2 check +permutation w2 r1 r2 w3 p3 p2 p1 c3 c1 c2 check +permutation w2 r1 r2 w3 p3 p2 p1 c3 c2 c1 check +permutation w2 r1 r2 w3 p3 p2 c3 p1 c1 c2 check +permutation w2 r1 r2 w3 p3 p2 c3 p1 c2 c1 check +permutation w2 r1 r2 w3 p3 p2 c3 c2 p1 c1 check +permutation w2 r1 r2 w3 p3 c3 p1 p2 c1 c2 check +permutation w2 r1 r2 w3 p3 c3 p1 p2 c2 c1 check +permutation w2 r1 r2 w3 p3 c3 p1 c1 p2 c2 check +permutation w2 r1 r2 w3 p3 c3 p2 p1 c1 c2 check +permutation w2 r1 r2 w3 p3 c3 p2 p1 c2 c1 check +permutation w2 r1 r2 w3 p3 c3 p2 c2 p1 c1 check +permutation w2 r1 r2 p1 w3 p2 p3 c3 c1 c2 check +permutation w2 r1 r2 p1 w3 p2 p3 c3 c2 c1 check +permutation w2 r1 r2 p1 w3 p3 p2 c3 c1 c2 check +permutation w2 r1 r2 p1 w3 p3 p2 c3 c2 c1 check +permutation w2 r1 r2 p1 w3 p3 c3 p2 c1 c2 check +permutation w2 r1 r2 p1 w3 p3 c3 p2 c2 c1 check +permutation w2 r1 r2 p1 w3 p3 c3 c1 p2 c2 check +permutation w2 r1 r2 p1 p2 w3 p3 c3 c1 c2 check +permutation w2 r1 r2 p1 p2 w3 p3 c3 c2 c1 check +permutation w2 r1 r2 p2 w3 p1 p3 c3 c1 c2 check +permutation w2 r1 r2 p2 w3 p1 p3 c3 c2 c1 check +permutation w2 r1 r2 p2 w3 p3 p1 c3 c1 c2 check +permutation w2 r1 r2 p2 w3 p3 p1 c3 c2 c1 check +permutation w2 r1 r2 p2 w3 p3 c3 p1 c1 c2 check +permutation w2 r1 r2 p2 w3 p3 c3 p1 c2 c1 check +permutation w2 r1 r2 p2 w3 p3 c3 c2 p1 c1 check +permutation w2 r1 r2 p2 p1 w3 p3 c3 c1 c2 check +permutation w2 r1 r2 p2 p1 w3 p3 c3 c2 c1 check +permutation w2 r1 w3 r2 p1 p2 p3 c3 c1 c2 check +permutation w2 r1 w3 r2 p1 p2 p3 c3 c2 c1 check +permutation w2 r1 w3 r2 p1 p3 p2 c3 c1 c2 check +permutation w2 r1 w3 r2 p1 p3 p2 c3 c2 c1 check +permutation w2 r1 w3 r2 p1 p3 c3 p2 c1 c2 check +permutation w2 r1 w3 r2 p1 p3 c3 p2 c2 c1 check +permutation w2 r1 w3 r2 p1 p3 c3 c1 p2 c2 check +permutation w2 r1 w3 r2 p2 p1 p3 c3 c1 c2 check +permutation w2 r1 w3 r2 p2 p1 p3 c3 c2 c1 check +permutation w2 r1 w3 r2 p2 p3 p1 c3 c1 c2 check +permutation w2 r1 w3 r2 p2 p3 p1 c3 c2 c1 check +permutation w2 r1 w3 r2 p2 p3 c3 p1 c1 c2 check +permutation w2 r1 w3 r2 p2 p3 c3 p1 c2 c1 check +permutation w2 r1 w3 r2 p2 p3 c3 c2 p1 c1 check +permutation w2 r1 w3 r2 p3 p1 p2 c3 c1 c2 check +permutation w2 r1 w3 r2 p3 p1 p2 c3 c2 c1 check +permutation w2 r1 w3 r2 p3 p1 c3 p2 c1 c2 check +permutation w2 r1 w3 r2 p3 p1 c3 p2 c2 c1 check +permutation w2 r1 w3 r2 p3 p1 c3 c1 p2 c2 check +permutation w2 r1 w3 r2 p3 p2 p1 c3 c1 c2 check +permutation w2 r1 w3 r2 p3 p2 p1 c3 c2 c1 check +permutation w2 r1 w3 r2 p3 p2 c3 p1 c1 c2 check +permutation w2 r1 w3 r2 p3 p2 c3 p1 c2 c1 check +permutation w2 r1 w3 r2 p3 p2 c3 c2 p1 c1 check +permutation w2 r1 w3 r2 p3 c3 p1 p2 c1 c2 check +permutation w2 r1 w3 r2 p3 c3 p1 p2 c2 c1 check +permutation w2 r1 w3 r2 p3 c3 p1 c1 p2 c2 check +permutation w2 r1 w3 r2 p3 c3 p2 p1 c1 c2 check +permutation w2 r1 w3 r2 p3 c3 p2 p1 c2 c1 check +permutation w2 r1 w3 r2 p3 c3 p2 c2 p1 c1 check +permutation w2 r1 w3 p1 r2 p2 p3 c3 c1 c2 check +permutation w2 r1 w3 p1 r2 p2 p3 c3 c2 c1 check +permutation w2 r1 w3 p1 r2 p3 p2 c3 c1 c2 check +permutation w2 r1 w3 p1 r2 p3 p2 c3 c2 c1 check +permutation w2 r1 w3 p1 r2 p3 c3 p2 c1 c2 check +permutation w2 r1 w3 p1 r2 p3 c3 p2 c2 c1 check +permutation w2 r1 w3 p1 r2 p3 c3 c1 p2 c2 check +permutation w2 r1 w3 p1 p3 r2 p2 c3 c1 c2 check +permutation w2 r1 w3 p1 p3 r2 p2 c3 c2 c1 check +permutation w2 r1 w3 p1 p3 r2 c3 p2 c1 c2 check +permutation w2 r1 w3 p1 p3 r2 c3 p2 c2 c1 check +permutation w2 r1 w3 p1 p3 r2 c3 c1 p2 c2 check +permutation w2 r1 w3 p1 p3 c3 r2 p2 c1 c2 check +permutation w2 r1 w3 p1 p3 c3 r2 p2 c2 c1 check +permutation w2 r1 w3 p1 p3 c3 r2 c1 p2 c2 check +permutation w2 r1 w3 p1 p3 c3 c1 r2 p2 c2 check +permutation w2 r1 w3 p3 r2 p1 p2 c3 c1 c2 check +permutation w2 r1 w3 p3 r2 p1 p2 c3 c2 c1 check +permutation w2 r1 w3 p3 r2 p1 c3 p2 c1 c2 check +permutation w2 r1 w3 p3 r2 p1 c3 p2 c2 c1 check +permutation w2 r1 w3 p3 r2 p1 c3 c1 p2 c2 check +permutation w2 r1 w3 p3 r2 p2 p1 c3 c1 c2 check +permutation w2 r1 w3 p3 r2 p2 p1 c3 c2 c1 check +permutation w2 r1 w3 p3 r2 p2 c3 p1 c1 c2 check +permutation w2 r1 w3 p3 r2 p2 c3 p1 c2 c1 check +permutation w2 r1 w3 p3 r2 p2 c3 c2 p1 c1 check +permutation w2 r1 w3 p3 r2 c3 p1 p2 c1 c2 check +permutation w2 r1 w3 p3 r2 c3 p1 p2 c2 c1 check +permutation w2 r1 w3 p3 r2 c3 p1 c1 p2 c2 check +permutation w2 r1 w3 p3 r2 c3 p2 p1 c1 c2 check +permutation w2 r1 w3 p3 r2 c3 p2 p1 c2 c1 check +permutation w2 r1 w3 p3 r2 c3 p2 c2 p1 c1 check +permutation w2 r1 w3 p3 p1 r2 p2 c3 c1 c2 check +permutation w2 r1 w3 p3 p1 r2 p2 c3 c2 c1 check +permutation w2 r1 w3 p3 p1 r2 c3 p2 c1 c2 check +permutation w2 r1 w3 p3 p1 r2 c3 p2 c2 c1 check +permutation w2 r1 w3 p3 p1 r2 c3 c1 p2 c2 check +permutation w2 r1 w3 p3 p1 c3 r2 p2 c1 c2 check +permutation w2 r1 w3 p3 p1 c3 r2 p2 c2 c1 check +permutation w2 r1 w3 p3 p1 c3 r2 c1 p2 c2 check +permutation w2 r1 w3 p3 p1 c3 c1 r2 p2 c2 check +permutation w2 r1 w3 p3 c3 r2 p1 p2 c1 c2 check +permutation w2 r1 w3 p3 c3 r2 p1 p2 c2 c1 check +permutation w2 r1 w3 p3 c3 r2 p1 c1 p2 c2 check +permutation w2 r1 w3 p3 c3 r2 p2 p1 c1 c2 check +permutation w2 r1 w3 p3 c3 r2 p2 p1 c2 c1 check +permutation w2 r1 w3 p3 c3 r2 p2 c2 p1 c1 check +permutation w2 r1 w3 p3 c3 p1 r2 p2 c1 c2 check +permutation w2 r1 w3 p3 c3 p1 r2 p2 c2 c1 check +permutation w2 r1 w3 p3 c3 p1 r2 c1 p2 c2 check +permutation w2 r1 w3 p3 c3 p1 c1 r2 p2 c2 check +permutation w2 r1 p1 r2 w3 p2 p3 c3 c1 c2 check +permutation w2 r1 p1 r2 w3 p2 p3 c3 c2 c1 check +permutation w2 r1 p1 r2 w3 p3 p2 c3 c1 c2 check +permutation w2 r1 p1 r2 w3 p3 p2 c3 c2 c1 check +permutation w2 r1 p1 r2 w3 p3 c3 p2 c1 c2 check +permutation w2 r1 p1 r2 w3 p3 c3 p2 c2 c1 check +permutation w2 r1 p1 r2 w3 p3 c3 c1 p2 c2 check +permutation w2 r1 p1 r2 p2 w3 p3 c3 c1 c2 check +permutation w2 r1 p1 r2 p2 w3 p3 c3 c2 c1 check +permutation w2 r1 p1 w3 r2 p2 p3 c3 c1 c2 check +permutation w2 r1 p1 w3 r2 p2 p3 c3 c2 c1 check +permutation w2 r1 p1 w3 r2 p3 p2 c3 c1 c2 check +permutation w2 r1 p1 w3 r2 p3 p2 c3 c2 c1 check +permutation w2 r1 p1 w3 r2 p3 c3 p2 c1 c2 check +permutation w2 r1 p1 w3 r2 p3 c3 p2 c2 c1 check +permutation w2 r1 p1 w3 r2 p3 c3 c1 p2 c2 check +permutation w2 r1 p1 w3 p3 r2 p2 c3 c1 c2 check +permutation w2 r1 p1 w3 p3 r2 p2 c3 c2 c1 check +permutation w2 r1 p1 w3 p3 r2 c3 p2 c1 c2 check +permutation w2 r1 p1 w3 p3 r2 c3 p2 c2 c1 check +permutation w2 r1 p1 w3 p3 r2 c3 c1 p2 c2 check +permutation w2 r1 p1 w3 p3 c3 r2 p2 c1 c2 check +permutation w2 r1 p1 w3 p3 c3 r2 p2 c2 c1 check +permutation w2 r1 p1 w3 p3 c3 r2 c1 p2 c2 check +permutation w2 r1 p1 w3 p3 c3 c1 r2 p2 c2 check +permutation w3 r1 r2 w2 p1 p2 p3 c3 c1 c2 check +permutation w3 r1 r2 w2 p1 p2 p3 c3 c2 c1 check +permutation w3 r1 r2 w2 p1 p3 p2 c3 c1 c2 check +permutation w3 r1 r2 w2 p1 p3 p2 c3 c2 c1 check +permutation w3 r1 r2 w2 p1 p3 c3 p2 c1 c2 check +permutation w3 r1 r2 w2 p1 p3 c3 p2 c2 c1 check +permutation w3 r1 r2 w2 p1 p3 c3 c1 p2 c2 check +permutation w3 r1 r2 w2 p2 p1 p3 c3 c1 c2 check +permutation w3 r1 r2 w2 p2 p1 p3 c3 c2 c1 check +permutation w3 r1 r2 w2 p2 p3 p1 c3 c1 c2 check +permutation w3 r1 r2 w2 p2 p3 p1 c3 c2 c1 check +permutation w3 r1 r2 w2 p2 p3 c3 p1 c1 c2 check +permutation w3 r1 r2 w2 p2 p3 c3 p1 c2 c1 check +permutation w3 r1 r2 w2 p2 p3 c3 c2 p1 c1 check +permutation w3 r1 r2 w2 p3 p1 p2 c3 c1 c2 check +permutation w3 r1 r2 w2 p3 p1 p2 c3 c2 c1 check +permutation w3 r1 r2 w2 p3 p1 c3 p2 c1 c2 check +permutation w3 r1 r2 w2 p3 p1 c3 p2 c2 c1 check +permutation w3 r1 r2 w2 p3 p1 c3 c1 p2 c2 check +permutation w3 r1 r2 w2 p3 p2 p1 c3 c1 c2 check +permutation w3 r1 r2 w2 p3 p2 p1 c3 c2 c1 check +permutation w3 r1 r2 w2 p3 p2 c3 p1 c1 c2 check +permutation w3 r1 r2 w2 p3 p2 c3 p1 c2 c1 check +permutation w3 r1 r2 w2 p3 p2 c3 c2 p1 c1 check +permutation w3 r1 r2 w2 p3 c3 p1 p2 c1 c2 check +permutation w3 r1 r2 w2 p3 c3 p1 p2 c2 c1 check +permutation w3 r1 r2 w2 p3 c3 p1 c1 p2 c2 check +permutation w3 r1 r2 w2 p3 c3 p2 p1 c1 c2 check +permutation w3 r1 r2 w2 p3 c3 p2 p1 c2 c1 check +permutation w3 r1 r2 w2 p3 c3 p2 c2 p1 c1 check +permutation w3 r1 r2 p1 w2 p2 p3 c3 c1 c2 check +permutation w3 r1 r2 p1 w2 p2 p3 c3 c2 c1 check +permutation w3 r1 r2 p1 w2 p3 p2 c3 c1 c2 check +permutation w3 r1 r2 p1 w2 p3 p2 c3 c2 c1 check +permutation w3 r1 r2 p1 w2 p3 c3 p2 c1 c2 check +permutation w3 r1 r2 p1 w2 p3 c3 p2 c2 c1 check +permutation w3 r1 r2 p1 w2 p3 c3 c1 p2 c2 check +permutation w3 r1 r2 p1 p3 w2 p2 c3 c1 c2 check +permutation w3 r1 r2 p1 p3 w2 p2 c3 c2 c1 check +permutation w3 r1 r2 p1 p3 w2 c3 p2 c1 c2 check +permutation w3 r1 r2 p1 p3 w2 c3 p2 c2 c1 check +permutation w3 r1 r2 p1 p3 w2 c3 c1 p2 c2 check +permutation w3 r1 r2 p1 p3 c3 w2 p2 c1 c2 check +permutation w3 r1 r2 p1 p3 c3 w2 p2 c2 c1 check +permutation w3 r1 r2 p1 p3 c3 w2 c1 p2 c2 check +permutation w3 r1 r2 p1 p3 c3 c1 w2 p2 c2 check +permutation w3 r1 r2 p3 w2 p1 p2 c3 c1 c2 check +permutation w3 r1 r2 p3 w2 p1 p2 c3 c2 c1 check +permutation w3 r1 r2 p3 w2 p1 c3 p2 c1 c2 check +permutation w3 r1 r2 p3 w2 p1 c3 p2 c2 c1 check +permutation w3 r1 r2 p3 w2 p1 c3 c1 p2 c2 check +permutation w3 r1 r2 p3 w2 p2 p1 c3 c1 c2 check +permutation w3 r1 r2 p3 w2 p2 p1 c3 c2 c1 check +permutation w3 r1 r2 p3 w2 p2 c3 p1 c1 c2 check +permutation w3 r1 r2 p3 w2 p2 c3 p1 c2 c1 check +permutation w3 r1 r2 p3 w2 p2 c3 c2 p1 c1 check +permutation w3 r1 r2 p3 w2 c3 p1 p2 c1 c2 check +permutation w3 r1 r2 p3 w2 c3 p1 p2 c2 c1 check +permutation w3 r1 r2 p3 w2 c3 p1 c1 p2 c2 check +permutation w3 r1 r2 p3 w2 c3 p2 p1 c1 c2 check +permutation w3 r1 r2 p3 w2 c3 p2 p1 c2 c1 check +permutation w3 r1 r2 p3 w2 c3 p2 c2 p1 c1 check +permutation w3 r1 r2 p3 p1 w2 p2 c3 c1 c2 check +permutation w3 r1 r2 p3 p1 w2 p2 c3 c2 c1 check +permutation w3 r1 r2 p3 p1 w2 c3 p2 c1 c2 check +permutation w3 r1 r2 p3 p1 w2 c3 p2 c2 c1 check +permutation w3 r1 r2 p3 p1 w2 c3 c1 p2 c2 check +permutation w3 r1 r2 p3 p1 c3 w2 p2 c1 c2 check +permutation w3 r1 r2 p3 p1 c3 w2 p2 c2 c1 check +permutation w3 r1 r2 p3 p1 c3 w2 c1 p2 c2 check +permutation w3 r1 r2 p3 p1 c3 c1 w2 p2 c2 check +permutation w3 r1 r2 p3 c3 w2 p1 p2 c1 c2 check +permutation w3 r1 r2 p3 c3 w2 p1 p2 c2 c1 check +permutation w3 r1 r2 p3 c3 w2 p1 c1 p2 c2 check +permutation w3 r1 r2 p3 c3 w2 p2 p1 c1 c2 check +permutation w3 r1 r2 p3 c3 w2 p2 p1 c2 c1 check +permutation w3 r1 r2 p3 c3 w2 p2 c2 p1 c1 check +permutation w3 r1 r2 p3 c3 p1 w2 p2 c1 c2 check +permutation w3 r1 r2 p3 c3 p1 w2 p2 c2 c1 check +permutation w3 r1 r2 p3 c3 p1 w2 c1 p2 c2 check +permutation w3 r1 r2 p3 c3 p1 c1 w2 p2 c2 check +permutation w3 r1 w2 r2 p1 p2 p3 c3 c1 c2 check +permutation w3 r1 w2 r2 p1 p2 p3 c3 c2 c1 check +permutation w3 r1 w2 r2 p1 p3 p2 c3 c1 c2 check +permutation w3 r1 w2 r2 p1 p3 p2 c3 c2 c1 check +permutation w3 r1 w2 r2 p1 p3 c3 p2 c1 c2 check +permutation w3 r1 w2 r2 p1 p3 c3 p2 c2 c1 check +permutation w3 r1 w2 r2 p1 p3 c3 c1 p2 c2 check +permutation w3 r1 w2 r2 p2 p1 p3 c3 c1 c2 check +permutation w3 r1 w2 r2 p2 p1 p3 c3 c2 c1 check +permutation w3 r1 w2 r2 p2 p3 p1 c3 c1 c2 check +permutation w3 r1 w2 r2 p2 p3 p1 c3 c2 c1 check +permutation w3 r1 w2 r2 p2 p3 c3 p1 c1 c2 check +permutation w3 r1 w2 r2 p2 p3 c3 p1 c2 c1 check +permutation w3 r1 w2 r2 p2 p3 c3 c2 p1 c1 check +permutation w3 r1 w2 r2 p3 p1 p2 c3 c1 c2 check +permutation w3 r1 w2 r2 p3 p1 p2 c3 c2 c1 check +permutation w3 r1 w2 r2 p3 p1 c3 p2 c1 c2 check +permutation w3 r1 w2 r2 p3 p1 c3 p2 c2 c1 check +permutation w3 r1 w2 r2 p3 p1 c3 c1 p2 c2 check +permutation w3 r1 w2 r2 p3 p2 p1 c3 c1 c2 check +permutation w3 r1 w2 r2 p3 p2 p1 c3 c2 c1 check +permutation w3 r1 w2 r2 p3 p2 c3 p1 c1 c2 check +permutation w3 r1 w2 r2 p3 p2 c3 p1 c2 c1 check +permutation w3 r1 w2 r2 p3 p2 c3 c2 p1 c1 check +permutation w3 r1 w2 r2 p3 c3 p1 p2 c1 c2 check +permutation w3 r1 w2 r2 p3 c3 p1 p2 c2 c1 check +permutation w3 r1 w2 r2 p3 c3 p1 c1 p2 c2 check +permutation w3 r1 w2 r2 p3 c3 p2 p1 c1 c2 check +permutation w3 r1 w2 r2 p3 c3 p2 p1 c2 c1 check +permutation w3 r1 w2 r2 p3 c3 p2 c2 p1 c1 check +permutation w3 r1 w2 p1 r2 p2 p3 c3 c1 c2 check +permutation w3 r1 w2 p1 r2 p2 p3 c3 c2 c1 check +permutation w3 r1 w2 p1 r2 p3 p2 c3 c1 c2 check +permutation w3 r1 w2 p1 r2 p3 p2 c3 c2 c1 check +permutation w3 r1 w2 p1 r2 p3 c3 p2 c1 c2 check +permutation w3 r1 w2 p1 r2 p3 c3 p2 c2 c1 check +permutation w3 r1 w2 p1 r2 p3 c3 c1 p2 c2 check +permutation w3 r1 w2 p1 p3 r2 p2 c3 c1 c2 check +permutation w3 r1 w2 p1 p3 r2 p2 c3 c2 c1 check +permutation w3 r1 w2 p1 p3 r2 c3 p2 c1 c2 check +permutation w3 r1 w2 p1 p3 r2 c3 p2 c2 c1 check +permutation w3 r1 w2 p1 p3 r2 c3 c1 p2 c2 check +permutation w3 r1 w2 p1 p3 c3 r2 p2 c1 c2 check +permutation w3 r1 w2 p1 p3 c3 r2 p2 c2 c1 check +permutation w3 r1 w2 p1 p3 c3 r2 c1 p2 c2 check +permutation w3 r1 w2 p1 p3 c3 c1 r2 p2 c2 check +permutation w3 r1 w2 p3 r2 p1 p2 c3 c1 c2 check +permutation w3 r1 w2 p3 r2 p1 p2 c3 c2 c1 check +permutation w3 r1 w2 p3 r2 p1 c3 p2 c1 c2 check +permutation w3 r1 w2 p3 r2 p1 c3 p2 c2 c1 check +permutation w3 r1 w2 p3 r2 p1 c3 c1 p2 c2 check +permutation w3 r1 w2 p3 r2 p2 p1 c3 c1 c2 check +permutation w3 r1 w2 p3 r2 p2 p1 c3 c2 c1 check +permutation w3 r1 w2 p3 r2 p2 c3 p1 c1 c2 check +permutation w3 r1 w2 p3 r2 p2 c3 p1 c2 c1 check +permutation w3 r1 w2 p3 r2 p2 c3 c2 p1 c1 check +permutation w3 r1 w2 p3 r2 c3 p1 p2 c1 c2 check +permutation w3 r1 w2 p3 r2 c3 p1 p2 c2 c1 check +permutation w3 r1 w2 p3 r2 c3 p1 c1 p2 c2 check +permutation w3 r1 w2 p3 r2 c3 p2 p1 c1 c2 check +permutation w3 r1 w2 p3 r2 c3 p2 p1 c2 c1 check +permutation w3 r1 w2 p3 r2 c3 p2 c2 p1 c1 check +permutation w3 r1 w2 p3 p1 r2 p2 c3 c1 c2 check +permutation w3 r1 w2 p3 p1 r2 p2 c3 c2 c1 check +permutation w3 r1 w2 p3 p1 r2 c3 p2 c1 c2 check +permutation w3 r1 w2 p3 p1 r2 c3 p2 c2 c1 check +permutation w3 r1 w2 p3 p1 r2 c3 c1 p2 c2 check +permutation w3 r1 w2 p3 p1 c3 r2 p2 c1 c2 check +permutation w3 r1 w2 p3 p1 c3 r2 p2 c2 c1 check +permutation w3 r1 w2 p3 p1 c3 r2 c1 p2 c2 check +permutation w3 r1 w2 p3 p1 c3 c1 r2 p2 c2 check +permutation w3 r1 w2 p3 c3 r2 p1 p2 c1 c2 check +permutation w3 r1 w2 p3 c3 r2 p1 p2 c2 c1 check +permutation w3 r1 w2 p3 c3 r2 p1 c1 p2 c2 check +permutation w3 r1 w2 p3 c3 r2 p2 p1 c1 c2 check +permutation w3 r1 w2 p3 c3 r2 p2 p1 c2 c1 check +permutation w3 r1 w2 p3 c3 r2 p2 c2 p1 c1 check +permutation w3 r1 w2 p3 c3 p1 r2 p2 c1 c2 check +permutation w3 r1 w2 p3 c3 p1 r2 p2 c2 c1 check +permutation w3 r1 w2 p3 c3 p1 r2 c1 p2 c2 check +permutation w3 r1 w2 p3 c3 p1 c1 r2 p2 c2 check +permutation w3 r1 p1 r2 w2 p2 p3 c3 c1 c2 check +permutation w3 r1 p1 r2 w2 p2 p3 c3 c2 c1 check +permutation w3 r1 p1 r2 w2 p3 p2 c3 c1 c2 check +permutation w3 r1 p1 r2 w2 p3 p2 c3 c2 c1 check +permutation w3 r1 p1 r2 w2 p3 c3 p2 c1 c2 check +permutation w3 r1 p1 r2 w2 p3 c3 p2 c2 c1 check +permutation w3 r1 p1 r2 w2 p3 c3 c1 p2 c2 check +permutation w3 r1 p1 r2 p3 w2 p2 c3 c1 c2 check +permutation w3 r1 p1 r2 p3 w2 p2 c3 c2 c1 check +permutation w3 r1 p1 r2 p3 w2 c3 p2 c1 c2 check +permutation w3 r1 p1 r2 p3 w2 c3 p2 c2 c1 check +permutation w3 r1 p1 r2 p3 w2 c3 c1 p2 c2 check +permutation w3 r1 p1 r2 p3 c3 w2 p2 c1 c2 check +permutation w3 r1 p1 r2 p3 c3 w2 p2 c2 c1 check +permutation w3 r1 p1 r2 p3 c3 w2 c1 p2 c2 check +permutation w3 r1 p1 r2 p3 c3 c1 w2 p2 c2 check +permutation w3 r1 p1 w2 r2 p2 p3 c3 c1 c2 check +permutation w3 r1 p1 w2 r2 p2 p3 c3 c2 c1 check +permutation w3 r1 p1 w2 r2 p3 p2 c3 c1 c2 check +permutation w3 r1 p1 w2 r2 p3 p2 c3 c2 c1 check +permutation w3 r1 p1 w2 r2 p3 c3 p2 c1 c2 check +permutation w3 r1 p1 w2 r2 p3 c3 p2 c2 c1 check +permutation w3 r1 p1 w2 r2 p3 c3 c1 p2 c2 check +permutation w3 r1 p1 w2 p3 r2 p2 c3 c1 c2 check +permutation w3 r1 p1 w2 p3 r2 p2 c3 c2 c1 check +permutation w3 r1 p1 w2 p3 r2 c3 p2 c1 c2 check +permutation w3 r1 p1 w2 p3 r2 c3 p2 c2 c1 check +permutation w3 r1 p1 w2 p3 r2 c3 c1 p2 c2 check +permutation w3 r1 p1 w2 p3 c3 r2 p2 c1 c2 check +permutation w3 r1 p1 w2 p3 c3 r2 p2 c2 c1 check +permutation w3 r1 p1 w2 p3 c3 r2 c1 p2 c2 check +permutation w3 r1 p1 w2 p3 c3 c1 r2 p2 c2 check +permutation w3 r1 p1 p3 r2 w2 p2 c3 c1 c2 check +permutation w3 r1 p1 p3 r2 w2 p2 c3 c2 c1 check +permutation w3 r1 p1 p3 r2 w2 c3 p2 c1 c2 check +permutation w3 r1 p1 p3 r2 w2 c3 p2 c2 c1 check +permutation w3 r1 p1 p3 r2 w2 c3 c1 p2 c2 check +permutation w3 r1 p1 p3 r2 c3 w2 p2 c1 c2 check +permutation w3 r1 p1 p3 r2 c3 w2 p2 c2 c1 check +permutation w3 r1 p1 p3 r2 c3 w2 c1 p2 c2 check +permutation w3 r1 p1 p3 r2 c3 c1 w2 p2 c2 check +permutation w3 r1 p1 p3 w2 r2 p2 c3 c1 c2 check +permutation w3 r1 p1 p3 w2 r2 p2 c3 c2 c1 check +permutation w3 r1 p1 p3 w2 r2 c3 p2 c1 c2 check +permutation w3 r1 p1 p3 w2 r2 c3 p2 c2 c1 check +permutation w3 r1 p1 p3 w2 r2 c3 c1 p2 c2 check +permutation w3 r1 p1 p3 w2 c3 r2 p2 c1 c2 check +permutation w3 r1 p1 p3 w2 c3 r2 p2 c2 c1 check +permutation w3 r1 p1 p3 w2 c3 r2 c1 p2 c2 check +permutation w3 r1 p1 p3 w2 c3 c1 r2 p2 c2 check +permutation w3 r1 p1 p3 c3 r2 w2 p2 c1 c2 check +permutation w3 r1 p1 p3 c3 r2 w2 p2 c2 c1 check +permutation w3 r1 p1 p3 c3 r2 w2 c1 p2 c2 check +permutation w3 r1 p1 p3 c3 r2 c1 w2 p2 c2 check +permutation w3 r1 p1 p3 c3 w2 r2 p2 c1 c2 check +permutation w3 r1 p1 p3 c3 w2 r2 p2 c2 c1 check +permutation w3 r1 p1 p3 c3 w2 r2 c1 p2 c2 check +permutation w3 r1 p1 p3 c3 w2 c1 r2 p2 c2 check +permutation w3 r1 p1 p3 c3 c1 r2 w2 p2 c2 check +permutation w3 r1 p1 p3 c3 c1 w2 r2 p2 c2 check +permutation w3 r1 p3 r2 w2 p1 p2 c3 c1 c2 check +permutation w3 r1 p3 r2 w2 p1 p2 c3 c2 c1 check +permutation w3 r1 p3 r2 w2 p1 c3 p2 c1 c2 check +permutation w3 r1 p3 r2 w2 p1 c3 p2 c2 c1 check +permutation w3 r1 p3 r2 w2 p1 c3 c1 p2 c2 check +permutation w3 r1 p3 r2 w2 p2 p1 c3 c1 c2 check +permutation w3 r1 p3 r2 w2 p2 p1 c3 c2 c1 check +permutation w3 r1 p3 r2 w2 p2 c3 p1 c1 c2 check +permutation w3 r1 p3 r2 w2 p2 c3 p1 c2 c1 check +permutation w3 r1 p3 r2 w2 p2 c3 c2 p1 c1 check +permutation w3 r1 p3 r2 w2 c3 p1 p2 c1 c2 check +permutation w3 r1 p3 r2 w2 c3 p1 p2 c2 c1 check +permutation w3 r1 p3 r2 w2 c3 p1 c1 p2 c2 check +permutation w3 r1 p3 r2 w2 c3 p2 p1 c1 c2 check +permutation w3 r1 p3 r2 w2 c3 p2 p1 c2 c1 check +permutation w3 r1 p3 r2 w2 c3 p2 c2 p1 c1 check +permutation w3 r1 p3 r2 p1 w2 p2 c3 c1 c2 check +permutation w3 r1 p3 r2 p1 w2 p2 c3 c2 c1 check +permutation w3 r1 p3 r2 p1 w2 c3 p2 c1 c2 check +permutation w3 r1 p3 r2 p1 w2 c3 p2 c2 c1 check +permutation w3 r1 p3 r2 p1 w2 c3 c1 p2 c2 check +permutation w3 r1 p3 r2 p1 c3 w2 p2 c1 c2 check +permutation w3 r1 p3 r2 p1 c3 w2 p2 c2 c1 check +permutation w3 r1 p3 r2 p1 c3 w2 c1 p2 c2 check +permutation w3 r1 p3 r2 p1 c3 c1 w2 p2 c2 check +permutation w3 r1 p3 r2 c3 w2 p1 p2 c1 c2 check +permutation w3 r1 p3 r2 c3 w2 p1 p2 c2 c1 check +permutation w3 r1 p3 r2 c3 w2 p1 c1 p2 c2 check +permutation w3 r1 p3 r2 c3 w2 p2 p1 c1 c2 check +permutation w3 r1 p3 r2 c3 w2 p2 p1 c2 c1 check +permutation w3 r1 p3 r2 c3 w2 p2 c2 p1 c1 check +permutation w3 r1 p3 r2 c3 p1 w2 p2 c1 c2 check +permutation w3 r1 p3 r2 c3 p1 w2 p2 c2 c1 check +permutation w3 r1 p3 r2 c3 p1 w2 c1 p2 c2 check +permutation w3 r1 p3 r2 c3 p1 c1 w2 p2 c2 check +permutation w3 r1 p3 w2 r2 p1 p2 c3 c1 c2 check +permutation w3 r1 p3 w2 r2 p1 p2 c3 c2 c1 check +permutation w3 r1 p3 w2 r2 p1 c3 p2 c1 c2 check +permutation w3 r1 p3 w2 r2 p1 c3 p2 c2 c1 check +permutation w3 r1 p3 w2 r2 p1 c3 c1 p2 c2 check +permutation w3 r1 p3 w2 r2 p2 p1 c3 c1 c2 check +permutation w3 r1 p3 w2 r2 p2 p1 c3 c2 c1 check +permutation w3 r1 p3 w2 r2 p2 c3 p1 c1 c2 check +permutation w3 r1 p3 w2 r2 p2 c3 p1 c2 c1 check +permutation w3 r1 p3 w2 r2 p2 c3 c2 p1 c1 check +permutation w3 r1 p3 w2 r2 c3 p1 p2 c1 c2 check +permutation w3 r1 p3 w2 r2 c3 p1 p2 c2 c1 check +permutation w3 r1 p3 w2 r2 c3 p1 c1 p2 c2 check +permutation w3 r1 p3 w2 r2 c3 p2 p1 c1 c2 check +permutation w3 r1 p3 w2 r2 c3 p2 p1 c2 c1 check +permutation w3 r1 p3 w2 r2 c3 p2 c2 p1 c1 check +permutation w3 r1 p3 w2 p1 r2 p2 c3 c1 c2 check +permutation w3 r1 p3 w2 p1 r2 p2 c3 c2 c1 check +permutation w3 r1 p3 w2 p1 r2 c3 p2 c1 c2 check +permutation w3 r1 p3 w2 p1 r2 c3 p2 c2 c1 check +permutation w3 r1 p3 w2 p1 r2 c3 c1 p2 c2 check +permutation w3 r1 p3 w2 p1 c3 r2 p2 c1 c2 check +permutation w3 r1 p3 w2 p1 c3 r2 p2 c2 c1 check +permutation w3 r1 p3 w2 p1 c3 r2 c1 p2 c2 check +permutation w3 r1 p3 w2 p1 c3 c1 r2 p2 c2 check +permutation w3 r1 p3 w2 c3 r2 p1 p2 c1 c2 check +permutation w3 r1 p3 w2 c3 r2 p1 p2 c2 c1 check +permutation w3 r1 p3 w2 c3 r2 p1 c1 p2 c2 check +permutation w3 r1 p3 w2 c3 r2 p2 p1 c1 c2 check +permutation w3 r1 p3 w2 c3 r2 p2 p1 c2 c1 check +permutation w3 r1 p3 w2 c3 r2 p2 c2 p1 c1 check +permutation w3 r1 p3 w2 c3 p1 r2 p2 c1 c2 check +permutation w3 r1 p3 w2 c3 p1 r2 p2 c2 c1 check +permutation w3 r1 p3 w2 c3 p1 r2 c1 p2 c2 check +permutation w3 r1 p3 w2 c3 p1 c1 r2 p2 c2 check +permutation w3 r1 p3 p1 r2 w2 p2 c3 c1 c2 check +permutation w3 r1 p3 p1 r2 w2 p2 c3 c2 c1 check +permutation w3 r1 p3 p1 r2 w2 c3 p2 c1 c2 check +permutation w3 r1 p3 p1 r2 w2 c3 p2 c2 c1 check +permutation w3 r1 p3 p1 r2 w2 c3 c1 p2 c2 check +permutation w3 r1 p3 p1 r2 c3 w2 p2 c1 c2 check +permutation w3 r1 p3 p1 r2 c3 w2 p2 c2 c1 check +permutation w3 r1 p3 p1 r2 c3 w2 c1 p2 c2 check +permutation w3 r1 p3 p1 r2 c3 c1 w2 p2 c2 check +permutation w3 r1 p3 p1 w2 r2 p2 c3 c1 c2 check +permutation w3 r1 p3 p1 w2 r2 p2 c3 c2 c1 check +permutation w3 r1 p3 p1 w2 r2 c3 p2 c1 c2 check +permutation w3 r1 p3 p1 w2 r2 c3 p2 c2 c1 check +permutation w3 r1 p3 p1 w2 r2 c3 c1 p2 c2 check +permutation w3 r1 p3 p1 w2 c3 r2 p2 c1 c2 check +permutation w3 r1 p3 p1 w2 c3 r2 p2 c2 c1 check +permutation w3 r1 p3 p1 w2 c3 r2 c1 p2 c2 check +permutation w3 r1 p3 p1 w2 c3 c1 r2 p2 c2 check +permutation w3 r1 p3 p1 c3 r2 w2 p2 c1 c2 check +permutation w3 r1 p3 p1 c3 r2 w2 p2 c2 c1 check +permutation w3 r1 p3 p1 c3 r2 w2 c1 p2 c2 check +permutation w3 r1 p3 p1 c3 r2 c1 w2 p2 c2 check +permutation w3 r1 p3 p1 c3 w2 r2 p2 c1 c2 check +permutation w3 r1 p3 p1 c3 w2 r2 p2 c2 c1 check +permutation w3 r1 p3 p1 c3 w2 r2 c1 p2 c2 check +permutation w3 r1 p3 p1 c3 w2 c1 r2 p2 c2 check +permutation w3 r1 p3 p1 c3 c1 r2 w2 p2 c2 check +permutation w3 r1 p3 p1 c3 c1 w2 r2 p2 c2 check +permutation w3 r1 p3 c3 r2 w2 p1 p2 c1 c2 check +permutation w3 r1 p3 c3 r2 w2 p1 p2 c2 c1 check +permutation w3 r1 p3 c3 r2 w2 p1 c1 p2 c2 check +permutation w3 r1 p3 c3 r2 w2 p2 p1 c1 c2 check +permutation w3 r1 p3 c3 r2 w2 p2 p1 c2 c1 check +permutation w3 r1 p3 c3 r2 w2 p2 c2 p1 c1 check +permutation w3 r1 p3 c3 r2 p1 w2 p2 c1 c2 check +permutation w3 r1 p3 c3 r2 p1 w2 p2 c2 c1 check +permutation w3 r1 p3 c3 r2 p1 w2 c1 p2 c2 check +permutation w3 r1 p3 c3 r2 p1 c1 w2 p2 c2 check +permutation w3 r1 p3 c3 w2 r2 p1 p2 c1 c2 check +permutation w3 r1 p3 c3 w2 r2 p1 p2 c2 c1 check +permutation w3 r1 p3 c3 w2 r2 p1 c1 p2 c2 check +permutation w3 r1 p3 c3 w2 r2 p2 p1 c1 c2 check +permutation w3 r1 p3 c3 w2 r2 p2 p1 c2 c1 check +permutation w3 r1 p3 c3 w2 r2 p2 c2 p1 c1 check +permutation w3 r1 p3 c3 w2 p1 r2 p2 c1 c2 check +permutation w3 r1 p3 c3 w2 p1 r2 p2 c2 c1 check +permutation w3 r1 p3 c3 w2 p1 r2 c1 p2 c2 check +permutation w3 r1 p3 c3 w2 p1 c1 r2 p2 c2 check +permutation w3 r1 p3 c3 p1 r2 w2 p2 c1 c2 check +permutation w3 r1 p3 c3 p1 r2 w2 p2 c2 c1 check +permutation w3 r1 p3 c3 p1 r2 w2 c1 p2 c2 check +permutation w3 r1 p3 c3 p1 r2 c1 w2 p2 c2 check +permutation w3 r1 p3 c3 p1 w2 r2 p2 c1 c2 check +permutation w3 r1 p3 c3 p1 w2 r2 p2 c2 c1 check +permutation w3 r1 p3 c3 p1 w2 r2 c1 p2 c2 check +permutation w3 r1 p3 c3 p1 w2 c1 r2 p2 c2 check +permutation w3 r1 p3 c3 p1 c1 r2 w2 p2 c2 check +permutation w3 r1 p3 c3 p1 c1 w2 r2 p2 c2 check +permutation w3 r2 r1 w2 p1 p2 p3 c3 c1 c2 check +permutation w3 r2 r1 w2 p1 p2 p3 c3 c2 c1 check +permutation w3 r2 r1 w2 p1 p3 p2 c3 c1 c2 check +permutation w3 r2 r1 w2 p1 p3 p2 c3 c2 c1 check +permutation w3 r2 r1 w2 p1 p3 c3 p2 c1 c2 check +permutation w3 r2 r1 w2 p1 p3 c3 p2 c2 c1 check +permutation w3 r2 r1 w2 p1 p3 c3 c1 p2 c2 check +permutation w3 r2 r1 w2 p2 p1 p3 c3 c1 c2 check +permutation w3 r2 r1 w2 p2 p1 p3 c3 c2 c1 check +permutation w3 r2 r1 w2 p2 p3 p1 c3 c1 c2 check +permutation w3 r2 r1 w2 p2 p3 p1 c3 c2 c1 check +permutation w3 r2 r1 w2 p2 p3 c3 p1 c1 c2 check +permutation w3 r2 r1 w2 p2 p3 c3 p1 c2 c1 check +permutation w3 r2 r1 w2 p2 p3 c3 c2 p1 c1 check +permutation w3 r2 r1 w2 p3 p1 p2 c3 c1 c2 check +permutation w3 r2 r1 w2 p3 p1 p2 c3 c2 c1 check +permutation w3 r2 r1 w2 p3 p1 c3 p2 c1 c2 check +permutation w3 r2 r1 w2 p3 p1 c3 p2 c2 c1 check +permutation w3 r2 r1 w2 p3 p1 c3 c1 p2 c2 check +permutation w3 r2 r1 w2 p3 p2 p1 c3 c1 c2 check +permutation w3 r2 r1 w2 p3 p2 p1 c3 c2 c1 check +permutation w3 r2 r1 w2 p3 p2 c3 p1 c1 c2 check +permutation w3 r2 r1 w2 p3 p2 c3 p1 c2 c1 check +permutation w3 r2 r1 w2 p3 p2 c3 c2 p1 c1 check +permutation w3 r2 r1 w2 p3 c3 p1 p2 c1 c2 check +permutation w3 r2 r1 w2 p3 c3 p1 p2 c2 c1 check +permutation w3 r2 r1 w2 p3 c3 p1 c1 p2 c2 check +permutation w3 r2 r1 w2 p3 c3 p2 p1 c1 c2 check +permutation w3 r2 r1 w2 p3 c3 p2 p1 c2 c1 check +permutation w3 r2 r1 w2 p3 c3 p2 c2 p1 c1 check +permutation w3 r2 r1 p1 w2 p2 p3 c3 c1 c2 check +permutation w3 r2 r1 p1 w2 p2 p3 c3 c2 c1 check +permutation w3 r2 r1 p1 w2 p3 p2 c3 c1 c2 check +permutation w3 r2 r1 p1 w2 p3 p2 c3 c2 c1 check +permutation w3 r2 r1 p1 w2 p3 c3 p2 c1 c2 check +permutation w3 r2 r1 p1 w2 p3 c3 p2 c2 c1 check +permutation w3 r2 r1 p1 w2 p3 c3 c1 p2 c2 check +permutation w3 r2 r1 p1 p3 w2 p2 c3 c1 c2 check +permutation w3 r2 r1 p1 p3 w2 p2 c3 c2 c1 check +permutation w3 r2 r1 p1 p3 w2 c3 p2 c1 c2 check +permutation w3 r2 r1 p1 p3 w2 c3 p2 c2 c1 check +permutation w3 r2 r1 p1 p3 w2 c3 c1 p2 c2 check +permutation w3 r2 r1 p1 p3 c3 w2 p2 c1 c2 check +permutation w3 r2 r1 p1 p3 c3 w2 p2 c2 c1 check +permutation w3 r2 r1 p1 p3 c3 w2 c1 p2 c2 check +permutation w3 r2 r1 p1 p3 c3 c1 w2 p2 c2 check +permutation w3 r2 r1 p3 w2 p1 p2 c3 c1 c2 check +permutation w3 r2 r1 p3 w2 p1 p2 c3 c2 c1 check +permutation w3 r2 r1 p3 w2 p1 c3 p2 c1 c2 check +permutation w3 r2 r1 p3 w2 p1 c3 p2 c2 c1 check +permutation w3 r2 r1 p3 w2 p1 c3 c1 p2 c2 check +permutation w3 r2 r1 p3 w2 p2 p1 c3 c1 c2 check +permutation w3 r2 r1 p3 w2 p2 p1 c3 c2 c1 check +permutation w3 r2 r1 p3 w2 p2 c3 p1 c1 c2 check +permutation w3 r2 r1 p3 w2 p2 c3 p1 c2 c1 check +permutation w3 r2 r1 p3 w2 p2 c3 c2 p1 c1 check +permutation w3 r2 r1 p3 w2 c3 p1 p2 c1 c2 check +permutation w3 r2 r1 p3 w2 c3 p1 p2 c2 c1 check +permutation w3 r2 r1 p3 w2 c3 p1 c1 p2 c2 check +permutation w3 r2 r1 p3 w2 c3 p2 p1 c1 c2 check +permutation w3 r2 r1 p3 w2 c3 p2 p1 c2 c1 check +permutation w3 r2 r1 p3 w2 c3 p2 c2 p1 c1 check +permutation w3 r2 r1 p3 p1 w2 p2 c3 c1 c2 check +permutation w3 r2 r1 p3 p1 w2 p2 c3 c2 c1 check +permutation w3 r2 r1 p3 p1 w2 c3 p2 c1 c2 check +permutation w3 r2 r1 p3 p1 w2 c3 p2 c2 c1 check +permutation w3 r2 r1 p3 p1 w2 c3 c1 p2 c2 check +permutation w3 r2 r1 p3 p1 c3 w2 p2 c1 c2 check +permutation w3 r2 r1 p3 p1 c3 w2 p2 c2 c1 check +permutation w3 r2 r1 p3 p1 c3 w2 c1 p2 c2 check +permutation w3 r2 r1 p3 p1 c3 c1 w2 p2 c2 check +permutation w3 r2 r1 p3 c3 w2 p1 p2 c1 c2 check +permutation w3 r2 r1 p3 c3 w2 p1 p2 c2 c1 check +permutation w3 r2 r1 p3 c3 w2 p1 c1 p2 c2 check +permutation w3 r2 r1 p3 c3 w2 p2 p1 c1 c2 check +permutation w3 r2 r1 p3 c3 w2 p2 p1 c2 c1 check +permutation w3 r2 r1 p3 c3 w2 p2 c2 p1 c1 check +permutation w3 r2 r1 p3 c3 p1 w2 p2 c1 c2 check +permutation w3 r2 r1 p3 c3 p1 w2 p2 c2 c1 check +permutation w3 r2 r1 p3 c3 p1 w2 c1 p2 c2 check +permutation w3 r2 r1 p3 c3 p1 c1 w2 p2 c2 check +permutation w3 r2 p3 r1 w2 p1 p2 c3 c1 c2 check +permutation w3 r2 p3 r1 w2 p1 p2 c3 c2 c1 check +permutation w3 r2 p3 r1 w2 p1 c3 p2 c1 c2 check +permutation w3 r2 p3 r1 w2 p1 c3 p2 c2 c1 check +permutation w3 r2 p3 r1 w2 p1 c3 c1 p2 c2 check +permutation w3 r2 p3 r1 w2 p2 p1 c3 c1 c2 check +permutation w3 r2 p3 r1 w2 p2 p1 c3 c2 c1 check +permutation w3 r2 p3 r1 w2 p2 c3 p1 c1 c2 check +permutation w3 r2 p3 r1 w2 p2 c3 p1 c2 c1 check +permutation w3 r2 p3 r1 w2 p2 c3 c2 p1 c1 check +permutation w3 r2 p3 r1 w2 c3 p1 p2 c1 c2 check +permutation w3 r2 p3 r1 w2 c3 p1 p2 c2 c1 check +permutation w3 r2 p3 r1 w2 c3 p1 c1 p2 c2 check +permutation w3 r2 p3 r1 w2 c3 p2 p1 c1 c2 check +permutation w3 r2 p3 r1 w2 c3 p2 p1 c2 c1 check +permutation w3 r2 p3 r1 w2 c3 p2 c2 p1 c1 check +permutation w3 r2 p3 r1 p1 w2 p2 c3 c1 c2 check +permutation w3 r2 p3 r1 p1 w2 p2 c3 c2 c1 check +permutation w3 r2 p3 r1 p1 w2 c3 p2 c1 c2 check +permutation w3 r2 p3 r1 p1 w2 c3 p2 c2 c1 check +permutation w3 r2 p3 r1 p1 w2 c3 c1 p2 c2 check +permutation w3 r2 p3 r1 p1 c3 w2 p2 c1 c2 check +permutation w3 r2 p3 r1 p1 c3 w2 p2 c2 c1 check +permutation w3 r2 p3 r1 p1 c3 w2 c1 p2 c2 check +permutation w3 r2 p3 r1 p1 c3 c1 w2 p2 c2 check +permutation w3 r2 p3 r1 c3 w2 p1 p2 c1 c2 check +permutation w3 r2 p3 r1 c3 w2 p1 p2 c2 c1 check +permutation w3 r2 p3 r1 c3 w2 p1 c1 p2 c2 check +permutation w3 r2 p3 r1 c3 w2 p2 p1 c1 c2 check +permutation w3 r2 p3 r1 c3 w2 p2 p1 c2 c1 check +permutation w3 r2 p3 r1 c3 w2 p2 c2 p1 c1 check +permutation w3 r2 p3 r1 c3 p1 w2 p2 c1 c2 check +permutation w3 r2 p3 r1 c3 p1 w2 p2 c2 c1 check +permutation w3 r2 p3 r1 c3 p1 w2 c1 p2 c2 check +permutation w3 r2 p3 r1 c3 p1 c1 w2 p2 c2 check +permutation w3 r2 p3 c3 r1 w2 p1 p2 c1 c2 check +permutation w3 r2 p3 c3 r1 w2 p1 p2 c2 c1 check +permutation w3 r2 p3 c3 r1 w2 p1 c1 p2 c2 check +permutation w3 r2 p3 c3 r1 w2 p2 p1 c1 c2 check +permutation w3 r2 p3 c3 r1 w2 p2 p1 c2 c1 check +permutation w3 r2 p3 c3 r1 w2 p2 c2 p1 c1 check +permutation w3 r2 p3 c3 r1 p1 w2 p2 c1 c2 check +permutation w3 r2 p3 c3 r1 p1 w2 p2 c2 c1 check +permutation w3 r2 p3 c3 r1 p1 w2 c1 p2 c2 check +permutation w3 r2 p3 c3 r1 p1 c1 w2 p2 c2 check +permutation w3 p3 r1 r2 w2 p1 p2 c3 c1 c2 check +permutation w3 p3 r1 r2 w2 p1 p2 c3 c2 c1 check +permutation w3 p3 r1 r2 w2 p1 c3 p2 c1 c2 check +permutation w3 p3 r1 r2 w2 p1 c3 p2 c2 c1 check +permutation w3 p3 r1 r2 w2 p1 c3 c1 p2 c2 check +permutation w3 p3 r1 r2 w2 p2 p1 c3 c1 c2 check +permutation w3 p3 r1 r2 w2 p2 p1 c3 c2 c1 check +permutation w3 p3 r1 r2 w2 p2 c3 p1 c1 c2 check +permutation w3 p3 r1 r2 w2 p2 c3 p1 c2 c1 check +permutation w3 p3 r1 r2 w2 p2 c3 c2 p1 c1 check +permutation w3 p3 r1 r2 w2 c3 p1 p2 c1 c2 check +permutation w3 p3 r1 r2 w2 c3 p1 p2 c2 c1 check +permutation w3 p3 r1 r2 w2 c3 p1 c1 p2 c2 check +permutation w3 p3 r1 r2 w2 c3 p2 p1 c1 c2 check +permutation w3 p3 r1 r2 w2 c3 p2 p1 c2 c1 check +permutation w3 p3 r1 r2 w2 c3 p2 c2 p1 c1 check +permutation w3 p3 r1 r2 p1 w2 p2 c3 c1 c2 check +permutation w3 p3 r1 r2 p1 w2 p2 c3 c2 c1 check +permutation w3 p3 r1 r2 p1 w2 c3 p2 c1 c2 check +permutation w3 p3 r1 r2 p1 w2 c3 p2 c2 c1 check +permutation w3 p3 r1 r2 p1 w2 c3 c1 p2 c2 check +permutation w3 p3 r1 r2 p1 c3 w2 p2 c1 c2 check +permutation w3 p3 r1 r2 p1 c3 w2 p2 c2 c1 check +permutation w3 p3 r1 r2 p1 c3 w2 c1 p2 c2 check +permutation w3 p3 r1 r2 p1 c3 c1 w2 p2 c2 check +permutation w3 p3 r1 r2 c3 w2 p1 p2 c1 c2 check +permutation w3 p3 r1 r2 c3 w2 p1 p2 c2 c1 check +permutation w3 p3 r1 r2 c3 w2 p1 c1 p2 c2 check +permutation w3 p3 r1 r2 c3 w2 p2 p1 c1 c2 check +permutation w3 p3 r1 r2 c3 w2 p2 p1 c2 c1 check +permutation w3 p3 r1 r2 c3 w2 p2 c2 p1 c1 check +permutation w3 p3 r1 r2 c3 p1 w2 p2 c1 c2 check +permutation w3 p3 r1 r2 c3 p1 w2 p2 c2 c1 check +permutation w3 p3 r1 r2 c3 p1 w2 c1 p2 c2 check +permutation w3 p3 r1 r2 c3 p1 c1 w2 p2 c2 check +permutation w3 p3 r1 w2 r2 p1 p2 c3 c1 c2 check +permutation w3 p3 r1 w2 r2 p1 p2 c3 c2 c1 check +permutation w3 p3 r1 w2 r2 p1 c3 p2 c1 c2 check +permutation w3 p3 r1 w2 r2 p1 c3 p2 c2 c1 check +permutation w3 p3 r1 w2 r2 p1 c3 c1 p2 c2 check +permutation w3 p3 r1 w2 r2 p2 p1 c3 c1 c2 check +permutation w3 p3 r1 w2 r2 p2 p1 c3 c2 c1 check +permutation w3 p3 r1 w2 r2 p2 c3 p1 c1 c2 check +permutation w3 p3 r1 w2 r2 p2 c3 p1 c2 c1 check +permutation w3 p3 r1 w2 r2 p2 c3 c2 p1 c1 check +permutation w3 p3 r1 w2 r2 c3 p1 p2 c1 c2 check +permutation w3 p3 r1 w2 r2 c3 p1 p2 c2 c1 check +permutation w3 p3 r1 w2 r2 c3 p1 c1 p2 c2 check +permutation w3 p3 r1 w2 r2 c3 p2 p1 c1 c2 check +permutation w3 p3 r1 w2 r2 c3 p2 p1 c2 c1 check +permutation w3 p3 r1 w2 r2 c3 p2 c2 p1 c1 check +permutation w3 p3 r1 w2 p1 r2 p2 c3 c1 c2 check +permutation w3 p3 r1 w2 p1 r2 p2 c3 c2 c1 check +permutation w3 p3 r1 w2 p1 r2 c3 p2 c1 c2 check +permutation w3 p3 r1 w2 p1 r2 c3 p2 c2 c1 check +permutation w3 p3 r1 w2 p1 r2 c3 c1 p2 c2 check +permutation w3 p3 r1 w2 p1 c3 r2 p2 c1 c2 check +permutation w3 p3 r1 w2 p1 c3 r2 p2 c2 c1 check +permutation w3 p3 r1 w2 p1 c3 r2 c1 p2 c2 check +permutation w3 p3 r1 w2 p1 c3 c1 r2 p2 c2 check +permutation w3 p3 r1 w2 c3 r2 p1 p2 c1 c2 check +permutation w3 p3 r1 w2 c3 r2 p1 p2 c2 c1 check +permutation w3 p3 r1 w2 c3 r2 p1 c1 p2 c2 check +permutation w3 p3 r1 w2 c3 r2 p2 p1 c1 c2 check +permutation w3 p3 r1 w2 c3 r2 p2 p1 c2 c1 check +permutation w3 p3 r1 w2 c3 r2 p2 c2 p1 c1 check +permutation w3 p3 r1 w2 c3 p1 r2 p2 c1 c2 check +permutation w3 p3 r1 w2 c3 p1 r2 p2 c2 c1 check +permutation w3 p3 r1 w2 c3 p1 r2 c1 p2 c2 check +permutation w3 p3 r1 w2 c3 p1 c1 r2 p2 c2 check +permutation w3 p3 r1 p1 r2 w2 p2 c3 c1 c2 check +permutation w3 p3 r1 p1 r2 w2 p2 c3 c2 c1 check +permutation w3 p3 r1 p1 r2 w2 c3 p2 c1 c2 check +permutation w3 p3 r1 p1 r2 w2 c3 p2 c2 c1 check +permutation w3 p3 r1 p1 r2 w2 c3 c1 p2 c2 check +permutation w3 p3 r1 p1 r2 c3 w2 p2 c1 c2 check +permutation w3 p3 r1 p1 r2 c3 w2 p2 c2 c1 check +permutation w3 p3 r1 p1 r2 c3 w2 c1 p2 c2 check +permutation w3 p3 r1 p1 r2 c3 c1 w2 p2 c2 check +permutation w3 p3 r1 p1 w2 r2 p2 c3 c1 c2 check +permutation w3 p3 r1 p1 w2 r2 p2 c3 c2 c1 check +permutation w3 p3 r1 p1 w2 r2 c3 p2 c1 c2 check +permutation w3 p3 r1 p1 w2 r2 c3 p2 c2 c1 check +permutation w3 p3 r1 p1 w2 r2 c3 c1 p2 c2 check +permutation w3 p3 r1 p1 w2 c3 r2 p2 c1 c2 check +permutation w3 p3 r1 p1 w2 c3 r2 p2 c2 c1 check +permutation w3 p3 r1 p1 w2 c3 r2 c1 p2 c2 check +permutation w3 p3 r1 p1 w2 c3 c1 r2 p2 c2 check +permutation w3 p3 r1 p1 c3 r2 w2 p2 c1 c2 check +permutation w3 p3 r1 p1 c3 r2 w2 p2 c2 c1 check +permutation w3 p3 r1 p1 c3 r2 w2 c1 p2 c2 check +permutation w3 p3 r1 p1 c3 r2 c1 w2 p2 c2 check +permutation w3 p3 r1 p1 c3 w2 r2 p2 c1 c2 check +permutation w3 p3 r1 p1 c3 w2 r2 p2 c2 c1 check +permutation w3 p3 r1 p1 c3 w2 r2 c1 p2 c2 check +permutation w3 p3 r1 p1 c3 w2 c1 r2 p2 c2 check +permutation w3 p3 r1 p1 c3 c1 r2 w2 p2 c2 check +permutation w3 p3 r1 p1 c3 c1 w2 r2 p2 c2 check +permutation w3 p3 r1 c3 r2 w2 p1 p2 c1 c2 check +permutation w3 p3 r1 c3 r2 w2 p1 p2 c2 c1 check +permutation w3 p3 r1 c3 r2 w2 p1 c1 p2 c2 check +permutation w3 p3 r1 c3 r2 w2 p2 p1 c1 c2 check +permutation w3 p3 r1 c3 r2 w2 p2 p1 c2 c1 check +permutation w3 p3 r1 c3 r2 w2 p2 c2 p1 c1 check +permutation w3 p3 r1 c3 r2 p1 w2 p2 c1 c2 check +permutation w3 p3 r1 c3 r2 p1 w2 p2 c2 c1 check +permutation w3 p3 r1 c3 r2 p1 w2 c1 p2 c2 check +permutation w3 p3 r1 c3 r2 p1 c1 w2 p2 c2 check +permutation w3 p3 r1 c3 w2 r2 p1 p2 c1 c2 check +permutation w3 p3 r1 c3 w2 r2 p1 p2 c2 c1 check +permutation w3 p3 r1 c3 w2 r2 p1 c1 p2 c2 check +permutation w3 p3 r1 c3 w2 r2 p2 p1 c1 c2 check +permutation w3 p3 r1 c3 w2 r2 p2 p1 c2 c1 check +permutation w3 p3 r1 c3 w2 r2 p2 c2 p1 c1 check +permutation w3 p3 r1 c3 w2 p1 r2 p2 c1 c2 check +permutation w3 p3 r1 c3 w2 p1 r2 p2 c2 c1 check +permutation w3 p3 r1 c3 w2 p1 r2 c1 p2 c2 check +permutation w3 p3 r1 c3 w2 p1 c1 r2 p2 c2 check +permutation w3 p3 r1 c3 p1 r2 w2 p2 c1 c2 check +permutation w3 p3 r1 c3 p1 r2 w2 p2 c2 c1 check +permutation w3 p3 r1 c3 p1 r2 w2 c1 p2 c2 check +permutation w3 p3 r1 c3 p1 r2 c1 w2 p2 c2 check +permutation w3 p3 r1 c3 p1 w2 r2 p2 c1 c2 check +permutation w3 p3 r1 c3 p1 w2 r2 p2 c2 c1 check +permutation w3 p3 r1 c3 p1 w2 r2 c1 p2 c2 check +permutation w3 p3 r1 c3 p1 w2 c1 r2 p2 c2 check +permutation w3 p3 r1 c3 p1 c1 r2 w2 p2 c2 check +permutation w3 p3 r1 c3 p1 c1 w2 r2 p2 c2 check +permutation w3 p3 r2 r1 w2 p1 p2 c3 c1 c2 check +permutation w3 p3 r2 r1 w2 p1 p2 c3 c2 c1 check +permutation w3 p3 r2 r1 w2 p1 c3 p2 c1 c2 check +permutation w3 p3 r2 r1 w2 p1 c3 p2 c2 c1 check +permutation w3 p3 r2 r1 w2 p1 c3 c1 p2 c2 check +permutation w3 p3 r2 r1 w2 p2 p1 c3 c1 c2 check +permutation w3 p3 r2 r1 w2 p2 p1 c3 c2 c1 check +permutation w3 p3 r2 r1 w2 p2 c3 p1 c1 c2 check +permutation w3 p3 r2 r1 w2 p2 c3 p1 c2 c1 check +permutation w3 p3 r2 r1 w2 p2 c3 c2 p1 c1 check +permutation w3 p3 r2 r1 w2 c3 p1 p2 c1 c2 check +permutation w3 p3 r2 r1 w2 c3 p1 p2 c2 c1 check +permutation w3 p3 r2 r1 w2 c3 p1 c1 p2 c2 check +permutation w3 p3 r2 r1 w2 c3 p2 p1 c1 c2 check +permutation w3 p3 r2 r1 w2 c3 p2 p1 c2 c1 check +permutation w3 p3 r2 r1 w2 c3 p2 c2 p1 c1 check +permutation w3 p3 r2 r1 p1 w2 p2 c3 c1 c2 check +permutation w3 p3 r2 r1 p1 w2 p2 c3 c2 c1 check +permutation w3 p3 r2 r1 p1 w2 c3 p2 c1 c2 check +permutation w3 p3 r2 r1 p1 w2 c3 p2 c2 c1 check +permutation w3 p3 r2 r1 p1 w2 c3 c1 p2 c2 check +permutation w3 p3 r2 r1 p1 c3 w2 p2 c1 c2 check +permutation w3 p3 r2 r1 p1 c3 w2 p2 c2 c1 check +permutation w3 p3 r2 r1 p1 c3 w2 c1 p2 c2 check +permutation w3 p3 r2 r1 p1 c3 c1 w2 p2 c2 check +permutation w3 p3 r2 r1 c3 w2 p1 p2 c1 c2 check +permutation w3 p3 r2 r1 c3 w2 p1 p2 c2 c1 check +permutation w3 p3 r2 r1 c3 w2 p1 c1 p2 c2 check +permutation w3 p3 r2 r1 c3 w2 p2 p1 c1 c2 check +permutation w3 p3 r2 r1 c3 w2 p2 p1 c2 c1 check +permutation w3 p3 r2 r1 c3 w2 p2 c2 p1 c1 check +permutation w3 p3 r2 r1 c3 p1 w2 p2 c1 c2 check +permutation w3 p3 r2 r1 c3 p1 w2 p2 c2 c1 check +permutation w3 p3 r2 r1 c3 p1 w2 c1 p2 c2 check +permutation w3 p3 r2 r1 c3 p1 c1 w2 p2 c2 check +permutation w3 p3 r2 c3 r1 w2 p1 p2 c1 c2 check +permutation w3 p3 r2 c3 r1 w2 p1 p2 c2 c1 check +permutation w3 p3 r2 c3 r1 w2 p1 c1 p2 c2 check +permutation w3 p3 r2 c3 r1 w2 p2 p1 c1 c2 check +permutation w3 p3 r2 c3 r1 w2 p2 p1 c2 c1 check +permutation w3 p3 r2 c3 r1 w2 p2 c2 p1 c1 check +permutation w3 p3 r2 c3 r1 p1 w2 p2 c1 c2 check +permutation w3 p3 r2 c3 r1 p1 w2 p2 c2 c1 check +permutation w3 p3 r2 c3 r1 p1 w2 c1 p2 c2 check +permutation w3 p3 r2 c3 r1 p1 c1 w2 p2 c2 check +permutation w3 p3 c3 r1 r2 w2 p1 p2 c1 c2 check +permutation w3 p3 c3 r1 r2 w2 p1 p2 c2 c1 check +permutation w3 p3 c3 r1 r2 w2 p1 c1 p2 c2 check +permutation w3 p3 c3 r1 r2 w2 p2 p1 c1 c2 check +permutation w3 p3 c3 r1 r2 w2 p2 p1 c2 c1 check +permutation w3 p3 c3 r1 r2 w2 p2 c2 p1 c1 check +permutation w3 p3 c3 r1 r2 p1 w2 p2 c1 c2 check +permutation w3 p3 c3 r1 r2 p1 w2 p2 c2 c1 check +permutation w3 p3 c3 r1 r2 p1 w2 c1 p2 c2 check +permutation w3 p3 c3 r1 r2 p1 c1 w2 p2 c2 check +permutation w3 p3 c3 r1 w2 r2 p1 p2 c1 c2 check +permutation w3 p3 c3 r1 w2 r2 p1 p2 c2 c1 check +permutation w3 p3 c3 r1 w2 r2 p1 c1 p2 c2 check +permutation w3 p3 c3 r1 w2 r2 p2 p1 c1 c2 check +permutation w3 p3 c3 r1 w2 r2 p2 p1 c2 c1 check +permutation w3 p3 c3 r1 w2 r2 p2 c2 p1 c1 check +permutation w3 p3 c3 r1 w2 p1 r2 p2 c1 c2 check +permutation w3 p3 c3 r1 w2 p1 r2 p2 c2 c1 check +permutation w3 p3 c3 r1 w2 p1 r2 c1 p2 c2 check +permutation w3 p3 c3 r1 w2 p1 c1 r2 p2 c2 check +permutation w3 p3 c3 r1 p1 r2 w2 p2 c1 c2 check +permutation w3 p3 c3 r1 p1 r2 w2 p2 c2 c1 check +permutation w3 p3 c3 r1 p1 r2 w2 c1 p2 c2 check +permutation w3 p3 c3 r1 p1 r2 c1 w2 p2 c2 check +permutation w3 p3 c3 r1 p1 w2 r2 p2 c1 c2 check +permutation w3 p3 c3 r1 p1 w2 r2 p2 c2 c1 check +permutation w3 p3 c3 r1 p1 w2 r2 c1 p2 c2 check +permutation w3 p3 c3 r1 p1 w2 c1 r2 p2 c2 check +permutation w3 p3 c3 r1 p1 c1 r2 w2 p2 c2 check +permutation w3 p3 c3 r1 p1 c1 w2 r2 p2 c2 check +permutation w3 p3 c3 r2 r1 w2 p1 p2 c1 c2 check +permutation w3 p3 c3 r2 r1 w2 p1 p2 c2 c1 check +permutation w3 p3 c3 r2 r1 w2 p1 c1 p2 c2 check +permutation w3 p3 c3 r2 r1 w2 p2 p1 c1 c2 check +permutation w3 p3 c3 r2 r1 w2 p2 p1 c2 c1 check +permutation w3 p3 c3 r2 r1 w2 p2 c2 p1 c1 check +permutation w3 p3 c3 r2 r1 p1 w2 p2 c1 c2 check +permutation w3 p3 c3 r2 r1 p1 w2 p2 c2 c1 check +permutation w3 p3 c3 r2 r1 p1 w2 c1 p2 c2 check +permutation w3 p3 c3 r2 r1 p1 c1 w2 p2 c2 check diff --git a/src/test/isolation/specs/project-manager.spec b/src/test/isolation/specs/project-manager.spec index 884012dd89..42e5fc53a2 100644 --- a/src/test/isolation/specs/project-manager.spec +++ b/src/test/isolation/specs/project-manager.spec @@ -17,14 +17,14 @@ teardown DROP TABLE person, project; } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "rx1" { SELECT count(*) FROM person WHERE person_id = 1 AND is_project_manager; } -step "wy1" { INSERT INTO project VALUES (101, 'Build Great Wall', 1); } -step "c1" { COMMIT; } +step rx1 { SELECT count(*) FROM person WHERE person_id = 1 AND is_project_manager; } +step wy1 { INSERT INTO project VALUES (101, 'Build Great Wall', 1); } +step c1 { COMMIT; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "ry2" { SELECT count(*) FROM project WHERE project_manager = 1; } -step "wx2" { UPDATE person SET is_project_manager = false WHERE person_id = 1; } -step "c2" { COMMIT; } +step ry2 { SELECT count(*) FROM project WHERE project_manager = 1; } +step wx2 { UPDATE person SET is_project_manager = false WHERE person_id = 1; } +step c2 { COMMIT; } diff --git a/src/test/isolation/specs/propagate-lock-delete.spec b/src/test/isolation/specs/propagate-lock-delete.spec index 857c36b3db..641fb84283 100644 --- a/src/test/isolation/specs/propagate-lock-delete.spec +++ b/src/test/isolation/specs/propagate-lock-delete.spec @@ -14,29 +14,29 @@ teardown drop table child, parent; } -session "s1" -step "s1b" { BEGIN; } -step "s1l" { INSERT INTO child VALUES (1); } -step "s1c" { COMMIT; } +session s1 +step s1b { BEGIN; } +step s1l { INSERT INTO child VALUES (1); } +step s1c { COMMIT; } -session "s2" -step "s2b" { BEGIN; } -step "s2l" { INSERT INTO child VALUES (1); } -step "s2c" { COMMIT; } +session s2 +step s2b { BEGIN; } +step s2l { INSERT INTO child VALUES (1); } +step s2c { COMMIT; } -session "s3" -step "s3b" { BEGIN; } -step "s3u" { UPDATE parent SET c=lower(c); } # no key update -step "s3u2" { UPDATE parent SET i = i; } # key update -step "s3svu" { SAVEPOINT f; UPDATE parent SET c = 'bbb'; ROLLBACK TO f; } -step "s3d" { DELETE FROM parent; } -step "s3c" { COMMIT; } +session s3 +step s3b { BEGIN; } +step s3u { UPDATE parent SET c=lower(c); } # no key update +step s3u2 { UPDATE parent SET i = i; } # key update +step s3svu { SAVEPOINT f; UPDATE parent SET c = 'bbb'; ROLLBACK TO f; } +step s3d { DELETE FROM parent; } +step s3c { COMMIT; } -permutation "s1b" "s1l" "s2b" "s2l" "s3b" "s3u" "s3d" "s1c" "s2c" "s3c" -permutation "s1b" "s1l" "s2b" "s2l" "s3b" "s3u" "s3svu" "s3d" "s1c" "s2c" "s3c" -permutation "s1b" "s1l" "s2b" "s2l" "s3b" "s3u2" "s3d" "s1c" "s2c" "s3c" -permutation "s1b" "s1l" "s2b" "s2l" "s3b" "s3u2" "s3svu" "s3d" "s1c" "s2c" "s3c" -permutation "s1b" "s1l" "s3b" "s3u" "s3d" "s1c" "s3c" -permutation "s1b" "s1l" "s3b" "s3u" "s3svu" "s3d" "s1c" "s3c" -permutation "s1b" "s1l" "s3b" "s3u2" "s3d" "s1c" "s3c" -permutation "s1b" "s1l" "s3b" "s3u2" "s3svu" "s3d" "s1c" "s3c" +permutation s1b s1l s2b s2l s3b s3u s3d s1c s2c s3c +permutation s1b s1l s2b s2l s3b s3u s3svu s3d s1c s2c s3c +permutation s1b s1l s2b s2l s3b s3u2 s3d s1c s2c s3c +permutation s1b s1l s2b s2l s3b s3u2 s3svu s3d s1c s2c s3c +permutation s1b s1l s3b s3u s3d s1c s3c +permutation s1b s1l s3b s3u s3svu s3d s1c s3c +permutation s1b s1l s3b s3u2 s3d s1c s3c +permutation s1b s1l s3b s3u2 s3svu s3d s1c s3c diff --git a/src/test/isolation/specs/read-only-anomaly-2.spec b/src/test/isolation/specs/read-only-anomaly-2.spec index 9812f49ee4..6b579a60c5 100644 --- a/src/test/isolation/specs/read-only-anomaly-2.spec +++ b/src/test/isolation/specs/read-only-anomaly-2.spec @@ -17,26 +17,26 @@ teardown DROP TABLE bank_account; } -session "s1" +session s1 setup { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; } -step "s1ry" { SELECT balance FROM bank_account WHERE id = 'Y'; } -step "s1wy" { UPDATE bank_account SET balance = 20 WHERE id = 'Y'; } -step "s1c" { COMMIT; } +step s1ry { SELECT balance FROM bank_account WHERE id = 'Y'; } +step s1wy { UPDATE bank_account SET balance = 20 WHERE id = 'Y'; } +step s1c { COMMIT; } -session "s2" +session s2 setup { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; } -step "s2rx" { SELECT balance FROM bank_account WHERE id = 'X'; } -step "s2ry" { SELECT balance FROM bank_account WHERE id = 'Y'; } -step "s2wx" { UPDATE bank_account SET balance = -11 WHERE id = 'X'; } -step "s2c" { COMMIT; } +step s2rx { SELECT balance FROM bank_account WHERE id = 'X'; } +step s2ry { SELECT balance FROM bank_account WHERE id = 'Y'; } +step s2wx { UPDATE bank_account SET balance = -11 WHERE id = 'X'; } +step s2c { COMMIT; } -session "s3" +session s3 setup { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; } -step "s3r" { SELECT id, balance FROM bank_account WHERE id IN ('X', 'Y') ORDER BY id; } -step "s3c" { COMMIT; } +step s3r { SELECT id, balance FROM bank_account WHERE id IN ('X', 'Y') ORDER BY id; } +step s3c { COMMIT; } # without s3, s1 and s2 commit -permutation "s2rx" "s2ry" "s1ry" "s1wy" "s1c" "s2wx" "s2c" "s3c" +permutation s2rx s2ry s1ry s1wy s1c s2wx s2c s3c # once s3 observes the data committed by s1, a cycle is created and s2 aborts -permutation "s2rx" "s2ry" "s1ry" "s1wy" "s1c" "s3r" "s3c" "s2wx" +permutation s2rx s2ry s1ry s1wy s1c s3r s3c s2wx diff --git a/src/test/isolation/specs/read-only-anomaly-3.spec b/src/test/isolation/specs/read-only-anomaly-3.spec index d43fc2e03f..61d9c0b9e0 100644 --- a/src/test/isolation/specs/read-only-anomaly-3.spec +++ b/src/test/isolation/specs/read-only-anomaly-3.spec @@ -18,22 +18,22 @@ teardown DROP TABLE bank_account; } -session "s1" +session s1 setup { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; } -step "s1ry" { SELECT balance FROM bank_account WHERE id = 'Y'; } -step "s1wy" { UPDATE bank_account SET balance = 20 WHERE id = 'Y'; } -step "s1c" { COMMIT; } +step s1ry { SELECT balance FROM bank_account WHERE id = 'Y'; } +step s1wy { UPDATE bank_account SET balance = 20 WHERE id = 'Y'; } +step s1c { COMMIT; } -session "s2" +session s2 setup { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; } -step "s2rx" { SELECT balance FROM bank_account WHERE id = 'X'; } -step "s2ry" { SELECT balance FROM bank_account WHERE id = 'Y'; } -step "s2wx" { UPDATE bank_account SET balance = -11 WHERE id = 'X'; } -step "s2c" { COMMIT; } +step s2rx { SELECT balance FROM bank_account WHERE id = 'X'; } +step s2ry { SELECT balance FROM bank_account WHERE id = 'Y'; } +step s2wx { UPDATE bank_account SET balance = -11 WHERE id = 'X'; } +step s2c { COMMIT; } -session "s3" +session s3 setup { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY DEFERRABLE; } -step "s3r" { SELECT id, balance FROM bank_account WHERE id IN ('X', 'Y') ORDER BY id; } -step "s3c" { COMMIT; } +step s3r { SELECT id, balance FROM bank_account WHERE id IN ('X', 'Y') ORDER BY id; } +step s3c { COMMIT; } -permutation "s2rx" "s2ry" "s1ry" "s1wy" "s1c" "s3r" "s2wx" "s2c" "s3c" +permutation s2rx s2ry s1ry s1wy s1c s3r s2wx s2c s3c diff --git a/src/test/isolation/specs/read-only-anomaly.spec b/src/test/isolation/specs/read-only-anomaly.spec index d331e4200a..8ff1af5512 100644 --- a/src/test/isolation/specs/read-only-anomaly.spec +++ b/src/test/isolation/specs/read-only-anomaly.spec @@ -17,22 +17,22 @@ teardown DROP TABLE bank_account; } -session "s1" +session s1 setup { BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; } -step "s1ry" { SELECT balance FROM bank_account WHERE id = 'Y'; } -step "s1wy" { UPDATE bank_account SET balance = 20 WHERE id = 'Y'; } -step "s1c" { COMMIT; } +step s1ry { SELECT balance FROM bank_account WHERE id = 'Y'; } +step s1wy { UPDATE bank_account SET balance = 20 WHERE id = 'Y'; } +step s1c { COMMIT; } -session "s2" +session s2 setup { BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; } -step "s2rx" { SELECT balance FROM bank_account WHERE id = 'X'; } -step "s2ry" { SELECT balance FROM bank_account WHERE id = 'Y'; } -step "s2wx" { UPDATE bank_account SET balance = -11 WHERE id = 'X'; } -step "s2c" { COMMIT; } +step s2rx { SELECT balance FROM bank_account WHERE id = 'X'; } +step s2ry { SELECT balance FROM bank_account WHERE id = 'Y'; } +step s2wx { UPDATE bank_account SET balance = -11 WHERE id = 'X'; } +step s2c { COMMIT; } -session "s3" +session s3 setup { BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; } -step "s3r" { SELECT id, balance FROM bank_account WHERE id IN ('X', 'Y') ORDER BY id; } -step "s3c" { COMMIT; } +step s3r { SELECT id, balance FROM bank_account WHERE id IN ('X', 'Y') ORDER BY id; } +step s3c { COMMIT; } -permutation "s2rx" "s2ry" "s1ry" "s1wy" "s1c" "s3r" "s2wx" "s2c" "s3c" +permutation s2rx s2ry s1ry s1wy s1c s3r s2wx s2c s3c diff --git a/src/test/isolation/specs/read-write-unique-2.spec b/src/test/isolation/specs/read-write-unique-2.spec index 5e7cbf2cf5..16c73e19c4 100644 --- a/src/test/isolation/specs/read-write-unique-2.spec +++ b/src/test/isolation/specs/read-write-unique-2.spec @@ -10,27 +10,27 @@ teardown DROP TABLE test; } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "r1" { SELECT * FROM test WHERE i = 42; } -step "w1" { INSERT INTO test VALUES (42); } -step "c1" { COMMIT; } +step r1 { SELECT * FROM test WHERE i = 42; } +step w1 { INSERT INTO test VALUES (42); } +step c1 { COMMIT; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "r2" { SELECT * FROM test WHERE i = 42; } -step "w2" { INSERT INTO test VALUES (42); } -step "c2" { COMMIT; } +step r2 { SELECT * FROM test WHERE i = 42; } +step w2 { INSERT INTO test VALUES (42); } +step c2 { COMMIT; } # Two SSI transactions see that there is no row with value 42 # in the table, then try to insert that value; T1 inserts, # and then T2 blocks waiting for T1 to commit. Finally, # T2 reports a serialization failure. -permutation "r1" "r2" "w1" "w2" "c1" "c2" +permutation r1 r2 w1 w2 c1 c2 # If the value is already visible before T2 begins, then a # regular unique constraint violation should still be raised # by T2. -permutation "r1" "w1" "c1" "r2" "w2" "c2" +permutation r1 w1 c1 r2 w2 c2 diff --git a/src/test/isolation/specs/read-write-unique-3.spec b/src/test/isolation/specs/read-write-unique-3.spec index 52d287721b..cba2c4c0bc 100644 --- a/src/test/isolation/specs/read-write-unique-3.spec +++ b/src/test/isolation/specs/read-write-unique-3.spec @@ -20,14 +20,14 @@ teardown DROP TABLE test; } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "rw1" { SELECT insert_unique(1, '1'); } -step "c1" { COMMIT; } +step rw1 { SELECT insert_unique(1, '1'); } +step c1 { COMMIT; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "rw2" { SELECT insert_unique(1, '2'); } -step "c2" { COMMIT; } +step rw2 { SELECT insert_unique(1, '2'); } +step c2 { COMMIT; } -permutation "rw1" "rw2" "c1" "c2" +permutation rw1 rw2 c1 c2 diff --git a/src/test/isolation/specs/read-write-unique-4.spec b/src/test/isolation/specs/read-write-unique-4.spec index ec44782348..9002248811 100644 --- a/src/test/isolation/specs/read-write-unique-4.spec +++ b/src/test/isolation/specs/read-write-unique-4.spec @@ -17,27 +17,27 @@ teardown DROP TABLE invoice; } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "r1" { SELECT COALESCE(MAX(invoice_number) + 1, 1) FROM invoice WHERE year = 2016; } -step "w1" { INSERT INTO invoice VALUES (2016, 3); } -step "c1" { COMMIT; } +step r1 { SELECT COALESCE(MAX(invoice_number) + 1, 1) FROM invoice WHERE year = 2016; } +step w1 { INSERT INTO invoice VALUES (2016, 3); } +step c1 { COMMIT; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "r2" { SELECT COALESCE(MAX(invoice_number) + 1, 1) FROM invoice WHERE year = 2016; } -step "w2" { INSERT INTO invoice VALUES (2016, 3); } -step "c2" { COMMIT; } +step r2 { SELECT COALESCE(MAX(invoice_number) + 1, 1) FROM invoice WHERE year = 2016; } +step w2 { INSERT INTO invoice VALUES (2016, 3); } +step c2 { COMMIT; } # if they both read first then there should be an SSI conflict -permutation "r1" "r2" "w1" "w2" "c1" "c2" +permutation r1 r2 w1 w2 c1 c2 # cases where one session doesn't explicitly read before writing: # if s2 doesn't explicitly read, then trying to insert the value # generates a unique constraint violation after s1 commits, as if s2 # ran after s1 -permutation "r1" "w1" "w2" "c1" "c2" +permutation r1 w1 w2 c1 c2 # if s1 doesn't explicitly read, but s2 does, then s1 inserts and # commits first, should s2 experience an SSI failure instead of a @@ -45,4 +45,4 @@ permutation "r1" "w1" "w2" "c1" "c2" # (s1, s2) or (s2, s1) where s1 succeeds, and s2 doesn't see the row # in an explicit select but then fails to insert due to unique # constraint violation -permutation "r2" "w1" "w2" "c1" "c2" +permutation r2 w1 w2 c1 c2 diff --git a/src/test/isolation/specs/read-write-unique.spec b/src/test/isolation/specs/read-write-unique.spec index c782f10c43..3ce059f5ce 100644 --- a/src/test/isolation/specs/read-write-unique.spec +++ b/src/test/isolation/specs/read-write-unique.spec @@ -10,17 +10,17 @@ teardown DROP TABLE test; } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "r1" { SELECT * FROM test; } -step "w1" { INSERT INTO test VALUES (42); } -step "c1" { COMMIT; } +step r1 { SELECT * FROM test; } +step w1 { INSERT INTO test VALUES (42); } +step c1 { COMMIT; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "r2" { SELECT * FROM test; } -step "w2" { INSERT INTO test VALUES (42); } -step "c2" { COMMIT; } +step r2 { SELECT * FROM test; } +step w2 { INSERT INTO test VALUES (42); } +step c2 { COMMIT; } # Two SSI transactions see that there is no row with value 42 # in the table, then try to insert that value; T1 inserts, @@ -30,10 +30,10 @@ step "c2" { COMMIT; } # (In an earlier version of Postgres, T2 would report a unique # constraint violation). -permutation "r1" "r2" "w1" "w2" "c1" "c2" +permutation r1 r2 w1 w2 c1 c2 # If the value is already visible before T2 begins, then a # regular unique constraint violation should still be raised # by T2. -permutation "r1" "w1" "c1" "r2" "w2" "c2" +permutation r1 w1 c1 r2 w2 c2 diff --git a/src/test/isolation/specs/receipt-report.spec b/src/test/isolation/specs/receipt-report.spec index 5e1d51d0bd..85ac60fb9f 100644 --- a/src/test/isolation/specs/receipt-report.spec +++ b/src/test/isolation/specs/receipt-report.spec @@ -30,18 +30,18 @@ teardown DROP TABLE ctl, receipt; } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "rxwy1" { INSERT INTO receipt VALUES (3, (SELECT deposit_date FROM ctl WHERE k = 'receipt'), 4.00); } -step "c1" { COMMIT; } +step rxwy1 { INSERT INTO receipt VALUES (3, (SELECT deposit_date FROM ctl WHERE k = 'receipt'), 4.00); } +step c1 { COMMIT; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "wx2" { UPDATE ctl SET deposit_date = DATE '2008-12-23' WHERE k = 'receipt'; } -step "c2" { COMMIT; } +step wx2 { UPDATE ctl SET deposit_date = DATE '2008-12-23' WHERE k = 'receipt'; } +step c2 { COMMIT; } -session "s3" +session s3 setup { BEGIN ISOLATION LEVEL SERIALIZABLE, READ ONLY; } -step "rx3" { SELECT * FROM ctl WHERE k = 'receipt'; } -step "ry3" { SELECT * FROM receipt WHERE deposit_date = DATE '2008-12-22'; } -step "c3" { COMMIT; } +step rx3 { SELECT * FROM ctl WHERE k = 'receipt'; } +step ry3 { SELECT * FROM receipt WHERE deposit_date = DATE '2008-12-22'; } +step c3 { COMMIT; } diff --git a/src/test/isolation/specs/referential-integrity.spec b/src/test/isolation/specs/referential-integrity.spec index 0bea3eab97..ecaa9bba02 100644 --- a/src/test/isolation/specs/referential-integrity.spec +++ b/src/test/isolation/specs/referential-integrity.spec @@ -18,15 +18,15 @@ teardown DROP TABLE a, b; } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "rx1" { SELECT i FROM a WHERE i = 1; } -step "wy1" { INSERT INTO b VALUES (1); } -step "c1" { COMMIT; } +step rx1 { SELECT i FROM a WHERE i = 1; } +step wy1 { INSERT INTO b VALUES (1); } +step c1 { COMMIT; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "rx2" { SELECT i FROM a WHERE i = 1; } -step "ry2" { SELECT a_id FROM b WHERE a_id = 1; } -step "wx2" { DELETE FROM a WHERE i = 1; } -step "c2" { COMMIT; } +step rx2 { SELECT i FROM a WHERE i = 1; } +step ry2 { SELECT a_id FROM b WHERE a_id = 1; } +step wx2 { DELETE FROM a WHERE i = 1; } +step c2 { COMMIT; } diff --git a/src/test/isolation/specs/reindex-concurrently.spec b/src/test/isolation/specs/reindex-concurrently.spec index eb59fe0cba..31844bdf8e 100644 --- a/src/test/isolation/specs/reindex-concurrently.spec +++ b/src/test/isolation/specs/reindex-concurrently.spec @@ -17,24 +17,24 @@ teardown DROP TABLE reind_con_tab; } -session "s1" +session s1 setup { BEGIN; } -step "sel1" { SELECT data FROM reind_con_tab WHERE id = 3; } -step "end1" { COMMIT; } +step sel1 { SELECT data FROM reind_con_tab WHERE id = 3; } +step end1 { COMMIT; } -session "s2" +session s2 setup { BEGIN; } -step "upd2" { UPDATE reind_con_tab SET data = 'bbbb' WHERE id = 3; } -step "ins2" { INSERT INTO reind_con_tab(data) VALUES ('cccc'); } -step "del2" { DELETE FROM reind_con_tab WHERE data = 'cccc'; } -step "end2" { COMMIT; } +step upd2 { UPDATE reind_con_tab SET data = 'bbbb' WHERE id = 3; } +step ins2 { INSERT INTO reind_con_tab(data) VALUES ('cccc'); } +step del2 { DELETE FROM reind_con_tab WHERE data = 'cccc'; } +step end2 { COMMIT; } -session "s3" -step "reindex" { REINDEX TABLE CONCURRENTLY reind_con_tab; } +session s3 +step reindex { REINDEX TABLE CONCURRENTLY reind_con_tab; } -permutation "reindex" "sel1" "upd2" "ins2" "del2" "end1" "end2" -permutation "sel1" "reindex" "upd2" "ins2" "del2" "end1" "end2" -permutation "sel1" "upd2" "reindex" "ins2" "del2" "end1" "end2" -permutation "sel1" "upd2" "ins2" "reindex" "del2" "end1" "end2" -permutation "sel1" "upd2" "ins2" "del2" "reindex" "end1" "end2" -permutation "sel1" "upd2" "ins2" "del2" "end1" "reindex" "end2" +permutation reindex sel1 upd2 ins2 del2 end1 end2 +permutation sel1 reindex upd2 ins2 del2 end1 end2 +permutation sel1 upd2 reindex ins2 del2 end1 end2 +permutation sel1 upd2 ins2 reindex del2 end1 end2 +permutation sel1 upd2 ins2 del2 reindex end1 end2 +permutation sel1 upd2 ins2 del2 end1 reindex end2 diff --git a/src/test/isolation/specs/reindex-schema.spec b/src/test/isolation/specs/reindex-schema.spec index feff8a5ec0..dee4ad76f0 100644 --- a/src/test/isolation/specs/reindex-schema.spec +++ b/src/test/isolation/specs/reindex-schema.spec @@ -15,18 +15,18 @@ teardown DROP SCHEMA reindex_schema CASCADE; } -session "s1" -step "begin1" { BEGIN; } -step "lock1" { LOCK reindex_schema.tab_locked IN SHARE UPDATE EXCLUSIVE MODE; } -step "end1" { COMMIT; } +session s1 +step begin1 { BEGIN; } +step lock1 { LOCK reindex_schema.tab_locked IN SHARE UPDATE EXCLUSIVE MODE; } +step end1 { COMMIT; } -session "s2" -step "reindex2" { REINDEX SCHEMA reindex_schema; } -step "reindex_conc2" { REINDEX SCHEMA CONCURRENTLY reindex_schema; } +session s2 +step reindex2 { REINDEX SCHEMA reindex_schema; } +step reindex_conc2 { REINDEX SCHEMA CONCURRENTLY reindex_schema; } -session "s3" -step "drop3" { DROP TABLE reindex_schema.tab_dropped; } +session s3 +step drop3 { DROP TABLE reindex_schema.tab_dropped; } # The table can be dropped while reindex is waiting. -permutation "begin1" "lock1" "reindex2" "drop3" "end1" -permutation "begin1" "lock1" "reindex_conc2" "drop3" "end1" +permutation begin1 lock1 reindex2 drop3 end1 +permutation begin1 lock1 reindex_conc2 drop3 end1 diff --git a/src/test/isolation/specs/ri-trigger.spec b/src/test/isolation/specs/ri-trigger.spec index 78d1f2f226..00fcdff414 100644 --- a/src/test/isolation/specs/ri-trigger.spec +++ b/src/test/isolation/specs/ri-trigger.spec @@ -41,13 +41,13 @@ teardown DROP FUNCTION ri_child(); } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "wxry1" { INSERT INTO child (parent_id) VALUES (0); } -step "c1" { COMMIT; } +step wxry1 { INSERT INTO child (parent_id) VALUES (0); } +step c1 { COMMIT; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "r2" { SELECT TRUE; } -step "wyrx2" { DELETE FROM parent WHERE parent_id = 0; } -step "c2" { COMMIT; } +step r2 { SELECT TRUE; } +step wyrx2 { DELETE FROM parent WHERE parent_id = 0; } +step c2 { COMMIT; } diff --git a/src/test/isolation/specs/sequence-ddl.spec b/src/test/isolation/specs/sequence-ddl.spec index f2a3ff628b..7ead8afad6 100644 --- a/src/test/isolation/specs/sequence-ddl.spec +++ b/src/test/isolation/specs/sequence-ddl.spec @@ -10,32 +10,32 @@ teardown DROP SEQUENCE seq1; } -session "s1" +session s1 setup { BEGIN; } -step "s1alter" { ALTER SEQUENCE seq1 MAXVALUE 10; } -step "s1alter2" { ALTER SEQUENCE seq1 MAXVALUE 20; } -step "s1restart" { ALTER SEQUENCE seq1 RESTART WITH 5; } -step "s1commit" { COMMIT; } +step s1alter { ALTER SEQUENCE seq1 MAXVALUE 10; } +step s1alter2 { ALTER SEQUENCE seq1 MAXVALUE 20; } +step s1restart { ALTER SEQUENCE seq1 RESTART WITH 5; } +step s1commit { COMMIT; } -session "s2" -step "s2begin" { BEGIN; } -step "s2nv" { SELECT nextval('seq1') FROM generate_series(1, 15); } -step "s2commit" { COMMIT; } +session s2 +step s2begin { BEGIN; } +step s2nv { SELECT nextval('seq1') FROM generate_series(1, 15); } +step s2commit { COMMIT; } -permutation "s1alter" "s1commit" "s2nv" +permutation s1alter s1commit s2nv # Prior to PG10, the s2nv step would see the uncommitted s1alter # change, but now it waits. -permutation "s1alter" "s2nv" "s1commit" +permutation s1alter s2nv s1commit # Prior to PG10, the s2nv step would see the uncommitted s1restart # change, but now it waits. -permutation "s1restart" "s2nv" "s1commit" +permutation s1restart s2nv s1commit # In contrast to ALTER setval() is non-transactional, so it doesn't # have to wait. -permutation "s1restart" "s2nv" "s1commit" +permutation s1restart s2nv s1commit # nextval doesn't release lock until transaction end, so s1alter2 has # to wait for s2commit. -permutation "s2begin" "s2nv" "s1alter2" "s2commit" "s1commit" +permutation s2begin s2nv s1alter2 s2commit s1commit diff --git a/src/test/isolation/specs/serializable-parallel-2.spec b/src/test/isolation/specs/serializable-parallel-2.spec index 7f90f75d88..f3941f7863 100644 --- a/src/test/isolation/specs/serializable-parallel-2.spec +++ b/src/test/isolation/specs/serializable-parallel-2.spec @@ -12,19 +12,19 @@ teardown DROP TABLE foo; } -session "s1" +session s1 setup { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; } -step "s1r" { SELECT * FROM foo; } -step "s1c" { COMMIT; } +step s1r { SELECT * FROM foo; } +step s1c { COMMIT; } -session "s2" +session s2 setup { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY; SET parallel_setup_cost = 0; SET parallel_tuple_cost = 0; } -step "s2r1" { SELECT * FROM foo; } -step "s2r2" { SELECT * FROM foo; } -step "s2c" { COMMIT; } +step s2r1 { SELECT * FROM foo; } +step s2r2 { SELECT * FROM foo; } +step s2c { COMMIT; } -permutation "s1r" "s2r1" "s1c" "s2r2" "s2c" +permutation s1r s2r1 s1c s2r2 s2c diff --git a/src/test/isolation/specs/serializable-parallel.spec b/src/test/isolation/specs/serializable-parallel.spec index a4f488adfc..508648e80c 100644 --- a/src/test/isolation/specs/serializable-parallel.spec +++ b/src/test/isolation/specs/serializable-parallel.spec @@ -19,29 +19,29 @@ teardown DROP TABLE bank_account; } -session "s1" +session s1 setup { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; } -step "s1ry" { SELECT balance FROM bank_account WHERE id = 'Y'; } -step "s1wy" { UPDATE bank_account SET balance = 20 WHERE id = 'Y'; } -step "s1c" { COMMIT; } +step s1ry { SELECT balance FROM bank_account WHERE id = 'Y'; } +step s1wy { UPDATE bank_account SET balance = 20 WHERE id = 'Y'; } +step s1c { COMMIT; } -session "s2" +session s2 setup { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; } -step "s2rx" { SELECT balance FROM bank_account WHERE id = 'X'; } -step "s2ry" { SELECT balance FROM bank_account WHERE id = 'Y'; } -step "s2wx" { UPDATE bank_account SET balance = -11 WHERE id = 'X'; } -step "s2c" { COMMIT; } +step s2rx { SELECT balance FROM bank_account WHERE id = 'X'; } +step s2ry { SELECT balance FROM bank_account WHERE id = 'Y'; } +step s2wx { UPDATE bank_account SET balance = -11 WHERE id = 'X'; } +step s2c { COMMIT; } -session "s3" +session s3 setup { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; SET force_parallel_mode = on; } -step "s3r" { SELECT id, balance FROM bank_account WHERE id IN ('X', 'Y') ORDER BY id; } -step "s3c" { COMMIT; } +step s3r { SELECT id, balance FROM bank_account WHERE id IN ('X', 'Y') ORDER BY id; } +step s3c { COMMIT; } # without s3, s1 and s2 commit -permutation "s2rx" "s2ry" "s1ry" "s1wy" "s1c" "s2wx" "s2c" "s3c" +permutation s2rx s2ry s1ry s1wy s1c s2wx s2c s3c # once s3 observes the data committed by s1, a cycle is created and s2 aborts -permutation "s2rx" "s2ry" "s1ry" "s1wy" "s1c" "s3r" "s3c" "s2wx" +permutation s2rx s2ry s1ry s1wy s1c s3r s3c s2wx diff --git a/src/test/isolation/specs/simple-write-skew.spec b/src/test/isolation/specs/simple-write-skew.spec index 0aee43f38e..ecabbf1ded 100644 --- a/src/test/isolation/specs/simple-write-skew.spec +++ b/src/test/isolation/specs/simple-write-skew.spec @@ -19,12 +19,12 @@ teardown DROP TABLE test; } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "rwx1" { UPDATE test SET t = 'apple' WHERE t = 'pear'; } -step "c1" { COMMIT; } +step rwx1 { UPDATE test SET t = 'apple' WHERE t = 'pear'; } +step c1 { COMMIT; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "rwx2" { UPDATE test SET t = 'pear' WHERE t = 'apple'} -step "c2" { COMMIT; } +step rwx2 { UPDATE test SET t = 'pear' WHERE t = 'apple'} +step c2 { COMMIT; } diff --git a/src/test/isolation/specs/skip-locked-2.spec b/src/test/isolation/specs/skip-locked-2.spec index a179d34353..cfdaa93878 100644 --- a/src/test/isolation/specs/skip-locked-2.spec +++ b/src/test/isolation/specs/skip-locked-2.spec @@ -15,27 +15,27 @@ teardown DROP TABLE queue; } -session "s1" +session s1 setup { BEGIN; } -step "s1a" { SELECT * FROM queue ORDER BY id FOR SHARE SKIP LOCKED LIMIT 1; } -step "s1b" { COMMIT; } +step s1a { SELECT * FROM queue ORDER BY id FOR SHARE SKIP LOCKED LIMIT 1; } +step s1b { COMMIT; } -session "s2" +session s2 setup { BEGIN; } -step "s2a" { SELECT * FROM queue ORDER BY id FOR SHARE SKIP LOCKED LIMIT 1; } -step "s2b" { SELECT * FROM queue ORDER BY id FOR UPDATE SKIP LOCKED LIMIT 1; } -step "s2c" { COMMIT; } +step s2a { SELECT * FROM queue ORDER BY id FOR SHARE SKIP LOCKED LIMIT 1; } +step s2b { SELECT * FROM queue ORDER BY id FOR UPDATE SKIP LOCKED LIMIT 1; } +step s2c { COMMIT; } # s1 and s2 both get SHARE lock, creating a multixact lock, then s2 # tries to update to UPDATE but skips the record because it can't # acquire a multixact lock -permutation "s1a" "s2a" "s2b" "s1b" "s2c" +permutation s1a s2a s2b s1b s2c # the same but with the SHARE locks acquired in a different order, so # s2 again skips because it can't acquired a multixact lock -permutation "s2a" "s1a" "s2b" "s1b" "s2c" +permutation s2a s1a s2b s1b s2c # s2 acquires SHARE then UPDATE, then s1 tries to acquire SHARE but # can't so skips the first record because it can't acquire a regular # lock -permutation "s2a" "s2b" "s1a" "s1b" "s2c" +permutation s2a s2b s1a s1b s2c diff --git a/src/test/isolation/specs/skip-locked-3.spec b/src/test/isolation/specs/skip-locked-3.spec index 30bf4c6b1a..7921425ed8 100644 --- a/src/test/isolation/specs/skip-locked-3.spec +++ b/src/test/isolation/specs/skip-locked-3.spec @@ -15,22 +15,22 @@ teardown DROP TABLE queue; } -session "s1" +session s1 setup { BEGIN; } -step "s1a" { SELECT * FROM queue ORDER BY id FOR UPDATE LIMIT 1; } -step "s1b" { COMMIT; } +step s1a { SELECT * FROM queue ORDER BY id FOR UPDATE LIMIT 1; } +step s1b { COMMIT; } -session "s2" +session s2 setup { BEGIN; } -step "s2a" { SELECT * FROM queue ORDER BY id FOR UPDATE LIMIT 1; } -step "s2b" { COMMIT; } +step s2a { SELECT * FROM queue ORDER BY id FOR UPDATE LIMIT 1; } +step s2b { COMMIT; } -session "s3" +session s3 setup { BEGIN; } -step "s3a" { SELECT * FROM queue ORDER BY id FOR UPDATE SKIP LOCKED LIMIT 1; } -step "s3b" { COMMIT; } +step s3a { SELECT * FROM queue ORDER BY id FOR UPDATE SKIP LOCKED LIMIT 1; } +step s3b { COMMIT; } # s3 skips to the second record because it can't obtain the tuple lock # (s2 holds the tuple lock because it is next in line to obtain the # row lock, and s1 holds the row lock) -permutation "s1a" "s2a" "s3a" "s1b" "s2b" "s3b" +permutation s1a s2a s3a s1b s2b s3b diff --git a/src/test/isolation/specs/skip-locked-4.spec b/src/test/isolation/specs/skip-locked-4.spec index ef18234880..02994a37bc 100644 --- a/src/test/isolation/specs/skip-locked-4.spec +++ b/src/test/isolation/specs/skip-locked-4.spec @@ -14,18 +14,18 @@ teardown DROP TABLE foo; } -session "s1" +session s1 setup { BEGIN; } -step "s1a" { SELECT * FROM foo WHERE pg_advisory_lock(0) IS NOT NULL ORDER BY id LIMIT 1 FOR UPDATE SKIP LOCKED; } -step "s1b" { COMMIT; } +step s1a { SELECT * FROM foo WHERE pg_advisory_lock(0) IS NOT NULL ORDER BY id LIMIT 1 FOR UPDATE SKIP LOCKED; } +step s1b { COMMIT; } -session "s2" -step "s2a" { SELECT pg_advisory_lock(0); } -step "s2b" { UPDATE foo SET data = data WHERE id = 1; } -step "s2c" { BEGIN; } -step "s2d" { UPDATE foo SET data = data WHERE id = 1; } -step "s2e" { SELECT pg_advisory_unlock(0); } -step "s2f" { COMMIT; } +session s2 +step s2a { SELECT pg_advisory_lock(0); } +step s2b { UPDATE foo SET data = data WHERE id = 1; } +step s2c { BEGIN; } +step s2d { UPDATE foo SET data = data WHERE id = 1; } +step s2e { SELECT pg_advisory_unlock(0); } +step s2f { COMMIT; } # s1 takes a snapshot but then waits on an advisory lock, then s2 # updates the row in one transaction, then again in another without @@ -33,4 +33,4 @@ step "s2f" { COMMIT; } # because it has a snapshot that sees the older version, we reach the # waiting code in EvalPlanQualFetch which skips rows when in SKIP # LOCKED mode, so s1 sees the second row -permutation "s2a" "s1a" "s2b" "s2c" "s2d" "s2e" "s1b" "s2f" +permutation s2a s1a s2b s2c s2d s2e s1b s2f diff --git a/src/test/isolation/specs/skip-locked.spec b/src/test/isolation/specs/skip-locked.spec index 3565963c45..12168f8f8a 100644 --- a/src/test/isolation/specs/skip-locked.spec +++ b/src/test/isolation/specs/skip-locked.spec @@ -15,14 +15,14 @@ teardown DROP TABLE queue; } -session "s1" +session s1 setup { BEGIN; } -step "s1a" { SELECT * FROM queue ORDER BY id FOR UPDATE SKIP LOCKED LIMIT 1; } -step "s1b" { SELECT * FROM queue ORDER BY id FOR UPDATE SKIP LOCKED LIMIT 1; } -step "s1c" { COMMIT; } +step s1a { SELECT * FROM queue ORDER BY id FOR UPDATE SKIP LOCKED LIMIT 1; } +step s1b { SELECT * FROM queue ORDER BY id FOR UPDATE SKIP LOCKED LIMIT 1; } +step s1c { COMMIT; } -session "s2" +session s2 setup { BEGIN; } -step "s2a" { SELECT * FROM queue ORDER BY id FOR UPDATE SKIP LOCKED LIMIT 1; } -step "s2b" { SELECT * FROM queue ORDER BY id FOR UPDATE SKIP LOCKED LIMIT 1; } -step "s2c" { COMMIT; } +step s2a { SELECT * FROM queue ORDER BY id FOR UPDATE SKIP LOCKED LIMIT 1; } +step s2b { SELECT * FROM queue ORDER BY id FOR UPDATE SKIP LOCKED LIMIT 1; } +step s2c { COMMIT; } diff --git a/src/test/isolation/specs/temporal-range-integrity.spec b/src/test/isolation/specs/temporal-range-integrity.spec index 63784ce0a7..2d4c59c21b 100644 --- a/src/test/isolation/specs/temporal-range-integrity.spec +++ b/src/test/isolation/specs/temporal-range-integrity.spec @@ -25,14 +25,14 @@ teardown DROP TABLE statute, offense; } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "rx1" { SELECT count(*) FROM statute WHERE statute_cite = '123.45(1)a' AND eff_date <= DATE '2009-05-15' AND (exp_date IS NULL OR exp_date > DATE '2009-05-15'); } -step "wy1" { INSERT INTO offense VALUES (1, '123.45(1)a', DATE '2009-05-15'); } -step "c1" { COMMIT; } +step rx1 { SELECT count(*) FROM statute WHERE statute_cite = '123.45(1)a' AND eff_date <= DATE '2009-05-15' AND (exp_date IS NULL OR exp_date > DATE '2009-05-15'); } +step wy1 { INSERT INTO offense VALUES (1, '123.45(1)a', DATE '2009-05-15'); } +step c1 { COMMIT; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "ry2" { SELECT count(*) FROM offense WHERE statute_cite = '123.45(1)a' AND offense_date >= DATE '2008-01-01'; } -step "wx2" { DELETE FROM statute WHERE statute_cite = '123.45(1)a' AND eff_date = DATE '2008-01-01'; } -step "c2" { COMMIT; } +step ry2 { SELECT count(*) FROM offense WHERE statute_cite = '123.45(1)a' AND offense_date >= DATE '2008-01-01'; } +step wx2 { DELETE FROM statute WHERE statute_cite = '123.45(1)a' AND eff_date = DATE '2008-01-01'; } +step c2 { COMMIT; } diff --git a/src/test/isolation/specs/timeouts.spec b/src/test/isolation/specs/timeouts.spec index e167e1885a..c747b4ae28 100644 --- a/src/test/isolation/specs/timeouts.spec +++ b/src/test/isolation/specs/timeouts.spec @@ -11,20 +11,20 @@ teardown DROP TABLE accounts; } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL READ COMMITTED; } -step "rdtbl" { SELECT * FROM accounts; } -step "wrtbl" { UPDATE accounts SET balance = balance + 100; } +step rdtbl { SELECT * FROM accounts; } +step wrtbl { UPDATE accounts SET balance = balance + 100; } teardown { ABORT; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL READ COMMITTED; } -step "sto" { SET statement_timeout = '10ms'; } -step "lto" { SET lock_timeout = '10ms'; } -step "lsto" { SET lock_timeout = '10ms'; SET statement_timeout = '10s'; } -step "slto" { SET lock_timeout = '10s'; SET statement_timeout = '10ms'; } -step "locktbl" { LOCK TABLE accounts; } -step "update" { DELETE FROM accounts WHERE accountid = 'checking'; } +step sto { SET statement_timeout = '10ms'; } +step lto { SET lock_timeout = '10ms'; } +step lsto { SET lock_timeout = '10ms'; SET statement_timeout = '10s'; } +step slto { SET lock_timeout = '10s'; SET statement_timeout = '10ms'; } +step locktbl { LOCK TABLE accounts; } +step update { DELETE FROM accounts WHERE accountid = 'checking'; } teardown { ABORT; } # It's possible that the isolation tester will not observe the final @@ -32,18 +32,18 @@ teardown { ABORT; } # We can ensure consistent test output by marking those steps with (*). # statement timeout, table-level lock -permutation "rdtbl" "sto" "locktbl"(*) +permutation rdtbl sto locktbl(*) # lock timeout, table-level lock -permutation "rdtbl" "lto" "locktbl"(*) +permutation rdtbl lto locktbl(*) # lock timeout expires first, table-level lock -permutation "rdtbl" "lsto" "locktbl"(*) +permutation rdtbl lsto locktbl(*) # statement timeout expires first, table-level lock -permutation "rdtbl" "slto" "locktbl"(*) +permutation rdtbl slto locktbl(*) # statement timeout, row-level lock -permutation "wrtbl" "sto" "update"(*) +permutation wrtbl sto update(*) # lock timeout, row-level lock -permutation "wrtbl" "lto" "update"(*) +permutation wrtbl lto update(*) # lock timeout expires first, row-level lock -permutation "wrtbl" "lsto" "update"(*) +permutation wrtbl lsto update(*) # statement timeout expires first, row-level lock -permutation "wrtbl" "slto" "update"(*) +permutation wrtbl slto update(*) diff --git a/src/test/isolation/specs/total-cash.spec b/src/test/isolation/specs/total-cash.spec index 843f41c77f..d98121a5f8 100644 --- a/src/test/isolation/specs/total-cash.spec +++ b/src/test/isolation/specs/total-cash.spec @@ -15,14 +15,14 @@ teardown DROP TABLE accounts; } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "wx1" { UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking'; } -step "rxy1" { SELECT SUM(balance) FROM accounts; } -step "c1" { COMMIT; } +step wx1 { UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking'; } +step rxy1 { SELECT SUM(balance) FROM accounts; } +step c1 { COMMIT; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "wy2" { UPDATE accounts SET balance = balance - 200 WHERE accountid = 'savings'; } -step "rxy2" { SELECT SUM(balance) FROM accounts; } -step "c2" { COMMIT; } +step wy2 { UPDATE accounts SET balance = balance - 200 WHERE accountid = 'savings'; } +step rxy2 { SELECT SUM(balance) FROM accounts; } +step c2 { COMMIT; } diff --git a/src/test/isolation/specs/truncate-conflict.spec b/src/test/isolation/specs/truncate-conflict.spec index 3c1b1d1b34..0f77ff0d72 100644 --- a/src/test/isolation/specs/truncate-conflict.spec +++ b/src/test/isolation/specs/truncate-conflict.spec @@ -12,27 +12,27 @@ teardown DROP ROLE regress_truncate_conflict; } -session "s1" -step "s1_begin" { BEGIN; } -step "s1_tab_lookup" { SELECT count(*) >= 0 FROM truncate_tab; } -step "s1_commit" { COMMIT; } +session s1 +step s1_begin { BEGIN; } +step s1_tab_lookup { SELECT count(*) >= 0 FROM truncate_tab; } +step s1_commit { COMMIT; } -session "s2" -step "s2_grant" { GRANT TRUNCATE ON truncate_tab TO regress_truncate_conflict; } -step "s2_auth" { SET ROLE regress_truncate_conflict; } -step "s2_truncate" { TRUNCATE truncate_tab; } -step "s2_reset" { RESET ROLE; } +session s2 +step s2_grant { GRANT TRUNCATE ON truncate_tab TO regress_truncate_conflict; } +step s2_auth { SET ROLE regress_truncate_conflict; } +step s2_truncate { TRUNCATE truncate_tab; } +step s2_reset { RESET ROLE; } # The role doesn't have privileges to truncate the table, so TRUNCATE should # immediately fail without waiting for a lock. -permutation "s1_begin" "s1_tab_lookup" "s2_auth" "s2_truncate" "s1_commit" "s2_reset" -permutation "s1_begin" "s2_auth" "s2_truncate" "s1_tab_lookup" "s1_commit" "s2_reset" -permutation "s1_begin" "s2_auth" "s1_tab_lookup" "s2_truncate" "s1_commit" "s2_reset" -permutation "s2_auth" "s2_truncate" "s1_begin" "s1_tab_lookup" "s1_commit" "s2_reset" +permutation s1_begin s1_tab_lookup s2_auth s2_truncate s1_commit s2_reset +permutation s1_begin s2_auth s2_truncate s1_tab_lookup s1_commit s2_reset +permutation s1_begin s2_auth s1_tab_lookup s2_truncate s1_commit s2_reset +permutation s2_auth s2_truncate s1_begin s1_tab_lookup s1_commit s2_reset # The role has privileges to truncate the table, TRUNCATE will block if # another session holds a lock on the table and succeed in all cases. -permutation "s1_begin" "s1_tab_lookup" "s2_grant" "s2_auth" "s2_truncate" "s1_commit" "s2_reset" -permutation "s1_begin" "s2_grant" "s2_auth" "s2_truncate" "s1_tab_lookup" "s1_commit" "s2_reset" -permutation "s1_begin" "s2_grant" "s2_auth" "s1_tab_lookup" "s2_truncate" "s1_commit" "s2_reset" -permutation "s2_grant" "s2_auth" "s2_truncate" "s1_begin" "s1_tab_lookup" "s1_commit" "s2_reset" +permutation s1_begin s1_tab_lookup s2_grant s2_auth s2_truncate s1_commit s2_reset +permutation s1_begin s2_grant s2_auth s2_truncate s1_tab_lookup s1_commit s2_reset +permutation s1_begin s2_grant s2_auth s1_tab_lookup s2_truncate s1_commit s2_reset +permutation s2_grant s2_auth s2_truncate s1_begin s1_tab_lookup s1_commit s2_reset diff --git a/src/test/isolation/specs/tuplelock-conflict.spec b/src/test/isolation/specs/tuplelock-conflict.spec index 922b572f2d..85582306c4 100644 --- a/src/test/isolation/specs/tuplelock-conflict.spec +++ b/src/test/isolation/specs/tuplelock-conflict.spec @@ -11,53 +11,53 @@ teardown { DROP TABLE multixact_conflict; } -session "s1" -step "s1_begin" { BEGIN; } -step "s1_lcksvpt" { SELECT * FROM multixact_conflict FOR KEY SHARE; SAVEPOINT foo; } -step "s1_tuplock1" { SELECT * FROM multixact_conflict FOR KEY SHARE; } -step "s1_tuplock2" { SELECT * FROM multixact_conflict FOR SHARE; } -step "s1_tuplock3" { SELECT * FROM multixact_conflict FOR NO KEY UPDATE; } -step "s1_tuplock4" { SELECT * FROM multixact_conflict FOR UPDATE; } -step "s1_commit" { COMMIT; } +session s1 +step s1_begin { BEGIN; } +step s1_lcksvpt { SELECT * FROM multixact_conflict FOR KEY SHARE; SAVEPOINT foo; } +step s1_tuplock1 { SELECT * FROM multixact_conflict FOR KEY SHARE; } +step s1_tuplock2 { SELECT * FROM multixact_conflict FOR SHARE; } +step s1_tuplock3 { SELECT * FROM multixact_conflict FOR NO KEY UPDATE; } +step s1_tuplock4 { SELECT * FROM multixact_conflict FOR UPDATE; } +step s1_commit { COMMIT; } -session "s2" -step "s2_tuplock1" { SELECT * FROM multixact_conflict FOR KEY SHARE; } -step "s2_tuplock2" { SELECT * FROM multixact_conflict FOR SHARE; } -step "s2_tuplock3" { SELECT * FROM multixact_conflict FOR NO KEY UPDATE; } -step "s2_tuplock4" { SELECT * FROM multixact_conflict FOR UPDATE; } +session s2 +step s2_tuplock1 { SELECT * FROM multixact_conflict FOR KEY SHARE; } +step s2_tuplock2 { SELECT * FROM multixact_conflict FOR SHARE; } +step s2_tuplock3 { SELECT * FROM multixact_conflict FOR NO KEY UPDATE; } +step s2_tuplock4 { SELECT * FROM multixact_conflict FOR UPDATE; } # The version with savepoints test the multixact cases -permutation "s1_begin" "s1_lcksvpt" "s1_tuplock1" "s2_tuplock1" "s1_commit" -permutation "s1_begin" "s1_lcksvpt" "s1_tuplock1" "s2_tuplock2" "s1_commit" -permutation "s1_begin" "s1_lcksvpt" "s1_tuplock1" "s2_tuplock3" "s1_commit" -permutation "s1_begin" "s1_lcksvpt" "s1_tuplock1" "s2_tuplock4" "s1_commit" -permutation "s1_begin" "s1_lcksvpt" "s1_tuplock2" "s2_tuplock1" "s1_commit" -permutation "s1_begin" "s1_lcksvpt" "s1_tuplock2" "s2_tuplock2" "s1_commit" -permutation "s1_begin" "s1_lcksvpt" "s1_tuplock2" "s2_tuplock3" "s1_commit" -permutation "s1_begin" "s1_lcksvpt" "s1_tuplock2" "s2_tuplock4" "s1_commit" -permutation "s1_begin" "s1_lcksvpt" "s1_tuplock3" "s2_tuplock1" "s1_commit" -permutation "s1_begin" "s1_lcksvpt" "s1_tuplock3" "s2_tuplock2" "s1_commit" -permutation "s1_begin" "s1_lcksvpt" "s1_tuplock3" "s2_tuplock3" "s1_commit" -permutation "s1_begin" "s1_lcksvpt" "s1_tuplock3" "s2_tuplock4" "s1_commit" -permutation "s1_begin" "s1_lcksvpt" "s1_tuplock4" "s2_tuplock1" "s1_commit" -permutation "s1_begin" "s1_lcksvpt" "s1_tuplock4" "s2_tuplock2" "s1_commit" -permutation "s1_begin" "s1_lcksvpt" "s1_tuplock4" "s2_tuplock3" "s1_commit" -permutation "s1_begin" "s1_lcksvpt" "s1_tuplock4" "s2_tuplock4" "s1_commit" +permutation s1_begin s1_lcksvpt s1_tuplock1 s2_tuplock1 s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock1 s2_tuplock2 s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock1 s2_tuplock3 s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock1 s2_tuplock4 s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock2 s2_tuplock1 s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock2 s2_tuplock2 s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock2 s2_tuplock3 s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock2 s2_tuplock4 s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock3 s2_tuplock1 s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock3 s2_tuplock2 s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock3 s2_tuplock3 s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock3 s2_tuplock4 s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock4 s2_tuplock1 s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock4 s2_tuplock2 s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock4 s2_tuplock3 s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock4 s2_tuplock4 s1_commit # no multixacts here -permutation "s1_begin" "s1_tuplock1" "s2_tuplock1" "s1_commit" -permutation "s1_begin" "s1_tuplock1" "s2_tuplock2" "s1_commit" -permutation "s1_begin" "s1_tuplock1" "s2_tuplock3" "s1_commit" -permutation "s1_begin" "s1_tuplock1" "s2_tuplock4" "s1_commit" -permutation "s1_begin" "s1_tuplock2" "s2_tuplock1" "s1_commit" -permutation "s1_begin" "s1_tuplock2" "s2_tuplock2" "s1_commit" -permutation "s1_begin" "s1_tuplock2" "s2_tuplock3" "s1_commit" -permutation "s1_begin" "s1_tuplock2" "s2_tuplock4" "s1_commit" -permutation "s1_begin" "s1_tuplock3" "s2_tuplock1" "s1_commit" -permutation "s1_begin" "s1_tuplock3" "s2_tuplock2" "s1_commit" -permutation "s1_begin" "s1_tuplock3" "s2_tuplock3" "s1_commit" -permutation "s1_begin" "s1_tuplock3" "s2_tuplock4" "s1_commit" -permutation "s1_begin" "s1_tuplock4" "s2_tuplock1" "s1_commit" -permutation "s1_begin" "s1_tuplock4" "s2_tuplock2" "s1_commit" -permutation "s1_begin" "s1_tuplock4" "s2_tuplock3" "s1_commit" -permutation "s1_begin" "s1_tuplock4" "s2_tuplock4" "s1_commit" +permutation s1_begin s1_tuplock1 s2_tuplock1 s1_commit +permutation s1_begin s1_tuplock1 s2_tuplock2 s1_commit +permutation s1_begin s1_tuplock1 s2_tuplock3 s1_commit +permutation s1_begin s1_tuplock1 s2_tuplock4 s1_commit +permutation s1_begin s1_tuplock2 s2_tuplock1 s1_commit +permutation s1_begin s1_tuplock2 s2_tuplock2 s1_commit +permutation s1_begin s1_tuplock2 s2_tuplock3 s1_commit +permutation s1_begin s1_tuplock2 s2_tuplock4 s1_commit +permutation s1_begin s1_tuplock3 s2_tuplock1 s1_commit +permutation s1_begin s1_tuplock3 s2_tuplock2 s1_commit +permutation s1_begin s1_tuplock3 s2_tuplock3 s1_commit +permutation s1_begin s1_tuplock3 s2_tuplock4 s1_commit +permutation s1_begin s1_tuplock4 s2_tuplock1 s1_commit +permutation s1_begin s1_tuplock4 s2_tuplock2 s1_commit +permutation s1_begin s1_tuplock4 s2_tuplock3 s1_commit +permutation s1_begin s1_tuplock4 s2_tuplock4 s1_commit diff --git a/src/test/isolation/specs/tuplelock-partition.spec b/src/test/isolation/specs/tuplelock-partition.spec index 9a585cb161..c267b28851 100644 --- a/src/test/isolation/specs/tuplelock-partition.spec +++ b/src/test/isolation/specs/tuplelock-partition.spec @@ -16,17 +16,17 @@ teardown DROP TABLE parttab; } -session "s1" -step "s1b" { BEGIN; } -step "s1update_nokey" { INSERT INTO parttab (key, col1, col2) VALUES (1, 'a', 'b') ON CONFLICT (key) DO UPDATE SET col1 = 'x', col2 = 'y'; } -step "s1update_key" { INSERT INTO parttab (key, col1, col2) VALUES (1, 'a', 'b') ON CONFLICT (key) DO UPDATE SET key=1; } -step "s1c" { COMMIT; } +session s1 +step s1b { BEGIN; } +step s1update_nokey { INSERT INTO parttab (key, col1, col2) VALUES (1, 'a', 'b') ON CONFLICT (key) DO UPDATE SET col1 = 'x', col2 = 'y'; } +step s1update_key { INSERT INTO parttab (key, col1, col2) VALUES (1, 'a', 'b') ON CONFLICT (key) DO UPDATE SET key=1; } +step s1c { COMMIT; } -session "s2" -step "s2locktuple" { SELECT * FROM parttab FOR KEY SHARE; } +session s2 +step s2locktuple { SELECT * FROM parttab FOR KEY SHARE; } # INSERT ON CONFLICT UPDATE, performs an UPDATE on non-key columns -permutation "s1b" "s1update_nokey" "s2locktuple" "s1c" +permutation s1b s1update_nokey s2locktuple s1c # INSERT ON CONFLICT UPDATE, performs an UPDATE on key column -permutation "s1b" "s1update_key" "s2locktuple" "s1c" +permutation s1b s1update_key s2locktuple s1c diff --git a/src/test/isolation/specs/tuplelock-update.spec b/src/test/isolation/specs/tuplelock-update.spec index d3de0bcbc7..4b940bcb12 100644 --- a/src/test/isolation/specs/tuplelock-update.spec +++ b/src/test/isolation/specs/tuplelock-update.spec @@ -8,30 +8,30 @@ teardown { DROP TABLE pktab; } -session "s1" -step "s1_advlock" { +session s1 +step s1_advlock { SELECT pg_advisory_lock(142857), pg_advisory_lock(285714), pg_advisory_lock(571428); } -step "s1_chain" { UPDATE pktab SET data = DEFAULT; } -step "s1_begin" { BEGIN; } -step "s1_grablock" { SELECT * FROM pktab FOR KEY SHARE; } -step "s1_advunlock1" { SELECT pg_advisory_unlock(142857); } -step "s1_advunlock2" { SELECT pg_advisory_unlock(285714); } -step "s1_advunlock3" { SELECT pg_advisory_unlock(571428); } -step "s1_commit" { COMMIT; } +step s1_chain { UPDATE pktab SET data = DEFAULT; } +step s1_begin { BEGIN; } +step s1_grablock { SELECT * FROM pktab FOR KEY SHARE; } +step s1_advunlock1 { SELECT pg_advisory_unlock(142857); } +step s1_advunlock2 { SELECT pg_advisory_unlock(285714); } +step s1_advunlock3 { SELECT pg_advisory_unlock(571428); } +step s1_commit { COMMIT; } -session "s2" -step "s2_update" { UPDATE pktab SET data = DEFAULT WHERE pg_advisory_lock_shared(142857) IS NOT NULL; } +session s2 +step s2_update { UPDATE pktab SET data = DEFAULT WHERE pg_advisory_lock_shared(142857) IS NOT NULL; } -session "s3" -step "s3_update" { UPDATE pktab SET data = DEFAULT WHERE pg_advisory_lock_shared(285714) IS NOT NULL; } +session s3 +step s3_update { UPDATE pktab SET data = DEFAULT WHERE pg_advisory_lock_shared(285714) IS NOT NULL; } -session "s4" -step "s4_update" { UPDATE pktab SET data = DEFAULT WHERE pg_advisory_lock_shared(571428) IS NOT NULL; } +session s4 +step s4_update { UPDATE pktab SET data = DEFAULT WHERE pg_advisory_lock_shared(571428) IS NOT NULL; } # We use blocker annotations on the s1_advunlockN steps so that we will not # move on to the next step until the other session's released step finishes. # This ensures stable ordering of the test output. -permutation "s1_advlock" "s2_update" "s3_update" "s4_update" "s1_chain" "s1_begin" "s1_grablock" "s1_advunlock1"("s2_update") "s1_advunlock2"("s3_update") "s1_advunlock3"("s4_update") "s1_commit" +permutation s1_advlock s2_update s3_update s4_update s1_chain s1_begin s1_grablock s1_advunlock1(s2_update) s1_advunlock2(s3_update) s1_advunlock3(s4_update) s1_commit diff --git a/src/test/isolation/specs/tuplelock-upgrade-no-deadlock.spec b/src/test/isolation/specs/tuplelock-upgrade-no-deadlock.spec index 106c2465c0..6221a27f4b 100644 --- a/src/test/isolation/specs/tuplelock-upgrade-no-deadlock.spec +++ b/src/test/isolation/specs/tuplelock-upgrade-no-deadlock.spec @@ -16,54 +16,54 @@ teardown drop table tlu_job; } -session "s0" -step "s0_begin" { begin; } -step "s0_keyshare" { select id from tlu_job where id = 1 for key share;} -step "s0_rollback" { rollback; } +session s0 +step s0_begin { begin; } +step s0_keyshare { select id from tlu_job where id = 1 for key share;} +step s0_rollback { rollback; } -session "s1" +session s1 setup { begin; } -step "s1_keyshare" { select id from tlu_job where id = 1 for key share;} -step "s1_share" { select id from tlu_job where id = 1 for share; } -step "s1_fornokeyupd" { select id from tlu_job where id = 1 for no key update; } -step "s1_update" { update tlu_job set name = 'b' where id = 1; } -step "s1_savept_e" { savepoint s1_e; } -step "s1_savept_f" { savepoint s1_f; } -step "s1_rollback_e" { rollback to s1_e; } -step "s1_rollback_f" { rollback to s1_f; } -step "s1_rollback" { rollback; } -step "s1_commit" { commit; } +step s1_keyshare { select id from tlu_job where id = 1 for key share;} +step s1_share { select id from tlu_job where id = 1 for share; } +step s1_fornokeyupd { select id from tlu_job where id = 1 for no key update; } +step s1_update { update tlu_job set name = 'b' where id = 1; } +step s1_savept_e { savepoint s1_e; } +step s1_savept_f { savepoint s1_f; } +step s1_rollback_e { rollback to s1_e; } +step s1_rollback_f { rollback to s1_f; } +step s1_rollback { rollback; } +step s1_commit { commit; } -session "s2" +session s2 setup { begin; } -step "s2_for_keyshare" { select id from tlu_job where id = 1 for key share; } -step "s2_fornokeyupd" { select id from tlu_job where id = 1 for no key update; } -step "s2_for_update" { select id from tlu_job where id = 1 for update; } -step "s2_update" { update tlu_job set name = 'b' where id = 1; } -step "s2_delete" { delete from tlu_job where id = 1; } -step "s2_rollback" { rollback; } +step s2_for_keyshare { select id from tlu_job where id = 1 for key share; } +step s2_fornokeyupd { select id from tlu_job where id = 1 for no key update; } +step s2_for_update { select id from tlu_job where id = 1 for update; } +step s2_update { update tlu_job set name = 'b' where id = 1; } +step s2_delete { delete from tlu_job where id = 1; } +step s2_rollback { rollback; } -session "s3" +session s3 setup { begin; } -step "s3_keyshare" { select id from tlu_job where id = 1 for key share; } -step "s3_share" { select id from tlu_job where id = 1 for share; } -step "s3_for_update" { select id from tlu_job where id = 1 for update; } -step "s3_update" { update tlu_job set name = 'c' where id = 1; } -step "s3_delete" { delete from tlu_job where id = 1; } -step "s3_rollback" { rollback; } -step "s3_commit" { commit; } +step s3_keyshare { select id from tlu_job where id = 1 for key share; } +step s3_share { select id from tlu_job where id = 1 for share; } +step s3_for_update { select id from tlu_job where id = 1 for update; } +step s3_update { update tlu_job set name = 'c' where id = 1; } +step s3_delete { delete from tlu_job where id = 1; } +step s3_rollback { rollback; } +step s3_commit { commit; } # test that s2 will not deadlock with s3 when s1 is rolled back -permutation "s1_share" "s2_for_update" "s3_share" "s3_for_update" "s1_rollback" "s3_rollback" "s2_rollback" +permutation s1_share s2_for_update s3_share s3_for_update s1_rollback s3_rollback s2_rollback # test that update does not cause deadlocks if it can proceed -permutation "s1_keyshare" "s2_for_update" "s3_keyshare" "s1_update" "s3_update" "s1_rollback" "s3_rollback" "s2_rollback" -permutation "s1_keyshare" "s2_for_update" "s3_keyshare" "s1_update" "s3_update" "s1_commit" "s3_rollback" "s2_rollback" +permutation s1_keyshare s2_for_update s3_keyshare s1_update s3_update s1_rollback s3_rollback s2_rollback +permutation s1_keyshare s2_for_update s3_keyshare s1_update s3_update s1_commit s3_rollback s2_rollback # test that delete does not cause deadlocks if it can proceed -permutation "s1_keyshare" "s2_for_update" "s3_keyshare" "s3_delete" "s1_rollback" "s3_rollback" "s2_rollback" -permutation "s1_keyshare" "s2_for_update" "s3_keyshare" "s3_delete" "s1_rollback" "s3_commit" "s2_rollback" +permutation s1_keyshare s2_for_update s3_keyshare s3_delete s1_rollback s3_rollback s2_rollback +permutation s1_keyshare s2_for_update s3_keyshare s3_delete s1_rollback s3_commit s2_rollback # test that sessions that don't upgrade locks acquire them in order -permutation "s1_share" "s2_for_update" "s3_for_update" "s1_rollback" "s2_rollback" "s3_rollback" -permutation "s1_share" "s2_update" "s3_update" "s1_rollback" "s2_rollback" "s3_rollback" -permutation "s1_share" "s2_delete" "s3_delete" "s1_rollback" "s2_rollback" "s3_rollback" +permutation s1_share s2_for_update s3_for_update s1_rollback s2_rollback s3_rollback +permutation s1_share s2_update s3_update s1_rollback s2_rollback s3_rollback +permutation s1_share s2_delete s3_delete s1_rollback s2_rollback s3_rollback # test s2 retrying the overall tuple lock algorithm after initially avoiding deadlock -permutation "s1_keyshare" "s3_for_update" "s2_for_keyshare" "s1_savept_e" "s1_share" "s1_savept_f" "s1_fornokeyupd" "s2_fornokeyupd" "s0_begin" "s0_keyshare" "s1_rollback_f" "s0_keyshare" "s1_rollback_e" "s1_rollback" "s2_rollback" "s0_rollback" "s3_rollback" +permutation s1_keyshare s3_for_update s2_for_keyshare s1_savept_e s1_share s1_savept_f s1_fornokeyupd s2_fornokeyupd s0_begin s0_keyshare s1_rollback_f s0_keyshare s1_rollback_e s1_rollback s2_rollback s0_rollback s3_rollback diff --git a/src/test/isolation/specs/two-ids.spec b/src/test/isolation/specs/two-ids.spec index 277097125a..fc0289f236 100644 --- a/src/test/isolation/specs/two-ids.spec +++ b/src/test/isolation/specs/two-ids.spec @@ -24,17 +24,17 @@ teardown DROP TABLE D1, D2; } -session "s1" +session s1 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "wx1" { update D1 set id = id + 1; } -step "c1" { COMMIT; } +step wx1 { update D1 set id = id + 1; } +step c1 { COMMIT; } -session "s2" +session s2 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "rxwy2" { update D2 set id = (select id+1 from D1); } -step "c2" { COMMIT; } +step rxwy2 { update D2 set id = (select id+1 from D1); } +step c2 { COMMIT; } -session "s3" +session s3 setup { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step "ry3" { select id from D2; } -step "c3" { COMMIT; } +step ry3 { select id from D2; } +step c3 { COMMIT; } diff --git a/src/test/isolation/specs/update-conflict-out.spec b/src/test/isolation/specs/update-conflict-out.spec index 25c27d4ca6..8aad6aa661 100644 --- a/src/test/isolation/specs/update-conflict-out.spec +++ b/src/test/isolation/specs/update-conflict-out.spec @@ -16,39 +16,39 @@ teardown DROP TABLE txn1; } -session "foo" +session foo setup { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; } -step "foo_select" { SELECT * FROM txn0 WHERE id = 42; } -step "foo_insert" { INSERT INTO txn1 SELECT 7, 'foo_insert'; } -step "foo_commit" { COMMIT; } +step foo_select { SELECT * FROM txn0 WHERE id = 42; } +step foo_insert { INSERT INTO txn1 SELECT 7, 'foo_insert'; } +step foo_commit { COMMIT; } -session "bar" +session bar setup { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; } -step "bar_select" { SELECT * FROM txn1 WHERE id = 7; } -step "bar_insert" { INSERT INTO txn0 SELECT 42, 'bar_insert'; } -step "bar_commit" { COMMIT; } +step bar_select { SELECT * FROM txn1 WHERE id = 7; } +step bar_insert { INSERT INTO txn0 SELECT 42, 'bar_insert'; } +step bar_commit { COMMIT; } # This session creates the conditions that confused bar's "conflict out" # handling in old releases affected by bug: -session "trouble" +session trouble setup { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; } -step "trouble_update" { UPDATE txn1 SET val = 'add physical version for "bar_select"' WHERE id = 7; } -step "trouble_delete" { DELETE FROM txn1 WHERE id = 7; } -step "trouble_abort" { ABORT; } +step trouble_update { UPDATE txn1 SET val = 'add physical version for "bar_select"' WHERE id = 7; } +step trouble_delete { DELETE FROM txn1 WHERE id = 7; } +step trouble_abort { ABORT; } -permutation "foo_select" - "bar_insert" - "foo_insert" "foo_commit" - "trouble_update" # Updates tuple... - "bar_select" # Should observe one distinct XID per version - "bar_commit" # "bar" should fail here at the latest - "trouble_abort" +permutation foo_select + bar_insert + foo_insert foo_commit + trouble_update # Updates tuple... + bar_select # Should observe one distinct XID per version + bar_commit # "bar" should fail here at the latest + trouble_abort # Same as above, but "trouble" session DELETEs this time around -permutation "foo_select" - "bar_insert" - "foo_insert" "foo_commit" - "trouble_delete" # Deletes tuple... - "bar_select" # Should observe foo's XID - "bar_commit" # "bar" should fail here at the latest - "trouble_abort" +permutation foo_select + bar_insert + foo_insert foo_commit + trouble_delete # Deletes tuple... + bar_select # Should observe foo's XID + bar_commit # "bar" should fail here at the latest + trouble_abort diff --git a/src/test/isolation/specs/update-locked-tuple.spec b/src/test/isolation/specs/update-locked-tuple.spec index 10dd3ef3d2..0dad792e79 100644 --- a/src/test/isolation/specs/update-locked-tuple.spec +++ b/src/test/isolation/specs/update-locked-tuple.spec @@ -19,20 +19,20 @@ teardown DROP TABLE users, orders; } -session "s1" -step "s1b" { BEGIN ISOLATION LEVEL REPEATABLE READ; } -step "s1u1" { UPDATE orders SET name = 'order of olivier (2)', user_id = 1 WHERE id = 1; } -step "s1u2" { UPDATE orders SET name = 'order of olivier (3)', user_id = 1 WHERE id = 1; } -step "s1c" { COMMIT; } +session s1 +step s1b { BEGIN ISOLATION LEVEL REPEATABLE READ; } +step s1u1 { UPDATE orders SET name = 'order of olivier (2)', user_id = 1 WHERE id = 1; } +step s1u2 { UPDATE orders SET name = 'order of olivier (3)', user_id = 1 WHERE id = 1; } +step s1c { COMMIT; } -session "s2" -step "s2b" { BEGIN ISOLATION LEVEL REPEATABLE READ; } -step "s2u" { UPDATE users SET sometime = '1830-10-04' WHERE id = 1; } -step "s2c" { COMMIT; } +session s2 +step s2b { BEGIN ISOLATION LEVEL REPEATABLE READ; } +step s2u { UPDATE users SET sometime = '1830-10-04' WHERE id = 1; } +step s2c { COMMIT; } -permutation "s1b" "s2b" "s2u" "s2c" "s1u1" "s1u2" "s1c" -permutation "s1b" "s2b" "s2u" "s1u1" "s2c" "s1u2" "s1c" -permutation "s1b" "s2b" "s1u1" "s2u" "s2c" "s1u2" "s1c" -permutation "s1b" "s1u1" "s2b" "s2u" "s2c" "s1u2" "s1c" -permutation "s1b" "s1u1" "s2b" "s1u2" "s2u" "s2c" "s1c" -permutation "s1b" "s1u1" "s1u2" "s2b" "s2u" "s2c" "s1c" +permutation s1b s2b s2u s2c s1u1 s1u2 s1c +permutation s1b s2b s2u s1u1 s2c s1u2 s1c +permutation s1b s2b s1u1 s2u s2c s1u2 s1c +permutation s1b s1u1 s2b s2u s2c s1u2 s1c +permutation s1b s1u1 s2b s1u2 s2u s2c s1c +permutation s1b s1u1 s1u2 s2b s2u s2c s1c diff --git a/src/test/isolation/specs/vacuum-concurrent-drop.spec b/src/test/isolation/specs/vacuum-concurrent-drop.spec index cae4092667..148a2d5c52 100644 --- a/src/test/isolation/specs/vacuum-concurrent-drop.spec +++ b/src/test/isolation/specs/vacuum-concurrent-drop.spec @@ -17,29 +17,29 @@ teardown DROP TABLE IF EXISTS parted; } -session "s1" -step "lock" +session s1 +step lock { BEGIN; LOCK part1 IN SHARE MODE; } -step "drop_and_commit" +step drop_and_commit { DROP TABLE part2; COMMIT; } -session "s2" -step "vac_specified" { VACUUM part1, part2; } -step "vac_all_parts" { VACUUM parted; } -step "analyze_specified" { ANALYZE part1, part2; } -step "analyze_all_parts" { ANALYZE parted; } -step "vac_analyze_specified" { VACUUM ANALYZE part1, part2; } -step "vac_analyze_all_parts" { VACUUM ANALYZE parted; } +session s2 +step vac_specified { VACUUM part1, part2; } +step vac_all_parts { VACUUM parted; } +step analyze_specified { ANALYZE part1, part2; } +step analyze_all_parts { ANALYZE parted; } +step vac_analyze_specified { VACUUM ANALYZE part1, part2; } +step vac_analyze_all_parts { VACUUM ANALYZE parted; } -permutation "lock" "vac_specified" "drop_and_commit" -permutation "lock" "vac_all_parts" "drop_and_commit" -permutation "lock" "analyze_specified" "drop_and_commit" -permutation "lock" "analyze_all_parts" "drop_and_commit" -permutation "lock" "vac_analyze_specified" "drop_and_commit" -permutation "lock" "vac_analyze_all_parts" "drop_and_commit" +permutation lock vac_specified drop_and_commit +permutation lock vac_all_parts drop_and_commit +permutation lock analyze_specified drop_and_commit +permutation lock analyze_all_parts drop_and_commit +permutation lock vac_analyze_specified drop_and_commit +permutation lock vac_analyze_all_parts drop_and_commit diff --git a/src/test/isolation/specs/vacuum-conflict.spec b/src/test/isolation/specs/vacuum-conflict.spec index 9b45d26c65..3cb89260dc 100644 --- a/src/test/isolation/specs/vacuum-conflict.spec +++ b/src/test/isolation/specs/vacuum-conflict.spec @@ -12,40 +12,40 @@ teardown DROP ROLE regress_vacuum_conflict; } -session "s1" -step "s1_begin" { BEGIN; } -step "s1_lock" { LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; } -step "s1_commit" { COMMIT; } +session s1 +step s1_begin { BEGIN; } +step s1_lock { LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; } +step s1_commit { COMMIT; } -session "s2" -step "s2_grant" { ALTER TABLE vacuum_tab OWNER TO regress_vacuum_conflict; } -step "s2_auth" { SET ROLE regress_vacuum_conflict; } -step "s2_vacuum" { VACUUM vacuum_tab; } -step "s2_analyze" { ANALYZE vacuum_tab; } -step "s2_reset" { RESET ROLE; } +session s2 +step s2_grant { ALTER TABLE vacuum_tab OWNER TO regress_vacuum_conflict; } +step s2_auth { SET ROLE regress_vacuum_conflict; } +step s2_vacuum { VACUUM vacuum_tab; } +step s2_analyze { ANALYZE vacuum_tab; } +step s2_reset { RESET ROLE; } # The role doesn't have privileges to vacuum the table, so VACUUM should # immediately skip the table without waiting for a lock. -permutation "s1_begin" "s1_lock" "s2_auth" "s2_vacuum" "s1_commit" "s2_reset" -permutation "s1_begin" "s2_auth" "s2_vacuum" "s1_lock" "s1_commit" "s2_reset" -permutation "s1_begin" "s2_auth" "s1_lock" "s2_vacuum" "s1_commit" "s2_reset" -permutation "s2_auth" "s2_vacuum" "s1_begin" "s1_lock" "s1_commit" "s2_reset" +permutation s1_begin s1_lock s2_auth s2_vacuum s1_commit s2_reset +permutation s1_begin s2_auth s2_vacuum s1_lock s1_commit s2_reset +permutation s1_begin s2_auth s1_lock s2_vacuum s1_commit s2_reset +permutation s2_auth s2_vacuum s1_begin s1_lock s1_commit s2_reset # Same as previously for ANALYZE -permutation "s1_begin" "s1_lock" "s2_auth" "s2_analyze" "s1_commit" "s2_reset" -permutation "s1_begin" "s2_auth" "s2_analyze" "s1_lock" "s1_commit" "s2_reset" -permutation "s1_begin" "s2_auth" "s1_lock" "s2_analyze" "s1_commit" "s2_reset" -permutation "s2_auth" "s2_analyze" "s1_begin" "s1_lock" "s1_commit" "s2_reset" +permutation s1_begin s1_lock s2_auth s2_analyze s1_commit s2_reset +permutation s1_begin s2_auth s2_analyze s1_lock s1_commit s2_reset +permutation s1_begin s2_auth s1_lock s2_analyze s1_commit s2_reset +permutation s2_auth s2_analyze s1_begin s1_lock s1_commit s2_reset # The role has privileges to vacuum the table, VACUUM will block if # another session holds a lock on the table and succeed in all cases. -permutation "s1_begin" "s2_grant" "s1_lock" "s2_auth" "s2_vacuum" "s1_commit" "s2_reset" -permutation "s1_begin" "s2_grant" "s2_auth" "s2_vacuum" "s1_lock" "s1_commit" "s2_reset" -permutation "s1_begin" "s2_grant" "s2_auth" "s1_lock" "s2_vacuum" "s1_commit" "s2_reset" -permutation "s2_grant" "s2_auth" "s2_vacuum" "s1_begin" "s1_lock" "s1_commit" "s2_reset" +permutation s1_begin s2_grant s1_lock s2_auth s2_vacuum s1_commit s2_reset +permutation s1_begin s2_grant s2_auth s2_vacuum s1_lock s1_commit s2_reset +permutation s1_begin s2_grant s2_auth s1_lock s2_vacuum s1_commit s2_reset +permutation s2_grant s2_auth s2_vacuum s1_begin s1_lock s1_commit s2_reset # Same as previously for ANALYZE -permutation "s1_begin" "s2_grant" "s1_lock" "s2_auth" "s2_analyze" "s1_commit" "s2_reset" -permutation "s1_begin" "s2_grant" "s2_auth" "s2_analyze" "s1_lock" "s1_commit" "s2_reset" -permutation "s1_begin" "s2_grant" "s2_auth" "s1_lock" "s2_analyze" "s1_commit" "s2_reset" -permutation "s2_grant" "s2_auth" "s2_analyze" "s1_begin" "s1_lock" "s1_commit" "s2_reset" +permutation s1_begin s2_grant s1_lock s2_auth s2_analyze s1_commit s2_reset +permutation s1_begin s2_grant s2_auth s2_analyze s1_lock s1_commit s2_reset +permutation s1_begin s2_grant s2_auth s1_lock s2_analyze s1_commit s2_reset +permutation s2_grant s2_auth s2_analyze s1_begin s1_lock s1_commit s2_reset diff --git a/src/test/isolation/specs/vacuum-reltuples.spec b/src/test/isolation/specs/vacuum-reltuples.spec index 6d9fa010b3..ae2f79b8fe 100644 --- a/src/test/isolation/specs/vacuum-reltuples.spec +++ b/src/test/isolation/specs/vacuum-reltuples.spec @@ -19,30 +19,30 @@ teardown { drop table smalltbl; } -session "worker" -step "open" { +session worker +step open { begin; declare c1 cursor for select 1 as dummy from smalltbl; } -step "fetch1" { +step fetch1 { fetch next from c1; } -step "close" { +step close { commit; } -step "stats" { +step stats { select relpages, reltuples from pg_class where oid='smalltbl'::regclass; } -session "vacuumer" -step "vac" { +session vacuumer +step vac { vacuum smalltbl; } -step "modify" { +step modify { insert into smalltbl select max(id)+1 from smalltbl; } -permutation "modify" "vac" "stats" -permutation "modify" "open" "fetch1" "vac" "close" "stats" -permutation "modify" "vac" "stats" +permutation modify vac stats +permutation modify open fetch1 vac close stats +permutation modify vac stats diff --git a/src/test/isolation/specs/vacuum-skip-locked.spec b/src/test/isolation/specs/vacuum-skip-locked.spec index 4f749e74b6..3fad6e1c92 100644 --- a/src/test/isolation/specs/vacuum-skip-locked.spec +++ b/src/test/isolation/specs/vacuum-skip-locked.spec @@ -17,45 +17,45 @@ teardown DROP TABLE IF EXISTS parted; } -session "s1" -step "lock_share" +session s1 +step lock_share { BEGIN; LOCK part1 IN SHARE MODE; } -step "lock_access_exclusive" +step lock_access_exclusive { BEGIN; LOCK part1 IN ACCESS EXCLUSIVE MODE; } -step "commit" +step commit { COMMIT; } -session "s2" -step "vac_specified" { VACUUM (SKIP_LOCKED) part1, part2; } -step "vac_all_parts" { VACUUM (SKIP_LOCKED) parted; } -step "analyze_specified" { ANALYZE (SKIP_LOCKED) part1, part2; } -step "analyze_all_parts" { ANALYZE (SKIP_LOCKED) parted; } -step "vac_analyze_specified" { VACUUM (ANALYZE, SKIP_LOCKED) part1, part2; } -step "vac_analyze_all_parts" { VACUUM (ANALYZE, SKIP_LOCKED) parted; } -step "vac_full_specified" { VACUUM (SKIP_LOCKED, FULL) part1, part2; } -step "vac_full_all_parts" { VACUUM (SKIP_LOCKED, FULL) parted; } +session s2 +step vac_specified { VACUUM (SKIP_LOCKED) part1, part2; } +step vac_all_parts { VACUUM (SKIP_LOCKED) parted; } +step analyze_specified { ANALYZE (SKIP_LOCKED) part1, part2; } +step analyze_all_parts { ANALYZE (SKIP_LOCKED) parted; } +step vac_analyze_specified { VACUUM (ANALYZE, SKIP_LOCKED) part1, part2; } +step vac_analyze_all_parts { VACUUM (ANALYZE, SKIP_LOCKED) parted; } +step vac_full_specified { VACUUM (SKIP_LOCKED, FULL) part1, part2; } +step vac_full_all_parts { VACUUM (SKIP_LOCKED, FULL) parted; } -permutation "lock_share" "vac_specified" "commit" -permutation "lock_share" "vac_all_parts" "commit" -permutation "lock_share" "analyze_specified" "commit" -permutation "lock_share" "analyze_all_parts" "commit" -permutation "lock_share" "vac_analyze_specified" "commit" -permutation "lock_share" "vac_analyze_all_parts" "commit" -permutation "lock_share" "vac_full_specified" "commit" -permutation "lock_share" "vac_full_all_parts" "commit" -permutation "lock_access_exclusive" "vac_specified" "commit" -permutation "lock_access_exclusive" "vac_all_parts" "commit" -permutation "lock_access_exclusive" "analyze_specified" "commit" -permutation "lock_access_exclusive" "analyze_all_parts" "commit" -permutation "lock_access_exclusive" "vac_analyze_specified" "commit" -permutation "lock_access_exclusive" "vac_analyze_all_parts" "commit" -permutation "lock_access_exclusive" "vac_full_specified" "commit" -permutation "lock_access_exclusive" "vac_full_all_parts" "commit" +permutation lock_share vac_specified commit +permutation lock_share vac_all_parts commit +permutation lock_share analyze_specified commit +permutation lock_share analyze_all_parts commit +permutation lock_share vac_analyze_specified commit +permutation lock_share vac_analyze_all_parts commit +permutation lock_share vac_full_specified commit +permutation lock_share vac_full_all_parts commit +permutation lock_access_exclusive vac_specified commit +permutation lock_access_exclusive vac_all_parts commit +permutation lock_access_exclusive analyze_specified commit +permutation lock_access_exclusive analyze_all_parts commit +permutation lock_access_exclusive vac_analyze_specified commit +permutation lock_access_exclusive vac_analyze_all_parts commit +permutation lock_access_exclusive vac_full_specified commit +permutation lock_access_exclusive vac_full_all_parts commit diff --git a/src/test/isolation/specscanner.l b/src/test/isolation/specscanner.l index a733bcf355..5de11abab5 100644 --- a/src/test/isolation/specscanner.l +++ b/src/test/isolation/specscanner.l @@ -34,17 +34,21 @@ static void addlitchar(char c); %x sql -%x qstr - -digit [0123456789] - -self [,()*] +%x qident non_newline [^\n\r] space [ \t\r\f] comment ("#"{non_newline}*) +digit [0-9] +ident_start [A-Za-z\200-\377_] +ident_cont [A-Za-z\200-\377_0-9\$] + +identifier {ident_start}{ident_cont}* + +self [,()*] + %% %{ @@ -52,6 +56,7 @@ comment ("#"{non_newline}*) litbufsize = LITBUF_INIT; %} + /* Keywords (must appear before the {identifier} rule!) */ notices { return NOTICES; } permutation { return PERMUTATION; } session { return SESSION; } @@ -59,33 +64,35 @@ setup { return SETUP; } step { return STEP; } teardown { return TEARDOWN; } -{digit}+ { - yylval.integer = atoi(yytext); - return INTEGER; - } - -{self} { return yytext[0]; } - + /* Whitespace and comments */ [\n] { yyline++; } {comment} { /* ignore */ } {space} { /* ignore */ } - /* Quoted strings: "foo" */ + /* Plain identifiers */ +{identifier} { + yylval.str = pg_strdup(yytext); + return(identifier); + } + + /* Quoted identifiers: "foo" */ \" { litbufpos = 0; - BEGIN(qstr); + BEGIN(qident); } -\" { +\"\" { addlitchar(yytext[0]); } +\" { litbuf[litbufpos] = '\0'; yylval.str = pg_strdup(litbuf); BEGIN(INITIAL); - return(string_literal); + return(identifier); } -. { addlitchar(yytext[0]); } -\n { yyerror("unexpected newline in quoted string"); } -<> { yyerror("unterminated quoted string"); } +. { addlitchar(yytext[0]); } +\n { yyerror("unexpected newline in quoted identifier"); } +<> { yyerror("unterminated quoted identifier"); } /* SQL blocks: { UPDATE ... } */ + /* We trim leading/trailing whitespace, otherwise they're unprocessed */ "{"{space}* { litbufpos = 0; @@ -108,6 +115,15 @@ teardown { return TEARDOWN; } yyerror("unterminated sql block"); } + /* Numbers and punctuation */ +{digit}+ { + yylval.integer = atoi(yytext); + return INTEGER; + } + +{self} { return yytext[0]; } + + /* Anything else is an error */ . { fprintf(stderr, "syntax error at line %d: unexpected character \"%s\"\n", yyline, yytext); exit(1);