| /*------------------------------------------------------------------------- |
| * |
| * relfilenode.h |
| * Physical access information for relations. |
| * |
| * |
| * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group |
| * Portions Copyright (c) 1994, Regents of the University of California |
| * |
| * src/include/storage/relfilenode.h |
| * |
| *------------------------------------------------------------------------- |
| */ |
| #ifndef RELFILENODE_H |
| #define RELFILENODE_H |
| |
| #include "common/relpath.h" |
| #include "storage/backendid.h" |
| |
| /* |
| * RelFileNode must provide all that we need to know to physically access |
| * a relation, with the exception of the backend ID, which can be provided |
| * separately. Note, however, that a "physical" relation is comprised of |
| * multiple files on the filesystem, as each fork is stored as a separate |
| * file, and each fork can be divided into multiple segments. See md.c. |
| * |
| * spcNode identifies the tablespace of the relation. It corresponds to |
| * pg_tablespace.oid. |
| * |
| * dbNode identifies the database of the relation. It is zero for |
| * "shared" relations (those common to all databases of a cluster). |
| * Nonzero dbNode values correspond to pg_database.oid. |
| * |
| * relNode identifies the specific relation. relNode corresponds to |
| * pg_class.relfilenode (NOT pg_class.oid, because we need to be able |
| * to assign new physical files to relations in some situations). |
| * Notice that relNode is only unique within a database in a particular |
| * tablespace. |
| * |
| * Note: spcNode must be GLOBALTABLESPACE_OID if and only if dbNode is |
| * zero. We support shared relations only in the "global" tablespace. |
| * |
| * Note: in pg_class we allow reltablespace == 0 to denote that the |
| * relation is stored in its database's "default" tablespace (as |
| * identified by pg_database.dattablespace). However this shorthand |
| * is NOT allowed in RelFileNode structs --- the real tablespace ID |
| * must be supplied when setting spcNode. |
| * |
| * Note: in pg_class, relfilenode can be zero to denote that the relation |
| * is a "mapped" relation, whose current true filenode number is available |
| * from relmapper.c. Again, this case is NOT allowed in RelFileNodes. |
| * |
| * Note: various places use RelFileNode in hashtable keys. Therefore, |
| * there *must not* be any unused padding bytes in this struct. That |
| * should be safe as long as all the fields are of type Oid. |
| */ |
| typedef struct RelFileNode |
| { |
| Oid spcNode; /* tablespace */ |
| Oid dbNode; /* database */ |
| Oid relNode; /* relation */ |
| } RelFileNode; |
| |
| /* |
| * Augmenting a relfilenode with the backend ID provides all the information |
| * we need to locate the physical storage. The backend ID is InvalidBackendId |
| * for regular relations (those accessible to more than one backend), or the |
| * owning backend's ID for backend-local relations. Backend-local relations |
| * are always transient and removed in case of a database crash; they are |
| * never WAL-logged or fsync'd. |
| */ |
| typedef struct RelFileNodeBackend |
| { |
| RelFileNode node; |
| BackendId backend; |
| } RelFileNodeBackend; |
| |
| #define RelFileNodeBackendIsTemp(rnode) \ |
| ((rnode).backend != InvalidBackendId) |
| |
| /* |
| * Note: RelFileNodeEquals and RelFileNodeBackendEquals compare relNode first |
| * since that is most likely to be different in two unequal RelFileNodes. It |
| * is probably redundant to compare spcNode if the other fields are found equal, |
| * but do it anyway to be sure. Likewise for checking the backend ID in |
| * RelFileNodeBackendEquals. |
| */ |
| #define RelFileNodeEquals(node1, node2) \ |
| ((node1).relNode == (node2).relNode && \ |
| (node1).dbNode == (node2).dbNode && \ |
| (node1).spcNode == (node2).spcNode) |
| |
| #define RelFileNodeBackendEquals(node1, node2) \ |
| ((node1).node.relNode == (node2).node.relNode && \ |
| (node1).node.dbNode == (node2).node.dbNode && \ |
| (node1).backend == (node2).backend && \ |
| (node1).node.spcNode == (node2).node.spcNode) |
| |
| inline static bool RelFileNode_IsEmpty( |
| RelFileNode *relFileNode) |
| { |
| return (relFileNode->spcNode == 0 && |
| relFileNode->dbNode == 0 && |
| relFileNode->relNode == 0); |
| } |
| |
| /* |
| * Augmenting a relfilenode with a SMGR implementation identifier provides a |
| * way to make optimal decisions in smgr and md layer. This is purposefully |
| * kept out of RelFileNode for performance concerns where RelFileNode used in |
| * a hotpath for BufferTag hashing. The isTempRelation flag is necessary to |
| * support file-system removal of temporary relations on a two-phase |
| * commit/abort. |
| */ |
| typedef struct RelFileNodePendingDelete |
| { |
| RelFileNode node; |
| int smgr_which; /* which SMGR implementation to use */ |
| bool isTempRelation; |
| } RelFileNodePendingDelete; |
| |
| #endif /* RELFILENODE_H */ |