Skip to content

Commit 9e9befa

Browse files
committed
Set relispartition correctly for index partitions
Oversight in commit 8b08f7d: pg_class.relispartition was not being set for index partitions, which is a bit odd, and was also causing the code to unnecessarily call has_superclass() when simply checking the flag was enough. Author: Álvaro Herrera Reported-by: Amit Langote Discussion: https://postgr.es/m/12085bc4-0bc6-0f3a-4c43-57fe0681772b@lab.ntt.co.jp
1 parent d1e9079 commit 9e9befa

File tree

2 files changed

+45
-7
lines changed

2 files changed

+45
-7
lines changed

src/backend/catalog/index.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,7 @@ index_create(Relation heapRelation,
933933
indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
934934
indexRelation->rd_rel->relam = accessMethodObjectId;
935935
indexRelation->rd_rel->relhasoids = false;
936+
indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
936937

937938
/*
938939
* store index's pg_class entry

src/backend/commands/tablecmds.c

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,8 @@ static ObjectAddress ATExecAttachPartitionIdx(List **wqueue, Relation rel,
490490
static void validatePartitionedIndex(Relation partedIdx, Relation partedTbl);
491491
static 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

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy