From 46651ce6fe013220ed397add242004d764fc0153 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 14:15:05 +0200 Subject: Adding upstream version 14.5. Signed-off-by: Daniel Baumann --- .../specs/detach-partition-concurrently-4.spec | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/test/isolation/specs/detach-partition-concurrently-4.spec (limited to 'src/test/isolation/specs/detach-partition-concurrently-4.spec') 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 -- cgit v1.2.3