aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/commands/indexcmds.c23
-rw-r--r--src/test/regress/expected/indexing.out66
-rw-r--r--src/test/regress/sql/indexing.sql15
3 files changed, 96 insertions, 8 deletions
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 8853f00a788..69086c8fcb0 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -1190,18 +1190,27 @@ DefineIndex(Oid relationId,
int nparts = partdesc->nparts;
Oid *part_oids = palloc(sizeof(Oid) * nparts);
bool invalidate_parent = false;
+ Relation parentIndex;
TupleDesc parentDesc;
- Oid *opfamOids;
pgstat_progress_update_param(PROGRESS_CREATEIDX_PARTITIONS_TOTAL,
nparts);
+ /* Make a local copy of partdesc->oids[], just for safety */
memcpy(part_oids, partdesc->oids, sizeof(Oid) * nparts);
+ /*
+ * We'll need an IndexInfo describing the parent index. The one
+ * built above is almost good enough, but not quite, because (for
+ * example) its predicate expression if any hasn't been through
+ * expression preprocessing. The most reliable way to get an
+ * IndexInfo that will match those for child indexes is to build
+ * it the same way, using BuildIndexInfo().
+ */
+ parentIndex = index_open(indexRelationId, lockmode);
+ indexInfo = BuildIndexInfo(parentIndex);
+
parentDesc = RelationGetDescr(rel);
- opfamOids = palloc(sizeof(Oid) * numberOfKeyAttributes);
- for (i = 0; i < numberOfKeyAttributes; i++)
- opfamOids[i] = get_opclass_family(classObjectId[i]);
/*
* For each partition, scan all existing indexes; if one matches
@@ -1272,9 +1281,9 @@ DefineIndex(Oid relationId,
cldIdxInfo = BuildIndexInfo(cldidx);
if (CompareIndexInfo(cldIdxInfo, indexInfo,
cldidx->rd_indcollation,
- collationObjectId,
+ parentIndex->rd_indcollation,
cldidx->rd_opfamily,
- opfamOids,
+ parentIndex->rd_opfamily,
attmap))
{
Oid cldConstrOid = InvalidOid;
@@ -1401,6 +1410,8 @@ DefineIndex(Oid relationId,
free_attrmap(attmap);
}
+ index_close(parentIndex, lockmode);
+
/*
* The pg_index row we inserted for this index was marked
* indisvalid=true. But if we attached an existing index that is
diff --git a/src/test/regress/expected/indexing.out b/src/test/regress/expected/indexing.out
index c93f4470c92..e15a20ff588 100644
--- a/src/test/regress/expected/indexing.out
+++ b/src/test/regress/expected/indexing.out
@@ -377,7 +377,7 @@ drop table idxpart;
-- When a table is attached a partition and it already has an index, a
-- duplicate index should not get created, but rather the index becomes
-- attached to the parent's index.
-create table idxpart (a int, b int, c text) partition by range (a);
+create table idxpart (a int, b int, c text, d bool) partition by range (a);
create index idxparti on idxpart (a);
create index idxparti2 on idxpart (b, c);
create table idxpart1 (like idxpart including indexes);
@@ -388,6 +388,7 @@ create table idxpart1 (like idxpart including indexes);
a | integer | | |
b | integer | | |
c | text | | |
+ d | boolean | | |
Indexes:
"idxpart1_a_idx" btree (a)
"idxpart1_b_c_idx" btree (b, c)
@@ -414,6 +415,7 @@ alter table idxpart attach partition idxpart1 for values from (0) to (10);
a | integer | | |
b | integer | | |
c | text | | |
+ d | boolean | | |
Partition of: idxpart FOR VALUES FROM (0) TO (10)
Indexes:
"idxpart1_a_idx" btree (a)
@@ -433,6 +435,68 @@ select relname, relkind, inhparent::regclass
idxparti2 | I |
(6 rows)
+-- While here, also check matching when creating an index after the fact.
+create index on idxpart1 ((a+b)) where d = true;
+\d idxpart1
+ Table "public.idxpart1"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ a | integer | | |
+ b | integer | | |
+ c | text | | |
+ d | boolean | | |
+Partition of: idxpart FOR VALUES FROM (0) TO (10)
+Indexes:
+ "idxpart1_a_idx" btree (a)
+ "idxpart1_b_c_idx" btree (b, c)
+ "idxpart1_expr_idx" btree ((a + b)) WHERE d = true
+
+select relname, relkind, inhparent::regclass
+ from pg_class left join pg_index ix on (indexrelid = oid)
+ left join pg_inherits on (ix.indexrelid = inhrelid)
+ where relname like 'idxpart%' order by relname;
+ relname | relkind | inhparent
+-------------------+---------+-----------
+ idxpart | p |
+ idxpart1 | r |
+ idxpart1_a_idx | i | idxparti
+ idxpart1_b_c_idx | i | idxparti2
+ idxpart1_expr_idx | i |
+ idxparti | I |
+ idxparti2 | I |
+(7 rows)
+
+create index idxparti3 on idxpart ((a+b)) where d = true;
+\d idxpart1
+ Table "public.idxpart1"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ a | integer | | |
+ b | integer | | |
+ c | text | | |
+ d | boolean | | |
+Partition of: idxpart FOR VALUES FROM (0) TO (10)
+Indexes:
+ "idxpart1_a_idx" btree (a)
+ "idxpart1_b_c_idx" btree (b, c)
+ "idxpart1_expr_idx" btree ((a + b)) WHERE d = true
+
+select relname, relkind, inhparent::regclass
+ from pg_class left join pg_index ix on (indexrelid = oid)
+ left join pg_inherits on (ix.indexrelid = inhrelid)
+ where relname like 'idxpart%' order by relname;
+ relname | relkind | inhparent
+-------------------+---------+-----------
+ idxpart | p |
+ idxpart1 | r |
+ idxpart1_a_idx | i | idxparti
+ idxpart1_b_c_idx | i | idxparti2
+ idxpart1_expr_idx | i | idxparti3
+ idxparti | I |
+ idxparti2 | I |
+ idxparti3 | I |
+(8 rows)
+
drop table idxpart;
-- Verify that attaching an invalid index does not mark the parent index valid.
-- On the other hand, attaching a valid index marks not only its direct
diff --git a/src/test/regress/sql/indexing.sql b/src/test/regress/sql/indexing.sql
index 42f398b67c2..429120e7104 100644
--- a/src/test/regress/sql/indexing.sql
+++ b/src/test/regress/sql/indexing.sql
@@ -192,7 +192,7 @@ drop table idxpart;
-- When a table is attached a partition and it already has an index, a
-- duplicate index should not get created, but rather the index becomes
-- attached to the parent's index.
-create table idxpart (a int, b int, c text) partition by range (a);
+create table idxpart (a int, b int, c text, d bool) partition by range (a);
create index idxparti on idxpart (a);
create index idxparti2 on idxpart (b, c);
create table idxpart1 (like idxpart including indexes);
@@ -207,6 +207,19 @@ select relname, relkind, inhparent::regclass
from pg_class left join pg_index ix on (indexrelid = oid)
left join pg_inherits on (ix.indexrelid = inhrelid)
where relname like 'idxpart%' order by relname;
+-- While here, also check matching when creating an index after the fact.
+create index on idxpart1 ((a+b)) where d = true;
+\d idxpart1
+select relname, relkind, inhparent::regclass
+ from pg_class left join pg_index ix on (indexrelid = oid)
+ left join pg_inherits on (ix.indexrelid = inhrelid)
+ where relname like 'idxpart%' order by relname;
+create index idxparti3 on idxpart ((a+b)) where d = true;
+\d idxpart1
+select relname, relkind, inhparent::regclass
+ from pg_class left join pg_index ix on (indexrelid = oid)
+ left join pg_inherits on (ix.indexrelid = inhrelid)
+ where relname like 'idxpart%' order by relname;
drop table idxpart;
-- Verify that attaching an invalid index does not mark the parent index valid.