Skip to content

Commit cee8db3

Browse files
committed
ATTACH PARTITION: Don't match a PK with a UNIQUE constraint
When matching constraints in AttachPartitionEnsureIndexes() we weren't testing the constraint type, which could make a UNIQUE key lacking a not-null constraint incorrectly satisfy a primary key requirement. Fix this by testing that the constraint types match. (Other possible mismatches are verified by comparing index properties.) Discussion: https://postgr.es/m/202402051447.wimb4xmtiiyb@alvherre.pgsql
1 parent 9dfcac8 commit cee8db3

File tree

5 files changed

+52
-0
lines changed

5 files changed

+52
-0
lines changed

src/backend/commands/tablecmds.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19550,6 +19550,11 @@ AttachPartitionEnsureIndexes(List **wqueue, Relation rel, Relation attachrel)
1955019550
/* no dice */
1955119551
if (!OidIsValid(cldConstrOid))
1955219552
continue;
19553+
19554+
/* Ensure they're both the same type of constraint */
19555+
if (get_constraint_type(constraintOid) !=
19556+
get_constraint_type(cldConstrOid))
19557+
continue;
1955319558
}
1955419559

1955519560
/* bingo. */

src/backend/utils/cache/lsyscache.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,6 +1133,28 @@ get_constraint_index(Oid conoid)
11331133
return InvalidOid;
11341134
}
11351135

1136+
/*
1137+
* get_constraint_type
1138+
* Return the pg_constraint.contype value for the given constraint.
1139+
*
1140+
* No frills.
1141+
*/
1142+
char
1143+
get_constraint_type(Oid conoid)
1144+
{
1145+
HeapTuple tp;
1146+
char contype;
1147+
1148+
tp = SearchSysCache1(CONSTROID, ObjectIdGetDatum(conoid));
1149+
if (!HeapTupleIsValid(tp))
1150+
elog(ERROR, "cache lookup failed for constraint %u", conoid);
1151+
1152+
contype = ((Form_pg_constraint) GETSTRUCT(tp))->contype;
1153+
ReleaseSysCache(tp);
1154+
1155+
return contype;
1156+
}
1157+
11361158
/* ---------- LANGUAGE CACHE ---------- */
11371159

11381160
char *

src/include/utils/lsyscache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ extern char *get_collation_name(Oid colloid);
100100
extern bool get_collation_isdeterministic(Oid colloid);
101101
extern char *get_constraint_name(Oid conoid);
102102
extern Oid get_constraint_index(Oid conoid);
103+
extern char get_constraint_type(Oid conoid);
104+
103105
extern char *get_language_name(Oid langoid, bool missing_ok);
104106
extern Oid get_opclass_family(Oid opclass);
105107
extern Oid get_opclass_input_type(Oid opclass);

src/test/regress/expected/constraints.out

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,22 @@ Inherits: cnn_grandchild,
10061006
ALTER TABLE cnn_parent DROP CONSTRAINT cnn_parent_pkey;
10071007
ERROR: constraint "cnn_parent_pkey" of relation "cnn_parent" does not exist
10081008
-- keeps these tables around, for pg_upgrade testing
1009+
-- A primary key shouldn't attach to a unique constraint
1010+
create table cnn2_parted (a int primary key) partition by list (a);
1011+
create table cnn2_part1 (a int unique);
1012+
alter table cnn2_parted attach partition cnn2_part1 for values in (1);
1013+
\d+ cnn2_part1
1014+
Table "public.cnn2_part1"
1015+
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
1016+
--------+---------+-----------+----------+---------+---------+--------------+-------------
1017+
a | integer | | not null | | plain | |
1018+
Partition of: cnn2_parted FOR VALUES IN (1)
1019+
Partition constraint: ((a IS NOT NULL) AND (a = 1))
1020+
Indexes:
1021+
"cnn2_part1_pkey" PRIMARY KEY, btree (a)
1022+
"cnn2_part1_a_key" UNIQUE CONSTRAINT, btree (a)
1023+
1024+
drop table cnn2_parted;
10091025
-- ensure columns in partitions are marked not-null
10101026
create table cnn2_parted(a int primary key) partition by list (a);
10111027
create table cnn2_part1(a int);

src/test/regress/sql/constraints.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,13 @@ ALTER TABLE cnn_parent ADD PRIMARY KEY USING INDEX b_uq;
657657
ALTER TABLE cnn_parent DROP CONSTRAINT cnn_parent_pkey;
658658
-- keeps these tables around, for pg_upgrade testing
659659

660+
-- A primary key shouldn't attach to a unique constraint
661+
create table cnn2_parted (a int primary key) partition by list (a);
662+
create table cnn2_part1 (a int unique);
663+
alter table cnn2_parted attach partition cnn2_part1 for values in (1);
664+
\d+ cnn2_part1
665+
drop table cnn2_parted;
666+
660667
-- ensure columns in partitions are marked not-null
661668
create table cnn2_parted(a int primary key) partition by list (a);
662669
create table cnn2_part1(a int);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy