mirror of https://github.com/citusdata/citus.git
943 lines
46 KiB
Plaintext
943 lines
46 KiB
Plaintext
--
|
|
-- MULTI_FOREIGN_KEY
|
|
--
|
|
SET citus.next_shard_id TO 1350000;
|
|
-- set shard_count to 4 for faster tests, because we create/drop lots of shards in this test.
|
|
SET citus.shard_count TO 32;
|
|
-- create tables
|
|
CREATE TABLE referenced_table(id int UNIQUE, test_column int, PRIMARY KEY(id, test_column));
|
|
SELECT create_distributed_table('referenced_table', 'id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
-- test foreign constraint creation with not supported parameters
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON DELETE SET NULL);
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: SET NULL or SET DEFAULT is not supported in ON DELETE operation when distribution key is included in the foreign key constraint
|
|
DROP TABLE referencing_table;
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON DELETE SET DEFAULT);
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: SET NULL or SET DEFAULT is not supported in ON DELETE operation when distribution key is included in the foreign key constraint
|
|
DROP TABLE referencing_table;
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON UPDATE SET NULL);
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: SET NULL, SET DEFAULT or CASCADE is not supported in ON UPDATE operation when distribution key included in the foreign constraint.
|
|
DROP TABLE referencing_table;
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON UPDATE SET DEFAULT);
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: SET NULL, SET DEFAULT or CASCADE is not supported in ON UPDATE operation when distribution key included in the foreign constraint.
|
|
DROP TABLE referencing_table;
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON UPDATE CASCADE);
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: SET NULL, SET DEFAULT or CASCADE is not supported in ON UPDATE operation when distribution key included in the foreign constraint.
|
|
DROP TABLE referencing_table;
|
|
-- self referencing table with replication factor > 1
|
|
CREATE TABLE self_referencing_table(id int, ref_id int, PRIMARY KEY (id, ref_id), FOREIGN KEY(id,ref_id) REFERENCES self_referencing_table(id, ref_id));
|
|
SELECT create_distributed_table('self_referencing_table', 'id', 'hash');
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: Citus currently supports foreign key constraints only for "citus.shard_replication_factor = 1".
|
|
HINT: Please change "citus.shard_replication_factor to 1". To learn more about using foreign keys with other replication factors, please contact us at https://citusdata.com/about/contact_us.
|
|
DROP TABLE self_referencing_table;
|
|
CREATE TABLE self_referencing_table(id int, ref_id int, PRIMARY KEY (id, ref_id));
|
|
SELECT create_distributed_table('self_referencing_table', 'id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
ALTER TABLE self_referencing_table ADD CONSTRAINT fkey FOREIGN KEY(id,ref_id) REFERENCES self_referencing_table(id, ref_id);
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: Citus currently supports foreign key constraints only for "citus.shard_replication_factor = 1".
|
|
HINT: Please change "citus.shard_replication_factor to 1". To learn more about using foreign keys with other replication factors, please contact us at https://citusdata.com/about/contact_us.
|
|
DROP TABLE self_referencing_table;
|
|
-- test foreign constraint creation on NOT co-located tables
|
|
SET citus.shard_count TO 8;
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY(ref_id) REFERENCES referenced_table(id));
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
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 TABLE referencing_table;
|
|
SET citus.shard_count TO 32;
|
|
-- test foreign constraint creation on non-partition columns
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY(id) REFERENCES referenced_table(id));
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: Foreign keys are supported in two cases, either in between two colocated tables including partition column in the same ordinal in the both tables or from distributed to reference tables
|
|
DROP TABLE referencing_table;
|
|
-- test foreign constraint creation while column list are in incorrect order
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY(id, ref_id) REFERENCES referenced_table(id, test_column));
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: Foreign keys are supported in two cases, either in between two colocated tables including partition column in the same ordinal in the both tables or from distributed to reference tables
|
|
DROP TABLE referencing_table;
|
|
-- test foreign constraint with replication factor > 1
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY(ref_id) REFERENCES referenced_table(id));
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: Citus currently supports foreign key constraints only for "citus.shard_replication_factor = 1".
|
|
HINT: Please change "citus.shard_replication_factor to 1". To learn more about using foreign keys with other replication factors, please contact us at https://citusdata.com/about/contact_us.
|
|
DROP TABLE referencing_table;
|
|
DROP TABLE referenced_table;
|
|
-- test foreign constraint creation on append and range distributed tables
|
|
-- foreign keys are supported either in between distributed tables including the
|
|
-- distribution column or from distributed tables to reference tables.
|
|
SET citus.shard_replication_factor TO 1;
|
|
CREATE TABLE referenced_table(id int UNIQUE, test_column int, PRIMARY KEY(id, test_column));
|
|
SELECT create_distributed_table('referenced_table', 'id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY (id) REFERENCES referenced_table(id));
|
|
SELECT create_distributed_table('referencing_table', 'id', 'append');
|
|
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 TABLE referencing_table;
|
|
DROP TABLE referenced_table;
|
|
CREATE TABLE referenced_table(id int UNIQUE, test_column int, PRIMARY KEY(id, test_column));
|
|
SELECT create_distributed_table('referenced_table', 'id', 'range');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
CREATE TABLE referencing_table(id int, ref_id int,FOREIGN KEY (id) REFERENCES referenced_table(id));
|
|
SELECT create_distributed_table('referencing_table', 'id', 'range');
|
|
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 TABLE referencing_table;
|
|
DROP TABLE referenced_table;
|
|
-- test foreign constraint with correct conditions
|
|
CREATE TABLE referenced_table(id int UNIQUE, test_column int, PRIMARY KEY(id, test_column));
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY(ref_id) REFERENCES referenced_table(id));
|
|
SELECT create_distributed_table('referenced_table', 'id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
-- test inserts
|
|
-- test insert to referencing table while there is NO corresponding value in referenced table
|
|
INSERT INTO referencing_table VALUES(1, 1);
|
|
ERROR: insert or update on table "referencing_table_xxxxxxx" violates foreign key constraint "referencing_table_ref_id_fkey_1350129"
|
|
DETAIL: Key (ref_id)=(X) is not present in table "referenced_table_xxxxxxx".
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
-- test insert to referencing while there is corresponding value in referenced table
|
|
INSERT INTO referenced_table VALUES(1, 1);
|
|
INSERT INTO referencing_table VALUES(1, 1);
|
|
-- test deletes
|
|
-- test delete from referenced table while there is corresponding value in referencing table
|
|
DELETE FROM referenced_table WHERE id = 1;
|
|
ERROR: update or delete on table "referenced_table_xxxxxxx" violates foreign key constraint "referencing_table_ref_id_fkey_1350129" on table "referencing_table_xxxxxxx"
|
|
DETAIL: Key (id)=(X) is still referenced from table "referencing_table_xxxxxxx".
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
-- test delete from referenced table while there is NO corresponding value in referencing table
|
|
DELETE FROM referencing_table WHERE ref_id = 1;
|
|
DELETE FROM referenced_table WHERE id = 1;
|
|
-- test cascading truncate
|
|
INSERT INTO referenced_table VALUES(2, 2);
|
|
INSERT INTO referencing_table VALUES(2, 2);
|
|
TRUNCATE referenced_table CASCADE;
|
|
NOTICE: truncate cascades to table "referencing_table"
|
|
SELECT * FROM referencing_table;
|
|
id | ref_id
|
|
---------------------------------------------------------------------
|
|
(0 rows)
|
|
|
|
-- drop table for next tests
|
|
DROP TABLE referencing_table;
|
|
DROP TABLE referenced_table;
|
|
-- test foreign constraint options
|
|
-- test ON DELETE CASCADE
|
|
CREATE TABLE referenced_table(id int UNIQUE, test_column int, PRIMARY KEY(id, test_column));
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON DELETE CASCADE);
|
|
SELECT create_distributed_table('referenced_table', 'id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
-- single shard cascading delete
|
|
INSERT INTO referenced_table VALUES(1, 1);
|
|
INSERT INTO referencing_table VALUES(1, 1);
|
|
DELETE FROM referenced_table WHERE id = 1;
|
|
SELECT * FROM referencing_table;
|
|
id | ref_id
|
|
---------------------------------------------------------------------
|
|
(0 rows)
|
|
|
|
SELECT * FROM referenced_table;
|
|
id | test_column
|
|
---------------------------------------------------------------------
|
|
(0 rows)
|
|
|
|
-- multi shard cascading delete
|
|
INSERT INTO referenced_table VALUES(2, 2);
|
|
INSERT INTO referencing_table VALUES(2, 2);
|
|
DELETE FROM referenced_table;
|
|
SELECT * FROM referencing_table;
|
|
id | ref_id
|
|
---------------------------------------------------------------------
|
|
(0 rows)
|
|
|
|
-- multi shard cascading delete with alter table
|
|
INSERT INTO referenced_table VALUES(3, 3);
|
|
INSERT INTO referencing_table VALUES(3, 3);
|
|
BEGIN;
|
|
ALTER TABLE referencing_table ADD COLUMN x int DEFAULT 0;
|
|
DELETE FROM referenced_table;
|
|
COMMIT;
|
|
DROP TABLE referencing_table;
|
|
DROP TABLE referenced_table;
|
|
-- test ON DELETE NO ACTION + DEFERABLE + INITIALLY DEFERRED
|
|
CREATE TABLE referenced_table(id int UNIQUE, test_column int, PRIMARY KEY(id, test_column));
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED);
|
|
SELECT create_distributed_table('referenced_table', 'id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
INSERT INTO referenced_table VALUES(1, 1);
|
|
INSERT INTO referencing_table VALUES(1, 1);
|
|
DELETE FROM referenced_table WHERE id = 1;
|
|
ERROR: update or delete on table "referenced_table_xxxxxxx" violates foreign key constraint "referencing_table_ref_id_fkey_1350257" on table "referencing_table_xxxxxxx"
|
|
DETAIL: Key (id)=(X) is still referenced from table "referencing_table_xxxxxxx".
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
BEGIN;
|
|
DELETE FROM referenced_table WHERE id = 1;
|
|
DELETE FROM referencing_table WHERE ref_id = 1;
|
|
COMMIT;
|
|
SELECT * FROM referencing_table;
|
|
id | ref_id
|
|
---------------------------------------------------------------------
|
|
(0 rows)
|
|
|
|
SELECT * FROM referenced_table;
|
|
id | test_column
|
|
---------------------------------------------------------------------
|
|
(0 rows)
|
|
|
|
DROP TABLE referencing_table;
|
|
DROP TABLE referenced_table;
|
|
-- test ON DELETE RESTRICT
|
|
CREATE TABLE referenced_table(id int UNIQUE, test_column int, PRIMARY KEY(id, test_column));
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON DELETE RESTRICT);
|
|
SELECT create_distributed_table('referenced_table', 'id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
INSERT INTO referenced_table VALUES(1, 1);
|
|
INSERT INTO referencing_table VALUES(1, 1);
|
|
BEGIN;
|
|
DELETE FROM referenced_table WHERE id = 1;
|
|
ERROR: update or delete on table "referenced_table_xxxxxxx" violates foreign key constraint "referencing_table_ref_id_fkey_1350321" on table "referencing_table_xxxxxxx"
|
|
DETAIL: Key (id)=(X) is still referenced from table "referencing_table_xxxxxxx".
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
DELETE FROM referencing_table WHERE ref_id = 1;
|
|
ERROR: current transaction is aborted, commands ignored until end of transaction block
|
|
COMMIT;
|
|
SELECT * FROM referencing_table;
|
|
id | ref_id
|
|
---------------------------------------------------------------------
|
|
1 | 1
|
|
(1 row)
|
|
|
|
SELECT * FROM referenced_table;
|
|
id | test_column
|
|
---------------------------------------------------------------------
|
|
1 | 1
|
|
(1 row)
|
|
|
|
DROP TABLE referencing_table;
|
|
DROP TABLE referenced_table;
|
|
-- test ON UPDATE NO ACTION + DEFERABLE + INITIALLY DEFERRED
|
|
CREATE TABLE referenced_table(id int UNIQUE, test_column int, PRIMARY KEY(id, test_column));
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY(ref_id, id) REFERENCES referenced_table(id, test_column) ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED);
|
|
SELECT create_distributed_table('referenced_table', 'id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
INSERT INTO referenced_table VALUES(1, 1);
|
|
INSERT INTO referencing_table VALUES(1, 1);
|
|
UPDATE referenced_table SET test_column = 10 WHERE id = 1;
|
|
ERROR: update or delete on table "referenced_table_xxxxxxx" violates foreign key constraint "referencing_table_ref_id_fkey_1350385" on table "referencing_table_xxxxxxx"
|
|
DETAIL: Key (id, test_column)=(1, 1) is still referenced from table "referencing_table_xxxxxxx".
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
BEGIN;
|
|
UPDATE referenced_table SET test_column = 10 WHERE id = 1;
|
|
UPDATE referencing_table SET id = 10 WHERE ref_id = 1;
|
|
COMMIT;
|
|
SELECT * FROM referencing_table;
|
|
id | ref_id
|
|
---------------------------------------------------------------------
|
|
10 | 1
|
|
(1 row)
|
|
|
|
SELECT * FROM referenced_table;
|
|
id | test_column
|
|
---------------------------------------------------------------------
|
|
1 | 10
|
|
(1 row)
|
|
|
|
DROP TABLE referencing_table;
|
|
DROP TABLE referenced_table;
|
|
-- test ON UPDATE RESTRICT
|
|
CREATE TABLE referenced_table(id int UNIQUE, test_column int, PRIMARY KEY(id, test_column));
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY(ref_id, id) REFERENCES referenced_table(id, test_column) ON UPDATE RESTRICT);
|
|
SELECT create_distributed_table('referenced_table', 'id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
INSERT INTO referenced_table VALUES(1, 1);
|
|
INSERT INTO referencing_table VALUES(1, 1);
|
|
BEGIN;
|
|
UPDATE referenced_table SET test_column = 20 WHERE id = 1;
|
|
ERROR: update or delete on table "referenced_table_xxxxxxx" violates foreign key constraint "referencing_table_ref_id_fkey_1350449" on table "referencing_table_xxxxxxx"
|
|
DETAIL: Key (id, test_column)=(1, 1) is still referenced from table "referencing_table_xxxxxxx".
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
UPDATE referencing_table SET id = 20 WHERE ref_id = 1;
|
|
ERROR: current transaction is aborted, commands ignored until end of transaction block
|
|
COMMIT;
|
|
SELECT * FROM referencing_table;
|
|
id | ref_id
|
|
---------------------------------------------------------------------
|
|
1 | 1
|
|
(1 row)
|
|
|
|
SELECT * FROM referenced_table;
|
|
id | test_column
|
|
---------------------------------------------------------------------
|
|
1 | 1
|
|
(1 row)
|
|
|
|
DROP TABLE referencing_table;
|
|
DROP TABLE referenced_table;
|
|
-- test MATCH SIMPLE
|
|
CREATE TABLE referenced_table(id int UNIQUE, test_column int, PRIMARY KEY(id, test_column));
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY(ref_id, id) REFERENCES referenced_table(id, test_column) MATCH SIMPLE);
|
|
SELECT create_distributed_table('referenced_table', 'id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
INSERT INTO referencing_table VALUES(null, 2);
|
|
SELECT * FROM referencing_table;
|
|
id | ref_id
|
|
---------------------------------------------------------------------
|
|
| 2
|
|
(1 row)
|
|
|
|
DELETE FROM referencing_table WHERE ref_id = 2;
|
|
DROP TABLE referencing_table;
|
|
DROP TABLE referenced_table;
|
|
-- test MATCH FULL
|
|
CREATE TABLE referenced_table(id int UNIQUE, test_column int, PRIMARY KEY(id, test_column));
|
|
CREATE TABLE referencing_table(id int, ref_id int, FOREIGN KEY(ref_id, id) REFERENCES referenced_table(id, test_column) MATCH FULL);
|
|
SELECT create_distributed_table('referenced_table', 'id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
INSERT INTO referencing_table VALUES(null, 2);
|
|
ERROR: insert or update on table "referencing_table_xxxxxxx" violates foreign key constraint "referencing_table_ref_id_fkey_1350600"
|
|
DETAIL: MATCH FULL does not allow mixing of null and nonnull key values.
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
SELECT * FROM referencing_table;
|
|
id | ref_id
|
|
---------------------------------------------------------------------
|
|
(0 rows)
|
|
|
|
DROP TABLE referencing_table;
|
|
DROP TABLE referenced_table;
|
|
-- Similar tests, but this time we push foreign key constraints created by ALTER TABLE queries
|
|
-- create tables
|
|
SET citus.shard_count TO 4;
|
|
CREATE TABLE referenced_table(id int UNIQUE, test_column int, PRIMARY KEY(id, test_column));
|
|
SELECT create_distributed_table('referenced_table', 'id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
CREATE TABLE referencing_table(id int, ref_id int);
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
-- verify that we skip foreign key validation when propagation is turned off
|
|
-- not skipping validation would result in a distributed query, which emits debug messages
|
|
BEGIN;
|
|
SET LOCAL citus.enable_ddl_propagation TO off;
|
|
SET LOCAL client_min_messages TO DEBUG1;
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY (ref_id) REFERENCES referenced_table (id);
|
|
ABORT;
|
|
-- test foreign constraint creation
|
|
-- test foreign constraint creation with not supported parameters
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON DELETE SET NULL;
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: SET NULL or SET DEFAULT is not supported in ON DELETE operation when distribution key is included in the foreign key constraint
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON DELETE SET DEFAULT;
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: SET NULL or SET DEFAULT is not supported in ON DELETE operation when distribution key is included in the foreign key constraint
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON UPDATE SET NULL;
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: SET NULL, SET DEFAULT or CASCADE is not supported in ON UPDATE operation when distribution key included in the foreign constraint.
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON UPDATE SET DEFAULT;
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: SET NULL, SET DEFAULT or CASCADE is not supported in ON UPDATE operation when distribution key included in the foreign constraint.
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON UPDATE CASCADE;
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: SET NULL, SET DEFAULT or CASCADE is not supported in ON UPDATE operation when distribution key included in the foreign constraint.
|
|
-- test foreign constraint creation while adding the column
|
|
ALTER TABLE referencing_table ADD COLUMN referencing_col int REFERENCES referenced_table(id) ON UPDATE CASCADE;;
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: Foreign keys are supported in two cases, either in between two colocated tables including partition column in the same ordinal in the both tables or from distributed to reference tables
|
|
-- test foreign constraint creation with multiple subcommands
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id) REFERENCES referenced_table(id),
|
|
ADD CONSTRAINT test_constraint FOREIGN KEY(id) REFERENCES referenced_table(test_column);
|
|
ERROR: cannot execute ADD CONSTRAINT command with other subcommands
|
|
HINT: You can issue each subcommand separately
|
|
-- test foreign constraint creation without giving explicit name
|
|
ALTER TABLE referencing_table ADD FOREIGN KEY(ref_id) REFERENCES referenced_table(id);
|
|
ERROR: cannot create constraint without a name on a distributed table
|
|
-- test foreign constraint creation on NOT co-located tables
|
|
DROP TABLE referencing_table;
|
|
DROP TABLE referenced_table;
|
|
CREATE TABLE referenced_table(id int UNIQUE, test_column int, PRIMARY KEY(id, test_column));
|
|
SELECT create_distributed_table('referenced_table', 'id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
CREATE TABLE referencing_table(id int, ref_id int);
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash', colocate_with => 'none');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id) REFERENCES referenced_table(id);
|
|
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
|
|
-- create co-located tables
|
|
DROP TABLE referencing_table;
|
|
DROP TABLE referenced_table;
|
|
CREATE TABLE referenced_table(id int UNIQUE, test_column int, PRIMARY KEY(id, test_column));
|
|
CREATE TABLE referencing_table(id int, ref_id int);
|
|
SELECT create_distributed_table('referenced_table', 'id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
SELECT create_distributed_table('referencing_table', 'ref_id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
-- columns for the referenced table is empty
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id) REFERENCES referenced_table ON DELETE CASCADE;
|
|
ERROR: number of referencing and referenced columns for foreign key disagree
|
|
-- test foreign constraint creation on non-partition columns
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(id) REFERENCES referenced_table(id);
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: Foreign keys are supported in two cases, either in between two colocated tables including partition column in the same ordinal in the both tables or from distributed to reference tables
|
|
-- test foreign constraint creation while column list are in incorrect order
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(id, ref_id) REFERENCES referenced_table(id, test_column);
|
|
ERROR: cannot create foreign key constraint
|
|
DETAIL: Foreign keys are supported in two cases, either in between two colocated tables including partition column in the same ordinal in the both tables or from distributed to reference tables
|
|
-- test foreign constraint creation while column list are not in same length
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id) REFERENCES referenced_table(id, test_column);
|
|
ERROR: number of referencing and referenced columns for foreign key disagree
|
|
-- test foreign constraint creation while existing tables does not satisfy the constraint
|
|
INSERT INTO referencing_table VALUES(1, 1);
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id) REFERENCES referenced_table(id);
|
|
ERROR: insert or update on table "referencing_table_xxxxxxx" violates foreign key constraint "test_constraint_1350628"
|
|
DETAIL: Key (ref_id)=(X) is not present in table "referenced_table_xxxxxxx".
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
-- test foreign constraint with correct conditions
|
|
DELETE FROM referencing_table WHERE ref_id = 1;
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id) REFERENCES referenced_table(id);
|
|
-- test inserts
|
|
-- test insert to referencing table while there is NO corresponding value in referenced table
|
|
INSERT INTO referencing_table VALUES(1, 1);
|
|
ERROR: insert or update on table "referencing_table_xxxxxxx" violates foreign key constraint "test_constraint_1350628"
|
|
DETAIL: Key (ref_id)=(X) is not present in table "referenced_table_xxxxxxx".
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
-- test insert to referencing while there is corresponding value in referenced table
|
|
INSERT INTO referenced_table VALUES(1, 1);
|
|
INSERT INTO referencing_table VALUES(1, 1);
|
|
-- test deletes
|
|
-- test delete from referenced table while there is corresponding value in referencing table
|
|
DELETE FROM referenced_table WHERE id = 1;
|
|
ERROR: update or delete on table "referenced_table_xxxxxxx" violates foreign key constraint "test_constraint_1350628" on table "referencing_table_xxxxxxx"
|
|
DETAIL: Key (id)=(X) is still referenced from table "referencing_table_xxxxxxx".
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
-- test delete from referenced table while there is NO corresponding value in referencing table
|
|
DELETE FROM referencing_table WHERE ref_id = 1;
|
|
DELETE FROM referenced_table WHERE id = 1;
|
|
-- test DROP CONSTRAINT
|
|
ALTER TABLE referencing_table DROP CONSTRAINT test_constraint;
|
|
-- test foreign constraint options
|
|
-- test ON DELETE CASCADE
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON DELETE CASCADE;
|
|
INSERT INTO referenced_table VALUES(1, 1);
|
|
INSERT INTO referencing_table VALUES(1, 1);
|
|
DELETE FROM referenced_table WHERE id = 1;
|
|
SELECT * FROM referencing_table;
|
|
id | ref_id
|
|
---------------------------------------------------------------------
|
|
(0 rows)
|
|
|
|
SELECT * FROM referenced_table;
|
|
id | test_column
|
|
---------------------------------------------------------------------
|
|
(0 rows)
|
|
|
|
ALTER TABLE referencing_table DROP CONSTRAINT test_constraint;
|
|
-- test ON DELETE NO ACTION + DEFERABLE + INITIALLY DEFERRED
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED;
|
|
INSERT INTO referenced_table VALUES(1, 1);
|
|
INSERT INTO referencing_table VALUES(1, 1);
|
|
DELETE FROM referenced_table WHERE id = 1;
|
|
ERROR: update or delete on table "referenced_table_xxxxxxx" violates foreign key constraint "test_constraint_1350628" on table "referencing_table_xxxxxxx"
|
|
DETAIL: Key (id)=(X) is still referenced from table "referencing_table_xxxxxxx".
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
BEGIN;
|
|
DELETE FROM referenced_table WHERE id = 1;
|
|
DELETE FROM referencing_table WHERE ref_id = 1;
|
|
COMMIT;
|
|
SELECT * FROM referencing_table;
|
|
id | ref_id
|
|
---------------------------------------------------------------------
|
|
(0 rows)
|
|
|
|
SELECT * FROM referenced_table;
|
|
id | test_column
|
|
---------------------------------------------------------------------
|
|
(0 rows)
|
|
|
|
ALTER TABLE referencing_table DROP CONSTRAINT test_constraint;
|
|
-- test ON DELETE RESTRICT
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON DELETE RESTRICT;
|
|
INSERT INTO referenced_table VALUES(1, 1);
|
|
INSERT INTO referencing_table VALUES(1, 1);
|
|
BEGIN;
|
|
DELETE FROM referenced_table WHERE id = 1;
|
|
ERROR: update or delete on table "referenced_table_xxxxxxx" violates foreign key constraint "test_constraint_1350628" on table "referencing_table_xxxxxxx"
|
|
DETAIL: Key (id)=(X) is still referenced from table "referencing_table_xxxxxxx".
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
DELETE FROM referencing_table WHERE ref_id = 1;
|
|
ERROR: current transaction is aborted, commands ignored until end of transaction block
|
|
COMMIT;
|
|
SELECT * FROM referencing_table;
|
|
id | ref_id
|
|
---------------------------------------------------------------------
|
|
1 | 1
|
|
(1 row)
|
|
|
|
SELECT * FROM referenced_table;
|
|
id | test_column
|
|
---------------------------------------------------------------------
|
|
1 | 1
|
|
(1 row)
|
|
|
|
ALTER TABLE referencing_table DROP CONSTRAINT test_constraint;
|
|
-- test ON UPDATE NO ACTION + DEFERABLE + INITIALLY DEFERRED
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id, id) REFERENCES referenced_table(id, test_column) ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED;
|
|
UPDATE referenced_table SET test_column = 10 WHERE id = 1;
|
|
ERROR: update or delete on table "referenced_table_xxxxxxx" violates foreign key constraint "test_constraint_1350628" on table "referencing_table_xxxxxxx"
|
|
DETAIL: Key (id, test_column)=(1, 1) is still referenced from table "referencing_table_xxxxxxx".
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
BEGIN;
|
|
UPDATE referenced_table SET test_column = 10 WHERE id = 1;
|
|
UPDATE referencing_table SET id = 10 WHERE ref_id = 1;
|
|
COMMIT;
|
|
SELECT * FROM referencing_table;
|
|
id | ref_id
|
|
---------------------------------------------------------------------
|
|
10 | 1
|
|
(1 row)
|
|
|
|
SELECT * FROM referenced_table;
|
|
id | test_column
|
|
---------------------------------------------------------------------
|
|
1 | 10
|
|
(1 row)
|
|
|
|
ALTER TABLE referencing_table DROP CONSTRAINT test_constraint;
|
|
-- test ON UPDATE RESTRICT
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id, id) REFERENCES referenced_table(id, test_column) ON UPDATE RESTRICT;
|
|
BEGIN;
|
|
UPDATE referenced_table SET test_column = 20 WHERE id = 1;
|
|
ERROR: update or delete on table "referenced_table_xxxxxxx" violates foreign key constraint "test_constraint_1350628" on table "referencing_table_xxxxxxx"
|
|
DETAIL: Key (id, test_column)=(1, 10) is still referenced from table "referencing_table_xxxxxxx".
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
UPDATE referencing_table SET id = 20 WHERE ref_id = 1;
|
|
ERROR: current transaction is aborted, commands ignored until end of transaction block
|
|
COMMIT;
|
|
SELECT * FROM referencing_table;
|
|
id | ref_id
|
|
---------------------------------------------------------------------
|
|
10 | 1
|
|
(1 row)
|
|
|
|
SELECT * FROM referenced_table;
|
|
id | test_column
|
|
---------------------------------------------------------------------
|
|
1 | 10
|
|
(1 row)
|
|
|
|
ALTER TABLE referencing_table DROP CONSTRAINT test_constraint;
|
|
-- test MATCH SIMPLE
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id, id) REFERENCES referenced_table(id, test_column) MATCH SIMPLE;
|
|
INSERT INTO referencing_table VALUES(null, 2);
|
|
SELECT * FROM referencing_table ORDER BY 1,2;
|
|
id | ref_id
|
|
---------------------------------------------------------------------
|
|
10 | 1
|
|
| 2
|
|
(2 rows)
|
|
|
|
DELETE FROM referencing_table WHERE ref_id = 2;
|
|
ALTER TABLE referencing_table DROP CONSTRAINT test_constraint;
|
|
-- test MATCH FULL
|
|
ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id, id) REFERENCES referenced_table(id, test_column) MATCH FULL;
|
|
INSERT INTO referencing_table VALUES(null, 2);
|
|
ERROR: insert or update on table "referencing_table_xxxxxxx" violates foreign key constraint "test_constraint_1350631"
|
|
DETAIL: MATCH FULL does not allow mixing of null and nonnull key values.
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
SELECT * FROM referencing_table;
|
|
id | ref_id
|
|
---------------------------------------------------------------------
|
|
10 | 1
|
|
(1 row)
|
|
|
|
ALTER TABLE referencing_table DROP CONSTRAINT test_constraint;
|
|
-- we no longer need those tables
|
|
DROP TABLE referencing_table;
|
|
DROP TABLE referenced_table;
|
|
-- test cyclical foreign keys
|
|
CREATE TABLE cyclic_reference_table1(id int, table2_id int, PRIMARY KEY(id, table2_id));
|
|
CREATE TABLE cyclic_reference_table2(id int, table1_id int, PRIMARY KEY(id, table1_id));
|
|
SELECT create_distributed_table('cyclic_reference_table1', 'id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
SELECT create_distributed_table('cyclic_reference_table2', 'table1_id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
ALTER TABLE cyclic_reference_table1 ADD CONSTRAINT cyclic_constraint1 FOREIGN KEY(id, table2_id) REFERENCES cyclic_reference_table2(table1_id, id) DEFERRABLE INITIALLY DEFERRED;
|
|
ALTER TABLE cyclic_reference_table2 ADD CONSTRAINT cyclic_constraint2 FOREIGN KEY(id, table1_id) REFERENCES cyclic_reference_table1(table2_id, id) DEFERRABLE INITIALLY DEFERRED;
|
|
-- test insertion to a table which has cyclic foreign constraints, we expect that to fail
|
|
INSERT INTO cyclic_reference_table1 VALUES(1, 1);
|
|
ERROR: insert or update on table "cyclic_reference_table1_1350632" violates foreign key constraint "cyclic_constraint1_1350632"
|
|
DETAIL: Key (id, table2_id)=(1, 1) is not present in table "cyclic_reference_table2_1350636".
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
-- proper insertion to table with cyclic dependency
|
|
BEGIN;
|
|
INSERT INTO cyclic_reference_table1 VALUES(1, 1);
|
|
INSERT INTO cyclic_reference_table2 VALUES(1, 1);
|
|
COMMIT;
|
|
-- verify that rows are actually inserted
|
|
SELECT * FROM cyclic_reference_table1;
|
|
id | table2_id
|
|
---------------------------------------------------------------------
|
|
1 | 1
|
|
(1 row)
|
|
|
|
SELECT * FROM cyclic_reference_table2;
|
|
id | table1_id
|
|
---------------------------------------------------------------------
|
|
1 | 1
|
|
(1 row)
|
|
|
|
-- test dropping cyclic referenced tables
|
|
-- we expect those two queries to fail
|
|
DROP TABLE cyclic_reference_table1;
|
|
ERROR: cannot drop table cyclic_reference_table1 because other objects depend on it
|
|
DETAIL: constraint cyclic_constraint2 on table cyclic_reference_table2 depends on table cyclic_reference_table1
|
|
HINT: Use DROP ... CASCADE to drop the dependent objects too.
|
|
DROP TABLE cyclic_reference_table2;
|
|
ERROR: cannot drop table cyclic_reference_table2 because other objects depend on it
|
|
DETAIL: constraint cyclic_constraint1 on table cyclic_reference_table1 depends on table cyclic_reference_table2
|
|
HINT: Use DROP ... CASCADE to drop the dependent objects too.
|
|
-- proper way of DROP with CASCADE option
|
|
DROP TABLE cyclic_reference_table1 CASCADE;
|
|
NOTICE: drop cascades to constraint cyclic_constraint2 on table cyclic_reference_table2
|
|
DROP TABLE cyclic_reference_table2 CASCADE;
|
|
-- test creation of foreign keys in a transaction
|
|
CREATE TABLE transaction_referenced_table(id int PRIMARY KEY);
|
|
CREATE TABLE transaction_referencing_table(id int, ref_id int);
|
|
BEGIN;
|
|
ALTER TABLE transaction_referencing_table ADD CONSTRAINT transaction_fk_constraint FOREIGN KEY(ref_id) REFERENCES transaction_referenced_table(id);
|
|
COMMIT;
|
|
-- test insertion to referencing table, we expect that to fail
|
|
INSERT INTO transaction_referencing_table VALUES(1, 1);
|
|
ERROR: insert or update on table "transaction_referencing_table" violates foreign key constraint "transaction_fk_constraint"
|
|
DETAIL: Key (ref_id)=(X) is not present in table "transaction_referenced_table".
|
|
-- proper insertion to both referenced and referencing tables
|
|
INSERT INTO transaction_referenced_table VALUES(1);
|
|
INSERT INTO transaction_referencing_table VALUES(1, 1);
|
|
-- verify that rows are actually inserted
|
|
SELECT * FROM transaction_referenced_table;
|
|
id
|
|
---------------------------------------------------------------------
|
|
1
|
|
(1 row)
|
|
|
|
SELECT * FROM transaction_referencing_table;
|
|
id | ref_id
|
|
---------------------------------------------------------------------
|
|
1 | 1
|
|
(1 row)
|
|
|
|
-- we no longer need those tables
|
|
DROP TABLE transaction_referencing_table;
|
|
DROP TABLE transaction_referenced_table;
|
|
-- test self referencing foreign key
|
|
CREATE TABLE self_referencing_table1(
|
|
id int,
|
|
other_column int,
|
|
other_column_ref int,
|
|
PRIMARY KEY(id, other_column),
|
|
FOREIGN KEY(id, other_column_ref) REFERENCES self_referencing_table1(id, other_column)
|
|
);
|
|
SELECT create_distributed_table('self_referencing_table1', 'id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
-- test insertion to self referencing table
|
|
INSERT INTO self_referencing_table1 VALUES(1, 1, 1);
|
|
-- we expect this query to fail
|
|
INSERT INTO self_referencing_table1 VALUES(1, 2, 3);
|
|
ERROR: insert or update on table "self_referencing_table1_1350640" violates foreign key constraint "self_referencing_table1_id_fkey_1350640"
|
|
DETAIL: Key (id, other_column_ref)=(1, 3) is not present in table "self_referencing_table1_1350640".
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
-- verify that rows are actually inserted
|
|
SELECT * FROM self_referencing_table1;
|
|
id | other_column | other_column_ref
|
|
---------------------------------------------------------------------
|
|
1 | 1 | 1
|
|
(1 row)
|
|
|
|
-- we no longer need those tables
|
|
DROP TABLE self_referencing_table1;
|
|
-- test self referencing foreign key with ALTER TABLE
|
|
CREATE TABLE self_referencing_table2(id int, other_column int, other_column_ref int, PRIMARY KEY(id, other_column));
|
|
SELECT create_distributed_table('self_referencing_table2', 'id', 'hash');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
ALTER TABLE self_referencing_table2 ADD CONSTRAINT self_referencing_fk_constraint FOREIGN KEY(id, other_column_ref) REFERENCES self_referencing_table2(id, other_column);
|
|
-- test insertion to self referencing table
|
|
INSERT INTO self_referencing_table2 VALUES(1, 1, 1);
|
|
-- we expect this query to fail
|
|
INSERT INTO self_referencing_table2 VALUES(1, 2, 3);
|
|
ERROR: insert or update on table "self_referencing_table2_1350644" violates foreign key constraint "self_referencing_fk_constraint_1350644"
|
|
DETAIL: Key (id, other_column_ref)=(1, 3) is not present in table "self_referencing_table2_1350644".
|
|
CONTEXT: while executing command on localhost:xxxxx
|
|
-- verify that rows are actually inserted
|
|
SELECT * FROM self_referencing_table2;
|
|
id | other_column | other_column_ref
|
|
---------------------------------------------------------------------
|
|
1 | 1 | 1
|
|
(1 row)
|
|
|
|
-- we no longer need those tables
|
|
DROP TABLE self_referencing_table2;
|
|
-- test reference tables
|
|
-- test foreign key creation on CREATE TABLE from reference table
|
|
CREATE TABLE referenced_by_reference_table(id int PRIMARY KEY, other_column int);
|
|
SELECT create_distributed_table('referenced_by_reference_table', 'id');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
CREATE TABLE reference_table(id int, referencing_column int REFERENCES referenced_by_reference_table(id));
|
|
SELECT create_reference_table('reference_table');
|
|
ERROR: cannot create foreign key constraint since foreign keys from reference tables to distributed tables are not supported
|
|
DETAIL: A reference table can only have reference keys to other reference tables
|
|
-- test foreign key creation on CREATE TABLE from + to reference table
|
|
DROP TABLE reference_table;
|
|
CREATE TABLE reference_table(id int PRIMARY KEY, referencing_column int);
|
|
SELECT create_reference_table('reference_table');
|
|
create_reference_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
CREATE TABLE reference_table_second(id int, referencing_column int REFERENCES reference_table(id));
|
|
SELECT create_reference_table('reference_table_second');
|
|
create_reference_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
-- test foreign key creation on CREATE TABLE from reference table to local table
|
|
CREATE TABLE referenced_local_table(id int PRIMARY KEY, other_column int);
|
|
DROP TABLE reference_table CASCADE;
|
|
NOTICE: drop cascades to constraint reference_table_second_referencing_column_fkey on table reference_table_second
|
|
CREATE TABLE reference_table(id int, referencing_column int REFERENCES referenced_local_table(id));
|
|
SELECT create_reference_table('reference_table');
|
|
ERROR: referenced table "referenced_local_table" must be a distributed table or a reference table
|
|
DETAIL: To enforce foreign keys, the referencing and referenced rows need to be stored on the same node.
|
|
HINT: You could use SELECT create_reference_table('referenced_local_table') to replicate the referenced table to all nodes
|
|
-- test foreign key creation on CREATE TABLE on self referencing reference table
|
|
CREATE TABLE self_referencing_reference_table(
|
|
id int,
|
|
other_column int,
|
|
other_column_ref int,
|
|
PRIMARY KEY(id, other_column),
|
|
FOREIGN KEY(id, other_column_ref) REFERENCES self_referencing_reference_table(id, other_column)
|
|
);
|
|
SELECT create_reference_table('self_referencing_reference_table');
|
|
create_reference_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
-- test foreign key creation on ALTER TABLE from reference table
|
|
DROP TABLE reference_table;
|
|
CREATE TABLE reference_table(id int PRIMARY KEY, referencing_column int);
|
|
SELECT create_reference_table('reference_table');
|
|
create_reference_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
ALTER TABLE reference_table ADD CONSTRAINT fk FOREIGN KEY(referencing_column) REFERENCES referenced_by_reference_table(id);
|
|
ERROR: cannot create foreign key constraint since foreign keys from reference tables to distributed tables are not supported
|
|
DETAIL: A reference table can only have reference keys to other reference tables
|
|
-- test foreign key creation on ALTER TABLE to reference table
|
|
CREATE TABLE references_to_reference_table(id int, referencing_column int);
|
|
SELECT create_distributed_table('references_to_reference_table', 'referencing_column');
|
|
create_distributed_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
ALTER TABLE references_to_reference_table ADD CONSTRAINT fk FOREIGN KEY(referencing_column) REFERENCES reference_table(id);
|
|
-- test foreign key creation on ALTER TABLE from + to reference table
|
|
DROP TABLE reference_table_second;
|
|
CREATE TABLE reference_table_second(id int, referencing_column int);
|
|
SELECT create_reference_table('reference_table_second');
|
|
create_reference_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
ALTER TABLE reference_table_second ADD CONSTRAINT fk FOREIGN KEY(referencing_column) REFERENCES reference_table(id);
|
|
-- test foreign key creation on ALTER TABLE from reference table to local table
|
|
DROP TABLE reference_table CASCADE;
|
|
NOTICE: drop cascades to 2 other objects
|
|
DETAIL: drop cascades to constraint fk on table references_to_reference_table
|
|
drop cascades to constraint fk on table reference_table_second
|
|
CREATE TABLE reference_table(id int PRIMARY KEY, referencing_column int);
|
|
SELECT create_reference_table('reference_table');
|
|
create_reference_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
ALTER TABLE reference_table ADD CONSTRAINT fk FOREIGN KEY(referencing_column) REFERENCES referenced_local_table(id);
|
|
ERROR: referenced table "referenced_local_table" must be a distributed table or a reference table
|
|
DETAIL: To enforce foreign keys, the referencing and referenced rows need to be stored on the same node.
|
|
HINT: You could use SELECT create_reference_table('referenced_local_table') to replicate the referenced table to all nodes
|
|
-- test foreign key creation on ALTER TABLE on self referencing reference table
|
|
DROP TABLE self_referencing_reference_table;
|
|
CREATE TABLE self_referencing_reference_table(
|
|
id int,
|
|
other_column int,
|
|
other_column_ref int,
|
|
PRIMARY KEY(id, other_column)
|
|
);
|
|
SELECT create_reference_table('self_referencing_reference_table');
|
|
create_reference_table
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
ALTER TABLE self_referencing_reference_table ADD CONSTRAINT fk FOREIGN KEY(id, other_column_ref) REFERENCES self_referencing_reference_table(id, other_column);
|
|
-- we no longer need those tables
|
|
DROP TABLE referenced_by_reference_table, references_to_reference_table, reference_table, reference_table_second, referenced_local_table, self_referencing_reference_table;
|