diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/commands/tablecmds.c | 20 | ||||
-rw-r--r-- | src/test/regress/expected/foreign_key.out | 10 | ||||
-rw-r--r-- | src/test/regress/sql/foreign_key.sql | 11 |
3 files changed, 31 insertions, 10 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 57662fd7662..96a48ba82c1 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -11564,22 +11564,22 @@ tryAttachPartitionForeignKey(List **wqueue, table_close(pg_constraint, RowShareLock); } + /* + * We updated this pg_constraint row above to set its parent; validating + * it will cause its convalidated flag to change, so we need CCI here. In + * addition, we need it unconditionally for the rare case where the parent + * table has *two* identical constraints; when reaching this function for + * the second one, we must have made our changes visible, otherwise we + * would try to attach both to this one. + */ + CommandCounterIncrement(); + /* If validation is needed, put it in the queue now. */ if (queueValidation) { Relation conrel; - /* - * We updated this pg_constraint row above to set its parent; - * validating it will cause its convalidated flag to change, so we - * need CCI here. XXX it might work better to effect the convalidated - * changes for all constraints together during phase 3, but that - * requires more invasive code surgery. - */ - CommandCounterIncrement(); - conrel = table_open(ConstraintRelationId, RowExclusiveLock); - partcontup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(fk->conoid)); if (!HeapTupleIsValid(partcontup)) elog(ERROR, "cache lookup failed for constraint %u", fk->conoid); diff --git a/src/test/regress/expected/foreign_key.out b/src/test/regress/expected/foreign_key.out index e5842a208c0..374dcb266e7 100644 --- a/src/test/regress/expected/foreign_key.out +++ b/src/test/regress/expected/foreign_key.out @@ -2062,6 +2062,16 @@ CREATE TABLE fk_partitioned_fk_6 (a int REFERENCES fk_partitioned_pk_6) PARTITIO ALTER TABLE fk_partitioned_fk_6 ATTACH PARTITION fk_partitioned_pk_6 FOR VALUES IN (1); ERROR: cannot attach table "fk_partitioned_pk_6" as a partition because it is referenced by foreign key "fk_partitioned_fk_6_a_fkey" DROP TABLE fk_partitioned_pk_6, fk_partitioned_fk_6; +-- Verify that attaching to a parent with two identical constraints work +CREATE TABLE fk_partitioned_pk_6 (a int PRIMARY KEY); +CREATE TABLE fk_partitioned_fk_6 (a int, + FOREIGN KEY (a) REFERENCES fk_partitioned_pk_6, + FOREIGN KEY (a) REFERENCES fk_partitioned_pk_6 +) PARTITION BY LIST (a); +CREATE TABLE fk_partitioned_fk_6_1 PARTITION OF fk_partitioned_fk_6 FOR VALUES IN (1); +ALTER TABLE fk_partitioned_fk_6 DETACH PARTITION fk_partitioned_fk_6_1; +ALTER TABLE fk_partitioned_fk_6 ATTACH PARTITION fk_partitioned_fk_6_1 FOR VALUES IN (1); +DROP TABLE fk_partitioned_pk_6, fk_partitioned_fk_6; -- This case is similar to above, but the referenced relation is one level -- lower in the hierarchy. This one fails in a different way as the above, -- because we don't bother to protect against this case explicitly. If the diff --git a/src/test/regress/sql/foreign_key.sql b/src/test/regress/sql/foreign_key.sql index 45ad41fe59f..bc0adb8cfe9 100644 --- a/src/test/regress/sql/foreign_key.sql +++ b/src/test/regress/sql/foreign_key.sql @@ -1491,6 +1491,17 @@ CREATE TABLE fk_partitioned_fk_6 (a int REFERENCES fk_partitioned_pk_6) PARTITIO ALTER TABLE fk_partitioned_fk_6 ATTACH PARTITION fk_partitioned_pk_6 FOR VALUES IN (1); DROP TABLE fk_partitioned_pk_6, fk_partitioned_fk_6; +-- Verify that attaching to a parent with two identical constraints work +CREATE TABLE fk_partitioned_pk_6 (a int PRIMARY KEY); +CREATE TABLE fk_partitioned_fk_6 (a int, + FOREIGN KEY (a) REFERENCES fk_partitioned_pk_6, + FOREIGN KEY (a) REFERENCES fk_partitioned_pk_6 +) PARTITION BY LIST (a); +CREATE TABLE fk_partitioned_fk_6_1 PARTITION OF fk_partitioned_fk_6 FOR VALUES IN (1); +ALTER TABLE fk_partitioned_fk_6 DETACH PARTITION fk_partitioned_fk_6_1; +ALTER TABLE fk_partitioned_fk_6 ATTACH PARTITION fk_partitioned_fk_6_1 FOR VALUES IN (1); +DROP TABLE fk_partitioned_pk_6, fk_partitioned_fk_6; + -- This case is similar to above, but the referenced relation is one level -- lower in the hierarchy. This one fails in a different way as the above, -- because we don't bother to protect against this case explicitly. If the |