1
0
mirror of https://github.com/postgres/postgres.git synced 2026-01-26 09:41:40 +03:00

Improve "constraint must include all partitioning columns" message.

This formerly said "unique constraint must ...", which was accurate
enough when it only applied to UNIQUE and PRIMARY KEY constraints.
However, now we use it for exclusion constraints too, and in that
case it's a tad confusing.  Do what we already did in the errdetail
message: print the constraint_type, so that it looks like "UNIQUE
constraint ...", "EXCLUDE constraint ...", etc.

Author: jian he <jian.universality@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CACJufxH6VhAf65Vghg4T2q315gY=Rt4BUfMyunkfRj0n2S9n-g@mail.gmail.com
This commit is contained in:
Tom Lane
2026-01-09 12:59:35 -05:00
parent 7a485bd641
commit 7a1d422e39
2 changed files with 17 additions and 14 deletions

View File

@@ -1093,7 +1093,10 @@ DefineIndex(ParseState *pstate,
key->partattrs[i] - 1);
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("unique constraint on partitioned table must include all partitioning columns"),
/* translator: %s is UNIQUE, PRIMARY KEY, etc */
errmsg("%s constraint on partitioned table must include all partitioning columns",
constraint_type),
/* translator: first %s is UNIQUE, PRIMARY KEY, etc */
errdetail("%s constraint on table \"%s\" lacks column \"%s\" which is part of the partition key.",
constraint_type, RelationGetRelationName(rel),
NameStr(att->attname))));

View File

@@ -972,16 +972,16 @@ Indexes:
drop table idxpart;
-- Failing to use the full partition key is not allowed
create table idxpart (a int unique, b int) partition by range (a, b);
ERROR: unique constraint on partitioned table must include all partitioning columns
ERROR: UNIQUE constraint on partitioned table must include all partitioning columns
DETAIL: UNIQUE constraint on table "idxpart" lacks column "b" which is part of the partition key.
create table idxpart (a int, b int unique) partition by range (a, b);
ERROR: unique constraint on partitioned table must include all partitioning columns
ERROR: UNIQUE constraint on partitioned table must include all partitioning columns
DETAIL: UNIQUE constraint on table "idxpart" lacks column "a" which is part of the partition key.
create table idxpart (a int primary key, b int) partition by range (b, a);
ERROR: unique constraint on partitioned table must include all partitioning columns
ERROR: PRIMARY KEY constraint on partitioned table must include all partitioning columns
DETAIL: PRIMARY KEY constraint on table "idxpart" lacks column "b" which is part of the partition key.
create table idxpart (a int, b int primary key) partition by range (b, a);
ERROR: unique constraint on partitioned table must include all partitioning columns
ERROR: PRIMARY KEY constraint on partitioned table must include all partitioning columns
DETAIL: PRIMARY KEY constraint on table "idxpart" lacks column "a" which is part of the partition key.
-- OK if you use them in some other order
create table idxpart (a int, b int, c text, primary key (a, b, c)) partition by range (b, c, a);
@@ -997,7 +997,7 @@ create table idxpart (a int4range, b int4range, exclude USING GIST (a with =, b
drop table idxpart;
-- Not OK more than one equal column: partition keys are a proper superset of constraint
create table idxpart (a int4range, b int4range, exclude USING GIST (a with = )) partition by range (a, b);
ERROR: unique constraint on partitioned table must include all partitioning columns
ERROR: EXCLUDE constraint on partitioned table must include all partitioning columns
DETAIL: EXCLUDE constraint on table "idxpart" lacks column "b" which is part of the partition key.
-- Not OK with just -|-
create table idxpart (a int4range, exclude USING GIST (a with -|- )) partition by range (a);
@@ -1007,7 +1007,7 @@ create table idxpart (a int4range, b int4range, exclude USING GIST (a with =, b
drop table idxpart;
-- Not OK with equals and &&, and equals is not the partition key
create table idxpart (a int4range, b int4range, c int4range, exclude USING GIST (b with =, c with &&)) partition by range (a);
ERROR: unique constraint on partitioned table must include all partitioning columns
ERROR: EXCLUDE constraint on partitioned table must include all partitioning columns
DETAIL: EXCLUDE constraint on table "idxpart" lacks column "a" which is part of the partition key.
-- OK more than one equal column and a && column
create table idxpart (a int4range, b int4range, c int4range, exclude USING GIST (a with =, b with =, c with &&)) partition by range (a, b);
@@ -1022,7 +1022,7 @@ DETAIL: UNIQUE constraints cannot be used when partition keys include expressio
-- use ALTER TABLE to add a primary key
create table idxpart (a int, b int, c text) partition by range (a, b);
alter table idxpart add primary key (a); -- not an incomplete one though
ERROR: unique constraint on partitioned table must include all partitioning columns
ERROR: PRIMARY KEY constraint on partitioned table must include all partitioning columns
DETAIL: PRIMARY KEY constraint on table "idxpart" lacks column "b" which is part of the partition key.
alter table idxpart add primary key (a, b); -- this works
\d idxpart
@@ -1053,7 +1053,7 @@ drop table idxpart;
-- use ALTER TABLE to add a unique constraint
create table idxpart (a int, b int) partition by range (a, b);
alter table idxpart add unique (a); -- not an incomplete one though
ERROR: unique constraint on partitioned table must include all partitioning columns
ERROR: UNIQUE constraint on partitioned table must include all partitioning columns
DETAIL: UNIQUE constraint on table "idxpart" lacks column "b" which is part of the partition key.
alter table idxpart add unique (b, a); -- this works
\d idxpart
@@ -1083,7 +1083,7 @@ drop table idxpart;
-- Not OK more than one equal column: partition keys are a proper superset of constraint
create table idxpart (a int4range, b int4range) partition by range (a, b);
alter table idxpart add exclude USING GIST (a with =);
ERROR: unique constraint on partitioned table must include all partitioning columns
ERROR: EXCLUDE constraint on partitioned table must include all partitioning columns
DETAIL: EXCLUDE constraint on table "idxpart" lacks column "b" which is part of the partition key.
drop table idxpart;
-- Not OK with just -|-
@@ -1098,7 +1098,7 @@ drop table idxpart;
-- Not OK with equals and &&, and equals is not the partition key
create table idxpart (a int4range, b int4range, c int4range) partition by range (a);
alter table idxpart add exclude USING GIST (b with =, c with &&);
ERROR: unique constraint on partitioned table must include all partitioning columns
ERROR: EXCLUDE constraint on partitioned table must include all partitioning columns
DETAIL: EXCLUDE constraint on table "idxpart" lacks column "a" which is part of the partition key.
drop table idxpart;
-- OK more than one equal column and a && column
@@ -1145,7 +1145,7 @@ drop table idxpart;
create table idxpart (a int, b int, primary key (a)) partition by range (a);
create table idxpart2 partition of idxpart
for values from (0) to (1000) partition by range (b); -- fail
ERROR: unique constraint on partitioned table must include all partitioning columns
ERROR: PRIMARY KEY constraint on partitioned table must include all partitioning columns
DETAIL: PRIMARY KEY constraint on table "idxpart2" lacks column "b" which is part of the partition key.
drop table idxpart;
-- Ditto for the ATTACH PARTITION case
@@ -1153,7 +1153,7 @@ create table idxpart (a int unique, b int) partition by range (a);
create table idxpart1 (a int not null, b int, unique (a, b))
partition by range (a, b);
alter table idxpart attach partition idxpart1 for values from (1) to (1000);
ERROR: unique constraint on partitioned table must include all partitioning columns
ERROR: UNIQUE constraint on partitioned table must include all partitioning columns
DETAIL: UNIQUE constraint on table "idxpart1" lacks column "b" which is part of the partition key.
DROP TABLE idxpart, idxpart1;
-- Multi-layer partitioning works correctly in this case:
@@ -1448,7 +1448,7 @@ insert into covidxpart values (4, 1);
ERROR: duplicate key value violates unique constraint "covidxpart4_a_b_idx"
DETAIL: Key (a)=(4) already exists.
create unique index on covidxpart (b) include (a); -- should fail
ERROR: unique constraint on partitioned table must include all partitioning columns
ERROR: UNIQUE constraint on partitioned table must include all partitioning columns
DETAIL: UNIQUE constraint on table "covidxpart" lacks column "a" which is part of the partition key.
-- check that detaching a partition also detaches the primary key constraint
create table parted_pk_detach_test (a int primary key) partition by list (a);