做自己的网站怎么赚钱/长清区seo网络优化软件
RelationData是访问引擎中最重要的一个结构体,贯穿整个Relation访问的流程。const struct TableAmRoutine *rd_tableam
用于存放该表的访问函数的结构体指针,见PostgreSQL数据库TableAM——Table Access Method。struct IndexAmRoutine *rd_indam;
用于存放该表的索引访问函数的结构体指针。
/* Here are the contents of a relation cache entry. */typedef struct RelationData {RelFileNode rd_node; /* relation physical identifier *//* use "struct" here to avoid needing to include smgr.h: */struct SMgrRelationData *rd_smgr; /* cached file handle, or NULL */int rd_refcnt; /* reference count */BackendId rd_backend; /* owning backend id, if temporary relation */bool rd_islocaltemp; /* rel is a temp rel of this session */bool rd_isnailed; /* rel is nailed in cache */bool rd_isvalid; /* relcache entry is valid */bool rd_indexvalid; /* is rd_indexlist valid? (also rd_pkindex and rd_replidindex) */bool rd_statvalid; /* is rd_statlist valid? *//*----------* rd_createSubid is the ID of the highest subtransaction the rel has* survived into; or zero if the rel was not created in the current top* transaction. This can be now be relied on, whereas previously it could* be "forgotten" in earlier releases. Likewise, rd_newRelfilenodeSubid is* the ID of the highest subtransaction the relfilenode change has* survived into, or zero if not changed in the current transaction (or we* have forgotten changing it). rd_newRelfilenodeSubid can be forgotten* when a relation has multiple new relfilenodes within a single* transaction, with one of them occurring in a subsequently aborted* subtransaction, e.g.* BEGIN;* TRUNCATE t;* SAVEPOINT save;* TRUNCATE t;* ROLLBACK TO save;* -- rd_newRelfilenodeSubid is now forgotten*/SubTransactionId rd_createSubid; /* rel was created in current xact */SubTransactionId rd_newRelfilenodeSubid; /* new relfilenode assigned in current xact */Form_pg_class rd_rel; /* RELATION tuple */TupleDesc rd_att; /* tuple descriptor */Oid rd_id; /* relation's object id */LockInfoData rd_lockInfo; /* lock mgr's info for locking relation */RuleLock *rd_rules; /* rewrite rules */MemoryContext rd_rulescxt; /* private memory cxt for rd_rules, if any */TriggerDesc *trigdesc; /* Trigger info, or NULL if rel has none *//* use "struct" here to avoid needing to include rowsecurity.h: */struct RowSecurityDesc *rd_rsdesc; /* row security policies, or NULL *//* data managed by RelationGetFKeyList: */List *rd_fkeylist; /* list of ForeignKeyCacheInfo (see below) */bool rd_fkeyvalid; /* true if list has been computed */struct PartitionKeyData *rd_partkey; /* partition key, or NULL */MemoryContext rd_partkeycxt; /* private context for rd_partkey, if any */struct PartitionDescData *rd_partdesc; /* partitions, or NULL */MemoryContext rd_pdcxt; /* private context for rd_partdesc, if any */List *rd_partcheck; /* partition CHECK quals */bool rd_partcheckvalid; /* true if list has been computed */MemoryContext rd_partcheckcxt; /* private cxt for rd_partcheck, if any *//* data managed by RelationGetIndexList: */List *rd_indexlist; /* list of OIDs of indexes on relation */Oid rd_pkindex; /* OID of primary key, if any */Oid rd_replidindex; /* OID of replica identity index, if any *//* data managed by RelationGetStatExtList: */List *rd_statlist; /* list of OIDs of extended stats *//* data managed by RelationGetIndexAttrBitmap: */Bitmapset *rd_indexattr; /* identifies columns used in indexes */Bitmapset *rd_keyattr; /* cols that can be ref'd by foreign keys */Bitmapset *rd_pkattr; /* cols included in primary key */Bitmapset *rd_idattr; /* included in replica identity index */PublicationActions *rd_pubactions; /* publication actions *//* rd_options is set whenever rd_rel is loaded into the relcache entry.* Note that you can NOT look into rd_rel for this data. NULL means "use* defaults". */bytea *rd_options; /* parsed pg_class.reloptions *//* Oid of the handler for this relation. For an index this is a function* returning IndexAmRoutine, for table like relations a function returning* TableAmRoutine. This is stored separately from rd_indam, rd_tableam as* its lookup requires syscache access, but during relcache bootstrap we* need to be able to initialize rd_tableam without syscache lookups. */Oid rd_amhandler; /* OID of index AM's handler function *//* Table access method. */const struct TableAmRoutine *rd_tableam;/* These are non-NULL only for an index relation: */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 *//* index access support info (used only for an index relation)** Note: only default support procs for each opclass are cached, namely* those with lefttype and righttype equal to the opclass's opcintype. The* arrays are indexed by support function number, which is a sufficient* identifier given that restriction. */MemoryContext rd_indexcxt; /* private memory cxt for this stuff *//* use "struct" here to avoid needing to include amapi.h: */struct IndexAmRoutine *rd_indam; /* index AM's API struct */Oid *rd_opfamily; /* OIDs of op families for each index col */Oid *rd_opcintype; /* OIDs of opclass declared input data types */RegProcedure *rd_support; /* OIDs of support procedures */FmgrInfo *rd_supportinfo; /* lookup info for support procedures */int16 *rd_indoption; /* per-column AM-specific flags */List *rd_indexprs; /* index expression trees, if any */List *rd_indpred; /* index predicate tree, if any */Oid *rd_exclops; /* OIDs of exclusion operators, if any */Oid *rd_exclprocs; /* OIDs of exclusion ops' procs, if any */uint16 *rd_exclstrats; /* exclusion ops' strategy numbers, if any */Oid *rd_indcollation; /* OIDs of index collations *//* rd_amcache is available for index and table AMs to cache private data* about the relation. This must be just a cache since it may get reset* at any time (in particular, it will get reset by a relcache inval* message for the relation). If used, it must point to a single memory* chunk palloc'd in CacheMemoryContext, or in rd_indexcxt for an index* relation. A relcache reset will include freeing that chunk and setting* rd_amcache = NULL. */void *rd_amcache; /* available for use by index/table AM *//* foreign-table support* rd_fdwroutine must point to a single memory chunk palloc'd in* CacheMemoryContext. It will be freed and reset to NULL on a relcache* reset. *//* use "struct" here to avoid needing to include fdwapi.h: */struct FdwRoutine *rd_fdwroutine; /* cached function pointers, or NULL *//** Hack for CLUSTER, rewriting ALTER TABLE, etc: when writing a new* version of a table, we need to make any toast pointers inserted into it* have the existing toast table's OID, not the OID of the transient toast* table. If rd_toastoid isn't InvalidOid, it is the OID to place in* toast pointers inserted into this rel. (Note it's set on the new* version of the main heap, not the toast table itself.) This also* causes toast_save_datum() to try to preserve toast value OIDs.*/Oid rd_toastoid; /* Real TOAST table's OID, or InvalidOid *//* use "struct" here to avoid needing to include pgstat.h: */struct PgStat_TableStatus *pgstat_info; /* statistics collection area */
} RelationData;
获取RelationData
src/backend/utils/cache/relcache.c
RelationIdGetRelation首先从cache中查看是否已经有相应的reldexc存在,则返回。如果不存在,调用RelationBuildDesc在cache中创建一个并返回。
Relation RelationIdGetRelation(Oid relationId) {Relation rd;/* Make sure we're in an xact, even if this ends up being a cache hit */Assert(IsTransactionState());/* first try to find reldesc in the cache */RelationIdCacheLookup(relationId, rd);if (RelationIsValid(rd)){RelationIncrementReferenceCount(rd);/* revalidate cache entry if necessary */if (!rd->rd_isvalid){/* Indexes only have a limited number of possible schema changes,* and we don't want to use the full-blown procedure because it's* a headache for indexes that reload itself depends on. */if (rd->rd_rel->relkind == RELKIND_INDEX || rd->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)RelationReloadIndexInfo(rd);elseRelationClearRelation(rd, true);/* Normally entries need to be valid here, but before the relcache* has been initialized, not enough infrastructure exists to* perform pg_class lookups. The structure of such entries doesn't* change, but we still want to update the rd_rel entry. So* rd_isvalid = false is left in place for a later lookup. */Assert(rd->rd_isvalid || (rd->rd_isnailed && !criticalRelcachesBuilt));}return rd;}/* no reldesc in the cache, so have RelationBuildDesc() build one and add it. */rd = RelationBuildDesc(relationId, true);if (RelationIsValid(rd)) RelationIncrementReferenceCount(rd);return rd;
}