diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 05409ff6f9..385616bdb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -16390,17 +16390,24 @@ validatePartitionedIndex(Relation partedIdx, Relation partedTbl) if (tuples == RelationGetPartitionDesc(partedTbl)->nparts) { Relation idxRel; - HeapTuple newtup; + HeapTuple indTup; + Form_pg_index indexForm; idxRel = heap_open(IndexRelationId, RowExclusiveLock); + indTup = SearchSysCacheCopy1(INDEXRELID, + ObjectIdGetDatum(RelationGetRelid(partedIdx))); + if (!HeapTupleIsValid(indTup)) + elog(ERROR, "cache lookup failed for index %u", + RelationGetRelid(partedIdx)); + indexForm = (Form_pg_index) GETSTRUCT(indTup); - newtup = heap_copytuple(partedIdx->rd_indextuple); - ((Form_pg_index) GETSTRUCT(newtup))->indisvalid = true; + indexForm->indisvalid = true; updated = true; - CatalogTupleUpdate(idxRel, &partedIdx->rd_indextuple->t_self, newtup); + CatalogTupleUpdate(idxRel, &indTup->t_self, indTup); heap_close(idxRel, RowExclusiveLock); + heap_freetuple(indTup); } /* diff --git a/src/test/regress/expected/indexing.out b/src/test/regress/expected/indexing.out index 3eec572e91..24d3ecad5a 100644 --- a/src/test/regress/expected/indexing.out +++ b/src/test/regress/expected/indexing.out @@ -1572,3 +1572,66 @@ select indexrelid::regclass, indisvalid, (5 rows) drop table parted_isvalid_tab; +-- Check state of replica indexes when attaching a partition. +begin; +create table parted_replica_tab (id int not null) partition by range (id); +create table parted_replica_tab_1 partition of parted_replica_tab + for values from (1) to (10) partition by range (id); +create table parted_replica_tab_11 partition of parted_replica_tab_1 + for values from (1) to (5); +create unique index parted_replica_idx + on only parted_replica_tab using btree (id); +create unique index parted_replica_idx_1 + on only parted_replica_tab_1 using btree (id); +-- This triggers an update of pg_index.indisreplident for parted_replica_idx. +alter table only parted_replica_tab_1 replica identity + using index parted_replica_idx_1; +create unique index parted_replica_idx_11 on parted_replica_tab_11 USING btree (id); +select indexrelid::regclass, indisvalid, indisreplident, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_replica%' + order by indexrelid::regclass::text collate "C"; + indexrelid | indisvalid | indisreplident | indrelid | inhparent +-----------------------+------------+----------------+-----------------------+----------- + parted_replica_idx | f | f | parted_replica_tab | + parted_replica_idx_1 | f | t | parted_replica_tab_1 | + parted_replica_idx_11 | t | f | parted_replica_tab_11 | +(3 rows) + +-- parted_replica_idx is not valid yet here, because parted_replica_idx_1 +-- is not valid. +alter index parted_replica_idx ATTACH PARTITION parted_replica_idx_1; +select indexrelid::regclass, indisvalid, indisreplident, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_replica%' + order by indexrelid::regclass::text collate "C"; + indexrelid | indisvalid | indisreplident | indrelid | inhparent +-----------------------+------------+----------------+-----------------------+-------------------- + parted_replica_idx | f | f | parted_replica_tab | + parted_replica_idx_1 | f | t | parted_replica_tab_1 | parted_replica_idx + parted_replica_idx_11 | t | f | parted_replica_tab_11 | +(3 rows) + +-- parted_replica_idx becomes valid here. +alter index parted_replica_idx_1 ATTACH PARTITION parted_replica_idx_11; +alter table only parted_replica_tab_1 replica identity + using index parted_replica_idx_1; +commit; +select indexrelid::regclass, indisvalid, indisreplident, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_replica%' + order by indexrelid::regclass::text collate "C"; + indexrelid | indisvalid | indisreplident | indrelid | inhparent +-----------------------+------------+----------------+-----------------------+---------------------- + parted_replica_idx | t | f | parted_replica_tab | + parted_replica_idx_1 | t | t | parted_replica_tab_1 | parted_replica_idx + parted_replica_idx_11 | t | f | parted_replica_tab_11 | parted_replica_idx_1 +(3 rows) + +drop table parted_replica_tab; diff --git a/src/test/regress/sql/indexing.sql b/src/test/regress/sql/indexing.sql index 5e89a0bcd9..7401c7cfb9 100644 --- a/src/test/regress/sql/indexing.sql +++ b/src/test/regress/sql/indexing.sql @@ -843,3 +843,46 @@ select indexrelid::regclass, indisvalid, where indexrelid::regclass::text like 'parted_isvalid%' order by indexrelid::regclass::text collate "C"; drop table parted_isvalid_tab; + +-- Check state of replica indexes when attaching a partition. +begin; +create table parted_replica_tab (id int not null) partition by range (id); +create table parted_replica_tab_1 partition of parted_replica_tab + for values from (1) to (10) partition by range (id); +create table parted_replica_tab_11 partition of parted_replica_tab_1 + for values from (1) to (5); +create unique index parted_replica_idx + on only parted_replica_tab using btree (id); +create unique index parted_replica_idx_1 + on only parted_replica_tab_1 using btree (id); +-- This triggers an update of pg_index.indisreplident for parted_replica_idx. +alter table only parted_replica_tab_1 replica identity + using index parted_replica_idx_1; +create unique index parted_replica_idx_11 on parted_replica_tab_11 USING btree (id); +select indexrelid::regclass, indisvalid, indisreplident, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_replica%' + order by indexrelid::regclass::text collate "C"; +-- parted_replica_idx is not valid yet here, because parted_replica_idx_1 +-- is not valid. +alter index parted_replica_idx ATTACH PARTITION parted_replica_idx_1; +select indexrelid::regclass, indisvalid, indisreplident, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_replica%' + order by indexrelid::regclass::text collate "C"; +-- parted_replica_idx becomes valid here. +alter index parted_replica_idx_1 ATTACH PARTITION parted_replica_idx_11; +alter table only parted_replica_tab_1 replica identity + using index parted_replica_idx_1; +commit; +select indexrelid::regclass, indisvalid, indisreplident, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_replica%' + order by indexrelid::regclass::text collate "C"; +drop table parted_replica_tab;