@@ -490,6 +490,8 @@ static ObjectAddress ATExecAttachPartitionIdx(List **wqueue, Relation rel,
490
490
static void validatePartitionedIndex (Relation partedIdx , Relation partedTbl );
491
491
static void refuseDupeIndexAttach (Relation parentIdx , Relation partIdx ,
492
492
Relation partitionTbl );
493
+ static void update_relispartition (Relation classRel , Oid relationId ,
494
+ bool newval );
493
495
494
496
495
497
/* ----------------------------------------------------------------
@@ -14405,10 +14407,11 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel)
14405
14407
*/
14406
14408
for (i = 0 ; i < list_length (attachRelIdxs ); i ++ )
14407
14409
{
14410
+ Oid cldIdxId = RelationGetRelid (attachrelIdxRels [i ]);
14408
14411
Oid cldConstrOid = InvalidOid ;
14409
14412
14410
14413
/* 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 )
14412
14415
continue ;
14413
14416
14414
14417
if (CompareIndexInfo (attachInfos [i ], info ,
@@ -14429,7 +14432,7 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel)
14429
14432
{
14430
14433
cldConstrOid =
14431
14434
get_relation_idx_constraint_oid (RelationGetRelid (attachrel ),
14432
- RelationGetRelid ( attachrelIdxRels [ i ]) );
14435
+ cldIdxId );
14433
14436
/* no dice */
14434
14437
if (!OidIsValid (cldConstrOid ))
14435
14438
continue ;
@@ -14439,6 +14442,7 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel)
14439
14442
IndexSetParentIndex (attachrelIdxRels [i ], idx );
14440
14443
if (OidIsValid (constraintOid ))
14441
14444
ConstraintSetParentConstraint (cldConstrOid , constraintOid );
14445
+ update_relispartition (NULL , cldIdxId , true);
14442
14446
found = true;
14443
14447
break ;
14444
14448
}
@@ -14659,7 +14663,6 @@ ATExecDetachPartition(Relation rel, RangeVar *name)
14659
14663
((Form_pg_class ) GETSTRUCT (newtuple ))-> relispartition = false;
14660
14664
CatalogTupleUpdate (classRel , & newtuple -> t_self , newtuple );
14661
14665
heap_freetuple (newtuple );
14662
- heap_close (classRel , RowExclusiveLock );
14663
14666
14664
14667
if (OidIsValid (defaultPartOid ))
14665
14668
{
@@ -14692,8 +14695,10 @@ ATExecDetachPartition(Relation rel, RangeVar *name)
14692
14695
14693
14696
idx = index_open (idxid , AccessExclusiveLock );
14694
14697
IndexSetParentIndex (idx , InvalidOid );
14698
+ update_relispartition (classRel , idxid , false);
14695
14699
relation_close (idx , AccessExclusiveLock );
14696
14700
}
14701
+ heap_close (classRel , RowExclusiveLock );
14697
14702
14698
14703
/*
14699
14704
* Invalidate the parent's relcache so that the partition is no longer
@@ -14815,8 +14820,8 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name)
14815
14820
ObjectAddressSet (address , RelationRelationId , RelationGetRelid (partIdx ));
14816
14821
14817
14822
/* 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 ;
14820
14825
if (currParent != RelationGetRelid (parentIdx ))
14821
14826
{
14822
14827
IndexInfo * childInfo ;
@@ -14909,6 +14914,7 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name)
14909
14914
IndexSetParentIndex (partIdx , RelationGetRelid (parentIdx ));
14910
14915
if (OidIsValid (constraintOid ))
14911
14916
ConstraintSetParentConstraint (cldConstrId , constraintOid );
14917
+ update_relispartition (NULL , partIdxId , true);
14912
14918
14913
14919
pfree (attmap );
14914
14920
@@ -15036,8 +15042,7 @@ validatePartitionedIndex(Relation partedIdx, Relation partedTbl)
15036
15042
* If this index is in turn a partition of a larger index, validating it
15037
15043
* might cause the parent to become valid also. Try that.
15038
15044
*/
15039
- if (updated &&
15040
- has_superclass (RelationGetRelid (partedIdx )))
15045
+ if (updated && partedIdx -> rd_rel -> relispartition )
15041
15046
{
15042
15047
Oid parentIdxId ,
15043
15048
parentTblId ;
@@ -15059,3 +15064,35 @@ validatePartitionedIndex(Relation partedIdx, Relation partedTbl)
15059
15064
relation_close (parentTbl , AccessExclusiveLock );
15060
15065
}
15061
15066
}
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