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
pull/4837/head
Nils Dijk 2021-03-22 15:33:56 +01:00 committed by GitHub
parent 6876e87f31
commit 787ee97867
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 0 deletions

View File

@ -1609,6 +1609,39 @@ BEGIN;
ROLLBACK; ROLLBACK;
DROP TABLE referenced_table CASCADE; DROP TABLE referenced_table CASCADE;
DROP TABLE referencing_table; 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; DROP SCHEMA fkey_reference_table CASCADE;
SET search_path TO DEFAULT; SET search_path TO DEFAULT;
RESET client_min_messages; RESET client_min_messages;

View File

@ -918,6 +918,25 @@ ROLLBACK;
DROP TABLE referenced_table CASCADE; DROP TABLE referenced_table CASCADE;
DROP TABLE referencing_table; 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; DROP SCHEMA fkey_reference_table CASCADE;
SET search_path TO DEFAULT; SET search_path TO DEFAULT;
RESET client_min_messages; RESET client_min_messages;