/*------------------------------------------------------------------------- * * relfilelocator.h * Physical access information for relations. * * * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/relfilelocator.h * *------------------------------------------------------------------------- */ #ifndef RELFILELOCATOR_H #define RELFILELOCATOR_H #include "common/relpath.h" #include "storage/backendid.h" /* * RelFileLocator 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. * * spcOid identifies the tablespace of the relation. It corresponds to * pg_tablespace.oid. * * dbOid identifies the database of the relation. It is zero for * "shared" relations (those common to all databases of a cluster). * Nonzero dbOid values correspond to pg_database.oid. * * relNumber identifies the specific relation. relNumber 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 relNumber is only unique within a database in a particular * tablespace. * * Note: spcOid must be GLOBALTABLESPACE_OID if and only if dbOid 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 RelFileLocator structs --- the real tablespace ID * must be supplied when setting spcOid. * * 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 RelFileLocators. * * Note: various places use RelFileLocator 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 RelFileLocator { Oid spcOid; /* tablespace */ Oid dbOid; /* database */ RelFileNumber relNumber; /* relation */ } RelFileLocator; /* * Augmenting a relfilelocator 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 RelFileLocatorBackend { RelFileLocator locator; BackendId backend; } RelFileLocatorBackend; #define RelFileLocatorBackendIsTemp(rlocator) \ ((rlocator).backend != InvalidBackendId) /* * Note: RelFileLocatorEquals and RelFileLocatorBackendEquals compare relNumber * first since that is most likely to be different in two unequal * RelFileLocators. It is probably redundant to compare spcOid if the other * fields are found equal, but do it anyway to be sure. Likewise for checking * the backend ID in RelFileLocatorBackendEquals. */ #define RelFileLocatorEquals(locator1, locator2) \ ((locator1).relNumber == (locator2).relNumber && \ (locator1).dbOid == (locator2).dbOid && \ (locator1).spcOid == (locator2).spcOid) #define RelFileLocatorBackendEquals(locator1, locator2) \ ((locator1).locator.relNumber == (locator2).locator.relNumber && \ (locator1).locator.dbOid == (locator2).locator.dbOid && \ (locator1).backend == (locator2).backend && \ (locator1).locator.spcOid == (locator2).locator.spcOid) #endif /* RELFILELOCATOR_H */