From 787ee97867953e7a5189a7fda0de5a9ce542010f Mon Sep 17 00:00:00 2001 From: Nils Dijk Date: Mon, 22 Mar 2021 15:33:56 +0100 Subject: [PATCH] Tests: foreign key non colocated tests (#4841) Earlier versions of Citus (pre 9.0) had a bug where a user was able to get in a situation where a foreign key between two non-colocated tables was allowed. This was caused by the wrongful scoping together with only setting to on of a boolean variable in a loop, causing the `true` from an earlier iteration to leak into a new iteration. This was 'by accident' solved in a refactor that was executed in the preparation of the 9.0 release. Only recently we had a user running into this and it was tracked down to this behaviour. Given the dire situation a user could get them self into when running into this bug we have backported a fix to the latest 8.3 release branch. To make sure this regression does not happen anymore in the future I propose we add the tests from the backport to our mainline. For reference: https://github.com/citusdata/citus/pull/4840 --- .../foreign_key_to_reference_table.out | 33 +++++++++++++++++++ .../sql/foreign_key_to_reference_table.sql | 19 +++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/test/regress/expected/foreign_key_to_reference_table.out b/src/test/regress/expected/foreign_key_to_reference_table.out index 98c85ed14..965ec528d 100644 --- a/src/test/regress/expected/foreign_key_to_reference_table.out +++ b/src/test/regress/expected/foreign_key_to_reference_table.out @@ -1609,6 +1609,39 @@ BEGIN; ROLLBACK; DROP TABLE referenced_table CASCADE; DROP TABLE referencing_table; +-- tests specific to an edgecase in citus 8.x where it was possible to create foreign keys +-- in between colocation groups due to a bug of foreign key to reference tables +CREATE TABLE t1 (a int PRIMARY KEY, b text); +CREATE TABLE t2 (a bigint PRIMARY KEY, b text); +CREATE TABLE r1 (a int PRIMARY KEY, b text); +SELECT create_distributed_table('t1', 'a'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +SELECT create_distributed_table('t2', 'a'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +SELECT create_reference_table('r1'); + create_reference_table +--------------------------------------------------------------------- + +(1 row) + +-- this always fails as it should be +ALTER TABLE t1 ADD CONSTRAINT c1 FOREIGN KEY (a) REFERENCES t2(a); +ERROR: cannot create foreign key constraint since relations are not colocated or not referencing a reference table +DETAIL: A distributed table can only have foreign keys if it is referencing another colocated hash distributed table or a reference table +-- after we create a foreign key to the reference table, that has a lower order by name, +-- we would have been able to create a FK to non-colocated tables +ALTER TABLE t1 ADD CONSTRAINT c2 FOREIGN KEY (a) REFERENCES r1(a); +ALTER TABLE t1 ADD CONSTRAINT c3 FOREIGN KEY (a) REFERENCES t2(a); +ERROR: cannot create foreign key constraint since relations are not colocated or not referencing a reference table +DETAIL: A distributed table can only have foreign keys if it is referencing another colocated hash distributed table or a reference table DROP SCHEMA fkey_reference_table CASCADE; SET search_path TO DEFAULT; RESET client_min_messages; diff --git a/src/test/regress/sql/foreign_key_to_reference_table.sql b/src/test/regress/sql/foreign_key_to_reference_table.sql index d4bfed9b7..c03cca61d 100644 --- a/src/test/regress/sql/foreign_key_to_reference_table.sql +++ b/src/test/regress/sql/foreign_key_to_reference_table.sql @@ -918,6 +918,25 @@ ROLLBACK; DROP TABLE referenced_table CASCADE; DROP TABLE referencing_table; +-- tests specific to an edgecase in citus 8.x where it was possible to create foreign keys +-- in between colocation groups due to a bug of foreign key to reference tables +CREATE TABLE t1 (a int PRIMARY KEY, b text); +CREATE TABLE t2 (a bigint PRIMARY KEY, b text); +CREATE TABLE r1 (a int PRIMARY KEY, b text); + +SELECT create_distributed_table('t1', 'a'); +SELECT create_distributed_table('t2', 'a'); +SELECT create_reference_table('r1'); + +-- this always fails as it should be +ALTER TABLE t1 ADD CONSTRAINT c1 FOREIGN KEY (a) REFERENCES t2(a); + +-- after we create a foreign key to the reference table, that has a lower order by name, +-- we would have been able to create a FK to non-colocated tables +ALTER TABLE t1 ADD CONSTRAINT c2 FOREIGN KEY (a) REFERENCES r1(a); +ALTER TABLE t1 ADD CONSTRAINT c3 FOREIGN KEY (a) REFERENCES t2(a); + + DROP SCHEMA fkey_reference_table CASCADE; SET search_path TO DEFAULT; RESET client_min_messages;