summaryrefslogtreecommitdiffstats
path: root/src/test/isolation/specs/detach-partition-concurrently-4.spec
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/test/isolation/specs/detach-partition-concurrently-4.spec83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/test/isolation/specs/detach-partition-concurrently-4.spec b/src/test/isolation/specs/detach-partition-concurrently-4.spec
new file mode 100644
index 0000000..2c02cae
--- /dev/null
+++ b/src/test/isolation/specs/detach-partition-concurrently-4.spec
@@ -0,0 +1,83 @@
+# This test exercises behavior of foreign keys in the face of concurrent
+# detach of partitions in the referenced table.
+# (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: When using "s1cancel", mark the target step (the one to be canceled)
+# as blocking "s1cancel". This ensures consistent reporting regardless of
+# whether "s1cancel" finishes before or after the other step reports failure.
+# Also, ensure the step after "s1cancel" is also an s1 step (use "s1noop" if
+# necessary). This ensures we won't move on to the next step until the cancel
+# is complete.
+
+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);
+ create table d4_primary1 partition of d4_primary for values in (1);
+ create table d4_primary2 partition of d4_primary for values in (2);
+ insert into d4_primary values (1);
+ insert into d4_primary values (2);
+ create table d4_fk (a int references d4_primary);
+ insert into d4_fk values (2);
+ 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 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; }
+
+# Trying to insert into a partially detached partition is rejected
+permutation s2snitch s1b s1s s2detach s1cancel(s2detach) s1insert s1c
+permutation s2snitch s1b s1s s2detach s1insert s1c
+# ... even under REPEATABLE READ mode.
+permutation s2snitch s1brr s1s s2detach s1cancel(s2detach) s1insert s1c
+permutation s2snitch s1brr s1s s2detach s1insert s1c
+
+# If you read the referenced table using a cursor, you can see a row that the
+# RI query does not see.
+permutation s2snitch s1b s1declare s2detach s1cancel(s2detach) s1fetchall s1insert s1c
+permutation s2snitch s1b s1declare s2detach s1fetchall s1insert s1c
+permutation s2snitch s1b s1declare s2detach s1cancel(s2detach) s1svpt s1insert s1rollback s1fetchall s1c
+permutation s2snitch s1b s1declare s2detach s1svpt s1insert s1rollback s1fetchall s1c
+permutation s2snitch s1b s2detach s1declare s1cancel(s2detach) s1fetchall s1insert s1c
+permutation s2snitch s1b s2detach s1declare s1fetchall s1insert s1c
+permutation s2snitch s1b s2detach s1declare s1cancel(s2detach) 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(s2detach) 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(s2detach) 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(s2detach) s1noop s3vacfreeze s1s s1insert s1c
+permutation s2snitch s1b s1s s2detach s1cancel(s2detach) s1noop s3vacfreeze s1s s1insert s1c