@@ -490,6 +490,8 @@ static ObjectAddress ATExecAttachPartitionIdx(List **wqueue, Relation rel,
490490static void validatePartitionedIndex(Relation partedIdx, Relation partedTbl);
491491static void refuseDupeIndexAttach(Relation parentIdx, Relation partIdx,
492492 Relation partitionTbl);
493+ static void update_relispartition(Relation classRel, Oid relationId,
494+ bool newval);
493495
494496
495497/* ----------------------------------------------------------------
@@ -14405,10 +14407,11 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel)
1440514407 */
1440614408 for (i = 0; i < list_length(attachRelIdxs); i++)
1440714409 {
14410+ Oid cldIdxId = RelationGetRelid(attachrelIdxRels[i]);
1440814411 Oid cldConstrOid = InvalidOid;
1440914412
1441014413 /* does this index have a parent? if so, can't use it */
14411- if (has_superclass(RelationGetRelid( attachrelIdxRels[i])) )
14414+ if (attachrelIdxRels[i]->rd_rel->relispartition )
1441214415 continue;
1441314416
1441414417 if (CompareIndexInfo(attachInfos[i], info,
@@ -14429,7 +14432,7 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel)
1442914432 {
1443014433 cldConstrOid =
1443114434 get_relation_idx_constraint_oid(RelationGetRelid(attachrel),
14432- RelationGetRelid(attachrelIdxRels[i]) );
14435+ cldIdxId );
1443314436 /* no dice */
1443414437 if (!OidIsValid(cldConstrOid))
1443514438 continue;
@@ -14439,6 +14442,7 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel)
1443914442 IndexSetParentIndex(attachrelIdxRels[i], idx);
1444014443 if (OidIsValid(constraintOid))
1444114444 ConstraintSetParentConstraint(cldConstrOid, constraintOid);
14445+ update_relispartition(NULL, cldIdxId, true);
1444214446 found = true;
1444314447 break;
1444414448 }
@@ -14659,7 +14663,6 @@ ATExecDetachPartition(Relation rel, RangeVar *name)
1465914663 ((Form_pg_class) GETSTRUCT(newtuple))->relispartition = false;
1466014664 CatalogTupleUpdate(classRel, &newtuple->t_self, newtuple);
1466114665 heap_freetuple(newtuple);
14662- heap_close(classRel, RowExclusiveLock);
1466314666
1466414667 if (OidIsValid(defaultPartOid))
1466514668 {
@@ -14692,8 +14695,10 @@ ATExecDetachPartition(Relation rel, RangeVar *name)
1469214695
1469314696 idx = index_open(idxid, AccessExclusiveLock);
1469414697 IndexSetParentIndex(idx, InvalidOid);
14698+ update_relispartition(classRel, idxid, false);
1469514699 relation_close(idx, AccessExclusiveLock);
1469614700 }
14701+ heap_close(classRel, RowExclusiveLock);
1469714702
1469814703 /*
1469914704 * Invalidate the parent's relcache so that the partition is no longer
@@ -14815,8 +14820,8 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name)
1481514820 ObjectAddressSet(address, RelationRelationId, RelationGetRelid(partIdx));
1481614821
1481714822 /* Silently do nothing if already in the right state */
14818- currParent = !has_superclass(partIdxId) ? InvalidOid :
14819- get_partition_parent(partIdxId);
14823+ currParent = partIdx->rd_rel->relispartition ?
14824+ get_partition_parent(partIdxId) : InvalidOid ;
1482014825 if (currParent != RelationGetRelid(parentIdx))
1482114826 {
1482214827 IndexInfo *childInfo;
@@ -14909,6 +14914,7 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name)
1490914914 IndexSetParentIndex(partIdx, RelationGetRelid(parentIdx));
1491014915 if (OidIsValid(constraintOid))
1491114916 ConstraintSetParentConstraint(cldConstrId, constraintOid);
14917+ update_relispartition(NULL, partIdxId, true);
1491214918
1491314919 pfree(attmap);
1491414920
@@ -15036,8 +15042,7 @@ validatePartitionedIndex(Relation partedIdx, Relation partedTbl)
1503615042 * If this index is in turn a partition of a larger index, validating it
1503715043 * might cause the parent to become valid also. Try that.
1503815044 */
15039- if (updated &&
15040- has_superclass(RelationGetRelid(partedIdx)))
15045+ if (updated && partedIdx->rd_rel->relispartition)
1504115046 {
1504215047 Oid parentIdxId,
1504315048 parentTblId;
@@ -15059,3 +15064,35 @@ validatePartitionedIndex(Relation partedIdx, Relation partedTbl)
1505915064 relation_close(parentTbl, AccessExclusiveLock);
1506015065 }
1506115066}
15067+
15068+ /*
15069+ * Update the relispartition flag of the given relation to the given value.
15070+ *
15071+ * classRel is the pg_class relation, already open and suitably locked.
15072+ * It can be passed as NULL, in which case it's opened and closed locally.
15073+ */
15074+ static void
15075+ update_relispartition(Relation classRel, Oid relationId, bool newval)
15076+ {
15077+ HeapTuple tup;
15078+ HeapTuple newtup;
15079+ Form_pg_class classForm;
15080+ bool opened = false;
15081+
15082+ if (classRel == NULL)
15083+ {
15084+ classRel = heap_open(RelationRelationId, RowExclusiveLock);
15085+ opened = true;
15086+ }
15087+
15088+ tup = SearchSysCache1(RELOID, ObjectIdGetDatum(relationId));
15089+ newtup = heap_copytuple(tup);
15090+ classForm = (Form_pg_class) GETSTRUCT(newtup);
15091+ classForm->relispartition = newval;
15092+ CatalogTupleUpdate(classRel, &tup->t_self, newtup);
15093+ heap_freetuple(newtup);
15094+ ReleaseSysCache(tup);
15095+
15096+ if (opened)
15097+ heap_close(classRel, RowExclusiveLock);
15098+ }
0 commit comments