Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5c6110c

Browse files
committed
Fix interference between cavering indexes and partitioned tables
The bug is caused due to the original IndexStmt that DefineIndex receives being overwritten when processing the INCLUDE columns. Use separate list of index params to propagate to child tables. Add tests covering this case. Amit Langote and Alexander Korotkov.
1 parent f1f537c commit 5c6110c

File tree

3 files changed

+57
-13
lines changed

3 files changed

+57
-13
lines changed

src/backend/commands/indexcmds.c

+14-13
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ DefineIndex(Oid relationId,
342342
Oid tablespaceId;
343343
Oid createdConstraintId = InvalidOid;
344344
List *indexColNames;
345+
List *allIndexParams;
345346
Relation rel;
346347
Relation indexRelation;
347348
HeapTuple tuple;
@@ -378,16 +379,16 @@ DefineIndex(Oid relationId,
378379
numberOfKeyAttributes = list_length(stmt->indexParams);
379380

380381
/*
381-
* We append any INCLUDE columns onto the indexParams list so that we have
382-
* one list with all columns. Later we can determine which of these are
383-
* key columns, and which are just part of the INCLUDE list by checking
384-
* the list position. A list item in a position less than
385-
* ii_NumIndexKeyAttrs is part of the key columns, and anything equal to
386-
* and over is part of the INCLUDE columns.
382+
* Calculate the new list of index columns including both key columns and
383+
* INCLUDE columns. Later we can determine which of these are key columns,
384+
* and which are just part of the INCLUDE list by checking the list
385+
* position. A list item in a position less than ii_NumIndexKeyAttrs is
386+
* part of the key columns, and anything equal to and over is part of the
387+
* INCLUDE columns.
387388
*/
388-
stmt->indexParams = list_concat(stmt->indexParams,
389-
stmt->indexIncludingParams);
390-
numberOfAttributes = list_length(stmt->indexParams);
389+
allIndexParams = list_concat(list_copy(stmt->indexParams),
390+
list_copy(stmt->indexIncludingParams));
391+
numberOfAttributes = list_length(allIndexParams);
391392

392393
if (numberOfAttributes <= 0)
393394
ereport(ERROR,
@@ -544,7 +545,7 @@ DefineIndex(Oid relationId,
544545
/*
545546
* Choose the index column names.
546547
*/
547-
indexColNames = ChooseIndexColumnNames(stmt->indexParams);
548+
indexColNames = ChooseIndexColumnNames(allIndexParams);
548549

549550
/*
550551
* Select name for index if caller didn't specify
@@ -658,7 +659,7 @@ DefineIndex(Oid relationId,
658659
coloptions = (int16 *) palloc(numberOfAttributes * sizeof(int16));
659660
ComputeIndexAttrs(indexInfo,
660661
typeObjectId, collationObjectId, classObjectId,
661-
coloptions, stmt->indexParams,
662+
coloptions, allIndexParams,
662663
stmt->excludeOpNames, relationId,
663664
accessMethodName, accessMethodId,
664665
amcanorder, stmt->isconstraint);
@@ -886,8 +887,8 @@ DefineIndex(Oid relationId,
886887
memcpy(part_oids, partdesc->oids, sizeof(Oid) * nparts);
887888

888889
parentDesc = CreateTupleDescCopy(RelationGetDescr(rel));
889-
opfamOids = palloc(sizeof(Oid) * numberOfAttributes);
890-
for (i = 0; i < numberOfAttributes; i++)
890+
opfamOids = palloc(sizeof(Oid) * numberOfKeyAttributes);
891+
for (i = 0; i < numberOfKeyAttributes; i++)
891892
opfamOids[i] = get_opclass_family(classObjectId[i]);
892893

893894
heap_close(rel, NoLock);

src/test/regress/expected/indexing.out

+24
Original file line numberDiff line numberDiff line change
@@ -1313,3 +1313,27 @@ alter index idxpart2_a_idx attach partition idxpart22_a_idx;
13131313
create index on idxpart (a);
13141314
create table idxpart_another (a int, b int, primary key (a, b)) partition by range (a);
13151315
create table idxpart_another_1 partition of idxpart_another for values from (0) to (100);
1316+
-- Test that covering partitioned indexes work in various cases
1317+
create table covidxpart (a int, b int) partition by list (a);
1318+
create unique index on covidxpart (a) include (b);
1319+
create table covidxpart1 partition of covidxpart for values in (1);
1320+
create table covidxpart2 partition of covidxpart for values in (2);
1321+
insert into covidxpart values (1, 1);
1322+
insert into covidxpart values (1, 1);
1323+
ERROR: duplicate key value violates unique constraint "covidxpart1_a_b_idx"
1324+
DETAIL: Key (a)=(1) already exists.
1325+
create table covidxpart3 (b int, c int, a int);
1326+
alter table covidxpart3 drop c;
1327+
alter table covidxpart attach partition covidxpart3 for values in (3);
1328+
insert into covidxpart values (3, 1);
1329+
insert into covidxpart values (3, 1);
1330+
ERROR: duplicate key value violates unique constraint "covidxpart3_a_b_idx"
1331+
DETAIL: Key (a)=(3) already exists.
1332+
create table covidxpart4 (b int, a int);
1333+
create unique index on covidxpart4 (a) include (b);
1334+
create unique index on covidxpart4 (a);
1335+
alter table covidxpart attach partition covidxpart4 for values in (4);
1336+
insert into covidxpart values (4, 1);
1337+
insert into covidxpart values (4, 1);
1338+
ERROR: duplicate key value violates unique constraint "covidxpart4_a_b_idx"
1339+
DETAIL: Key (a)=(4) already exists.

src/test/regress/sql/indexing.sql

+19
Original file line numberDiff line numberDiff line change
@@ -701,3 +701,22 @@ alter index idxpart2_a_idx attach partition idxpart22_a_idx;
701701
create index on idxpart (a);
702702
create table idxpart_another (a int, b int, primary key (a, b)) partition by range (a);
703703
create table idxpart_another_1 partition of idxpart_another for values from (0) to (100);
704+
705+
-- Test that covering partitioned indexes work in various cases
706+
create table covidxpart (a int, b int) partition by list (a);
707+
create unique index on covidxpart (a) include (b);
708+
create table covidxpart1 partition of covidxpart for values in (1);
709+
create table covidxpart2 partition of covidxpart for values in (2);
710+
insert into covidxpart values (1, 1);
711+
insert into covidxpart values (1, 1);
712+
create table covidxpart3 (b int, c int, a int);
713+
alter table covidxpart3 drop c;
714+
alter table covidxpart attach partition covidxpart3 for values in (3);
715+
insert into covidxpart values (3, 1);
716+
insert into covidxpart values (3, 1);
717+
create table covidxpart4 (b int, a int);
718+
create unique index on covidxpart4 (a) include (b);
719+
create unique index on covidxpart4 (a);
720+
alter table covidxpart attach partition covidxpart4 for values in (4);
721+
insert into covidxpart values (4, 1);
722+
insert into covidxpart values (4, 1);

0 commit comments

Comments
 (0)