aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/tablecmds.c20
-rw-r--r--src/test/regress/expected/foreign_key.out10
-rw-r--r--src/test/regress/sql/foreign_key.sql11
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