RelationData是访问引擎中最重要的一个结构体,贯穿整个Relation访问的流程。const struct TableAmRoutine *rd_tableam用于存放该表的访问函数的结构体指针,见PostgreSQL数据库TableAM——Table Access Method。struct IndexAmRoutine *rd_indam;用于存放该表的索引访问函数的结构体指针。
typedef struct RelationData {
RelFileNode rd_node;
struct SMgrRelationData *rd_smgr;
int rd_refcnt;
BackendId rd_backend;
bool rd_islocaltemp;
bool rd_isnailed;
bool rd_isvalid;
bool rd_indexvalid;
bool rd_statvalid;
SubTransactionId rd_createSubid;
SubTransactionId rd_newRelfilenodeSubid;
Form_pg_class rd_rel;
TupleDesc rd_att;
Oid rd_id;
LockInfoData rd_lockInfo;
RuleLock *rd_rules;
MemoryContext rd_rulescxt;
TriggerDesc *trigdesc;
struct RowSecurityDesc *rd_rsdesc;
List *rd_fkeylist;
bool rd_fkeyvalid;
struct PartitionKeyData *rd_partkey;
MemoryContext rd_partkeycxt;
struct PartitionDescData *rd_partdesc;
MemoryContext rd_pdcxt;
List *rd_partcheck;
bool rd_partcheckvalid;
MemoryContext rd_partcheckcxt;
List *rd_indexlist;
Oid rd_pkindex;
Oid rd_replidindex;
List *rd_statlist;
Bitmapset *rd_indexattr;
Bitmapset *rd_keyattr;
Bitmapset *rd_pkattr;
Bitmapset *rd_idattr;
PublicationActions *rd_pubactions;
bytea *rd_options;
Oid rd_amhandler;
const struct TableAmRoutine *rd_tableam;
Form_pg_index rd_index;
struct HeapTupleData *rd_indextuple;
MemoryContext rd_indexcxt;
struct IndexAmRoutine *rd_indam;
Oid *rd_opfamily;
Oid *rd_opcintype;
RegProcedure *rd_support;
FmgrInfo *rd_supportinfo;
int16 *rd_indoption;
List *rd_indexprs;
List *rd_indpred;
Oid *rd_exclops;
Oid *rd_exclprocs;
uint16 *rd_exclstrats;
Oid *rd_indcollation;
void *rd_amcache;
struct FdwRoutine *rd_fdwroutine;
Oid rd_toastoid;
struct PgStat_TableStatus *pgstat_info;
} RelationData;
获取RelationData
src/backend/utils/cache/relcache.c
RelationIdGetRelation首先从cache中查看是否已经有相应的reldexc存在,则返回。如果不存在,调用RelationBuildDesc在cache中创建一个并返回。
Relation RelationIdGetRelation(Oid relationId) {
Relation rd;
Assert(IsTransactionState());
RelationIdCacheLookup(relationId, rd);
if (RelationIsValid(rd)){
RelationIncrementReferenceCount(rd);
if (!rd->rd_isvalid){
if (rd->rd_rel->relkind == RELKIND_INDEX || rd->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
RelationReloadIndexInfo(rd);
else
RelationClearRelation(rd, true);
Assert(rd->rd_isvalid || (rd->rd_isnailed && !criticalRelcachesBuilt));
}
return rd;
}
rd = RelationBuildDesc(relationId, true);
if (RelationIsValid(rd)) RelationIncrementReferenceCount(rd);
return rd;
}



