citus/src/test/regress/spec/isolation_ref2ref_foreign_k...

227 lines
7.6 KiB
Python

setup
{
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 8429800;
CREATE TABLE ref_table_1(id int PRIMARY KEY, value int);
SELECT create_reference_table('ref_table_1');
CREATE TABLE ref_table_2(id int PRIMARY KEY, value int REFERENCES ref_table_1(id) ON DELETE CASCADE ON UPDATE CASCADE);
SELECT create_reference_table('ref_table_2');
CREATE TABLE ref_table_3(id int PRIMARY KEY, value int REFERENCES ref_table_2(id) ON DELETE CASCADE ON UPDATE CASCADE);
SELECT create_reference_table('ref_table_3');
INSERT INTO ref_table_1 VALUES (1, 1), (3, 3), (5, 5);
INSERT INTO ref_table_2 SELECT * FROM ref_table_1;
INSERT INTO ref_table_3 SELECT * FROM ref_table_2;
}
teardown
{
DROP TABLE ref_table_1, ref_table_2, ref_table_3;
}
session "s1"
step "s1-begin"
{
BEGIN;
}
step "s1-delete-table-2"
{
DELETE FROM ref_table_2 WHERE value = 2;
}
step "s1-insert-table-2"
{
INSERT INTO ref_table_2 VALUES (7, 2);
}
step "s1-update-table-2"
{
UPDATE ref_table_2 SET id = 0 WHERE value = 2;
}
step "s1-delete-table-3"
{
DELETE FROM ref_table_3 WHERE value = 1 RETURNING id;
}
step "s1-insert-table-3"
{
INSERT INTO ref_table_3 VALUES (7, 1);
}
step "s1-update-table-3"
{
UPDATE ref_table_3 SET id = 2 WHERE value = 1 RETURNING id;
}
step "s1-select-table-1"
{
SELECT * FROM ref_table_1 ORDER BY id, value;
}
step "s1-select-table-2"
{
SELECT * FROM ref_table_2 ORDER BY id, value;
}
step "s1-select-table-3"
{
SELECT * FROM ref_table_3 ORDER BY id, value;
}
step "s1-view-locks"
{
-- The following output changed in PG versions 13.6 and 14.2. The output is expected
-- to change in earlier versions of PG as the and application_name format did not use
-- to include session name at the end.
SELECT classid,
objid,
objsubid,
mode,
application_name,
backend_type,
regexp_replace(query, E'[\\n\\r\\u2028]+', ' ', 'g' ) query
FROM pg_locks l
JOIN pg_stat_activity a
ON l.pid = a.pid
WHERE locktype='advisory'
AND application_name <> 'Citus Maintenance Daemon'
ORDER BY 1, 2, 3, 4;
}
step "s1-rollback"
{
ROLLBACK;
}
step "s1-commit"
{
COMMIT;
}
session "s2"
step "s2-begin"
{
BEGIN;
}
step "s2-insert-table-1"
{
INSERT INTO ref_table_1 VALUES (7, 7);
}
step "s2-update-table-1"
{
UPDATE ref_table_1 SET id = 2 WHERE id = 1;
}
step "s2-delete-table-1"
{
DELETE FROM ref_table_1 WHERE id = 1;
}
step "s2-insert-table-2"
{
INSERT INTO ref_table_2 VALUES (7, 5);
}
step "s2-update-table-2"
{
UPDATE ref_table_2 SET id = 2 WHERE id = 1;
}
step "s2-delete-table-2"
{
DELETE FROM ref_table_2 WHERE id = 1;
}
step "s2-insert-table-3"
{
INSERT INTO ref_table_3 VALUES (7, 5);
}
step "s2-update-table-3"
{
UPDATE ref_table_3 SET id = 2 WHERE id = 1;
}
step "s2-delete-table-3"
{
DELETE FROM ref_table_3 WHERE id = 1;
}
step "s2-rollback"
{
ROLLBACK;
}
step "s2-commit"
{
COMMIT;
}
// Check that we get necessary resource locks
// Case 1. UPDATE/DELETE ref_table_1 should only lock its own shard in Exclusive mode.
permutation "s2-begin" "s2-update-table-1" "s1-begin" "s1-view-locks" "s1-rollback" "s2-rollback" "s1-view-locks"
permutation "s2-begin" "s2-delete-table-1" "s1-view-locks" "s2-rollback" "s1-view-locks"
// Case 2. Modifying ref_table_2 should also lock ref_table_1 shard in Exclusive mode.
permutation "s2-begin" "s2-update-table-2" "s1-view-locks" "s2-rollback" "s1-view-locks"
permutation "s2-begin" "s2-delete-table-2" "s1-view-locks" "s2-rollback" "s1-view-locks"
// Case 3. Modifying ref_table_3 should also lock ref_table_1 and ref_table_2 shards in Exclusive mode.
permutation "s2-begin" "s2-update-table-3" "s1-begin" "s1-view-locks" "s1-rollback" "s2-rollback" "s1-view-locks"
permutation "s2-begin" "s2-delete-table-3" "s1-begin" "s1-view-locks" "s1-rollback" "s2-rollback" "s1-view-locks"
// Case 4. Inserting into ref_table_1 should only lock its own shard in RowExclusive mode.
permutation "s2-begin" "s2-insert-table-1" "s1-view-locks" "s2-rollback" "s1-view-locks"
// Case 5. Modifying ref_table_2 should also lock ref_table_1 in RowExclusive mode.
permutation "s2-begin" "s2-insert-table-2" "s1-view-locks" "s2-rollback" "s1-view-locks"
// Case 6. Modifying ref_table_2 should also lock ref_table_1 in RowExclusive mode.
permutation "s2-begin" "s2-insert-table-3" "s1-view-locks" "s2-rollback" "s1-view-locks"
// Now some concurrent operations
// Updates/Deletes from ref_table_1 cascade to ref_table_2, so DML on ref_table_2 should block
// Case 1. UPDATE -> DELETE
permutation "s1-begin" "s2-begin" "s2-update-table-1" "s1-delete-table-2" "s2-commit" "s1-commit" "s1-select-table-2"
// Case 2. UPDATE -> INSERT
permutation "s1-begin" "s2-begin" "s2-update-table-1" "s1-insert-table-2" "s2-commit" "s1-commit" "s1-select-table-2"
// Case 3. UPDATE -> UPDATE
permutation "s1-begin" "s2-begin" "s2-update-table-1" "s1-update-table-2" "s2-commit" "s1-commit" "s1-select-table-2"
// Case 4. DELETE -> DELETE
permutation "s1-begin" "s2-begin" "s2-delete-table-1" "s1-delete-table-2" "s2-commit" "s1-commit" "s1-select-table-2"
// Case 5. DELETE -> INSERT
permutation "s1-begin" "s2-begin" "s2-delete-table-1" "s1-insert-table-2" "s2-commit" "s1-commit" "s1-select-table-2"
// Case 6. DELETE -> UPDATE
permutation "s1-begin" "s2-begin" "s2-delete-table-1" "s1-update-table-2" "s2-commit" "s1-commit" "s1-select-table-2"
// Deletes from ref_table_1 can transitively cascade to ref_table_3, so DML on ref_table_3 should block
// Case 1. DELETE -> DELETE
permutation "s1-begin" "s2-begin" "s2-delete-table-1" "s1-delete-table-3" "s2-commit" "s1-commit" "s1-select-table-3"
// Case 2. DELETE -> INSERT, should error out
permutation "s1-begin" "s2-begin" "s2-delete-table-1" "s1-insert-table-3" "s2-commit" "s1-commit" "s1-select-table-3"
// Case 3. DELETE -> UPDATE
permutation "s1-begin" "s2-begin" "s2-delete-table-1" "s1-update-table-3" "s2-commit" "s1-commit" "s1-select-table-3"
// Any DML on any of ref_table_{1,2,3} should block others from DML in the foreign constraint graph ...
permutation "s1-begin" "s2-begin" "s2-insert-table-1" "s1-update-table-3" "s2-commit" "s1-commit" "s1-select-table-3"
permutation "s1-begin" "s2-begin" "s1-update-table-3" "s2-insert-table-1" "s1-commit" "s2-commit" "s1-select-table-3"
permutation "s1-begin" "s2-begin" "s2-insert-table-1" "s1-update-table-2" "s2-commit" "s1-commit" "s1-select-table-3"
permutation "s1-begin" "s2-begin" "s1-update-table-2" "s2-insert-table-1" "s1-commit" "s2-commit" "s1-select-table-3"
permutation "s1-begin" "s2-begin" "s2-insert-table-2" "s1-update-table-3" "s2-commit" "s1-commit" "s1-select-table-3"
permutation "s1-begin" "s2-begin" "s1-update-table-3" "s2-insert-table-2" "s1-commit" "s2-commit" "s1-select-table-3"
// DMLs shouldn't block select on tables in the same foreign constraint graph
permutation "s1-begin" "s2-begin" "s2-insert-table-1" "s1-select-table-1" "s2-commit" "s1-commit"
permutation "s1-begin" "s2-begin" "s2-insert-table-1" "s1-select-table-2" "s2-commit" "s1-commit"
permutation "s1-begin" "s2-begin" "s2-insert-table-1" "s1-select-table-3" "s2-commit" "s1-commit"
permutation "s1-begin" "s2-begin" "s2-delete-table-2" "s1-select-table-1" "s2-commit" "s1-commit"
permutation "s1-begin" "s2-begin" "s2-delete-table-2" "s1-select-table-2" "s2-commit" "s1-commit"
permutation "s1-begin" "s2-begin" "s2-delete-table-2" "s1-select-table-3" "s2-commit" "s1-commit"
permutation "s1-begin" "s2-begin" "s2-update-table-3" "s1-select-table-1" "s2-commit" "s1-commit"
permutation "s1-begin" "s2-begin" "s2-update-table-3" "s1-select-table-2" "s2-commit" "s1-commit"
permutation "s1-begin" "s2-begin" "s2-update-table-3" "s1-select-table-3" "s2-commit" "s1-commit"