From 290b873bc07edc2709e8e6ccdc122c5c0e2f615f Mon Sep 17 00:00:00 2001 From: David Geier Date: Thu, 3 Sep 2026 15:25:09 +0200 Subject: [PATCH v1 7/8] Remove rd_index --- contrib/amcheck/verify_common.c | 2 +- contrib/amcheck/verify_nbtree.c | 2 +- contrib/pgstattuple/pgstatindex.c | 6 +-- contrib/pgstattuple/pgstattuple.c | 2 +- src/backend/access/brin/brin.c | 4 +- src/backend/access/common/toast_internals.c | 6 +-- src/backend/access/gin/ginfast.c | 2 +- src/backend/access/heap/heapam.c | 4 +- src/backend/access/index/genam.c | 6 +-- src/backend/access/nbtree/nbtutils.c | 2 +- src/backend/access/spgist/spgutils.c | 12 +++--- src/backend/catalog/catalog.c | 4 +- src/backend/catalog/index.c | 8 ++-- src/backend/catalog/indexing.c | 4 +- src/backend/commands/indexcmds.c | 14 +++--- src/backend/commands/matview.c | 4 +- src/backend/commands/repack.c | 20 ++++----- src/backend/commands/tablecmds.c | 44 +++++++++---------- src/backend/commands/vacuum.c | 2 +- src/backend/executor/execIndexing.c | 16 +++---- src/backend/executor/execPartition.c | 10 ++--- src/backend/executor/execReplication.c | 2 +- src/backend/executor/nodeIndexonlyscan.c | 2 +- src/backend/optimizer/util/plancat.c | 12 +++--- src/backend/parser/parse_utilcmd.c | 2 +- src/backend/replication/logical/conflict.c | 2 +- src/backend/replication/logical/relation.c | 8 ++-- src/backend/statistics/stat_utils.c | 4 +- src/backend/storage/lmgr/predicate.c | 8 ++-- src/backend/utils/adt/ri_triggers.c | 2 +- src/backend/utils/cache/catcache.c | 4 +- src/backend/utils/cache/relcache.c | 47 ++++++++++----------- src/include/utils/rel.h | 22 +++++++++- src/include/utils/rel_internal.h | 1 - 34 files changed, 153 insertions(+), 137 deletions(-) diff --git a/contrib/amcheck/verify_common.c b/contrib/amcheck/verify_common.c index 46e53b3f99a..5e7228287ba 100644 --- a/contrib/amcheck/verify_common.c +++ b/contrib/amcheck/verify_common.c @@ -181,7 +181,7 @@ index_checkable(Relation rel, Oid am_id) errdetail("Index \"%s\" is associated with temporary relation.", RelationGetRelationName(rel)))); - if (!rel->rd_index->indisvalid) + if (!RelationGetIndex(rel)->indisvalid) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("cannot check index \"%s\"", diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c index 3ef2d66f826..092ecb5a1c2 100644 --- a/contrib/amcheck/verify_nbtree.c +++ b/contrib/amcheck/verify_nbtree.c @@ -456,7 +456,7 @@ bt_check_every_level(Relation rel, Relation heaprel, bool heapkeyspace, * horizon. Throwing an error here should be very rare. It doesn't * seem worth using a secondary snapshot to avoid this. */ - if (IsolationUsesXactSnapshot() && rel->rd_index->indcheckxmin && + if (IsolationUsesXactSnapshot() && RelationGetIndex(rel)->indcheckxmin && !TransactionIdPrecedes(HeapTupleHeaderGetXmin(rel->rd_indextuple->t_data), state->snapshot->xmin)) ereport(ERROR, diff --git a/contrib/pgstattuple/pgstatindex.c b/contrib/pgstattuple/pgstatindex.c index 8951ad0aac4..ae0fba426f3 100644 --- a/contrib/pgstattuple/pgstatindex.c +++ b/contrib/pgstattuple/pgstatindex.c @@ -244,7 +244,7 @@ pgstatindex_impl(Relation rel, FunctionCallInfo fcinfo) * but the results could be confusing. For example, the index's size * could be too low for a valid index of the table. */ - if (!rel->rd_index->indisvalid) + if (!RelationGetIndex(rel)->indisvalid) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("index \"%s\" is not valid", @@ -558,7 +558,7 @@ pgstatginindex_internal(Oid relid, FunctionCallInfo fcinfo) errmsg("cannot access temporary indexes of other sessions"))); /* see pgstatindex_impl */ - if (!rel->rd_index->indisvalid) + if (!RelationGetIndex(rel)->indisvalid) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("index \"%s\" is not valid", @@ -648,7 +648,7 @@ pgstathashindex(PG_FUNCTION_ARGS) errmsg("cannot access temporary indexes of other sessions"))); /* see pgstatindex_impl */ - if (!rel->rd_index->indisvalid) + if (!RelationGetIndex(rel)->indisvalid) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("index \"%s\" is not valid", diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c index 6a7f8cb4a7c..89116b52250 100644 --- a/contrib/pgstattuple/pgstattuple.c +++ b/contrib/pgstattuple/pgstattuple.c @@ -262,7 +262,7 @@ pgstat_relation(Relation rel, FunctionCallInfo fcinfo) else if (rel->rd_rel->relkind == RELKIND_INDEX) { /* see pgstatindex_impl */ - if (!rel->rd_index->indisvalid) + if (!RelationGetIndex(rel)->indisvalid) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("index \"%s\" is not valid", diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index 5059da8dce7..8eb25c1e175 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -1469,7 +1469,7 @@ brin_summarize_range(PG_FUNCTION_ARGS) RelationGetRelationName(indexRel)))); /* see gin_clean_pending_list() */ - if (indexRel->rd_index->indisvalid) + if (RelationGetIndex(indexRel)->indisvalid) brinsummarize(indexRel, heapRel, heapBlk, true, &numSummarized, NULL); else ereport(DEBUG1, @@ -1558,7 +1558,7 @@ brin_desummarize_range(PG_FUNCTION_ARGS) RelationGetRelationName(indexRel)))); /* see gin_clean_pending_list() */ - if (indexRel->rd_index->indisvalid) + if (RelationGetIndex(indexRel)->indisvalid) { /* the revmap does the hard work */ do diff --git a/src/backend/access/common/toast_internals.c b/src/backend/access/common/toast_internals.c index 0f234661bfa..a3290c2f97a 100644 --- a/src/backend/access/common/toast_internals.c +++ b/src/backend/access/common/toast_internals.c @@ -327,11 +327,11 @@ toast_save_datum(Relation rel, Datum value, for (int i = 0; i < num_indexes; i++) { /* Only index relations marked as ready can be updated */ - if (toastidxs[i]->rd_index->indisready) + if (RelationGetIndex(toastidxs[i])->indisready) index_insert(toastidxs[i], t_values, t_isnull, &(toasttup->t_self), toastrel, - toastidxs[i]->rd_index->indisunique ? + RelationGetIndex(toastidxs[i])->indisunique ? UNIQUE_CHECK_YES : UNIQUE_CHECK_NO, false, NULL); } @@ -577,7 +577,7 @@ toast_open_indexes(Relation toastrel, { Relation toastidx = (*toastidxs)[i]; - if (toastidx->rd_index->indisvalid) + if (RelationGetIndex(toastidx)->indisvalid) { res = i; found = true; diff --git a/src/backend/access/gin/ginfast.c b/src/backend/access/gin/ginfast.c index 46fc60115a8..df5e3545a19 100644 --- a/src/backend/access/gin/ginfast.c +++ b/src/backend/access/gin/ginfast.c @@ -1075,7 +1075,7 @@ gin_clean_pending_list(PG_FUNCTION_ARGS) * is merely awaiting missed aminsert calls, we're capable of processing * it. Decline to do so, out of an abundance of caution. */ - if (indexRel->rd_index->indisvalid) + if (RelationGetIndex(indexRel)->indisvalid) { GinState ginstate; diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index b507b3e996b..8a0d12465e4 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -4419,7 +4419,7 @@ check_lock_if_inplace_updateable_rel(Relation relation, { Relation irel = index_open(relid, AccessShareLock); - SET_LOCKTAG_RELATION(tag, dbid, irel->rd_index->indrelid); + SET_LOCKTAG_RELATION(tag, dbid, RelationGetIndex(irel)->indrelid); index_close(irel, AccessShareLock); } else @@ -4473,7 +4473,7 @@ check_inplace_rel_lock(HeapTuple oldtup) { Relation irel = index_open(relid, AccessShareLock); - SET_LOCKTAG_RELATION(tag, dbid, irel->rd_index->indrelid); + SET_LOCKTAG_RELATION(tag, dbid, RelationGetIndex(irel)->indrelid); index_close(irel, AccessShareLock); } else diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c index 1408989c568..02d711c0a74 100644 --- a/src/backend/access/index/genam.c +++ b/src/backend/access/index/genam.c @@ -199,7 +199,7 @@ BuildIndexValueDescription(Relation indexRelation, * Next we need to check table-level SELECT access and then, if there is * no access there, check column-level permissions. */ - idxrec = indexRelation->rd_index; + idxrec = RelationGetIndex(indexRelation); indrelid = idxrec->indrelid; Assert(indexrelid == idxrec->indexrelid); @@ -444,7 +444,7 @@ systable_beginscan(Relation heapRelation, for (j = 0; j < IndexRelationGetNumberOfAttributes(irel); j++) { - if (key[i].sk_attno == irel->rd_index->indkey.values[j]) + if (key[i].sk_attno == RelationGetIndex(irel)->indkey.values[j]) { idxkey[i].sk_attno = j + 1; break; @@ -698,7 +698,7 @@ systable_beginscan_ordered(Relation heapRelation, for (j = 0; j < IndexRelationGetNumberOfAttributes(indexRelation); j++) { - if (key[i].sk_attno == indexRelation->rd_index->indkey.values[j]) + if (key[i].sk_attno == RelationGetIndex(indexRelation)->indkey.values[j]) { idxkey[i].sk_attno = j + 1; break; diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index b3032b1f1de..474a6e5bea2 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -141,7 +141,7 @@ _bt_mkscankey(Relation rel, IndexTuple itup) * In NULLS NOT DISTINCT mode, we pretend that there are no null keys, so * that full uniqueness check is done. */ - if (rel->rd_index->indnullsnotdistinct) + if (RelationGetIndex(rel)->indnullsnotdistinct) key->anynullkeys = false; return key; diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c index f2ee333f60d..90a3380a7a0 100644 --- a/src/backend/access/spgist/spgutils.c +++ b/src/backend/access/spgist/spgutils.c @@ -126,14 +126,14 @@ GetIndexInputType(Relation index, AttrNumber indexcol) List *indexprs; ListCell *indexpr_item; - Assert(index->rd_index != NULL); - Assert(indexcol > 0 && indexcol <= index->rd_index->indnkeyatts); + Assert(RelationGetIndex(index) != NULL); + Assert(indexcol > 0 && indexcol <= RelationGetIndex(index)->indnkeyatts); opcintype = index->rd_opcintype[indexcol - 1]; if (!IsPolymorphicType(opcintype)) return opcintype; - heapcol = index->rd_index->indkey.values[indexcol - 1]; + heapcol = RelationGetIndex(index)->indkey.values[indexcol - 1]; if (heapcol != 0) /* Simple index column? */ - return getBaseType(get_atttype(index->rd_index->indrelid, heapcol)); + return getBaseType(get_atttype(RelationGetIndex(index)->indrelid, heapcol)); /* * If the index expressions are already cached, skip calling @@ -146,9 +146,9 @@ GetIndexInputType(Relation index, AttrNumber indexcol) else indexprs = RelationGetIndexExpressions(index); indexpr_item = list_head(indexprs); - for (int i = 1; i <= index->rd_index->indnkeyatts; i++) + for (int i = 1; i <= RelationGetIndex(index)->indnkeyatts; i++) { - if (index->rd_index->indkey.values[i - 1] == 0) + if (RelationGetIndex(index)->indkey.values[i - 1] == 0) { /* expression column */ if (indexpr_item == NULL) diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c index cf9b88b3e25..a38c398bd66 100644 --- a/src/backend/catalog/catalog.c +++ b/src/backend/catalog/catalog.c @@ -697,7 +697,7 @@ pg_nextoid(PG_FUNCTION_ARGS) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("pg_nextoid() can only be used on system catalogs"))); - if (idx->rd_index->indrelid != RelationGetRelid(rel)) + if (RelationGetIndex(idx)->indrelid != RelationGetRelid(rel)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("index \"%s\" does not belong to table \"%s\"", @@ -721,7 +721,7 @@ pg_nextoid(PG_FUNCTION_ARGS) NameStr(*attname), "oid"))); if (IndexRelationGetNumberOfKeyAttributes(idx) != 1 || - idx->rd_index->indkey.values[0] != attno) + RelationGetIndex(idx)->indkey.values[0] != attno) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("index \"%s\" is not the index for column \"%s\"", diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index ce84c124cc1..deb785303fc 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -1250,7 +1250,7 @@ index_create(Relation heapRelation, else Assert(indexRelation->rd_indexcxt != NULL); - indexRelation->rd_index->indnkeyatts = indexInfo->ii_NumIndexKeyAttrs; + RelationGetIndex(indexRelation)->indnkeyatts = indexInfo->ii_NumIndexKeyAttrs; /* Validate opclass-specific options */ if (opclassOptions) @@ -1420,7 +1420,7 @@ index_create_copy(Relation heapRelation, uint16 flags, oldInfo->ii_WithoutOverlaps); /* fetch exclusion constraint info if any */ - if (indexRelation->rd_index->indisexclusion) + if (RelationGetIndex(indexRelation)->indisexclusion) { /* * XXX Beware: we're making newInfo point to oldInfo-owned memory. It @@ -2461,7 +2461,7 @@ IndexInfo * BuildIndexInfo(Relation index) { IndexInfo *ii; - Form_pg_index indexStruct = index->rd_index; + Form_pg_index indexStruct = RelationGetIndex(index); int i; int numAtts; @@ -2521,7 +2521,7 @@ IndexInfo * BuildDummyIndexInfo(Relation index) { IndexInfo *ii; - Form_pg_index indexStruct = index->rd_index; + Form_pg_index indexStruct = RelationGetIndex(index); int i; int numAtts; diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c index fd7d2ec0e3a..bfaec5bf2d7 100644 --- a/src/backend/catalog/indexing.c +++ b/src/backend/catalog/indexing.c @@ -135,7 +135,7 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple, Assert(indexInfo->ii_Expressions == NIL); Assert(indexInfo->ii_Predicate == NIL); Assert(indexInfo->ii_ExclusionOps == NULL); - Assert(index->rd_index->indimmediate); + Assert(RelationGetIndex(index)->indimmediate); Assert(indexInfo->ii_NumIndexKeyAttrs != 0); /* see earlier check above */ @@ -172,7 +172,7 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple, isnull, /* is-null flags */ &(heapTuple->t_self), /* tid of heap tuple */ heapRelation, - index->rd_index->indisunique ? + RelationGetIndex(index)->indisunique ? UNIQUE_CHECK_YES : UNIQUE_CHECK_NO, false, indexInfo); diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index b8a0c908637..763a37db586 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -1496,7 +1496,7 @@ DefineIndex(ParseState *pstate, createdConstraintId, childRelid); - if (!cldidx->rd_index->indisvalid) + if (!RelationGetIndex(cldidx)->indisvalid) invalidate_parent = true; found = true; @@ -3858,14 +3858,14 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein Relation indexRelation = index_open(cellOid, ShareUpdateExclusiveLock); - if (!indexRelation->rd_index->indisvalid) + if (!RelationGetIndex(indexRelation)->indisvalid) ereport(WARNING, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("skipping reindex of invalid index \"%s.%s\"", get_namespace_name(get_rel_namespace(cellOid)), get_rel_name(cellOid)), errhint("Use DROP INDEX or REINDEX INDEX."))); - else if (indexRelation->rd_index->indisexclusion) + else if (RelationGetIndex(indexRelation)->indisexclusion) ereport(WARNING, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot reindex exclusion constraint index \"%s.%s\" concurrently, skipping", @@ -3911,7 +3911,7 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein Relation indexRelation = index_open(cellOid, ShareUpdateExclusiveLock); - if (!indexRelation->rd_index->indisvalid) + if (!RelationGetIndex(indexRelation)->indisvalid) ereport(WARNING, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("skipping reindex of invalid index \"%s.%s\"", @@ -4088,7 +4088,7 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein Oid tablespaceid; indexRel = index_open(idx->indexId, ShareUpdateExclusiveLock); - heapRel = table_open(indexRel->rd_index->indrelid, + heapRel = table_open(RelationGetIndex(indexRel)->indrelid, ShareUpdateExclusiveLock); /* @@ -4132,7 +4132,7 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein concurrentName = ChooseRelationName(get_rel_name(idx->indexId), NULL, "ccnew", - get_rel_namespace(indexRel->rd_index->indrelid), + get_rel_namespace(RelationGetIndex(indexRel)->indrelid), false); /* Choose the new tablespace, indexes of toast tables are not moved */ @@ -4736,7 +4736,7 @@ IndexSetParentIndex(Relation partitionIdx, Oid parentOid) ObjectAddressSet(partIdx, RelationRelationId, partRelid); ObjectAddressSet(parentIdx, RelationRelationId, parentOid); ObjectAddressSet(partitionTbl, RelationRelationId, - partitionIdx->rd_index->indrelid); + RelationGetIndex(partitionIdx)->indrelid); recordDependencyOn(&partIdx, &parentIdx, DEPENDENCY_PARTITION_PRI); recordDependencyOn(&partIdx, &partitionTbl, diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index 40748958eaf..a949482d99c 100644 --- a/src/backend/commands/matview.c +++ b/src/backend/commands/matview.c @@ -727,7 +727,7 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner, indexRel = index_open(indexoid, RowExclusiveLock); if (is_usable_unique_index(indexRel)) { - Form_pg_index indexStruct = indexRel->rd_index; + Form_pg_index indexStruct = RelationGetIndex(indexRel); int indnkeyatts = indexStruct->indnkeyatts; oidvector *indclass; Datum indclassDatum; @@ -904,7 +904,7 @@ refresh_by_heap_swap(Oid matviewOid, Oid OIDNewHeap, char relpersistence) static bool is_usable_unique_index(Relation indexRel) { - Form_pg_index indexStruct = indexRel->rd_index; + Form_pg_index indexStruct = RelationGetIndex(indexRel); /* * Must be unique, valid, immediate, non-partial, and be defined over diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 89aa038d23d..cee17fe6636 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -608,7 +608,7 @@ cluster_rel(RepackCommand cmd, Relation OldHeap, Oid indexOid, */ if (cmd != REPACK_COMMAND_CLUSTER && !allowSystemTableMods && OidIsValid(indexOid) && - IsCatalogRelation(OldHeap) && !index->rd_index->indisclustered) + IsCatalogRelation(OldHeap) && !RelationGetIndex(index)->indisclustered) ereport(ERROR, errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied: \"%s\" is a system catalog", @@ -757,8 +757,8 @@ check_index_is_clusterable(Relation OldHeap, Oid indexOid, LOCKMODE lockmode) /* * Check that index is in fact an index on the given relation */ - if (OldIndex->rd_index == NULL || - OldIndex->rd_index->indrelid != RelationGetRelid(OldHeap)) + if (RelationGetIndex(OldIndex) == NULL || + RelationGetIndex(OldIndex)->indrelid != RelationGetRelid(OldHeap)) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is not an index for table \"%s\"", @@ -792,7 +792,7 @@ check_index_is_clusterable(Relation OldHeap, Oid indexOid, LOCKMODE lockmode) * might put recently-dead tuples out-of-order in the new table, and there * is little harm in that.) */ - if (!OldIndex->rd_index->indisvalid) + if (!RelationGetIndex(OldIndex)->indisvalid) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot cluster on invalid index \"%s\"", @@ -2904,7 +2904,7 @@ static bool find_target_tuple(Relation rel, ChangeContext *chgcxt, TupleTableSlot *locator, TupleTableSlot *retrieved) { - Form_pg_index idx = chgcxt->cc_ident_index->rd_index; + Form_pg_index idx = RelationGetIndex(chgcxt->cc_ident_index); IndexScanDesc scan; bool retval = false; @@ -2963,7 +2963,7 @@ identity_key_equal(ChangeContext *chgcxt, TupleTableSlot *locator, for (int i = 0; i < chgcxt->cc_ident_key_nentries; i++) { ScanKey entry = &chgcxt->cc_ident_key[i]; - AttrNumber attno = chgcxt->cc_ident_index->rd_index->indkey.values[i]; + AttrNumber attno = RelationGetIndex(chgcxt->cc_ident_index)->indkey.values[i]; Assert(attno > 0); @@ -3134,7 +3134,7 @@ initialize_change_context(ChangeContext *chgcxt, { Form_pg_index indexForm; - indexForm = chgcxt->cc_ident_index->rd_index; + indexForm = RelationGetIndex(chgcxt->cc_ident_index); chgcxt->cc_ident_key_nentries = indexForm->indnkeyatts; chgcxt->cc_ident_key = (ScanKey) palloc_array(ScanKeyData, indexForm->indnkeyatts); for (int i = 0; i < indexForm->indnkeyatts; i++) @@ -3178,7 +3178,7 @@ initialize_change_context(ChangeContext *chgcxt, chgcxt->cc_last_key_attno = InvalidAttrNumber; for (int i = 0; i < chgcxt->cc_ident_key_nentries; i++) { - AttrNumber attno = chgcxt->cc_ident_index->rd_index->indkey.values[i]; + AttrNumber attno = RelationGetIndex(chgcxt->cc_ident_index)->indkey.values[i]; Assert(attno > 0); chgcxt->cc_last_key_attno = Max(chgcxt->cc_last_key_attno, attno); @@ -3443,7 +3443,7 @@ build_new_indexes(Relation NewHeap, Relation OldHeap, List *OldIndexes) newName = ChooseRelationName(get_rel_name(oldindex), NULL, "repacknew", - get_rel_namespace(ind->rd_index->indrelid), + get_rel_namespace(RelationGetIndex(ind)->indrelid), false); newindex = index_create_copy(NewHeap, INDEX_CREATE_SUPPRESS_PROGRESS, oldindex, ind->rd_rel->reltablespace, @@ -3489,7 +3489,7 @@ copy_index_constraints(Relation old_index, Oid new_index_id, Oid new_heap_id) ScanKeyInit(&skey, Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(old_index->rd_index->indrelid)); + ObjectIdGetDatum(RelationGetIndex(old_index)->indrelid)); scan = systable_beginscan(rel, ConstraintRelidTypidNameIndexId, true, NULL, 1, &skey); desc = RelationGetDescr(rel); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 8dc70bfa0f1..e08a17f482c 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -1306,7 +1306,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE) { - if (idxRel->rd_index->indisunique) + if (RelationGetIndex(idxRel)->indisunique) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot create foreign partition of partitioned table \"%s\"", @@ -9075,12 +9075,12 @@ ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newVa if (rel->rd_rel->relkind == RELKIND_INDEX || rel->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) { - if (attnum > rel->rd_index->indnkeyatts) + if (attnum > RelationGetIndex(rel)->indnkeyatts) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot alter statistics on included column \"%s\" of index \"%s\"", NameStr(attrtuple->attname), RelationGetRelationName(rel)))); - else if (rel->rd_index->indkey.values[attnum - 1] != 0) + else if (RelationGetIndex(rel)->indkey.values[attnum - 1] != 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot alter statistics on non-expression column \"%s\" of index \"%s\"", @@ -9215,9 +9215,9 @@ SetIndexStorageProperties(Relation rel, Relation attrelation, indrel = index_open(indexoid, lockmode); - for (int i = 0; i < indrel->rd_index->indnatts; i++) + for (int i = 0; i < RelationGetIndex(indrel)->indnatts; i++) { - if (indrel->rd_index->indkey.values[i] == attnum) + if (RelationGetIndex(indrel)->indkey.values[i] == attnum) { indattnum = i + 1; break; @@ -14620,8 +14620,8 @@ dropconstraint_internal(Relation rel, HeapTuple constraintTup, DropBehavior beha Relation pk = relation_open(pkindex, AccessShareLock); pkattrs = NULL; - for (int i = 0; i < pk->rd_index->indnkeyatts; i++) - pkattrs = bms_add_member(pkattrs, pk->rd_index->indkey.values[i]); + for (int i = 0; i < RelationGetIndex(pk)->indnkeyatts; i++) + pkattrs = bms_add_member(pkattrs, RelationGetIndex(pk)->indkey.values[i]); relation_close(pk, AccessShareLock); } @@ -19193,8 +19193,8 @@ ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode indexRel = index_open(indexOid, ShareLock); /* Check that the index is on the relation we're altering. */ - if (indexRel->rd_index == NULL || - indexRel->rd_index->indrelid != RelationGetRelid(rel)) + if (RelationGetIndex(indexRel) == NULL || + RelationGetIndex(indexRel)->indrelid != RelationGetRelid(rel)) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is not an index for table \"%s\"", @@ -19207,14 +19207,14 @@ ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode * exclusion), we can use that too. */ if ((!indexRel->rd_indam->amcanunique || - !indexRel->rd_index->indisunique) && - !(indexRel->rd_index->indisunique && indexRel->rd_index->indisexclusion)) + !RelationGetIndex(indexRel)->indisunique) && + !(RelationGetIndex(indexRel)->indisunique && RelationGetIndex(indexRel)->indisexclusion)) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot use non-unique index \"%s\" as replica identity", RelationGetRelationName(indexRel)))); /* Deferred indexes are not guaranteed to be always unique. */ - if (!indexRel->rd_index->indimmediate) + if (!RelationGetIndex(indexRel)->indimmediate) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot use non-immediate index \"%s\" as replica identity", @@ -19235,7 +19235,7 @@ ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode /* Check index for nullable columns. */ for (key = 0; key < IndexRelationGetNumberOfKeyAttributes(indexRel); key++) { - int16 attno = indexRel->rd_index->indkey.values[key]; + int16 attno = RelationGetIndex(indexRel)->indkey.values[key]; Form_pg_attribute attr; HeapTuple contup; Form_pg_constraint conForm; @@ -21361,8 +21361,8 @@ AttachPartitionEnsureIndexes(List **wqueue, Relation rel, Relation attachrel) Oid idx = lfirst_oid(cell); Relation idxRel = index_open(idx, AccessShareLock); - if (idxRel->rd_index->indisunique || - idxRel->rd_index->indisprimary) + if (RelationGetIndex(idxRel)->indisunique || + RelationGetIndex(idxRel)->indisprimary) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot attach foreign table \"%s\" as partition of partitioned table \"%s\"", @@ -21421,7 +21421,7 @@ AttachPartitionEnsureIndexes(List **wqueue, Relation rel, Relation attachrel) continue; /* If this index is invalid, can't use it */ - if (!attachrelIdxRels[i]->rd_index->indisvalid) + if (!RelationGetIndex(attachrelIdxRels[i])->indisvalid) continue; if (CompareIndexInfo(attachInfos[i], info, @@ -22345,7 +22345,7 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name) * partition, so lock that one too. */ state.partitionOid = InvalidOid; - state.parentTblOid = parentIdx->rd_index->indrelid; + state.parentTblOid = RelationGetIndex(parentIdx)->indrelid; state.lockedParentTbl = false; partIdxId = RangeVarGetRelidExtended(name, AccessExclusiveLock, 0, @@ -22361,8 +22361,8 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name) partIdx = relation_open(partIdxId, AccessExclusiveLock); /* we already hold locks on both tables, so this is safe: */ - parentTbl = relation_open(parentIdx->rd_index->indrelid, AccessShareLock); - partTbl = relation_open(partIdx->rd_index->indrelid, NoLock); + parentTbl = relation_open(RelationGetIndex(parentIdx)->indrelid, AccessShareLock); + partTbl = relation_open(RelationGetIndex(partIdx)->indrelid, NoLock); ObjectAddressSet(address, RelationRelationId, RelationGetRelid(partIdx)); @@ -22465,7 +22465,7 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name) * If it's a primary key, make sure the columns in the partition are * NOT NULL. */ - if (parentIdx->rd_index->indisprimary) + if (RelationGetIndex(parentIdx)->indisprimary) verifyPartitionIndexNotNull(childInfo, partTbl); /* All good -- do it */ @@ -22478,7 +22478,7 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name) validatePartitionedIndex(parentIdx, parentTbl); } - else if (!parentIdx->rd_index->indisvalid) + else if (!RelationGetIndex(parentIdx)->indisvalid) { /* * The index is attached, but the parent is still invalid; see if it @@ -22611,7 +22611,7 @@ validatePartitionedIndex(Relation partedIdx, Relation partedTbl) parentTblId = get_partition_parent(RelationGetRelid(partedTbl), false); parentIdx = relation_open(parentIdxId, AccessExclusiveLock); parentTbl = relation_open(parentTblId, AccessExclusiveLock); - Assert(!parentIdx->rd_index->indisvalid); + Assert(!RelationGetIndex(parentIdx)->indisvalid); validatePartitionedIndex(parentIdx, parentTbl); diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 161f50ea560..a14dac060e3 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2441,7 +2441,7 @@ vac_open_indexes(Relation relation, LOCKMODE lockmode, Relation indrel; indrel = index_open(indexoid, lockmode); - if (indrel->rd_index->indisready) + if (RelationGetIndex(indrel)->indisready) (*Irel)[i++] = indrel; else index_close(indrel, lockmode); diff --git a/src/backend/executor/execIndexing.c b/src/backend/executor/execIndexing.c index eb383812901..f02abe64872 100644 --- a/src/backend/executor/execIndexing.c +++ b/src/backend/executor/execIndexing.c @@ -219,7 +219,7 @@ ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative) * If the indexes are to be used for speculative insertion, add extra * information required by unique index entries. */ - if (speculative && ii->ii_Unique && !indexDesc->rd_index->indisexclusion) + if (speculative && ii->ii_Unique && !RelationGetIndex(indexDesc)->indisexclusion) BuildSpeculativeIndexInfo(indexDesc, ii); relationDescs[i] = indexDesc; @@ -411,7 +411,7 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, applyNoDupErr = (flags & EIIT_NO_DUPE_ERROR) && (arbiterIndexes == NIL || list_member_oid(arbiterIndexes, - indexRelation->rd_index->indexrelid)); + RelationGetIndex(indexRelation)->indexrelid)); /* * The index AM does the actual insertion, plus uniqueness checking. @@ -426,11 +426,11 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, * For a speculative insertion (used by INSERT ... ON CONFLICT), do * the same as for a deferrable unique index. */ - if (!indexRelation->rd_index->indisunique) + if (!RelationGetIndex(indexRelation)->indisunique) checkUnique = UNIQUE_CHECK_NO; else if (applyNoDupErr) checkUnique = UNIQUE_CHECK_PARTIAL; - else if (indexRelation->rd_index->indimmediate) + else if (RelationGetIndex(indexRelation)->indimmediate) checkUnique = UNIQUE_CHECK_YES; else checkUnique = UNIQUE_CHECK_PARTIAL; @@ -480,7 +480,7 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, violationOK = true; waitMode = CEOUC_LIVELOCK_PREVENTING_WAIT; } - else if (!indexRelation->rd_index->indimmediate) + else if (!RelationGetIndex(indexRelation)->indimmediate) { violationOK = true; waitMode = CEOUC_NOWAIT; @@ -510,7 +510,7 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, * speculative conflict, since that always requires a restart. */ result = lappend_oid(result, RelationGetRelid(indexRelation)); - if (indexRelation->rd_index->indimmediate && specConflict) + if (RelationGetIndex(indexRelation)->indimmediate && specConflict) *specConflict = true; } } @@ -600,10 +600,10 @@ ExecCheckIndexConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, /* When specific arbiter indexes requested, only examine them */ if (arbiterIndexes != NIL && !list_member_oid(arbiterIndexes, - indexRelation->rd_index->indexrelid)) + RelationGetIndex(indexRelation)->indexrelid)) continue; - if (!indexRelation->rd_index->indimmediate) + if (!RelationGetIndex(indexRelation)->indimmediate) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters"), diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index 83f5f0cad43..1da8db73cbd 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -506,7 +506,7 @@ IsIndexCompatibleAsArbiter(Relation arbiterIndexRelation, Relation indexRelation, IndexInfo *indexInfo) { - Assert(arbiterIndexRelation->rd_index->indrelid == indexRelation->rd_index->indrelid); + Assert(RelationGetIndex(arbiterIndexRelation)->indrelid == RelationGetIndex(indexRelation)->indrelid); /* must match whether they're unique */ if (arbiterIndexInfo->ii_Unique != indexInfo->ii_Unique) @@ -537,8 +537,8 @@ IsIndexCompatibleAsArbiter(Relation arbiterIndexRelation, indexRelation->rd_opfamily[i]) return false; - if (arbiterIndexRelation->rd_index->indkey.values[i] != - indexRelation->rd_index->indkey.values[i]) + if (RelationGetIndex(arbiterIndexRelation)->indkey.values[i] != + RelationGetIndex(indexRelation)->indkey.values[i]) return false; } @@ -847,7 +847,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, unparented_ii = leaf_part_rri->ri_IndexRelationInfo[unparented_i]; Assert(!list_member_oid(arbiterIndexes, - unparented_rel->rd_index->indexrelid)); + RelationGetIndex(unparented_rel)->indexrelid)); /* Ignore indexes not ready */ if (!unparented_ii->ii_ReadyForInserts) @@ -871,7 +871,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, unparented_ii)) { arbiterIndexes = lappend_oid(arbiterIndexes, - unparented_rel->rd_index->indexrelid); + RelationGetIndex(unparented_rel)->indexrelid); additional_arbiters++; break; } diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c index b2ca5cbf117..75d4bb332d9 100644 --- a/src/backend/executor/execReplication.c +++ b/src/backend/executor/execReplication.c @@ -62,7 +62,7 @@ build_replindex_scan_key(ScanKey skey, Relation rel, Relation idxrel, int skey_attoff = 0; Datum indclassDatum; oidvector *opclass; - int2vector *indkey = &idxrel->rd_index->indkey; + int2vector *indkey = &RelationGetIndex(idxrel)->indkey; indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, idxrel->rd_indextuple, Anum_pg_index_indclass); diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c index 856df2ba51d..059d5de1056 100644 --- a/src/backend/executor/nodeIndexonlyscan.c +++ b/src/backend/executor/nodeIndexonlyscan.c @@ -656,7 +656,7 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags) } indexstate->ioss_NameCStringAttNums = NULL; - indnkeyatts = indexRelation->rd_index->indnkeyatts; + indnkeyatts = RelationGetIndex(indexRelation)->indnkeyatts; namecount = 0; /* diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 4c9c5e9fc33..2793d2c371b 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -236,7 +236,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, * Extract info from the relation descriptor for the index. */ indexRelation = index_open(indexoid, lmode); - index = indexRelation->rd_index; + index = RelationGetIndex(indexRelation); /* * Ignore invalid indexes, since they can't safely be used for @@ -916,7 +916,7 @@ infer_arbiter_indexes(PlannerInfo *root) */ foreach_ptr(RelationData, idxRel, indexRelList) { - Form_pg_index idxForm = idxRel->rd_index; + Form_pg_index idxForm = RelationGetIndex(idxRel); if (indexOidFromConstraint == idxForm->indexrelid) { @@ -932,7 +932,7 @@ infer_arbiter_indexes(PlannerInfo *root) { int attno; - attno = idxRel->rd_index->indkey.values[natt]; + attno = RelationGetIndex(idxRel)->indkey.values[natt]; if (attno != InvalidAttrNumber) inferAttrs = bms_add_member(inferAttrs, @@ -966,7 +966,7 @@ infer_arbiter_indexes(PlannerInfo *root) * enforcement needs to occur there anyway when an inference clause is * omitted. */ - idxForm = idxRel->rd_index; + idxForm = RelationGetIndex(idxRel); /* * Ignore indexes that aren't indisready, because we cannot trust @@ -1058,7 +1058,7 @@ infer_arbiter_indexes(PlannerInfo *root) indexedAttrs = NULL; for (natt = 0; natt < idxForm->indnkeyatts; natt++) { - int attno = idxRel->rd_index->indkey.values[natt]; + int attno = RelationGetIndex(idxRel)->indkey.values[natt]; if (attno != 0) indexedAttrs = bms_add_member(indexedAttrs, @@ -1247,7 +1247,7 @@ infer_collation_opclass_match(InferenceElem *elem, Relation idxRel, Oid opfamily = idxRel->rd_opfamily[natt - 1]; Oid opcinputtype = idxRel->rd_opcintype[natt - 1]; Oid collation = idxRel->rd_indcollation[natt - 1]; - int attno = idxRel->rd_index->indkey.values[natt - 1]; + int attno = RelationGetIndex(idxRel)->indkey.values[natt - 1]; if (attno != 0) nplain++; diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index d83616a8507..bc40fc29a83 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -2443,7 +2443,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) /* Open the index (this will throw an error if it is not an index) */ index_rel = index_open(index_oid, AccessShareLock); - index_form = index_rel->rd_index; + index_form = RelationGetIndex(index_rel); /* Check that it does not have an associated constraint already */ if (OidIsValid(get_index_constraint(index_oid))) diff --git a/src/backend/replication/logical/conflict.c b/src/backend/replication/logical/conflict.c index b71a0c9e206..bb05e0754c8 100644 --- a/src/backend/replication/logical/conflict.c +++ b/src/backend/replication/logical/conflict.c @@ -325,7 +325,7 @@ InitConflictIndexes(ResultRelInfo *relInfo) continue; /* Don't support conflict detection for deferrable index */ - if (!indexRelation->rd_index->indimmediate) + if (!RelationGetIndex(indexRelation)->indimmediate) continue; uniqueIndexes = lappend_oid(uniqueIndexes, diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c index 8ffd2583afb..b9fd0233d96 100644 --- a/src/backend/replication/logical/relation.c +++ b/src/backend/replication/logical/relation.c @@ -800,7 +800,7 @@ FindUsableIndexForReplicaIdentityFull(Relation localrel, AttrMap *attrmap) * permanently invalid leftover of a failed CREATE INDEX CONCURRENTLY * must never be chosen here. */ - isUsableIdx = idxRel->rd_index->indisvalid && + isUsableIdx = RelationGetIndex(idxRel)->indisvalid && IsIndexUsableForReplicaIdentityFull(idxRel, attrmap); index_close(idxRel, AccessShareLock); @@ -849,14 +849,14 @@ IsIndexUsableForReplicaIdentityFull(Relation idxrel, AttrMap *attrmap) if (!heap_attisnull(idxrel->rd_indextuple, Anum_pg_index_indpred, NULL)) return false; - Assert(idxrel->rd_index->indnatts >= 1); + Assert(RelationGetIndex(idxrel)->indnatts >= 1); indclass = (oidvector *) DatumGetPointer(SysCacheGetAttrNotNull(INDEXRELID, idxrel->rd_indextuple, Anum_pg_index_indclass)); /* Ensure that the index has a valid equal strategy for each key column */ - for (int i = 0; i < idxrel->rd_index->indnkeyatts; i++) + for (int i = 0; i < RelationGetIndex(idxrel)->indnkeyatts; i++) { Oid opfamily; @@ -881,7 +881,7 @@ IsIndexUsableForReplicaIdentityFull(Relation idxrel, AttrMap *attrmap) } /* The leftmost index field must not be an expression */ - keycol = idxrel->rd_index->indkey.values[0]; + keycol = RelationGetIndex(idxrel)->indkey.values[0]; if (!AttributeNumberIsValid(keycol)) return false; diff --git a/src/backend/statistics/stat_utils.c b/src/backend/statistics/stat_utils.c index f4ff9ab9b20..2029676463d 100644 --- a/src/backend/statistics/stat_utils.c +++ b/src/backend/statistics/stat_utils.c @@ -323,13 +323,13 @@ statatt_get_index_expr(Relation rel, int attnum) * The index's attnum points directly to a relation attnum, hence it is * not an expression attribute. */ - if (rel->rd_index->indkey.values[attnum - 1] != 0) + if (RelationGetIndex(rel)->indkey.values[attnum - 1] != 0) return NULL; indexpr_item = list_head(rel->rd_indexprs); for (int i = 0; i < attnum - 1; i++) - if (rel->rd_index->indkey.values[i] == 0) + if (RelationGetIndex(rel)->indkey.values[i] == 0) indexpr_item = lnext(rel->rd_indexprs, indexpr_item); if (indexpr_item == NULL) /* shouldn't happen */ diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c index 0ae85b7d5b4..cd3f725f221 100644 --- a/src/backend/storage/lmgr/predicate.c +++ b/src/backend/storage/lmgr/predicate.c @@ -2558,7 +2558,7 @@ PredicateLockTID(Relation relation, const ItemPointerData *tid, Snapshot snapsho /* * Return if this xact wrote it. */ - if (relation->rd_index == NULL) + if (RelationGetIndex(relation) == NULL) { /* If we wrote it; we already have a write lock. */ if (TransactionIdIsCurrentTransactionId(tuple_xid)) @@ -2890,7 +2890,7 @@ DropAllPredicateLocksFromTable(Relation relation, bool transfer) dbId = relation->rd_locator.dbOid; relId = relation->rd_id; - if (relation->rd_index == NULL) + if (RelationGetIndex(relation) == NULL) { isIndex = false; heapId = relId; @@ -2898,7 +2898,7 @@ DropAllPredicateLocksFromTable(Relation relation, bool transfer) else { isIndex = true; - heapId = relation->rd_index->indrelid; + heapId = RelationGetIndex(relation)->indrelid; } Assert(heapId != InvalidOid); Assert(transfer || !isIndex); /* index OID only makes sense with @@ -4371,7 +4371,7 @@ CheckTableForSerializableConflictIn(Relation relation) */ MyXactDidWrite = true; - Assert(relation->rd_index == NULL); /* not an index relation */ + Assert(RelationGetIndex(relation) == NULL); /* not an index relation */ dbId = relation->rd_locator.dbOid; heapId = relation->rd_id; diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index d4545618634..85911de07b3 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -3658,7 +3658,7 @@ ri_populate_fastpath_metadata(RI_ConstraintInfo *riinfo, */ for (idx_col = 0; idx_col < riinfo->nkeys; idx_col++) { - if (idx_rel->rd_index->indkey.values[idx_col] == riinfo->pk_attnums[i]) + if (RelationGetIndex(idx_rel)->indkey.values[idx_col] == riinfo->pk_attnums[i]) break; } Assert(idx_col < riinfo->nkeys); diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 511270edfda..482c1bcdd89 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -1278,8 +1278,8 @@ InitCatCachePhase2(CatCache *cache, bool touch_index) * catch thinkos in definitions of new catcaches, so we don't worry * about the pg_am indexes not getting tested. */ - Assert(idesc->rd_index->indisunique && - idesc->rd_index->indimmediate); + Assert(RelationGetIndex(idesc)->indisunique && + RelationGetIndex(idesc)->indimmediate); index_close(idesc, AccessShareLock); UnlockRelationOid(cache->cc_reloid, AccessShareLock); diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index ac1636106fc..2970baa0810 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -1463,7 +1463,6 @@ RelationInitIndexAccessInfo(Relation relation) RelationGetRelid(relation)); oldcontext = MemoryContextSwitchTo(CacheMemoryContext); relation->rd_indextuple = heap_copytuple(tuple); - relation->rd_index = (Form_pg_index) GETSTRUCT(relation->rd_indextuple); MemoryContextSwitchTo(oldcontext); ReleaseSysCache(tuple); @@ -2338,7 +2337,7 @@ RelationReloadIndexInfo(Relation relation) if (!IsSystemRelation(relation)) { HeapTuple tuple; - Form_pg_index index; + Form_pg_index index, rd_index; tuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(RelationGetRelid(relation))); @@ -2353,17 +2352,18 @@ RelationReloadIndexInfo(Relation relation) * it's not worth it to track exactly which ones they are. None of * the array fields are allowed to change, though. */ - relation->rd_index->indisunique = index->indisunique; - relation->rd_index->indnullsnotdistinct = index->indnullsnotdistinct; - relation->rd_index->indisprimary = index->indisprimary; - relation->rd_index->indisexclusion = index->indisexclusion; - relation->rd_index->indimmediate = index->indimmediate; - relation->rd_index->indisclustered = index->indisclustered; - relation->rd_index->indisvalid = index->indisvalid; - relation->rd_index->indcheckxmin = index->indcheckxmin; - relation->rd_index->indisready = index->indisready; - relation->rd_index->indislive = index->indislive; - relation->rd_index->indisreplident = index->indisreplident; + rd_index = RelationGetIndex(relation); + rd_index->indisunique = index->indisunique; + rd_index->indnullsnotdistinct = index->indnullsnotdistinct; + rd_index->indisprimary = index->indisprimary; + rd_index->indisexclusion = index->indisexclusion; + rd_index->indimmediate = index->indimmediate; + rd_index->indisclustered = index->indisclustered; + rd_index->indisvalid = index->indisvalid; + rd_index->indcheckxmin = index->indcheckxmin; + rd_index->indisready = index->indisready; + rd_index->indislive = index->indislive; + rd_index->indisreplident = index->indisreplident; /* Copy xmin too, as that is needed to make sense of indcheckxmin */ HeapTupleHeaderSetXmin(relation->rd_indextuple->t_data, @@ -5483,7 +5483,7 @@ restart: indexPredicate = NULL; /* Can this index be referenced by a foreign key? */ - isKey = indexDesc->rd_index->indisunique && + isKey = RelationGetIndex(indexDesc)->indisunique && indexExpressions == NULL && indexPredicate == NULL; @@ -5504,9 +5504,9 @@ restart: attrs = &hotblockingattrs; /* Collect simple attribute references */ - for (i = 0; i < indexDesc->rd_index->indnatts; i++) + for (i = 0; i < RelationGetIndex(indexDesc)->indnatts; i++) { - int attrnum = indexDesc->rd_index->indkey.values[i]; + int attrnum = RelationGetIndex(indexDesc)->indkey.values[i]; /* * Since we have covering indexes with non-key columns, we must @@ -5527,15 +5527,15 @@ restart: *attrs = bms_add_member(*attrs, attrnum - FirstLowInvalidHeapAttributeNumber); - if (isKey && i < indexDesc->rd_index->indnkeyatts) + if (isKey && i < RelationGetIndex(indexDesc)->indnkeyatts) uindexattrs = bms_add_member(uindexattrs, attrnum - FirstLowInvalidHeapAttributeNumber); - if (isPK && i < indexDesc->rd_index->indnkeyatts) + if (isPK && i < RelationGetIndex(indexDesc)->indnkeyatts) pkindexattrs = bms_add_member(pkindexattrs, attrnum - FirstLowInvalidHeapAttributeNumber); - if (isIDKey && i < indexDesc->rd_index->indnkeyatts) + if (isIDKey && i < RelationGetIndex(indexDesc)->indnkeyatts) idindexattrs = bms_add_member(idindexattrs, attrnum - FirstLowInvalidHeapAttributeNumber); } @@ -5676,9 +5676,9 @@ RelationGetIdentityKeyBitmap(Relation relation) relation->rd_replidindex); /* Add referenced attributes to idindexattrs */ - for (i = 0; i < indexDesc->rd_index->indnatts; i++) + for (i = 0; i < RelationGetIndex(indexDesc)->indnatts; i++) { - int attrnum = indexDesc->rd_index->indkey.values[i]; + int attrnum = RelationGetIndex(indexDesc)->indkey.values[i]; /* * We don't include non-key columns into idindexattrs bitmaps. See @@ -5686,7 +5686,7 @@ RelationGetIdentityKeyBitmap(Relation relation) */ if (attrnum != 0) { - if (i < indexDesc->rd_index->indnkeyatts) + if (i < RelationGetIndex(indexDesc)->indnkeyatts) idindexattrs = bms_add_member(idindexattrs, attrnum - FirstLowInvalidHeapAttributeNumber); } @@ -5765,7 +5765,7 @@ RelationGetExclusionInfo(Relation indexRelation, ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(indexRelation->rd_index->indrelid)); + ObjectIdGetDatum(RelationGetIndex(indexRelation)->indrelid)); conrel = table_open(ConstraintRelationId, AccessShareLock); conscan = systable_beginscan(conrel, ConstraintRelidTypidNameIndexId, true, @@ -6421,7 +6421,6 @@ load_relcache_init_file(bool shared) /* Fix up internal pointers in the tuple -- see heap_copytuple */ rel->rd_indextuple->t_data = (HeapTupleHeader) ((char *) rel->rd_indextuple + HEAPTUPLESIZE); - rel->rd_index = (Form_pg_index) GETSTRUCT(rel->rd_indextuple); /* * prepare index info context --- parameters should match diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 5c39086ca0c..63409b8ce2d 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -14,6 +14,7 @@ #ifndef REL_H #define REL_H +#include "access/htup_details.h" #include "access/tupdesc.h" #include "access/xlog.h" #include "catalog/catalog.h" @@ -319,19 +320,36 @@ RelationGetLockRelId(Relation relation) */ #define RelationGetNumberOfAttributes(relation) ((relation)->rd_rel->relnatts) +/* + * RelationGetIndex + * Returns the pg_index tuple describing an index relation. + * + * rd_index is not stored directly in RelationData; it is always equal to + * GETSTRUCT(relation->rd_indextuple), so we derive it on the fly instead of + * spending a pointer-sized field on it. + */ +static inline Form_pg_index +RelationGetIndex(Relation relation) +{ + if (relation->rd_indextuple == NULL) + return NULL; + + return (Form_pg_index) GETSTRUCT(relation->rd_indextuple); +} + /* * IndexRelationGetNumberOfAttributes * Returns the number of attributes in an index. */ #define IndexRelationGetNumberOfAttributes(relation) \ - ((relation)->rd_index->indnatts) + (RelationGetIndex(relation)->indnatts) /* * IndexRelationGetNumberOfKeyAttributes * Returns the number of key attributes in an index. */ #define IndexRelationGetNumberOfKeyAttributes(relation) \ - ((relation)->rd_index->indnkeyatts) + (RelationGetIndex(relation)->indnkeyatts) /* * RelationGetDescr diff --git a/src/include/utils/rel_internal.h b/src/include/utils/rel_internal.h index e059b8bf18b..a9079e72be9 100644 --- a/src/include/utils/rel_internal.h +++ b/src/include/utils/rel_internal.h @@ -220,7 +220,6 @@ typedef struct RelationData /* fields used only for an index relation */ struct { - Form_pg_index rd_index; /* pg_index tuple describing this index */ /* use "struct" here to avoid needing to include htup.h: */ struct HeapTupleData *rd_indextuple; /* all of pg_index tuple */ -- 2.55.0