Parsed test spec with 3 sessions
-starting permutation: s2snitch s1b s1s s2detach s1cancel s1insert s1c
+starting permutation: s2snitch s1b s1s s2detach s1cancel s2noop s1insert s1c
step s2snitch: insert into d4_pid select pg_backend_pid();
step s1b: begin;
step s1s: select * from d4_primary;
1
2
step s2detach: alter table d4_primary detach partition d4_primary1 concurrently; <waiting ...>
-step s1cancel: select pg_cancel_backend(pid) from d4_pid;
-pg_cancel_backend
+step s1cancel: select pg_cancel_backend(pid), pg_sleep(0.1) from d4_pid;
+pg_cancel_backendpg_sleep
-t
+t
step s2detach: <... completed>
error in steps s1cancel s2detach: ERROR: canceling statement due to user request
+step s2noop: UNLISTEN noop;
step s1insert: insert into d4_fk values (1);
ERROR: insert or update on table "d4_fk" violates foreign key constraint "d4_fk_a_fkey"
step s1c: commit;
error in steps s1insert s2detach: ERROR: insert or update on table "d4_fk" violates foreign key constraint "d4_fk_a_fkey"
step s1c: commit;
-starting permutation: s2snitch s1brr s1s s2detach s1cancel s1insert s1c
+starting permutation: s2snitch s1brr s1s s2detach s1cancel s2noop s1insert s1c
step s2snitch: insert into d4_pid select pg_backend_pid();
step s1brr: begin isolation level repeatable read;
step s1s: select * from d4_primary;
1
2
step s2detach: alter table d4_primary detach partition d4_primary1 concurrently; <waiting ...>
-step s1cancel: select pg_cancel_backend(pid) from d4_pid;
-pg_cancel_backend
+step s1cancel: select pg_cancel_backend(pid), pg_sleep(0.1) from d4_pid;
+pg_cancel_backendpg_sleep
-t
+t
step s2detach: <... completed>
error in steps s1cancel s2detach: ERROR: canceling statement due to user request
+step s2noop: UNLISTEN noop;
step s1insert: insert into d4_fk values (1);
ERROR: insert or update on table "d4_fk" violates foreign key constraint "d4_fk_a_fkey"
step s1c: commit;
error in steps s1insert s2detach: ERROR: insert or update on table "d4_fk" violates foreign key constraint "d4_fk_a_fkey"
step s1c: commit;
-starting permutation: s2snitch s1b s1declare s2detach s1cancel s1fetchall s1insert s1c
+starting permutation: s2snitch s1b s1declare s2detach s1cancel s2noop s1fetchall s1insert s1c
step s2snitch: insert into d4_pid select pg_backend_pid();
step s1b: begin;
step s1declare: declare f cursor for select * from d4_primary;
step s2detach: alter table d4_primary detach partition d4_primary1 concurrently; <waiting ...>
-step s1cancel: select pg_cancel_backend(pid) from d4_pid;
-pg_cancel_backend
+step s1cancel: select pg_cancel_backend(pid), pg_sleep(0.1) from d4_pid;
+pg_cancel_backendpg_sleep
-t
+t
step s2detach: <... completed>
error in steps s1cancel s2detach: ERROR: canceling statement due to user request
+step s2noop: UNLISTEN noop;
step s1fetchall: fetch all from f;
a
error in steps s1insert s2detach: ERROR: insert or update on table "d4_fk" violates foreign key constraint "d4_fk_a_fkey"
step s1c: commit;
-starting permutation: s2snitch s1b s1declare s2detach s1cancel s1svpt s1insert s1rollback s1fetchall s1c
+starting permutation: s2snitch s1b s1declare s2detach s1cancel s2noop s1svpt s1insert s1rollback s1fetchall s1c
step s2snitch: insert into d4_pid select pg_backend_pid();
step s1b: begin;
step s1declare: declare f cursor for select * from d4_primary;
step s2detach: alter table d4_primary detach partition d4_primary1 concurrently; <waiting ...>
-step s1cancel: select pg_cancel_backend(pid) from d4_pid;
-pg_cancel_backend
+step s1cancel: select pg_cancel_backend(pid), pg_sleep(0.1) from d4_pid;
+pg_cancel_backendpg_sleep
-t
+t
step s2detach: <... completed>
error in steps s1cancel s2detach: ERROR: canceling statement due to user request
+step s2noop: UNLISTEN noop;
step s1svpt: savepoint f;
step s1insert: insert into d4_fk values (1);
ERROR: insert or update on table "d4_fk" violates foreign key constraint "d4_fk_a_fkey"
step s1c: commit;
step s2detach: <... completed>
-starting permutation: s2snitch s1b s2detach s1declare s1cancel s1fetchall s1insert s1c
+starting permutation: s2snitch s1b s2detach s1declare s1cancel s2noop s1fetchall s1insert s1c
step s2snitch: insert into d4_pid select pg_backend_pid();
step s1b: begin;
step s2detach: alter table d4_primary detach partition d4_primary1 concurrently;
step s1declare: declare f cursor for select * from d4_primary;
-step s1cancel: select pg_cancel_backend(pid) from d4_pid;
-pg_cancel_backend
+step s1cancel: select pg_cancel_backend(pid), pg_sleep(0.1) from d4_pid;
+pg_cancel_backendpg_sleep
-t
+t
+step s2noop: UNLISTEN noop;
step s1fetchall: fetch all from f;
a
ERROR: insert or update on table "d4_fk" violates foreign key constraint "d4_fk_a_fkey"
step s1c: commit;
-starting permutation: s2snitch s1b s2detach s1declare s1cancel s1svpt s1insert s1rollback s1fetchall s1c
+starting permutation: s2snitch s1b s2detach s1declare s1cancel s2noop s1svpt s1insert s1rollback s1fetchall s1c
step s2snitch: insert into d4_pid select pg_backend_pid();
step s1b: begin;
step s2detach: alter table d4_primary detach partition d4_primary1 concurrently;
step s1declare: declare f cursor for select * from d4_primary;
-step s1cancel: select pg_cancel_backend(pid) from d4_pid;
-pg_cancel_backend
+step s1cancel: select pg_cancel_backend(pid), pg_sleep(0.1) from d4_pid;
+pg_cancel_backendpg_sleep
-t
+t
+step s2noop: UNLISTEN noop;
step s1svpt: savepoint f;
step s1insert: insert into d4_fk values (1);
ERROR: insert or update on table "d4_fk" violates foreign key constraint "d4_fk_a_fkey"
2
step s1c: commit;
-starting permutation: s2snitch s1brr s1declare2 s1fetchone s2detach s1cancel s1updcur s1c
+starting permutation: s2snitch s1brr s1declare2 s1fetchone s2detach s1cancel s2noop s1updcur s1c
step s2snitch: insert into d4_pid select pg_backend_pid();
step s1brr: begin isolation level repeatable read;
step s1declare2: declare f cursor for select * from d4_fk where a = 2;
2
step s2detach: alter table d4_primary detach partition d4_primary1 concurrently; <waiting ...>
-step s1cancel: select pg_cancel_backend(pid) from d4_pid;
-pg_cancel_backend
+step s1cancel: select pg_cancel_backend(pid), pg_sleep(0.1) from d4_pid;
+pg_cancel_backendpg_sleep
-t
+t
step s2detach: <... completed>
error in steps s1cancel s2detach: ERROR: canceling statement due to user request
+step s2noop: UNLISTEN noop;
step s1updcur: update d4_fk set a = 1 where current of f;
ERROR: insert or update on table "d4_fk" violates foreign key constraint "d4_fk_a_fkey"
step s1c: commit;
step s1c: commit;
step s2detach: <... completed>
-starting permutation: s2snitch s1b s1s s2detach s3brr s3insert s3commit s1cancel s1c
+starting permutation: s2snitch s1b s1s s2detach s3brr s3insert s3commit s1cancel s2noop s1c
step s2snitch: insert into d4_pid select pg_backend_pid();
step s1b: begin;
step s1s: select * from d4_primary;
step s3insert: insert into d4_fk values (1);
ERROR: insert or update on table "d4_fk" violates foreign key constraint "d4_fk_a_fkey"
step s3commit: commit;
-step s1cancel: select pg_cancel_backend(pid) from d4_pid;
-pg_cancel_backend
+step s1cancel: select pg_cancel_backend(pid), pg_sleep(0.1) from d4_pid;
+pg_cancel_backendpg_sleep
-t
+t
step s2detach: <... completed>
error in steps s1cancel s2detach: ERROR: canceling statement due to user request
+step s2noop: UNLISTEN noop;
step s1c: commit;
starting permutation: s2snitch s1b s1s s2detach s3brr s3insert s3commit s1c
step s1c: commit;
step s2detach: <... completed>
-starting permutation: s2snitch s1brr s1s s2detach s1cancel s3vacfreeze s1s s1insert s1c
+starting permutation: s2snitch s1brr s1s s2detach s1cancel s2noop s3vacfreeze s1s s1insert s1c
step s2snitch: insert into d4_pid select pg_backend_pid();
step s1brr: begin isolation level repeatable read;
step s1s: select * from d4_primary;
1
2
step s2detach: alter table d4_primary detach partition d4_primary1 concurrently; <waiting ...>
-step s1cancel: select pg_cancel_backend(pid) from d4_pid;
-pg_cancel_backend
+step s1cancel: select pg_cancel_backend(pid), pg_sleep(0.1) from d4_pid;
+pg_cancel_backendpg_sleep
-t
+t
step s2detach: <... completed>
error in steps s1cancel s2detach: ERROR: canceling statement due to user request
+step s2noop: UNLISTEN noop;
step s3vacfreeze: vacuum freeze pg_catalog.pg_inherits;
step s1s: select * from d4_primary;
a
ERROR: insert or update on table "d4_fk" violates foreign key constraint "d4_fk_a_fkey"
step s1c: commit;
-starting permutation: s2snitch s1b s1s s2detach s1cancel s3vacfreeze s1s s1insert s1c
+starting permutation: s2snitch s1b s1s s2detach s1cancel s2noop s3vacfreeze s1s s1insert s1c
step s2snitch: insert into d4_pid select pg_backend_pid();
step s1b: begin;
step s1s: select * from d4_primary;
1
2
step s2detach: alter table d4_primary detach partition d4_primary1 concurrently; <waiting ...>
-step s1cancel: select pg_cancel_backend(pid) from d4_pid;
-pg_cancel_backend
+step s1cancel: select pg_cancel_backend(pid), pg_sleep(0.1) from d4_pid;
+pg_cancel_backendpg_sleep
-t
+t
step s2detach: <... completed>
error in steps s1cancel s2detach: ERROR: canceling statement due to user request
+step s2noop: UNLISTEN noop;
step s3vacfreeze: vacuum freeze pg_catalog.pg_inherits;
step s1s: select * from d4_primary;
a
# (The cases where the detaching transaction is cancelled is interesting
# because the locking situation is completely different. I didn't verify
# that keeping both variants adds any extra coverage.)
+#
+# Note: Always keep "s2noop" right after "s1cancel" in permutations. This
+# reduces the probability of the timing problem that the cancel error report
+# is shown together with the next query instead of with the cancel query.
+
setup {
drop table if exists d4_primary, d4_primary1, d4_fk, d4_pid;
create table d4_primary (a int primary key) partition by list (a);
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; }
+# Sleep 0.1s after sending cancel, to give s2 time to react
+step "s1cancel" { select pg_cancel_backend(pid), pg_sleep(0.1) from d4_pid; }
step "s1insert" { insert into d4_fk values (1); }
step "s1c" { commit; }
step "s1declare" { declare f cursor for select * from d4_primary; }
session "s2"
step "s2snitch" { insert into d4_pid select pg_backend_pid(); }
step "s2detach" { alter table d4_primary detach partition d4_primary1 concurrently; }
+step "s2noop" { UNLISTEN noop; }
session "s3"
step "s3brr" { begin isolation level repeatable read; }
step "s3vacfreeze" { vacuum freeze pg_catalog.pg_inherits; }
# Trying to insert into a partially detached partition is rejected
-permutation "s2snitch" "s1b" "s1s" "s2detach" "s1cancel" "s1insert" "s1c"
+permutation "s2snitch" "s1b" "s1s" "s2detach" "s1cancel" "s2noop" "s1insert" "s1c"
permutation "s2snitch" "s1b" "s1s" "s2detach" "s1insert" "s1c"
# ... even under REPEATABLE READ mode.
-permutation "s2snitch" "s1brr" "s1s" "s2detach" "s1cancel" "s1insert" "s1c"
+permutation "s2snitch" "s1brr" "s1s" "s2detach" "s1cancel" "s2noop" "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" "s1fetchall" "s1insert" "s1c"
+permutation "s2snitch" "s1b" "s1declare" "s2detach" "s1cancel" "s2noop" "s1fetchall" "s1insert" "s1c"
permutation "s2snitch" "s1b" "s1declare" "s2detach" "s1fetchall" "s1insert" "s1c"
-permutation "s2snitch" "s1b" "s1declare" "s2detach" "s1cancel" "s1svpt" "s1insert" "s1rollback" "s1fetchall" "s1c"
+permutation "s2snitch" "s1b" "s1declare" "s2detach" "s1cancel" "s2noop" "s1svpt" "s1insert" "s1rollback" "s1fetchall" "s1c"
permutation "s2snitch" "s1b" "s1declare" "s2detach" "s1svpt" "s1insert" "s1rollback" "s1fetchall" "s1c"
-permutation "s2snitch" "s1b" "s2detach" "s1declare" "s1cancel" "s1fetchall" "s1insert" "s1c"
+permutation "s2snitch" "s1b" "s2detach" "s1declare" "s1cancel" "s2noop" "s1fetchall" "s1insert" "s1c"
permutation "s2snitch" "s1b" "s2detach" "s1declare" "s1fetchall" "s1insert" "s1c"
-permutation "s2snitch" "s1b" "s2detach" "s1declare" "s1cancel" "s1svpt" "s1insert" "s1rollback" "s1fetchall" "s1c"
+permutation "s2snitch" "s1b" "s2detach" "s1declare" "s1cancel" "s2noop" "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" "s1updcur" "s1c"
+permutation "s2snitch" "s1brr" "s1declare2" "s1fetchone" "s2detach" "s1cancel" "s2noop" "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" "s3brr" "s3insert" "s3commit" "s1cancel" "s1c"
+permutation "s2snitch" "s1b" "s1s" "s2detach" "s3brr" "s3insert" "s3commit" "s1cancel" "s2noop" "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" "s3vacfreeze" "s1s" "s1insert" "s1c"
-permutation "s2snitch" "s1b" "s1s" "s2detach" "s1cancel" "s3vacfreeze" "s1s" "s1insert" "s1c"
+permutation "s2snitch" "s1brr" "s1s" "s2detach" "s1cancel" "s2noop" "s3vacfreeze" "s1s" "s1insert" "s1c"
+permutation "s2snitch" "s1b" "s1s" "s2detach" "s1cancel" "s2noop" "s3vacfreeze" "s1s" "s1insert" "s1c"