mirror of https://github.com/citusdata/citus.git
Address Onder's comments
parent
bb9e95e134
commit
88ee7802dd
|
@ -408,7 +408,13 @@ ErrorIfNotSupportedConstraint(Relation relation, char distributionMethod,
|
|||
List *indexOidList = NULL;
|
||||
ListCell *indexOidCell = NULL;
|
||||
|
||||
/* we first perform check for foreign constraints */
|
||||
/*
|
||||
* We first perform check for foreign constraints. It is important to do this check
|
||||
* before next check, because other types of constraints are allowed on reference
|
||||
* tables and we return early for those constraints thanks to next check. Therefore,
|
||||
* for reference tables, we first check for foreing constraints and if they are OK,
|
||||
* we do not error out for other types of constraints.
|
||||
*/
|
||||
ErrorIfNotSupportedForeignConstraint(relation, distributionMethod, distributionColumn,
|
||||
colocationId);
|
||||
|
||||
|
@ -540,6 +546,7 @@ ErrorIfNotSupportedForeignConstraint(Relation relation, char distributionMethod,
|
|||
bool isNull = false;
|
||||
int attrIdx = 0;
|
||||
bool foreignConstraintOnPartitionColumn = false;
|
||||
bool selfReferencingTable = false;
|
||||
|
||||
pgConstraint = heap_open(ConstraintRelationId, AccessShareLock);
|
||||
ScanKeyInit(&scanKey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ,
|
||||
|
@ -559,10 +566,18 @@ ErrorIfNotSupportedForeignConstraint(Relation relation, char distributionMethod,
|
|||
}
|
||||
|
||||
referencedTableId = constraintForm->confrelid;
|
||||
selfReferencingTable = relation->rd_id == referencedTableId;
|
||||
|
||||
/* we do not support foreign keys for reference tables */
|
||||
/*
|
||||
* We do not support foreign keys for reference tables. Here we skip the second
|
||||
* part of check if the table is a self referencing table because;
|
||||
* - PartitionMethod only works for distributed tables and this table is not
|
||||
* distributed yet.
|
||||
* - Since referencing and referenced tables are same, it is OK to not checking
|
||||
* distribution method twice.
|
||||
*/
|
||||
if (distributionMethod == DISTRIBUTE_BY_NONE ||
|
||||
(relation->rd_id != referencedTableId &&
|
||||
(!selfReferencingTable &&
|
||||
PartitionMethod(referencedTableId) == DISTRIBUTE_BY_NONE))
|
||||
{
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
|
@ -604,7 +619,7 @@ ErrorIfNotSupportedForeignConstraint(Relation relation, char distributionMethod,
|
|||
* Some checks are not meaningful if foreign key references the table itself.
|
||||
* Therefore we will skip those checks.
|
||||
*/
|
||||
if (referencedTableId != relation->rd_id)
|
||||
if (!selfReferencingTable)
|
||||
{
|
||||
if (!IsDistributedTable(referencedTableId))
|
||||
{
|
||||
|
|
|
@ -800,11 +800,40 @@ SELECT create_distributed_table('references_to_reference_table', 'referencing_co
|
|||
ERROR: cannot create foreign key constraint
|
||||
DETAIL: Foreign key constraints are not allowed from or to reference tables.
|
||||
-- test foreign key creation on CREATE TABLE from + to reference table
|
||||
CREATE TABLE reference_table2(id int, referencing_column int REFERENCES reference_table(id));
|
||||
SELECT create_reference_table('reference_table2');
|
||||
CREATE TABLE reference_table_second(id int, referencing_column int REFERENCES reference_table(id));
|
||||
SELECT create_reference_table('reference_table_second');
|
||||
ERROR: cannot create foreign key constraint
|
||||
DETAIL: Foreign key constraints are not allowed from or to reference tables.
|
||||
-- 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 2 other objects
|
||||
DETAIL: drop cascades to constraint references_to_reference_table_referencing_column_fkey on table references_to_reference_table
|
||||
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: cannot create foreign key constraint
|
||||
DETAIL: Foreign key constraints are not allowed from or to reference tables.
|
||||
-- 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');
|
||||
ERROR: cannot create foreign key constraint
|
||||
DETAIL: Foreign key constraints are not allowed from or to reference tables.
|
||||
-- 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
|
||||
DETAIL: Foreign key constraints are not allowed from or to reference tables.
|
||||
|
@ -821,16 +850,45 @@ ALTER TABLE references_to_reference_table ADD CONSTRAINT fk FOREIGN KEY(referenc
|
|||
ERROR: cannot create foreign key constraint
|
||||
DETAIL: Foreign key constraints are not allowed from or to reference tables.
|
||||
-- test foreign key creation on ALTER TABLE from + to reference table
|
||||
DROP TABLE reference_table2;
|
||||
CREATE TABLE reference_table2(id int, referencing_column int);
|
||||
SELECT create_reference_table('reference_table2');
|
||||
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_table2 ADD CONSTRAINT fk FOREIGN KEY(referencing_column) REFERENCES reference_table(id);
|
||||
ALTER TABLE reference_table_second ADD CONSTRAINT fk FOREIGN KEY(referencing_column) REFERENCES reference_table(id);
|
||||
ERROR: cannot create foreign key constraint
|
||||
DETAIL: Foreign key constraints are not allowed from or to reference tables.
|
||||
-- test foreign key creation on ALTER TABLE from reference table to local 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_local_table(id);
|
||||
ERROR: cannot create foreign key constraint
|
||||
DETAIL: Foreign key constraints are not allowed from or to reference tables.
|
||||
-- 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);
|
||||
ERROR: cannot create foreign key constraint
|
||||
DETAIL: Foreign key constraints are not allowed from or to reference tables.
|
||||
-- we no longer need those tables
|
||||
DROP TABLE referenced_by_reference_table, references_to_reference_table, reference_table, reference_table2;
|
||||
DROP TABLE referenced_by_reference_table, references_to_reference_table, reference_table, reference_table_second, referenced_local_table, self_referencing_reference_table;
|
||||
|
|
|
@ -468,10 +468,29 @@ CREATE TABLE references_to_reference_table(id int, referencing_column int REFERE
|
|||
SELECT create_distributed_table('references_to_reference_table', 'referencing_column');
|
||||
|
||||
-- test foreign key creation on CREATE TABLE from + to reference table
|
||||
CREATE TABLE reference_table2(id int, referencing_column int REFERENCES reference_table(id));
|
||||
SELECT create_reference_table('reference_table2');
|
||||
CREATE TABLE reference_table_second(id int, referencing_column int REFERENCES reference_table(id));
|
||||
SELECT create_reference_table('reference_table_second');
|
||||
|
||||
-- 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;
|
||||
CREATE TABLE reference_table(id int, referencing_column int REFERENCES referenced_local_table(id));
|
||||
SELECT create_reference_table('reference_table');
|
||||
|
||||
-- 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');
|
||||
|
||||
-- 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');
|
||||
ALTER TABLE reference_table ADD CONSTRAINT fk FOREIGN KEY(referencing_column) REFERENCES referenced_by_reference_table(id);
|
||||
|
||||
-- test foreign key creation on ALTER TABLE to reference table
|
||||
|
@ -481,10 +500,27 @@ SELECT create_distributed_table('references_to_reference_table', 'referencing_co
|
|||
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_table2;
|
||||
CREATE TABLE reference_table2(id int, referencing_column int);
|
||||
SELECT create_reference_table('reference_table2');
|
||||
ALTER TABLE reference_table2 ADD CONSTRAINT fk FOREIGN KEY(referencing_column) REFERENCES reference_table(id);
|
||||
DROP TABLE reference_table_second;
|
||||
CREATE TABLE reference_table_second(id int, referencing_column int);
|
||||
SELECT create_reference_table('reference_table_second');
|
||||
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;
|
||||
CREATE TABLE reference_table(id int PRIMARY KEY, referencing_column int);
|
||||
SELECT create_reference_table('reference_table');
|
||||
ALTER TABLE reference_table ADD CONSTRAINT fk FOREIGN KEY(referencing_column) REFERENCES referenced_local_table(id);
|
||||
|
||||
-- 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');
|
||||
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_table2;
|
||||
DROP TABLE referenced_by_reference_table, references_to_reference_table, reference_table, reference_table_second, referenced_local_table, self_referencing_reference_table;
|
||||
|
|
Loading…
Reference in New Issue