static void validatePartitionedIndex(Relation partedIdx, Relation partedTbl);
static void refuseDupeIndexAttach(Relation parentIdx, Relation partIdx,
Relation partitionTbl);
+static void update_relispartition(Relation classRel, Oid relationId,
+ bool newval);
/* ----------------------------------------------------------------
*/
for (i = 0; i < list_length(attachRelIdxs); i++)
{
+ Oid cldIdxId = RelationGetRelid(attachrelIdxRels[i]);
Oid cldConstrOid = InvalidOid;
/* does this index have a parent? if so, can't use it */
- if (has_superclass(RelationGetRelid(attachrelIdxRels[i])))
+ if (attachrelIdxRels[i]->rd_rel->relispartition)
continue;
if (CompareIndexInfo(attachInfos[i], info,
{
cldConstrOid =
get_relation_idx_constraint_oid(RelationGetRelid(attachrel),
- RelationGetRelid(attachrelIdxRels[i]));
+ cldIdxId);
/* no dice */
if (!OidIsValid(cldConstrOid))
continue;
IndexSetParentIndex(attachrelIdxRels[i], idx);
if (OidIsValid(constraintOid))
ConstraintSetParentConstraint(cldConstrOid, constraintOid);
+ update_relispartition(NULL, cldIdxId, true);
found = true;
break;
}
((Form_pg_class) GETSTRUCT(newtuple))->relispartition = false;
CatalogTupleUpdate(classRel, &newtuple->t_self, newtuple);
heap_freetuple(newtuple);
- heap_close(classRel, RowExclusiveLock);
if (OidIsValid(defaultPartOid))
{
idx = index_open(idxid, AccessExclusiveLock);
IndexSetParentIndex(idx, InvalidOid);
+ update_relispartition(classRel, idxid, false);
relation_close(idx, AccessExclusiveLock);
}
+ heap_close(classRel, RowExclusiveLock);
/*
* Invalidate the parent's relcache so that the partition is no longer
ObjectAddressSet(address, RelationRelationId, RelationGetRelid(partIdx));
/* Silently do nothing if already in the right state */
- currParent = !has_superclass(partIdxId) ? InvalidOid :
- get_partition_parent(partIdxId);
+ currParent = partIdx->rd_rel->relispartition ?
+ get_partition_parent(partIdxId) : InvalidOid;
if (currParent != RelationGetRelid(parentIdx))
{
IndexInfo *childInfo;
IndexSetParentIndex(partIdx, RelationGetRelid(parentIdx));
if (OidIsValid(constraintOid))
ConstraintSetParentConstraint(cldConstrId, constraintOid);
+ update_relispartition(NULL, partIdxId, true);
pfree(attmap);
* 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 &&
- has_superclass(RelationGetRelid(partedIdx)))
+ if (updated && partedIdx->rd_rel->relispartition)
{
Oid parentIdxId,
parentTblId;
relation_close(parentTbl, AccessExclusiveLock);
}
}
+
+/*
+ * Update the relispartition flag of the given relation to the given value.
+ *
+ * classRel is the pg_class relation, already open and suitably locked.
+ * It can be passed as NULL, in which case it's opened and closed locally.
+ */
+static void
+update_relispartition(Relation classRel, Oid relationId, bool newval)
+{
+ HeapTuple tup;
+ HeapTuple newtup;
+ Form_pg_class classForm;
+ bool opened = false;
+
+ if (classRel == NULL)
+ {
+ classRel = heap_open(RelationRelationId, RowExclusiveLock);
+ opened = true;
+ }
+
+ tup = SearchSysCache1(RELOID, ObjectIdGetDatum(relationId));
+ newtup = heap_copytuple(tup);
+ classForm = (Form_pg_class) GETSTRUCT(newtup);
+ classForm->relispartition = newval;
+ CatalogTupleUpdate(classRel, &tup->t_self, newtup);
+ heap_freetuple(newtup);
+ ReleaseSysCache(tup);
+
+ if (opened)
+ heap_close(classRel, RowExclusiveLock);
+}