Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1f8a332

Browse files
committed
Avoid having two PKs in a partition
If a table containing a primary key is attach as partition to apartitioned table which has a primary key with a different definition,we would happily create a second one in the new partition. Oops. Itturns out that this is because an error check in DefineIndex is executedonly if you tell it that it's being run by ALTER TABLE, and the originalcode here wasn't. Change it so that it does.Added a couple of test cases for this, also. A previously working teststarted to fail in a different way than before patch because the newcheck is called earlier; change the PK to plain UNIQUE so that the newbehavior isn't invoked, so that the test continues to verify what wewant it to verify.Reported by: Noriyoshi ShinodaDiscussion:https://postgr.es/m/DF4PR8401MB102060EC2615EC9227CC73F7EEDF0@DF4PR8401MB1020.NAMPRD84.PROD.OUTLOOK.COM
1 parent63cbee6 commit1f8a332

File tree

4 files changed

+42
-10
lines changed

4 files changed

+42
-10
lines changed

‎src/backend/commands/indexcmds.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,7 @@ DefineIndex(Oid relationId,
973973
InvalidOid,/* no predefined OID */
974974
indexRelationId,/* this is our child */
975975
createdConstraintId,
976-
false,check_rights,check_not_in_use,
976+
is_alter_table,check_rights,check_not_in_use,
977977
false,quiet);
978978
}
979979

‎src/backend/commands/tablecmds.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14256,7 +14256,7 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel)
1425614256
DefineIndex(RelationGetRelid(attachrel),stmt,InvalidOid,
1425714257
RelationGetRelid(idxRel),
1425814258
constraintOid,
14259-
false, false, false, false, false);
14259+
true, false, false, false, false);
1426014260
}
1426114261

1426214262
index_close(idxRel,AccessShareLock);

‎src/test/regress/expected/indexing.out

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -878,20 +878,20 @@ select conname, contype, conrelid::regclass, conindid::regclass, conkey
878878

879879
drop table idxpart;
880880
-- Verify that multi-layer partitioning honors the requirement that all
881-
-- columns in the partition key must appear in primary key
881+
-- columns in the partition key must appear in primary/unique key
882882
create table idxpart (a int, b int, primary key (a)) partition by range (a);
883883
create table idxpart2 partition of idxpart
884884
for values from (0) to (1000) partition by range (b); -- fail
885885
ERROR: insufficient columns in PRIMARY KEY constraint definition
886886
DETAIL: PRIMARY KEY constraint on table "idxpart2" lacks column "b" which is part of the partition key.
887887
drop table idxpart;
888888
-- Ditto for the ATTACH PARTITION case
889-
create table idxpart (a intprimary key, b int) partition by range (a);
890-
create table idxpart1 (a int not null, b int,primary key (a, b))
889+
create table idxpart (a intunique, b int) partition by range (a);
890+
create table idxpart1 (a int not null, b int,unique (a, b))
891891
partition by range (a, b);
892892
alter table idxpart attach partition idxpart1 for values from (1) to (1000);
893-
ERROR: insufficient columns inPRIMARY KEY constraint definition
894-
DETAIL:PRIMARY KEY constraint on table "idxpart1" lacks column "b" which is part of the partition key.
893+
ERROR: insufficient columns inUNIQUE constraint definition
894+
DETAIL:UNIQUE constraint on table "idxpart1" lacks column "b" which is part of the partition key.
895895
DROP TABLE idxpart, idxpart1;
896896
-- Multi-layer partitioning works correctly in this case:
897897
create table idxpart (a int, b int, primary key (a, b)) partition by range (a);
@@ -952,6 +952,22 @@ select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid
952952
(0 rows)
953953

954954
drop table idxpart;
955+
-- If the partition to be attached already has a primary key, fail if
956+
-- it doesn't match the parent's PK.
957+
CREATE TABLE idxpart (c1 INT PRIMARY KEY, c2 INT, c3 VARCHAR(10)) PARTITION BY RANGE(c1);
958+
CREATE TABLE idxpart1 (LIKE idxpart);
959+
ALTER TABLE idxpart1 ADD PRIMARY KEY (c1, c2);
960+
ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (100) TO (200);
961+
ERROR: multiple primary keys for table "idxpart1" are not allowed
962+
DROP TABLE idxpart, idxpart1;
963+
-- Ditto if there is some distance between the PKs (subpartitioning)
964+
create table idxpart (a int, b int, primary key (a)) partition by range (a);
965+
create table idxpart1 (a int not null, b int) partition by range (a);
966+
create table idxpart11 (a int not null, b int primary key);
967+
alter table idxpart1 attach partition idxpart11 for values from (0) to (1000);
968+
alter table idxpart attach partition idxpart1 for values from (0) to (10000);
969+
ERROR: multiple primary keys for table "idxpart11" are not allowed
970+
drop table idxpart, idxpart1, idxpart11;
955971
-- If a partitioned table has a constraint whose index is not valid,
956972
-- attaching a missing partition makes it valid.
957973
create table idxpart (a int) partition by range (a);

‎src/test/regress/sql/indexing.sql

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -444,15 +444,15 @@ select conname, contype, conrelid::regclass, conindid::regclass, conkey
444444
droptable idxpart;
445445

446446
-- Verify that multi-layer partitioning honors the requirement that all
447-
-- columns in the partition key must appear in primary key
447+
-- columns in the partition key must appear in primary/unique key
448448
createtableidxpart (aint, bint,primary key (a)) partition by range (a);
449449
createtableidxpart2 partition of idxpart
450450
forvaluesfrom (0) to (1000) partition by range (b);-- fail
451451
droptable idxpart;
452452

453453
-- Ditto for the ATTACH PARTITION case
454-
createtableidxpart (aintprimary key, bint) partition by range (a);
455-
createtableidxpart1 (aintnot null, bint,primary key (a, b))
454+
createtableidxpart (aintunique, bint) partition by range (a);
455+
createtableidxpart1 (aintnot null, bint,unique (a, b))
456456
partition by range (a, b);
457457
altertable idxpart attach partition idxpart1 forvaluesfrom (1) to (1000);
458458
DROPTABLE idxpart, idxpart1;
@@ -494,6 +494,22 @@ select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid
494494
order by indexrelid::regclass::text collate"C";
495495
droptable idxpart;
496496

497+
-- If the partition to be attached already has a primary key, fail if
498+
-- it doesn't match the parent's PK.
499+
CREATETABLEidxpart (c1INTPRIMARY KEY, c2INT, c3VARCHAR(10)) PARTITION BY RANGE(c1);
500+
CREATETABLEidxpart1 (LIKE idxpart);
501+
ALTERTABLE idxpart1 ADDPRIMARY KEY (c1, c2);
502+
ALTERTABLE idxpart ATTACH PARTITION idxpart1 FORVALUESFROM (100) TO (200);
503+
DROPTABLE idxpart, idxpart1;
504+
505+
-- Ditto if there is some distance between the PKs (subpartitioning)
506+
createtableidxpart (aint, bint,primary key (a)) partition by range (a);
507+
createtableidxpart1 (aintnot null, bint) partition by range (a);
508+
createtableidxpart11 (aintnot null, bintprimary key);
509+
altertable idxpart1 attach partition idxpart11 forvaluesfrom (0) to (1000);
510+
altertable idxpart attach partition idxpart1 forvaluesfrom (0) to (10000);
511+
droptable idxpart, idxpart1, idxpart11;
512+
497513
-- If a partitioned table has a constraint whose index is not valid,
498514
-- attaching a missing partition makes it valid.
499515
createtableidxpart (aint) partition by range (a);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp