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
