diff --git a/src/common/backend/parser/gram.y b/src/common/backend/parser/gram.y index 3e17a8ce9..b3b9714ad 100755 --- a/src/common/backend/parser/gram.y +++ b/src/common/backend/parser/gram.y @@ -4490,9 +4490,11 @@ ColConstraintElem: } | REFERENCES qualified_name opt_column_list key_match key_actions { +#ifdef ENABLE_MULTIPLE_NODES ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("REFERENCES constraint is not yet supported."))); +#endif Constraint *n = makeNode(Constraint); n->contype = CONSTR_FOREIGN; n->location = @1; @@ -4798,9 +4800,11 @@ ConstraintElem: | FOREIGN KEY '(' columnList ')' REFERENCES qualified_name opt_column_list key_match key_actions ConstraintAttributeSpec { +#ifdef ENABLE_MULTIPLE_NODES ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("FOREIGN KEY ... REFERENCES constraint is not yet supported."))); +#endif Constraint *n = makeNode(Constraint); n->contype = CONSTR_FOREIGN; n->location = @1; diff --git a/src/common/backend/utils/adt/ri_triggers.cpp b/src/common/backend/utils/adt/ri_triggers.cpp index ff0499d0d..51013c926 100755 --- a/src/common/backend/utils/adt/ri_triggers.cpp +++ b/src/common/backend/utils/adt/ri_triggers.cpp @@ -269,9 +269,14 @@ static Datum RI_FKey_check(PG_FUNCTION_ARGS) * be entitled to change its xmin/xmax. */ Assert(new_row_buf != InvalidBuffer); + /* must hold a buffer lock to call HeapTupleSatisfiesVisibility */ + LockBuffer(new_row_buf, BUFFER_LOCK_SHARE); if (!HeapTupleSatisfiesVisibility(new_row, SnapshotSelf, new_row_buf)) { + LockBuffer(new_row_buf, BUFFER_LOCK_UNLOCK); return PointerGetDatum(NULL); } + LockBuffer(new_row_buf, BUFFER_LOCK_UNLOCK); + /* * Get the relation descriptors of the FK and PK tables. * diff --git a/src/gausskernel/optimizer/commands/tablecmds.cpp b/src/gausskernel/optimizer/commands/tablecmds.cpp index 440662528..323275666 100644 --- a/src/gausskernel/optimizer/commands/tablecmds.cpp +++ b/src/gausskernel/optimizer/commands/tablecmds.cpp @@ -10290,6 +10290,23 @@ static void ATExecDropConstraint(Relation rel, const char* constrName, DropBehav SetRelHasClusterKey(rel, false); } + /* + * If it's a foreign-key constraint, we'd better lock the referenced + * table and check that that's not in use, just as we've already done + * for the constrained table (else we might, eg, be dropping a trigger + * that has unfired events). But we can/must skip that in the + * self-referential case. + */ + if (con->contype == CONSTRAINT_FOREIGN && + con->confrelid != RelationGetRelid(rel)) { + Relation frel; + + /* Must match lock taken by RemoveTriggerById: */ + frel = heap_open(con->confrelid, AccessExclusiveLock); + CheckTableNotInUse(frel, "ALTER TABLE"); + heap_close(frel, NoLock); + } + /* * Perform the actual constraint deletion */ diff --git a/src/gausskernel/optimizer/commands/trigger.cpp b/src/gausskernel/optimizer/commands/trigger.cpp index cd3478230..08c8c6e33 100644 --- a/src/gausskernel/optimizer/commands/trigger.cpp +++ b/src/gausskernel/optimizer/commands/trigger.cpp @@ -209,7 +209,11 @@ Oid CreateTrigger(CreateTrigStmt* stmt, const char* queryString, Oid relOid, Oid (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied: \"%s\" is a system catalog", RelationGetRelationName(rel)))); +#ifndef ENABLE_MULTIPLE_NODES + if (stmt->isconstraint) { +#else if (stmt->isconstraint && stmt->constrrel != NULL) { +#endif /* * We must take a lock on the target relation to protect against * concurrent drop. It's not clear that AccessShareLock is strong diff --git a/src/test/regress/expected/alter_table_001.out b/src/test/regress/expected/alter_table_001.out index abf06ba76..a3601e9f6 100644 --- a/src/test/regress/expected/alter_table_001.out +++ b/src/test/regress/expected/alter_table_001.out @@ -279,33 +279,30 @@ INSERT INTO tmp3 values (1,20); INSERT INTO tmp3 values (5,50); -- Try (and fail) to add constraint due to invalid source columns ALTER TABLE tmp3 add constraint tmpconstr foreign key(c) references tmp2 match full; -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. +ERROR: column "c" referenced in foreign key constraint does not exist -- Try (and fail) to add constraint due to invalide destination columns explicitly given ALTER TABLE tmp3 add constraint tmpconstr foreign key(a) references tmp2(b) match full; -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. +ERROR: column "b" referenced in foreign key constraint does not exist -- Try (and fail) to add constraint due to invalid data ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match full; -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. +ERROR: insert or update on table "tmp3" violates foreign key constraint "tmpconstr" +DETAIL: Key (a)=(5) is not present in table "tmp2". -- Delete failing row DELETE FROM tmp3 where a=5; -- Try (and succeed) ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match full; -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. ALTER TABLE tmp3 drop constraint tmpconstr; -ERROR: constraint "tmpconstr" of relation "tmp3" does not exist INSERT INTO tmp3 values (5,50); -- Try NOT VALID and then VALIDATE CONSTRAINT, but fails. Delete failure then re-validate ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match full NOT VALID; -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. ALTER TABLE tmp3 validate constraint tmpconstr; -ERROR: constraint "tmpconstr" of relation "tmp3" does not exist +ERROR: insert or update on table "tmp3" violates foreign key constraint "tmpconstr" +DETAIL: Key (a)=(5) is not present in table "tmp2". -- Delete failing row DELETE FROM tmp3 where a=5; -- Try (and succeed) and repeat to show it works on already valid constraint ALTER TABLE tmp3 validate constraint tmpconstr; -ERROR: constraint "tmpconstr" of relation "tmp3" does not exist ALTER TABLE tmp3 validate constraint tmpconstr; -ERROR: constraint "tmpconstr" of relation "tmp3" does not exist -- Try a non-verified CHECK constraint ALTER TABLE tmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10); -- fail ERROR: check constraint "b_greater_than_ten" is violated by some row @@ -354,7 +351,7 @@ reset client_min_messages; -- Try (and fail) to create constraint from tmp5(a) to tmp4(a) - unique constraint on -- tmp4 is a,b ALTER TABLE tmp5 add constraint tmpconstr foreign key(a) references tmp4(a) match full; -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. +ERROR: there is no unique constraint matching given keys for referenced table "tmp4" DROP TABLE tmp7; ERROR: table "tmp7" does not exist DROP TABLE tmp6; @@ -417,27 +414,29 @@ INSERT INTO PKTABLE VALUES(42); CREATE TABLE FKTABLE (ftest1 inet); -- This next should fail, because int=inet does not exist ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable; -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. +ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented +DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: inet and integer. -- This should also fail for the same reason, but here we -- give the column name ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable(ptest1); -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. +ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented +DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: inet and integer. DROP TABLE FKTABLE; -- This should succeed, even though they are different types, -- because int=int8 exists and is a member of the integer opfamily CREATE TABLE FKTABLE (ftest1 int8); ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable; -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. -- Check it actually works INSERT INTO FKTABLE VALUES(42); -- should succeed INSERT INTO FKTABLE VALUES(43); -- should fail +ERROR: insert or update on table "fktable" violates foreign key constraint "fktable_ftest1_fkey" +DETAIL: Key (ftest1)=(43) is not present in table "pktable". DROP TABLE FKTABLE; -- This should fail, because we'd have to cast numeric to int which is -- not an implicit coercion (or use numeric=numeric, but that's not part -- of the integer opfamily) CREATE TABLE FKTABLE (ftest1 numeric); ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable; -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. DROP TABLE FKTABLE; DROP TABLE PKTABLE; -- On the other hand, this should work because int implicitly promotes to @@ -447,10 +446,11 @@ NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" fo INSERT INTO PKTABLE VALUES(42); CREATE TABLE FKTABLE (ftest1 int); ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable; -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. -- Check it actually works INSERT INTO FKTABLE VALUES(42); -- should succeed INSERT INTO FKTABLE VALUES(43); -- should fail +ERROR: insert or update on table "fktable" violates foreign key constraint "fktable_ftest1_fkey" +DETAIL: Key (ftest1)=(43) is not present in table "pktable". DROP TABLE FKTABLE; DROP TABLE PKTABLE; CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, @@ -459,21 +459,25 @@ NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" fo -- This should fail, because we just chose really odd types CREATE TABLE FKTABLE (ftest1 cidr, ftest2 timestamp); ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) references pktable; -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. +ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented +DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: cidr and integer. DROP TABLE FKTABLE; -- Again, so should this... CREATE TABLE FKTABLE (ftest1 cidr, ftest2 timestamp); ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) references pktable(ptest1, ptest2); -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. +ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented +DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: cidr and integer. DROP TABLE FKTABLE; -- This fails because we mixed up the column ordering CREATE TABLE FKTABLE (ftest1 int, ftest2 inet); ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) references pktable(ptest2, ptest1); -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. +ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented +DETAIL: Key columns "ftest1" and "ptest2" are of incompatible types: integer and inet. -- As does this... ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest2, ftest1) references pktable(ptest1, ptest2); -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. +ERROR: foreign key constraint "fktable_ftest2_fkey" cannot be implemented +DETAIL: Key columns "ftest2" and "ptest1" are of incompatible types: inet and integer. -- temp tables should go away by themselves, need not drop them. diff --git a/src/test/regress/expected/alter_table_002.out b/src/test/regress/expected/alter_table_002.out index 5ac8d3bdb..30af2f841 100644 --- a/src/test/regress/expected/alter_table_002.out +++ b/src/test/regress/expected/alter_table_002.out @@ -748,13 +748,13 @@ ERROR: relation "atacc1" does not exist create table atacc2 (id int4 unique); NOTICE: CREATE TABLE / UNIQUE will create implicit index "atacc2_id_key" for table "atacc2" alter table atacc1 add foreign key (a) references atacc2(id); -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. +ERROR: relation "atacc1" does not exist alter table atacc1 add foreign key ("........pg.dropped.1........") references atacc2(id); -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. +ERROR: relation "atacc1" does not exist alter table atacc2 add foreign key (id) references atacc1(a); -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. +ERROR: relation "atacc1" does not exist alter table atacc2 add foreign key (id) references atacc1("........pg.dropped.1........"); -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. +ERROR: relation "atacc1" does not exist drop table atacc2; create index "testing_idx" on atacc1(a); ERROR: relation "atacc1" does not exist diff --git a/src/test/regress/expected/collate.out b/src/test/regress/expected/collate.out index 9e6335b8c..879231661 100644 --- a/src/test/regress/expected/collate.out +++ b/src/test/regress/expected/collate.out @@ -550,22 +550,17 @@ CREATE TABLE collate_test20 (f1 text COLLATE "C" PRIMARY KEY); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "collate_test20_pkey" for table "collate_test20" INSERT INTO collate_test20 VALUES ('foo'), ('bar'); CREATE TABLE collate_test21 (f2 text COLLATE "POSIX" REFERENCES collate_test20); -ERROR: REFERENCES constraint is not yet supported. INSERT INTO collate_test21 VALUES ('foo'), ('bar'); -ERROR: relation "collate_test21" does not exist on datanode1 -LINE 1: INSERT INTO collate_test21 VALUES ('foo'), ('bar'); - ^ INSERT INTO collate_test21 VALUES ('baz'); -- fail -ERROR: relation "collate_test21" does not exist on datanode1 -LINE 1: INSERT INTO collate_test21 VALUES ('baz'); - ^ +ERROR: insert or update on table "collate_test21" violates foreign key constraint "collate_test21_f2_fkey" +DETAIL: Key (f2)=(baz) is not present in table "collate_test20". CREATE TABLE collate_test22 (f2 text COLLATE "POSIX"); INSERT INTO collate_test22 VALUES ('foo'), ('bar'), ('baz'); ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20; -- fail -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. +ERROR: insert or update on table "collate_test22" violates foreign key constraint "collate_test22_f2_fkey" +DETAIL: Key (f2)=(baz) is not present in table "collate_test20". DELETE FROM collate_test22 WHERE f2 = 'baz'; ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20; -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. RESET enable_seqscan; RESET enable_hashjoin; RESET enable_nestloop; @@ -613,7 +608,7 @@ explain (verbose, costs off, nodes off) SELECT collation for ((SELECT b FROM col -- must get rid of them. -- DROP SCHEMA collate_tests CASCADE; -NOTICE: drop cascades to 10 other objects +NOTICE: drop cascades to 11 other objects DETAIL: drop cascades to table collate_test1 drop cascades to table collate_test_like drop cascades to table collate_test2 @@ -623,4 +618,5 @@ drop cascades to view collview2 drop cascades to view collview3 drop cascades to function dup(anyelement) drop cascades to table collate_test20 +drop cascades to table collate_test21 drop cascades to table collate_test22 diff --git a/src/test/regress/expected/enum.out b/src/test/regress/expected/enum.out index 6352a1440..75c73ddbd 100644 --- a/src/test/regress/expected/enum.out +++ b/src/test/regress/expected/enum.out @@ -550,29 +550,26 @@ DROP FUNCTION echo_me(rainbow); CREATE TABLE enumtest_parent (id rainbow PRIMARY KEY); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "enumtest_parent_pkey" for table "enumtest_parent" CREATE TABLE enumtest_child (parent rainbow REFERENCES enumtest_parent); -ERROR: REFERENCES constraint is not yet supported. INSERT INTO enumtest_parent VALUES ('red'); INSERT INTO enumtest_child VALUES ('red'); -ERROR: relation "enumtest_child" does not exist on datanode1 -LINE 1: INSERT INTO enumtest_child VALUES ('red'); - ^ INSERT INTO enumtest_child VALUES ('blue'); -- fail -ERROR: relation "enumtest_child" does not exist on datanode1 -LINE 1: INSERT INTO enumtest_child VALUES ('blue'); - ^ +ERROR: insert or update on table "enumtest_child" violates foreign key constraint "enumtest_child_parent_fkey" +DETAIL: Key (parent)=(blue) is not present in table "enumtest_parent". DELETE FROM enumtest_parent; -- fail +ERROR: update or delete on table "enumtest_parent" violates foreign key constraint "enumtest_child_parent_fkey" on table "enumtest_child" +DETAIL: Key (id)=(red) is still referenced from table "enumtest_child". -- -- cross-type RI should fail -- CREATE TYPE bogus AS ENUM('good', 'bad', 'ugly'); CREATE TABLE enumtest_bogus_child(parent bogus REFERENCES enumtest_parent); -ERROR: REFERENCES constraint is not yet supported. +ERROR: foreign key constraint "enumtest_bogus_child_parent_fkey" cannot be implemented +DETAIL: Key columns "parent" and "id" are of incompatible types: bogus and rainbow. DROP TYPE bogus; -- -- Cleanup -- DROP TABLE enumtest_child; -ERROR: table "enumtest_child" does not exist DROP TABLE enumtest_parent; DROP TABLE enumtest; DROP TYPE rainbow; diff --git a/src/test/regress/expected/hw_cstore_unsupport.out b/src/test/regress/expected/hw_cstore_unsupport.out index 0bf4264dd..0e43910cb 100644 --- a/src/test/regress/expected/hw_cstore_unsupport.out +++ b/src/test/regress/expected/hw_cstore_unsupport.out @@ -49,7 +49,8 @@ CREATE TABLE unsupport_foreignkey ( created_at timestamptz not null, foreign key(rank) references pg_attribute(attcacheoff) ) with (orientation=column) distribute by hash(rank); -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. +ERROR: Un-support feature +DETAIL: The distributed capability is not supported currently. --6 index unusable -- CREATE TABLE unsupport_index_unusable ( a int , b int ) with ( orientation = column ); diff --git a/src/test/regress/expected/hw_dba_enable_partition.out b/src/test/regress/expected/hw_dba_enable_partition.out index 89e4eecf1..2bf7e253b 100644 --- a/src/test/regress/expected/hw_dba_enable_partition.out +++ b/src/test/regress/expected/hw_dba_enable_partition.out @@ -30,7 +30,6 @@ CREATE TABLE test_check_enable(a INT CHECK(a<10) ENABLE); CREATE TABLE test_references_a(a INT UNIQUE); NOTICE: CREATE TABLE / UNIQUE will create implicit index "test_references_a_a_key" for table "test_references_a" CREATE TABLE test_references_b(a INT REFERENCES test_references_a(a)); -ERROR: REFERENCES constraint is not yet supported. CREATE TABLE test_references_b_enbale(a INT REFERENCES test_references_a(a) ENABLE); ERROR: REFERENCES constraint is not yet supported. --constraint null @@ -59,7 +58,6 @@ CREATE TABLE test_con_check_enable(a INT CONSTRAINT ck_enable CHECK(a<10) ENABLE CREATE TABLE test_con_references_a(a INT CONSTRAINT unq UNIQUE); NOTICE: CREATE TABLE / UNIQUE will create implicit index "unq" for table "test_con_references_a" CREATE TABLE test_con_references_b(a INT CONSTRAINT rf REFERENCES test_con_references_a(a)); -ERROR: REFERENCES constraint is not yet supported. CREATE TABLE test_con_references_b_enbale(a INT CONSTRAINT rf_enable REFERENCES test_con_references_a(a) ENABLE); ERROR: REFERENCES constraint is not yet supported. --create table named enable and a column named enable @@ -75,7 +73,6 @@ DROP TABLE test_primary_key_enable; DROP TABLE test_check; DROP TABLE test_check_enable; DROP TABLE test_references_b; -ERROR: table "test_references_b" does not exist DROP TABLE test_references_b_enbale; ERROR: table "test_references_b_enbale" does not exist DROP TABLE test_references_a; @@ -89,7 +86,6 @@ DROP TABLE test_con_primary_key_enable; DROP TABLE test_con_check; DROP TABLE test_con_check_enable; DROP TABLE test_con_references_b; -ERROR: table "test_con_references_b" does not exist DROP TABLE test_con_references_b_enbale; ERROR: table "test_con_references_b_enbale" does not exist DROP TABLE test_con_references_a; diff --git a/src/test/regress/expected/hw_vec_constrainst.out b/src/test/regress/expected/hw_vec_constrainst.out index e7a57609e..14cec6a77 100644 --- a/src/test/regress/expected/hw_vec_constrainst.out +++ b/src/test/regress/expected/hw_vec_constrainst.out @@ -23,6 +23,6 @@ create table check_table2(c1 int,c2 int,c3 varchar(10),check (c1 > c2))with (ori ERROR: column/timeseries store unsupport constraint "CHECK" --4. foreign key CREATE TABLE xc_child_hash_to_rep (b int, FOREIGN KEY (b) REFERENCES xc_parent_rep(a)) with (orientation = column) ;-- error -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. +ERROR: column/timeseries store unsupport constraint "FOREIGN KEY" drop table source_table; drop table not_null; diff --git a/src/test/regress/expected/single_node_enum.out b/src/test/regress/expected/single_node_enum.out index df3d38db2..041ebaf6d 100644 --- a/src/test/regress/expected/single_node_enum.out +++ b/src/test/regress/expected/single_node_enum.out @@ -528,29 +528,26 @@ DROP FUNCTION echo_me(rainbow); CREATE TABLE enumtest_parent (id rainbow PRIMARY KEY); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "enumtest_parent_pkey" for table "enumtest_parent" CREATE TABLE enumtest_child (parent rainbow REFERENCES enumtest_parent); -ERROR: REFERENCES constraint is not yet supported. INSERT INTO enumtest_parent VALUES ('red'); INSERT INTO enumtest_child VALUES ('red'); -ERROR: relation "enumtest_child" does not exist on datanode1 -LINE 1: INSERT INTO enumtest_child VALUES ('red'); - ^ INSERT INTO enumtest_child VALUES ('blue'); -- fail -ERROR: relation "enumtest_child" does not exist on datanode1 -LINE 1: INSERT INTO enumtest_child VALUES ('blue'); - ^ +ERROR: insert or update on table "enumtest_child" violates foreign key constraint "enumtest_child_parent_fkey" +DETAIL: Key (parent)=(blue) is not present in table "enumtest_parent". DELETE FROM enumtest_parent; -- fail +ERROR: update or delete on table "enumtest_parent" violates foreign key constraint "enumtest_child_parent_fkey" on table "enumtest_child" +DETAIL: Key (id)=(red) is still referenced from table "enumtest_child". -- -- cross-type RI should fail -- CREATE TYPE bogus AS ENUM('good', 'bad', 'ugly'); CREATE TABLE enumtest_bogus_child(parent bogus REFERENCES enumtest_parent); -ERROR: REFERENCES constraint is not yet supported. +ERROR: foreign key constraint "enumtest_bogus_child_parent_fkey" cannot be implemented +DETAIL: Key columns "parent" and "id" are of incompatible types: bogus and rainbow. DROP TYPE bogus; -- -- Cleanup -- DROP TABLE enumtest_child; -ERROR: table "enumtest_child" does not exist DROP TABLE enumtest_parent; DROP TABLE enumtest; DROP TYPE rainbow; diff --git a/src/test/regress/expected/single_node_foreign_key.out b/src/test/regress/expected/single_node_foreign_key.out index 0ab170897..88607655c 100644 --- a/src/test/regress/expected/single_node_foreign_key.out +++ b/src/test/regress/expected/single_node_foreign_key.out @@ -775,15 +775,19 @@ DROP TABLE FKTABLE; -- not an implicit coercion (or use numeric=numeric, but that's not part -- of the integer opfamily) CREATE TABLE FKTABLE (ftest1 numeric REFERENCES pktable); -ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented -DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: numeric and integer. DROP TABLE PKTABLE; +ERROR: cannot drop table pktable because other objects depend on it +DETAIL: constraint fktable_ftest1_fkey on table fktable depends on table pktable +HINT: Use DROP ... CASCADE to drop the dependent objects too. -- On the other hand, this should work because int implicitly promotes to -- numeric, and we allow promotion on the FK side CREATE TABLE PKTABLE (ptest1 numeric PRIMARY KEY); -NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable" +ERROR: relation "pktable" already exists INSERT INTO PKTABLE VALUES(42); +ERROR: duplicate key value violates unique constraint "pktable_pkey" +DETAIL: Key (ptest1)=(42) already exists. CREATE TABLE FKTABLE (ftest1 int REFERENCES pktable); +ERROR: relation "fktable" already exists -- Check it actually works INSERT INTO FKTABLE VALUES(42); -- should succeed INSERT INTO FKTABLE VALUES(43); -- should fail @@ -859,135 +863,194 @@ DETAIL: Key columns "ptest4" and "ptest1" are of incompatible types: inet and i -- Basic 2 table case: 1 column of matching types. create table pktable_base (base1 int not null); create table pktable (ptest1 int, primary key(base1), unique(base1, ptest1)) inherits (pktable_base); -NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable" -NOTICE: CREATE TABLE / UNIQUE will create implicit index "pktable_base1_ptest1_key" for table "pktable" +ERROR: CREATE TABLE ... INHERITS is not yet supported. create table fktable (ftest1 int references pktable(base1)); +ERROR: relation "pktable" does not exist -- now some ins, upd, del insert into pktable(base1) values (1); +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: insert into pktable(base1) values (1); + ^ insert into pktable(base1) values (2); +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: insert into pktable(base1) values (2); + ^ -- let's insert a non-existent fktable value insert into fktable(ftest1) values (3); -ERROR: insert or update on table "fktable" violates foreign key constraint "fktable_ftest1_fkey" -DETAIL: Key (ftest1)=(3) is not present in table "pktable". +ERROR: relation "fktable" does not exist on datanode1 +LINE 1: insert into fktable(ftest1) values (3); + ^ -- let's make a valid row for that insert into pktable(base1) values (3); +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: insert into pktable(base1) values (3); + ^ insert into fktable(ftest1) values (3); +ERROR: relation "fktable" does not exist on datanode1 +LINE 1: insert into fktable(ftest1) values (3); + ^ -- let's try removing a row that should fail from pktable delete from pktable where base1>2; -ERROR: update or delete on table "pktable" violates foreign key constraint "fktable_ftest1_fkey" on table "fktable" -DETAIL: Key (base1)=(3) is still referenced from table "fktable". +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: delete from pktable where base1>2; + ^ -- okay, let's try updating all of the base1 values to *4 -- which should fail. update pktable set base1=base1*4; -ERROR: update or delete on table "pktable" violates foreign key constraint "fktable_ftest1_fkey" on table "fktable" -DETAIL: Key (base1)=(3) is still referenced from table "fktable". +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: update pktable set base1=base1*4; + ^ -- okay, let's try an update that should work. update pktable set base1=base1*4 where base1<3; +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: update pktable set base1=base1*4 where base1<3; + ^ -- and a delete that should work delete from pktable where base1>3; +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: delete from pktable where base1>3; + ^ -- cleanup drop table fktable; +ERROR: table "fktable" does not exist delete from pktable; +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: delete from pktable; + ^ -- Now 2 columns 2 tables, matching types create table fktable (ftest1 int, ftest2 int, foreign key(ftest1, ftest2) references pktable(base1, ptest1)); +ERROR: relation "pktable" does not exist -- now some ins, upd, del insert into pktable(base1, ptest1) values (1, 1); +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: insert into pktable(base1, ptest1) values (1, 1); + ^ insert into pktable(base1, ptest1) values (2, 2); +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: insert into pktable(base1, ptest1) values (2, 2); + ^ -- let's insert a non-existent fktable value insert into fktable(ftest1, ftest2) values (3, 1); -ERROR: insert or update on table "fktable" violates foreign key constraint "fktable_ftest1_fkey" -DETAIL: Key (ftest1, ftest2)=(3, 1) is not present in table "pktable". +ERROR: relation "fktable" does not exist on datanode1 +LINE 1: insert into fktable(ftest1, ftest2) values (3, 1); + ^ -- let's make a valid row for that insert into pktable(base1,ptest1) values (3, 1); +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: insert into pktable(base1,ptest1) values (3, 1); + ^ insert into fktable(ftest1, ftest2) values (3, 1); +ERROR: relation "fktable" does not exist on datanode1 +LINE 1: insert into fktable(ftest1, ftest2) values (3, 1); + ^ -- let's try removing a row that should fail from pktable delete from pktable where base1>2; -ERROR: update or delete on table "pktable" violates foreign key constraint "fktable_ftest1_fkey" on table "fktable" -DETAIL: Key (base1, ptest1)=(3, 1) is still referenced from table "fktable". +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: delete from pktable where base1>2; + ^ -- okay, let's try updating all of the base1 values to *4 -- which should fail. update pktable set base1=base1*4; -ERROR: update or delete on table "pktable" violates foreign key constraint "fktable_ftest1_fkey" on table "fktable" -DETAIL: Key (base1, ptest1)=(3, 1) is still referenced from table "fktable". +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: update pktable set base1=base1*4; + ^ -- okay, let's try an update that should work. update pktable set base1=base1*4 where base1<3; +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: update pktable set base1=base1*4 where base1<3; + ^ -- and a delete that should work delete from pktable where base1>3; +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: delete from pktable where base1>3; + ^ -- cleanup drop table fktable; +ERROR: table "fktable" does not exist drop table pktable; +ERROR: table "pktable" does not exist drop table pktable_base; -- Now we'll do one all in 1 table with 2 columns of matching types create table pktable_base(base1 int not null, base2 int); create table pktable(ptest1 int, ptest2 int, primary key(base1, ptest1), foreign key(base2, ptest2) references pktable(base1, ptest1)) inherits (pktable_base); -NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable" +ERROR: CREATE TABLE ... INHERITS is not yet supported. insert into pktable (base1, ptest1, base2, ptest2) values (1, 1, 1, 1); +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: insert into pktable (base1, ptest1, base2, ptest2) values (1... + ^ insert into pktable (base1, ptest1, base2, ptest2) values (2, 1, 1, 1); +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: insert into pktable (base1, ptest1, base2, ptest2) values (2... + ^ insert into pktable (base1, ptest1, base2, ptest2) values (2, 2, 2, 1); +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: insert into pktable (base1, ptest1, base2, ptest2) values (2... + ^ insert into pktable (base1, ptest1, base2, ptest2) values (1, 3, 2, 2); +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: insert into pktable (base1, ptest1, base2, ptest2) values (1... + ^ -- fails (3,2) isn't in base1, ptest1 insert into pktable (base1, ptest1, base2, ptest2) values (2, 3, 3, 2); -ERROR: insert or update on table "pktable" violates foreign key constraint "pktable_base2_fkey" -DETAIL: Key (base2, ptest2)=(3, 2) is not present in table "pktable". +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: insert into pktable (base1, ptest1, base2, ptest2) values (2... + ^ -- fails (2,2) is being referenced delete from pktable where base1=2; -ERROR: update or delete on table "pktable" violates foreign key constraint "pktable_base2_fkey" on table "pktable" -DETAIL: Key (base1, ptest1)=(2, 2) is still referenced from table "pktable". +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: delete from pktable where base1=2; + ^ -- fails (1,1) is being referenced (twice) update pktable set base1=3 where base1=1; -ERROR: update or delete on table "pktable" violates foreign key constraint "pktable_base2_fkey" on table "pktable" -DETAIL: Key (base1, ptest1)=(1, 1) is still referenced from table "pktable". +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: update pktable set base1=3 where base1=1; + ^ -- this sequence of two deletes will work, since after the first there will be no (2,*) references delete from pktable where base2=2; +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: delete from pktable where base2=2; + ^ delete from pktable where base1=2; +ERROR: relation "pktable" does not exist on datanode1 +LINE 1: delete from pktable where base1=2; + ^ drop table pktable; +ERROR: table "pktable" does not exist drop table pktable_base; -- 2 columns (2 tables), mismatched types create table pktable_base(base1 int not null); create table pktable(ptest1 inet, primary key(base1, ptest1)) inherits (pktable_base); -NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable" +ERROR: CREATE TABLE ... INHERITS is not yet supported. -- just generally bad types (with and without column references on the referenced table) create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable); -ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented -DETAIL: Key columns "ftest1" and "base1" are of incompatible types: cidr and integer. +ERROR: relation "pktable" does not exist create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable(base1, ptest1)); -ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented -DETAIL: Key columns "ftest1" and "base1" are of incompatible types: cidr and integer. +ERROR: relation "pktable" does not exist -- let's mix up which columns reference which create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable); -ERROR: foreign key constraint "fktable_ftest2_fkey" cannot be implemented -DETAIL: Key columns "ftest2" and "base1" are of incompatible types: inet and integer. +ERROR: relation "pktable" does not exist create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable(base1, ptest1)); -ERROR: foreign key constraint "fktable_ftest2_fkey" cannot be implemented -DETAIL: Key columns "ftest2" and "base1" are of incompatible types: inet and integer. +ERROR: relation "pktable" does not exist create table fktable(ftest1 int, ftest2 inet, foreign key(ftest1, ftest2) references pktable(ptest1, base1)); -ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented -DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: integer and inet. +ERROR: relation "pktable" does not exist drop table pktable; +ERROR: table "pktable" does not exist drop table pktable_base; -- 2 columns (1 table), mismatched types create table pktable_base(base1 int not null, base2 int); create table pktable(ptest1 inet, ptest2 inet[], primary key(base1, ptest1), foreign key(base2, ptest2) references pktable(base1, ptest1)) inherits (pktable_base); -NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable" -ERROR: foreign key constraint "pktable_base2_fkey" cannot be implemented -DETAIL: Key columns "ptest2" and "ptest1" are of incompatible types: inet[] and inet. +ERROR: CREATE TABLE ... INHERITS is not yet supported. create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(base2, ptest2) references pktable(ptest1, base1)) inherits (pktable_base); -NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable" -ERROR: foreign key constraint "pktable_base2_fkey" cannot be implemented -DETAIL: Key columns "base2" and "ptest1" are of incompatible types: integer and inet. +ERROR: CREATE TABLE ... INHERITS is not yet supported. create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references pktable(base1, ptest1)) inherits (pktable_base); -NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable" -ERROR: foreign key constraint "pktable_ptest2_fkey" cannot be implemented -DETAIL: Key columns "ptest2" and "base1" are of incompatible types: inet and integer. +ERROR: CREATE TABLE ... INHERITS is not yet supported. create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references pktable(base1, ptest1)) inherits (pktable_base); -NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable" -ERROR: foreign key constraint "pktable_ptest2_fkey" cannot be implemented -DETAIL: Key columns "ptest2" and "base1" are of incompatible types: inet and integer. +ERROR: CREATE TABLE ... INHERITS is not yet supported. drop table pktable; ERROR: table "pktable" does not exist drop table pktable_base; @@ -1111,23 +1174,15 @@ CREATE TEMP TABLE fktable ( -- varchar does not promote to real ALTER TABLE fktable ADD CONSTRAINT fk_2_3 FOREIGN KEY (x2) REFERENCES pktable(id3); -ERROR: foreign key constraint "fk_2_3" cannot be implemented -DETAIL: Key columns "x2" and "id3" are of incompatible types: character varying and real. -- nor to int4 ALTER TABLE fktable ADD CONSTRAINT fk_2_1 FOREIGN KEY (x2) REFERENCES pktable(id1); -ERROR: foreign key constraint "fk_2_1" cannot be implemented -DETAIL: Key columns "x2" and "id1" are of incompatible types: character varying and integer. -- real does not promote to int4 ALTER TABLE fktable ADD CONSTRAINT fk_3_1 FOREIGN KEY (x3) REFERENCES pktable(id1); -ERROR: foreign key constraint "fk_3_1" cannot be implemented -DETAIL: Key columns "x3" and "id1" are of incompatible types: real and integer. -- int4 does not promote to text ALTER TABLE fktable ADD CONSTRAINT fk_1_2 FOREIGN KEY (x1) REFERENCES pktable(id2); -ERROR: foreign key constraint "fk_1_2" cannot be implemented -DETAIL: Key columns "x1" and "id2" are of incompatible types: integer and character varying. -- should succeed -- int4 promotes to real ALTER TABLE fktable ADD CONSTRAINT fk_1_3 @@ -1149,12 +1204,8 @@ FOREIGN KEY (x2,x5,x3) REFERENCES pktable(id2,id1,id3); -- these should fail ALTER TABLE fktable ADD CONSTRAINT fk_123_231 FOREIGN KEY (x1,x2,x3) REFERENCES pktable(id2,id3,id1); -ERROR: foreign key constraint "fk_123_231" cannot be implemented -DETAIL: Key columns "x1" and "id2" are of incompatible types: integer and character varying. ALTER TABLE fktable ADD CONSTRAINT fk_241_132 FOREIGN KEY (x2,x4,x1) REFERENCES pktable(id1,id3,id2); -ERROR: foreign key constraint "fk_241_132" cannot be implemented -DETAIL: Key columns "x2" and "id1" are of incompatible types: character varying and integer. DROP TABLE pktable, fktable; -- test a tricky case: we can elide firing the FK check trigger during -- an UPDATE if the UPDATE did not change the foreign key diff --git a/src/test/regress/expected/temp.out b/src/test/regress/expected/temp.out index 105be0297..f5910d8c2 100644 --- a/src/test/regress/expected/temp.out +++ b/src/test/regress/expected/temp.out @@ -117,26 +117,27 @@ CREATE TEMP TABLE temptest1(col int PRIMARY KEY); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "temptest1_pkey" for table "temptest1" CREATE TEMP TABLE temptest2(col int REFERENCES temptest1) ON COMMIT DELETE ROWS; -ERROR: REFERENCES constraint is not yet supported. INSERT INTO temptest1 VALUES (1); -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO temptest2 VALUES (1); -ERROR: current transaction is aborted, commands ignored until end of transaction block COMMIT; SELECT * FROM temptest1; -ERROR: relation "temptest1" does not exist on datanode1 -LINE 1: SELECT * FROM temptest1; - ^ + col +----- + 1 +(1 row) + SELECT * FROM temptest2; -ERROR: relation "temptest2" does not exist on datanode1 -LINE 1: SELECT * FROM temptest2; - ^ + col +----- +(0 rows) + START TRANSACTION; CREATE TEMP TABLE temptest3(col int PRIMARY KEY) ON COMMIT DELETE ROWS; NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "temptest3_pkey" for table "temptest3" CREATE TEMP TABLE temptest4(col int REFERENCES temptest3); -ERROR: REFERENCES constraint is not yet supported. COMMIT; +ERROR: unsupported ON COMMIT and foreign key combination +DETAIL: Table "temptest4" references "temptest3", but they do not have the same ON COMMIT setting. -- Test manipulation of temp schema's placement in search path create table public.whereami (f1 text); insert into public.whereami values ('public'); diff --git a/src/test/regress/expected/xc_constraints.out b/src/test/regress/expected/xc_constraints.out index 60513b7ac..00e34165f 100644 --- a/src/test/regress/expected/xc_constraints.out +++ b/src/test/regress/expected/xc_constraints.out @@ -53,35 +53,35 @@ NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "xc_parent_rr_pke -- Test creation of child tables referencing to parents -- To replicated parent CREATE TABLE xc_child_rep_to_rep (b int, FOREIGN KEY (b) REFERENCES xc_parent_rep(a)); -- OK -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. CREATE TABLE xc_child_rr_to_rep (b int, FOREIGN KEY (b) REFERENCES xc_parent_rep(a)); -- OK -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. CREATE TABLE xc_child_modulo_to_rep (b int, FOREIGN KEY (b) REFERENCES xc_parent_rep(a)); -- OK -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. CREATE TABLE xc_child_hash_to_rep (b int, FOREIGN KEY (b) REFERENCES xc_parent_rep(a)); -- OK -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. -- To hash parent CREATE TABLE xc_child_rep_to_hash (b int, FOREIGN KEY (b) REFERENCES xc_parent_hash(a)); -- error -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. CREATE TABLE xc_child_rr_to_hash (b int, FOREIGN KEY (b) REFERENCES xc_parent_hash(a)); -- error -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. CREATE TABLE xc_child_modulo_to_hash (b int, FOREIGN KEY (b) REFERENCES xc_parent_hash(a)); -- error -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. CREATE TABLE xc_child_hash_to_hash (b int, FOREIGN KEY (b) REFERENCES xc_parent_hash(a)); -- OK -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. -- To modulo parent CREATE TABLE xc_child_rep_to_modulo (b int, FOREIGN KEY (b) REFERENCES xc_parent_modulo(a)); -- error -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. CREATE TABLE xc_child_rr_to_modulo (b int, FOREIGN KEY (b) REFERENCES xc_parent_modulo(a)); -- error -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. CREATE TABLE xc_child_modulo_to_modulo (b int, FOREIGN KEY (b) REFERENCES xc_parent_modulo(a)); -- OK -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. CREATE TABLE xc_child_hash_to_modulo (b int, FOREIGN KEY (b) REFERENCES xc_parent_modulo(a)); -- error -ERROR: FOREIGN KEY ... REFERENCES constraint is not yet supported. -- Clean up DROP SCHEMA xc_constraints_tests CASCADE; -NOTICE: drop cascades to 4 other objects +NOTICE: drop cascades to 16 other objects DETAIL: drop cascades to table xc_parent_rep drop cascades to table xc_parent_hash drop cascades to table xc_parent_modulo drop cascades to table xc_parent_rr +drop cascades to table xc_child_rep_to_rep +drop cascades to table xc_child_rr_to_rep +drop cascades to table xc_child_modulo_to_rep +drop cascades to table xc_child_hash_to_rep +drop cascades to table xc_child_rep_to_hash +drop cascades to table xc_child_rr_to_hash +drop cascades to table xc_child_modulo_to_hash +drop cascades to table xc_child_hash_to_hash +drop cascades to table xc_child_rep_to_modulo +drop cascades to table xc_child_rr_to_modulo +drop cascades to table xc_child_modulo_to_modulo +drop cascades to table xc_child_hash_to_modulo diff --git a/src/test/regress/parallel_schedule0 b/src/test/regress/parallel_schedule0 index 2e4cf7707..639f4f5c1 100644 --- a/src/test/regress/parallel_schedule0 +++ b/src/test/regress/parallel_schedule0 @@ -131,7 +131,8 @@ test: single_node_privileges2 # ---------- #test: single_node_select_views #test: single_node_portals_p2 -#test: single_node_foreign_key single_node_cluster single_node_dependency +test: single_node_foreign_key +#test: single_node_cluster single_node_dependency #test: single_node_guc test: single_node_guc2 test: single_node_bitmapops single_node_combocid