diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 78b0829ffc..027d68e5d2 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -19550,6 +19550,11 @@ AttachPartitionEnsureIndexes(List **wqueue, Relation rel, Relation attachrel) /* no dice */ if (!OidIsValid(cldConstrOid)) continue; + + /* Ensure they're both the same type of constraint */ + if (get_constraint_type(constraintOid) != + get_constraint_type(cldConstrOid)) + continue; } /* bingo. */ diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index 26368ffcc9..48a280d089 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -1133,6 +1133,28 @@ get_constraint_index(Oid conoid) return InvalidOid; } +/* + * get_constraint_type + * Return the pg_constraint.contype value for the given constraint. + * + * No frills. + */ +char +get_constraint_type(Oid conoid) +{ + HeapTuple tp; + char contype; + + tp = SearchSysCache1(CONSTROID, ObjectIdGetDatum(conoid)); + if (!HeapTupleIsValid(tp)) + elog(ERROR, "cache lookup failed for constraint %u", conoid); + + contype = ((Form_pg_constraint) GETSTRUCT(tp))->contype; + ReleaseSysCache(tp); + + return contype; +} + /* ---------- LANGUAGE CACHE ---------- */ char * diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h index 35a8dec2b9..20446f6f83 100644 --- a/src/include/utils/lsyscache.h +++ b/src/include/utils/lsyscache.h @@ -100,6 +100,8 @@ extern char *get_collation_name(Oid colloid); extern bool get_collation_isdeterministic(Oid colloid); extern char *get_constraint_name(Oid conoid); extern Oid get_constraint_index(Oid conoid); +extern char get_constraint_type(Oid conoid); + extern char *get_language_name(Oid langoid, bool missing_ok); extern Oid get_opclass_family(Oid opclass); extern Oid get_opclass_input_type(Oid opclass); diff --git a/src/test/regress/expected/constraints.out b/src/test/regress/expected/constraints.out index 483681ef2c..51157181c6 100644 --- a/src/test/regress/expected/constraints.out +++ b/src/test/regress/expected/constraints.out @@ -1006,6 +1006,22 @@ Inherits: cnn_grandchild, ALTER TABLE cnn_parent DROP CONSTRAINT cnn_parent_pkey; ERROR: constraint "cnn_parent_pkey" of relation "cnn_parent" does not exist -- keeps these tables around, for pg_upgrade testing +-- A primary key shouldn't attach to a unique constraint +create table cnn2_parted (a int primary key) partition by list (a); +create table cnn2_part1 (a int unique); +alter table cnn2_parted attach partition cnn2_part1 for values in (1); +\d+ cnn2_part1 + Table "public.cnn2_part1" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | integer | | not null | | plain | | +Partition of: cnn2_parted FOR VALUES IN (1) +Partition constraint: ((a IS NOT NULL) AND (a = 1)) +Indexes: + "cnn2_part1_pkey" PRIMARY KEY, btree (a) + "cnn2_part1_a_key" UNIQUE CONSTRAINT, btree (a) + +drop table cnn2_parted; -- ensure columns in partitions are marked not-null create table cnn2_parted(a int primary key) partition by list (a); create table cnn2_part1(a int); diff --git a/src/test/regress/sql/constraints.sql b/src/test/regress/sql/constraints.sql index 7c95f6c2aa..2efb63e9d8 100644 --- a/src/test/regress/sql/constraints.sql +++ b/src/test/regress/sql/constraints.sql @@ -657,6 +657,13 @@ ALTER TABLE cnn_parent ADD PRIMARY KEY USING INDEX b_uq; ALTER TABLE cnn_parent DROP CONSTRAINT cnn_parent_pkey; -- keeps these tables around, for pg_upgrade testing +-- A primary key shouldn't attach to a unique constraint +create table cnn2_parted (a int primary key) partition by list (a); +create table cnn2_part1 (a int unique); +alter table cnn2_parted attach partition cnn2_part1 for values in (1); +\d+ cnn2_part1 +drop table cnn2_parted; + -- ensure columns in partitions are marked not-null create table cnn2_parted(a int primary key) partition by list (a); create table cnn2_part1(a int);