From 126d631222328d3def7910934bfa9cbdc99d79cc Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Tue, 26 Mar 2019 20:19:28 -0300 Subject: [PATCH] Fix partitioned index creation bug with dropped columns ALTER INDEX .. ATTACH PARTITION fails if the partitioned table where the index is defined contains more dropped columns than its partition, with this message: ERROR: incorrect attribute map The cause was that one caller of CompareIndexInfo was passing the number of attributes of the partition rather than the parent, which confused the length check. Repair. This can cause pg_upgrade to fail when used on such a database. Leave some more objects around after regression tests, so that the case is detected by pg_upgrade test suite. Remove some spurious empty lines noticed while looking for other cases of the same problem. Discussion: https://postgr.es/m/20190326213924.GA2322@alvherre.pgsql --- src/backend/catalog/index.c | 1 - src/backend/commands/indexcmds.c | 1 - src/backend/commands/tablecmds.c | 2 +- src/test/regress/expected/indexing.out | 5 +++++ src/test/regress/sql/indexing.sql | 5 +++++ 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index d2e284f6de..af367c95c0 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -1850,7 +1850,6 @@ CompareIndexInfo(IndexInfo *info1, IndexInfo *info2, if (info1->ii_NumIndexKeyAttrs != info2->ii_NumIndexKeyAttrs) return false; - /* * and columns match through the attribute map (actual attribute numbers * might differ!) Note that this implies that index columns that are diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index c3a53d81aa..d6eb48cb4e 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -925,7 +925,6 @@ DefineIndex(Oid relationId, gettext_noop("could not convert row type")); maplen = parentDesc->natts; - foreach(cell, childidxs) { Oid cldidxid = lfirst_oid(cell); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 3183b2aaa1..048c119668 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -15591,7 +15591,7 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name) partIdx->rd_opfamily, parentIdx->rd_opfamily, attmap, - RelationGetDescr(partTbl)->natts)) + RelationGetDescr(parentTbl)->natts)) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("cannot attach index \"%s\" as a partition of index \"%s\"", diff --git a/src/test/regress/expected/indexing.out b/src/test/regress/expected/indexing.out index 8f25d71ba1..cfbc06da07 100644 --- a/src/test/regress/expected/indexing.out +++ b/src/test/regress/expected/indexing.out @@ -1411,6 +1411,11 @@ alter index idxpart2_a_idx attach partition idxpart22_a_idx; create index on idxpart (a); create table idxpart_another (a int, b int, primary key (a, b)) partition by range (a); create table idxpart_another_1 partition of idxpart_another for values from (0) to (100); +create table idxpart3 (c int, b int, a int) partition by range (a); +alter table idxpart3 drop column b, drop column c; +create table idxpart31 partition of idxpart3 for values from (1000) to (1200); +create table idxpart32 partition of idxpart3 for values from (1200) to (1400); +alter table idxpart attach partition idxpart3 for values from (1000) to (2000); -- More objects intentionally left behind, to verify some pg_dump/pg_upgrade -- behavior; see https://postgr.es/m/20190321204928.GA17535@alvherre.pgsql create schema regress_indexing; diff --git a/src/test/regress/sql/indexing.sql b/src/test/regress/sql/indexing.sql index 2ccea02cae..954632b14e 100644 --- a/src/test/regress/sql/indexing.sql +++ b/src/test/regress/sql/indexing.sql @@ -747,6 +747,11 @@ alter index idxpart2_a_idx attach partition idxpart22_a_idx; create index on idxpart (a); create table idxpart_another (a int, b int, primary key (a, b)) partition by range (a); create table idxpart_another_1 partition of idxpart_another for values from (0) to (100); +create table idxpart3 (c int, b int, a int) partition by range (a); +alter table idxpart3 drop column b, drop column c; +create table idxpart31 partition of idxpart3 for values from (1000) to (1200); +create table idxpart32 partition of idxpart3 for values from (1200) to (1400); +alter table idxpart attach partition idxpart3 for values from (1000) to (2000); -- More objects intentionally left behind, to verify some pg_dump/pg_upgrade -- behavior; see https://postgr.es/m/20190321204928.GA17535@alvherre.pgsql