pg-13_15.patch
text/x-patch
Filename: pg-13_15.patch
Type: text/x-patch
Part: 0
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index f5f88644455..be4d9e83d2c 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -64,6 +64,7 @@
#include "nodes/nodeFuncs.h"
#include "optimizer/optimizer.h"
#include "parser/parser.h"
+#include "partitioning/partdesc.h"
#include "pgstat.h"
#include "rewrite/rewriteManip.h"
#include "storage/bufmgr.h"
@@ -1813,6 +1814,26 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName)
table_close(pg_attribute, RowExclusiveLock);
}
+ /*
+ * Check whether this reindex made parent partitioned index whole
+ */
+ CommandCounterIncrement();
+ if (newClassRel->rd_rel->relispartition)
+ {
+ Oid parentIdxId;
+ Relation parentIdx;
+
+ parentIdxId = get_partition_parent(RelationGetRelid(newClassRel));
+ parentIdx = relation_open(parentIdxId, AccessExclusiveLock);
+ if(!parentIdx->rd_index->indisvalid) {
+ Relation parentTbl;
+ parentTbl = relation_open(parentIdx->rd_index->indrelid, AccessExclusiveLock);
+ validatePartitionedIndex(parentIdx, parentTbl);
+ relation_close(parentTbl, AccessExclusiveLock);
+ }
+ relation_close(parentIdx, AccessExclusiveLock);
+ }
+
/* Close relations */
table_close(pg_class, RowExclusiveLock);
table_close(pg_index, RowExclusiveLock);
@@ -4104,3 +4125,106 @@ RestoreReindexState(void *reindexstate)
/* Note the worker has its own transaction nesting level */
reindexingNestLevel = GetCurrentTransactionNestLevel();
}
+
+/*
+ * Verify whether the set of attached partition indexes to a parent index on
+ * a partitioned table is complete. If it is, mark the parent index valid.
+ *
+ * This should be called each time a partition index is attached.
+ */
+void
+validatePartitionedIndex(Relation partedIdx, Relation partedTbl)
+{
+ Relation inheritsRel;
+ SysScanDesc scan;
+ ScanKeyData key;
+ int tuples = 0;
+ HeapTuple inhTup;
+ bool updated = false;
+
+ Assert(partedIdx->rd_rel->relkind == RELKIND_PARTITIONED_INDEX);
+
+ /*
+ * Scan pg_inherits for this parent index. Count each valid index we find
+ * (verifying the pg_index entry for each), and if we reach the total
+ * amount we expect, we can mark this parent index as valid.
+ */
+ inheritsRel = table_open(InheritsRelationId, AccessShareLock);
+ ScanKeyInit(&key, Anum_pg_inherits_inhparent,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(RelationGetRelid(partedIdx)));
+ scan = systable_beginscan(inheritsRel, InheritsParentIndexId, true,
+ NULL, 1, &key);
+ while ((inhTup = systable_getnext(scan)) != NULL)
+ {
+ Form_pg_inherits inhForm = (Form_pg_inherits) GETSTRUCT(inhTup);
+ HeapTuple indTup;
+ Form_pg_index indexForm;
+
+ indTup = SearchSysCache1(INDEXRELID,
+ ObjectIdGetDatum(inhForm->inhrelid));
+ if (!HeapTupleIsValid(indTup))
+ elog(ERROR, "cache lookup failed for index %u", inhForm->inhrelid);
+ indexForm = (Form_pg_index) GETSTRUCT(indTup);
+ if (indexForm->indisvalid)
+ tuples += 1;
+ ReleaseSysCache(indTup);
+ }
+
+ /* Done with pg_inherits */
+ systable_endscan(scan);
+ table_close(inheritsRel, AccessShareLock);
+
+ /*
+ * If we found as many inherited indexes as the partitioned table has
+ * partitions, we're good; update pg_index to set indisvalid.
+ */
+ if (tuples == RelationGetPartitionDesc(partedTbl)->nparts)
+ {
+ Relation idxRel;
+ HeapTuple indTup;
+ Form_pg_index indexForm;
+
+ idxRel = table_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);
+
+ indexForm->indisvalid = true;
+ updated = true;
+
+ CatalogTupleUpdate(idxRel, &indTup->t_self, indTup);
+
+ table_close(idxRel, RowExclusiveLock);
+ heap_freetuple(indTup);
+ }
+
+ /*
+ * If this index is in turn a partition of a larger index, validating it
+ * might cause the parent to become valid also. Try that.
+ */
+ if (updated && partedIdx->rd_rel->relispartition)
+ {
+ Oid parentIdxId,
+ parentTblId;
+ Relation parentIdx,
+ parentTbl;
+
+ /* make sure we see the validation we just did */
+ CommandCounterIncrement();
+
+ parentIdxId = get_partition_parent(RelationGetRelid(partedIdx));
+ parentTblId = get_partition_parent(RelationGetRelid(partedTbl));
+ parentIdx = relation_open(parentIdxId, AccessExclusiveLock);
+ parentTbl = relation_open(parentTblId, AccessExclusiveLock);
+ Assert(!parentIdx->rd_index->indisvalid);
+
+ validatePartitionedIndex(parentIdx, parentTbl);
+
+ relation_close(parentIdx, AccessExclusiveLock);
+ relation_close(parentTbl, AccessExclusiveLock);
+ }
+}
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 4a7cfb3ce42..4647934a51b 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -25,6 +25,7 @@
#include "catalog/catalog.h"
#include "catalog/index.h"
#include "catalog/indexing.h"
+#include "catalog/partition.h"
#include "catalog/pg_am.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_inherits.h"
@@ -2585,9 +2586,30 @@ ReindexIndex(RangeVar *indexRelation, int options, bool concurrent)
if (concurrent && persistence != RELPERSISTENCE_TEMP)
ReindexRelationConcurrently(indOid, options);
- else
+ else {
reindex_index(indOid, false, persistence,
options | REINDEXOPT_REPORT_PROGRESS);
+
+ /*
+ * Check whether this reindex made parent partitioned index whole
+ */
+ CommandCounterIncrement();
+ if (irel->rd_rel->relispartition)
+ {
+ Oid parentIdxId;
+ Relation parentIdx;
+
+ parentIdxId = get_partition_parent(RelationGetRelid(irel));
+ parentIdx = relation_open(parentIdxId, AccessExclusiveLock);
+ if(!parentIdx->rd_index->indisvalid) {
+ Relation parentTbl;
+ parentTbl = relation_open(parentIdx->rd_index->indrelid, AccessExclusiveLock);
+ validatePartitionedIndex(parentIdx, parentTbl);
+ relation_close(parentTbl, AccessExclusiveLock);
+ }
+ relation_close(parentIdx, AccessExclusiveLock);
+ }
+ }
}
/*
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 241cc8e68e2..8f186d34ab6 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -563,7 +563,6 @@ static void DropClonedTriggersFromPartition(Oid partitionId);
static ObjectAddress ATExecDetachPartition(Relation rel, RangeVar *name);
static ObjectAddress ATExecAttachPartitionIdx(List **wqueue, Relation rel,
RangeVar *name);
-static void validatePartitionedIndex(Relation partedIdx, Relation partedTbl);
static void refuseDupeIndexAttach(Relation parentIdx, Relation partIdx,
Relation partitionTbl);
static List *GetParentedForeignKeyRefs(Relation partition);
@@ -17850,108 +17849,6 @@ refuseDupeIndexAttach(Relation parentIdx, Relation partIdx, Relation partitionTb
RelationGetRelationName(partitionTbl))));
}
-/*
- * Verify whether the set of attached partition indexes to a parent index on
- * a partitioned table is complete. If it is, mark the parent index valid.
- *
- * This should be called each time a partition index is attached.
- */
-static void
-validatePartitionedIndex(Relation partedIdx, Relation partedTbl)
-{
- Relation inheritsRel;
- SysScanDesc scan;
- ScanKeyData key;
- int tuples = 0;
- HeapTuple inhTup;
- bool updated = false;
-
- Assert(partedIdx->rd_rel->relkind == RELKIND_PARTITIONED_INDEX);
-
- /*
- * Scan pg_inherits for this parent index. Count each valid index we find
- * (verifying the pg_index entry for each), and if we reach the total
- * amount we expect, we can mark this parent index as valid.
- */
- inheritsRel = table_open(InheritsRelationId, AccessShareLock);
- ScanKeyInit(&key, Anum_pg_inherits_inhparent,
- BTEqualStrategyNumber, F_OIDEQ,
- ObjectIdGetDatum(RelationGetRelid(partedIdx)));
- scan = systable_beginscan(inheritsRel, InheritsParentIndexId, true,
- NULL, 1, &key);
- while ((inhTup = systable_getnext(scan)) != NULL)
- {
- Form_pg_inherits inhForm = (Form_pg_inherits) GETSTRUCT(inhTup);
- HeapTuple indTup;
- Form_pg_index indexForm;
-
- indTup = SearchSysCache1(INDEXRELID,
- ObjectIdGetDatum(inhForm->inhrelid));
- if (!HeapTupleIsValid(indTup))
- elog(ERROR, "cache lookup failed for index %u", inhForm->inhrelid);
- indexForm = (Form_pg_index) GETSTRUCT(indTup);
- if (indexForm->indisvalid)
- tuples += 1;
- ReleaseSysCache(indTup);
- }
-
- /* Done with pg_inherits */
- systable_endscan(scan);
- table_close(inheritsRel, AccessShareLock);
-
- /*
- * If we found as many inherited indexes as the partitioned table has
- * partitions, we're good; update pg_index to set indisvalid.
- */
- if (tuples == RelationGetPartitionDesc(partedTbl)->nparts)
- {
- Relation idxRel;
- HeapTuple indTup;
- Form_pg_index indexForm;
-
- idxRel = table_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);
-
- indexForm->indisvalid = true;
- updated = true;
-
- CatalogTupleUpdate(idxRel, &indTup->t_self, indTup);
-
- table_close(idxRel, RowExclusiveLock);
- heap_freetuple(indTup);
- }
-
- /*
- * If this index is in turn a partition of a larger index, validating it
- * might cause the parent to become valid also. Try that.
- */
- if (updated && partedIdx->rd_rel->relispartition)
- {
- Oid parentIdxId,
- parentTblId;
- Relation parentIdx,
- parentTbl;
-
- /* make sure we see the validation we just did */
- CommandCounterIncrement();
-
- parentIdxId = get_partition_parent(RelationGetRelid(partedIdx));
- parentTblId = get_partition_parent(RelationGetRelid(partedTbl));
- parentIdx = relation_open(parentIdxId, AccessExclusiveLock);
- parentTbl = relation_open(parentTblId, AccessExclusiveLock);
- Assert(!parentIdx->rd_index->indisvalid);
-
- validatePartitionedIndex(parentIdx, parentTbl);
-
- relation_close(parentIdx, AccessExclusiveLock);
- relation_close(parentTbl, AccessExclusiveLock);
- }
-}
/*
* Return an OID list of constraints that reference the given relation
diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h
index f58e8675f32..2ca9106a0e3 100644
--- a/src/include/catalog/index.h
+++ b/src/include/catalog/index.h
@@ -136,6 +136,8 @@ extern Oid IndexGetRelation(Oid indexId, bool missing_ok);
extern void reindex_index(Oid indexId, bool skip_constraint_checks,
char relpersistence, int options);
+extern void validatePartitionedIndex(Relation partedIdx, Relation partedTbl);
+
/* Flag bits for reindex_relation(): */
#define REINDEX_REL_PROCESS_TOAST 0x01
#define REINDEX_REL_SUPPRESS_INDEX_USE 0x02