Commit 126d6312 authored by Alvaro Herrera's avatar Alvaro Herrera

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
parent 53bcf5e3
...@@ -1850,7 +1850,6 @@ CompareIndexInfo(IndexInfo *info1, IndexInfo *info2, ...@@ -1850,7 +1850,6 @@ CompareIndexInfo(IndexInfo *info1, IndexInfo *info2,
if (info1->ii_NumIndexKeyAttrs != info2->ii_NumIndexKeyAttrs) if (info1->ii_NumIndexKeyAttrs != info2->ii_NumIndexKeyAttrs)
return false; return false;
/* /*
* and columns match through the attribute map (actual attribute numbers * and columns match through the attribute map (actual attribute numbers
* might differ!) Note that this implies that index columns that are * might differ!) Note that this implies that index columns that are
......
...@@ -925,7 +925,6 @@ DefineIndex(Oid relationId, ...@@ -925,7 +925,6 @@ DefineIndex(Oid relationId,
gettext_noop("could not convert row type")); gettext_noop("could not convert row type"));
maplen = parentDesc->natts; maplen = parentDesc->natts;
foreach(cell, childidxs) foreach(cell, childidxs)
{ {
Oid cldidxid = lfirst_oid(cell); Oid cldidxid = lfirst_oid(cell);
......
...@@ -15591,7 +15591,7 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name) ...@@ -15591,7 +15591,7 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name)
partIdx->rd_opfamily, partIdx->rd_opfamily,
parentIdx->rd_opfamily, parentIdx->rd_opfamily,
attmap, attmap,
RelationGetDescr(partTbl)->natts)) RelationGetDescr(parentTbl)->natts))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION), (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("cannot attach index \"%s\" as a partition of index \"%s\"", errmsg("cannot attach index \"%s\" as a partition of index \"%s\"",
......
...@@ -1411,6 +1411,11 @@ alter index idxpart2_a_idx attach partition idxpart22_a_idx; ...@@ -1411,6 +1411,11 @@ alter index idxpart2_a_idx attach partition idxpart22_a_idx;
create index on idxpart (a); 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 (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 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 -- More objects intentionally left behind, to verify some pg_dump/pg_upgrade
-- behavior; see https://postgr.es/m/20190321204928.GA17535@alvherre.pgsql -- behavior; see https://postgr.es/m/20190321204928.GA17535@alvherre.pgsql
create schema regress_indexing; create schema regress_indexing;
......
...@@ -747,6 +747,11 @@ alter index idxpart2_a_idx attach partition idxpart22_a_idx; ...@@ -747,6 +747,11 @@ alter index idxpart2_a_idx attach partition idxpart22_a_idx;
create index on idxpart (a); 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 (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 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 -- More objects intentionally left behind, to verify some pg_dump/pg_upgrade
-- behavior; see https://postgr.es/m/20190321204928.GA17535@alvherre.pgsql -- behavior; see https://postgr.es/m/20190321204928.GA17535@alvherre.pgsql
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment