@@ -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