LCOV - code coverage report
Current view: top level - src/include/utils - rel.h (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 100.0 % 11 11
Test Date: 2026-07-23 23:15:35 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 100.0 % 4 4

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * rel.h
       4                 :             :  *    POSTGRES relation descriptor (a/k/a relcache entry) definitions.
       5                 :             :  *
       6                 :             :  *
       7                 :             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       8                 :             :  * Portions Copyright (c) 1994, Regents of the University of California
       9                 :             :  *
      10                 :             :  * src/include/utils/rel.h
      11                 :             :  *
      12                 :             :  *-------------------------------------------------------------------------
      13                 :             :  */
      14                 :             : #ifndef REL_H
      15                 :             : #define REL_H
      16                 :             : 
      17                 :             : #include "access/tupdesc.h"
      18                 :             : #include "access/xlog.h"
      19                 :             : #include "catalog/catalog.h"
      20                 :             : #include "catalog/pg_class.h"
      21                 :             : #include "catalog/pg_index.h"
      22                 :             : #include "catalog/pg_publication.h"
      23                 :             : #include "nodes/bitmapset.h"
      24                 :             : #include "partitioning/partdefs.h"
      25                 :             : #include "rewrite/prs2lock.h"
      26                 :             : #include "storage/block.h"
      27                 :             : #include "storage/relfilelocator.h"
      28                 :             : #include "storage/smgr.h"
      29                 :             : #include "utils/relcache.h"
      30                 :             : #include "utils/reltrigger.h"
      31                 :             : 
      32                 :             : 
      33                 :             : /*
      34                 :             :  * LockRelId and LockInfo really belong to lmgr.h, but it's more convenient
      35                 :             :  * to declare them here so we can have a LockInfoData field in a Relation.
      36                 :             :  */
      37                 :             : 
      38                 :             : typedef struct LockRelId
      39                 :             : {
      40                 :             :     Oid         relId;          /* a relation identifier */
      41                 :             :     Oid         dbId;           /* a database identifier */
      42                 :             : } LockRelId;
      43                 :             : 
      44                 :             : typedef struct LockInfoData
      45                 :             : {
      46                 :             :     LockRelId   lockRelId;
      47                 :             : } LockInfoData;
      48                 :             : 
      49                 :             : typedef LockInfoData *LockInfo;
      50                 :             : 
      51                 :             : /*
      52                 :             :  * Here are the contents of a relation cache entry.
      53                 :             :  */
      54                 :             : 
      55                 :             : typedef struct RelationData
      56                 :             : {
      57                 :             :     RelFileLocator rd_locator;  /* relation physical identifier */
      58                 :             :     SMgrRelation rd_smgr;       /* cached file handle, or NULL */
      59                 :             :     int         rd_refcnt;      /* reference count */
      60                 :             :     ProcNumber  rd_backend;     /* owning backend's proc number, if temp rel */
      61                 :             :     bool        rd_islocaltemp; /* rel is a temp rel of this session */
      62                 :             :     bool        rd_isnailed;    /* rel is nailed in cache */
      63                 :             :     bool        rd_isvalid;     /* relcache entry is valid */
      64                 :             :     bool        rd_indexvalid;  /* is rd_indexlist valid? (also rd_pkindex and
      65                 :             :                                  * rd_replidindex) */
      66                 :             :     bool        rd_statvalid;   /* is rd_statlist valid? */
      67                 :             : 
      68                 :             :     /*----------
      69                 :             :      * rd_createSubid is the ID of the highest subtransaction the rel has
      70                 :             :      * survived into or zero if the rel or its storage was created before the
      71                 :             :      * current top transaction.  (IndexStmt.oldNumber leads to the case of a new
      72                 :             :      * rel with an old rd_locator.)  rd_firstRelfilelocatorSubid is the ID of the
      73                 :             :      * highest subtransaction an rd_locator change has survived into or zero if
      74                 :             :      * rd_locator matches the value it had at the start of the current top
      75                 :             :      * transaction.  (Rolling back the subtransaction that
      76                 :             :      * rd_firstRelfilelocatorSubid denotes would restore rd_locator to the value it
      77                 :             :      * had at the start of the current top transaction.  Rolling back any
      78                 :             :      * lower subtransaction would not.)  Their accuracy is critical to
      79                 :             :      * RelationNeedsWAL().
      80                 :             :      *
      81                 :             :      * rd_newRelfilelocatorSubid is the ID of the highest subtransaction the
      82                 :             :      * most-recent relfilenumber change has survived into or zero if not changed
      83                 :             :      * in the current transaction (or we have forgotten changing it).  This
      84                 :             :      * field is accurate when non-zero, but it can be zero when a relation has
      85                 :             :      * multiple new relfilenumbers within a single transaction, with one of them
      86                 :             :      * occurring in a subsequently aborted subtransaction, e.g.
      87                 :             :      *      BEGIN;
      88                 :             :      *      TRUNCATE t;
      89                 :             :      *      SAVEPOINT save;
      90                 :             :      *      TRUNCATE t;
      91                 :             :      *      ROLLBACK TO save;
      92                 :             :      *      -- rd_newRelfilelocatorSubid is now forgotten
      93                 :             :      *
      94                 :             :      * If every rd_*Subid field is zero, they are read-only outside
      95                 :             :      * relcache.c.  Files that trigger rd_locator changes by updating
      96                 :             :      * pg_class.reltablespace and/or pg_class.relfilenode call
      97                 :             :      * RelationAssumeNewRelfilelocator() to update rd_*Subid.
      98                 :             :      *
      99                 :             :      * rd_droppedSubid is the ID of the highest subtransaction that a drop of
     100                 :             :      * the rel has survived into.  In entries visible outside relcache.c, this
     101                 :             :      * is always zero.
     102                 :             :      */
     103                 :             :     SubTransactionId rd_createSubid;    /* rel was created in current xact */
     104                 :             :     SubTransactionId rd_newRelfilelocatorSubid; /* highest subxact changing
     105                 :             :                                                  * rd_locator to current value */
     106                 :             :     SubTransactionId rd_firstRelfilelocatorSubid;   /* highest subxact
     107                 :             :                                                      * changing rd_locator to
     108                 :             :                                                      * any value */
     109                 :             :     SubTransactionId rd_droppedSubid;   /* dropped with another Subid set */
     110                 :             : 
     111                 :             :     Form_pg_class rd_rel;       /* RELATION tuple */
     112                 :             :     TupleDesc   rd_att;         /* tuple descriptor */
     113                 :             :     Oid         rd_id;          /* relation's object id */
     114                 :             :     LockInfoData rd_lockInfo;   /* lock mgr's info for locking relation */
     115                 :             :     RuleLock   *rd_rules;       /* rewrite rules */
     116                 :             :     MemoryContext rd_rulescxt;  /* private memory cxt for rd_rules, if any */
     117                 :             :     TriggerDesc *trigdesc;      /* Trigger info, or NULL if rel has none */
     118                 :             :     /* use "struct" here to avoid needing to include rowsecurity.h: */
     119                 :             :     struct RowSecurityDesc *rd_rsdesc;  /* row security policies, or NULL */
     120                 :             : 
     121                 :             :     /* data managed by RelationGetFKeyList: */
     122                 :             :     List       *rd_fkeylist;    /* list of ForeignKeyCacheInfo (see below) */
     123                 :             :     bool        rd_fkeyvalid;   /* true if list has been computed */
     124                 :             : 
     125                 :             :     /* data managed by RelationGetPartitionKey: */
     126                 :             :     PartitionKey rd_partkey;    /* partition key, or NULL */
     127                 :             :     MemoryContext rd_partkeycxt;    /* private context for rd_partkey, if any */
     128                 :             : 
     129                 :             :     /* data managed by RelationGetPartitionDesc: */
     130                 :             :     PartitionDesc rd_partdesc;  /* partition descriptor, or NULL */
     131                 :             :     MemoryContext rd_pdcxt;     /* private context for rd_partdesc, if any */
     132                 :             : 
     133                 :             :     /* Same as above, for partdescs that omit detached partitions */
     134                 :             :     PartitionDesc rd_partdesc_nodetached;   /* partdesc w/o detached parts */
     135                 :             :     MemoryContext rd_pddcxt;    /* for rd_partdesc_nodetached, if any */
     136                 :             : 
     137                 :             :     /*
     138                 :             :      * pg_inherits.xmin of the partition that was excluded in
     139                 :             :      * rd_partdesc_nodetached.  This informs a future user of that partdesc:
     140                 :             :      * if this value is not in progress for the active snapshot, then the
     141                 :             :      * partdesc can be used, otherwise they have to build a new one.  (This
     142                 :             :      * matches what find_inheritance_children_extended would do).
     143                 :             :      */
     144                 :             :     TransactionId rd_partdesc_nodetached_xmin;
     145                 :             : 
     146                 :             :     /* data managed by RelationGetPartitionQual: */
     147                 :             :     List       *rd_partcheck;   /* partition CHECK quals */
     148                 :             :     bool        rd_partcheckvalid;  /* true if list has been computed */
     149                 :             :     MemoryContext rd_partcheckcxt;  /* private cxt for rd_partcheck, if any */
     150                 :             : 
     151                 :             :     /* data managed by RelationGetIndexList: */
     152                 :             :     List       *rd_indexlist;   /* list of OIDs of indexes on relation */
     153                 :             :     Oid         rd_pkindex;     /* OID of (deferrable?) primary key, if any */
     154                 :             :     bool        rd_ispkdeferrable;  /* is rd_pkindex a deferrable PK? */
     155                 :             :     Oid         rd_replidindex; /* OID of replica identity index, if any */
     156                 :             : 
     157                 :             :     /* data managed by RelationGetStatExtList: */
     158                 :             :     List       *rd_statlist;    /* list of OIDs of extended stats */
     159                 :             : 
     160                 :             :     /* data managed by RelationGetIndexAttrBitmap: */
     161                 :             :     bool        rd_attrsvalid;  /* are bitmaps of attrs valid? */
     162                 :             :     Bitmapset  *rd_keyattr;     /* cols that can be ref'd by foreign keys */
     163                 :             :     Bitmapset  *rd_pkattr;      /* cols included in primary key */
     164                 :             :     Bitmapset  *rd_idattr;      /* included in replica identity index */
     165                 :             :     Bitmapset  *rd_hotblockingattr; /* cols blocking HOT update */
     166                 :             :     Bitmapset  *rd_summarizedattr;  /* cols indexed by summarizing indexes */
     167                 :             : 
     168                 :             :     PublicationDesc *rd_pubdesc;    /* publication descriptor, or NULL */
     169                 :             : 
     170                 :             :     /*
     171                 :             :      * rd_options is set whenever rd_rel is loaded into the relcache entry.
     172                 :             :      * Note that you can NOT look into rd_rel for this data.  NULL means "use
     173                 :             :      * defaults".
     174                 :             :      */
     175                 :             :     bytea      *rd_options;     /* parsed pg_class.reloptions */
     176                 :             : 
     177                 :             :     /*
     178                 :             :      * Oid of the handler for this relation. For an index this is a function
     179                 :             :      * returning IndexAmRoutine, for table like relations a function returning
     180                 :             :      * TableAmRoutine.  This is stored separately from rd_indam, rd_tableam as
     181                 :             :      * its lookup requires syscache access, but during relcache bootstrap we
     182                 :             :      * need to be able to initialize rd_tableam without syscache lookups.
     183                 :             :      */
     184                 :             :     Oid         rd_amhandler;   /* OID of index AM's handler function */
     185                 :             : 
     186                 :             :     /*
     187                 :             :      * Table access method.
     188                 :             :      */
     189                 :             :     const struct TableAmRoutine *rd_tableam;
     190                 :             : 
     191                 :             :     /* These are non-NULL only for an index relation: */
     192                 :             :     Form_pg_index rd_index;     /* pg_index tuple describing this index */
     193                 :             :     /* use "struct" here to avoid needing to include htup.h: */
     194                 :             :     struct HeapTupleData *rd_indextuple;    /* all of pg_index tuple */
     195                 :             : 
     196                 :             :     /*
     197                 :             :      * index access support info (used only for an index relation)
     198                 :             :      *
     199                 :             :      * Note: only default support procs for each opclass are cached, namely
     200                 :             :      * those with lefttype and righttype equal to the opclass's opcintype. The
     201                 :             :      * arrays are indexed by support function number, which is a sufficient
     202                 :             :      * identifier given that restriction.
     203                 :             :      */
     204                 :             :     MemoryContext rd_indexcxt;  /* private memory cxt for this stuff */
     205                 :             :     /* use "struct" here to avoid needing to include amapi.h: */
     206                 :             :     const struct IndexAmRoutine *rd_indam;  /* index AM's API struct */
     207                 :             :     Oid        *rd_opfamily;    /* OIDs of op families for each index col */
     208                 :             :     Oid        *rd_opcintype;   /* OIDs of opclass declared input data types */
     209                 :             :     RegProcedure *rd_support;   /* OIDs of support procedures */
     210                 :             :     struct FmgrInfo *rd_supportinfo;    /* lookup info for support procedures */
     211                 :             :     int16      *rd_indoption;   /* per-column AM-specific flags */
     212                 :             :     List       *rd_indexprs;    /* index expression trees, if any */
     213                 :             :     List       *rd_indpred;     /* index predicate tree, if any */
     214                 :             :     Oid        *rd_exclops;     /* OIDs of exclusion operators, if any */
     215                 :             :     Oid        *rd_exclprocs;   /* OIDs of exclusion ops' procs, if any */
     216                 :             :     uint16     *rd_exclstrats;  /* exclusion ops' strategy numbers, if any */
     217                 :             :     Oid        *rd_indcollation;    /* OIDs of index collations */
     218                 :             :     bytea     **rd_opcoptions;  /* parsed opclass-specific options */
     219                 :             : 
     220                 :             :     /*
     221                 :             :      * rd_amcache is available for index and table AMs to cache private data
     222                 :             :      * about the relation.  This must be just a cache since it may get reset
     223                 :             :      * at any time (in particular, it will get reset by a relcache inval
     224                 :             :      * message for the relation).  If used, it must point to a single memory
     225                 :             :      * chunk palloc'd in CacheMemoryContext, or in rd_indexcxt for an index
     226                 :             :      * relation.  A relcache reset will include freeing that chunk and setting
     227                 :             :      * rd_amcache = NULL.
     228                 :             :      */
     229                 :             :     void       *rd_amcache;     /* available for use by index/table AM */
     230                 :             : 
     231                 :             :     /*
     232                 :             :      * foreign-table support
     233                 :             :      *
     234                 :             :      * rd_fdwroutine must point to a single memory chunk palloc'd in
     235                 :             :      * CacheMemoryContext.  It will be freed and reset to NULL on a relcache
     236                 :             :      * reset.
     237                 :             :      */
     238                 :             : 
     239                 :             :     /* use "struct" here to avoid needing to include fdwapi.h: */
     240                 :             :     struct FdwRoutine *rd_fdwroutine;   /* cached function pointers, or NULL */
     241                 :             : 
     242                 :             :     /*
     243                 :             :      * Hack for CLUSTER, rewriting ALTER TABLE, etc: when writing a new
     244                 :             :      * version of a table, we need to make any toast pointers inserted into it
     245                 :             :      * have the existing toast table's OID, not the OID of the transient toast
     246                 :             :      * table.  If rd_toastoid isn't InvalidOid, it is the OID to place in
     247                 :             :      * toast pointers inserted into this rel.  (Note it's set on the new
     248                 :             :      * version of the main heap, not the toast table itself.)  This also
     249                 :             :      * causes toast_save_datum() to try to preserve toast value OIDs.
     250                 :             :      */
     251                 :             :     Oid         rd_toastoid;    /* Real TOAST table's OID, or InvalidOid */
     252                 :             : 
     253                 :             :     bool        pgstat_enabled; /* should relation stats be counted */
     254                 :             :     /* use "struct" here to avoid needing to include pgstat.h: */
     255                 :             :     struct PgStat_TableStatus *pgstat_info; /* statistics collection area */
     256                 :             : } RelationData;
     257                 :             : 
     258                 :             : 
     259                 :             : /*
     260                 :             :  * ForeignKeyCacheInfo
     261                 :             :  *      Information the relcache can cache about foreign key constraints
     262                 :             :  *
     263                 :             :  * This is basically just an image of relevant columns from pg_constraint.
     264                 :             :  * We make it a subclass of Node so that copyObject() can be used on a list
     265                 :             :  * of these, but we also ensure it is a "flat" object without substructure,
     266                 :             :  * so that list_free_deep() is sufficient to free such a list.
     267                 :             :  * The per-FK-column arrays can be fixed-size because we allow at most
     268                 :             :  * INDEX_MAX_KEYS columns in a foreign key constraint.
     269                 :             :  *
     270                 :             :  * Currently, we mostly cache fields of interest to the planner, but the set
     271                 :             :  * of fields has already grown the constraint OID for other uses.
     272                 :             :  */
     273                 :             : typedef struct ForeignKeyCacheInfo
     274                 :             : {
     275                 :             :     pg_node_attr(no_equal, no_read, no_query_jumble)
     276                 :             : 
     277                 :             :     NodeTag     type;
     278                 :             :     /* oid of the constraint itself */
     279                 :             :     Oid         conoid;
     280                 :             :     /* relation constrained by the foreign key */
     281                 :             :     Oid         conrelid;
     282                 :             :     /* relation referenced by the foreign key */
     283                 :             :     Oid         confrelid;
     284                 :             :     /* number of columns in the foreign key */
     285                 :             :     int         nkeys;
     286                 :             : 
     287                 :             :     /* Is enforced ? */
     288                 :             :     bool        conenforced;
     289                 :             : 
     290                 :             :     /*
     291                 :             :      * these arrays each have nkeys valid entries:
     292                 :             :      */
     293                 :             :     /* cols in referencing table */
     294                 :             :     AttrNumber  conkey[INDEX_MAX_KEYS] pg_node_attr(array_size(nkeys));
     295                 :             :     /* cols in referenced table */
     296                 :             :     AttrNumber  confkey[INDEX_MAX_KEYS] pg_node_attr(array_size(nkeys));
     297                 :             :     /* PK = FK operator OIDs */
     298                 :             :     Oid         conpfeqop[INDEX_MAX_KEYS] pg_node_attr(array_size(nkeys));
     299                 :             : } ForeignKeyCacheInfo;
     300                 :             : 
     301                 :             : 
     302                 :             : /*
     303                 :             :  * StdRdOptions
     304                 :             :  *      Standard contents of rd_options for heaps.
     305                 :             :  *
     306                 :             :  * RelationGetFillFactor() and RelationGetTargetPageFreeSpace() can only
     307                 :             :  * be applied to relations that use this format or a superset for
     308                 :             :  * private options data.
     309                 :             :  */
     310                 :             :  /* autovacuum-related reloptions. */
     311                 :             : typedef struct AutoVacOpts
     312                 :             : {
     313                 :             :     bool        enabled;
     314                 :             : 
     315                 :             :     int         autovacuum_parallel_workers;
     316                 :             :     int         vacuum_threshold;
     317                 :             :     int         vacuum_max_threshold;
     318                 :             :     int         vacuum_ins_threshold;
     319                 :             :     int         analyze_threshold;
     320                 :             :     int         vacuum_cost_limit;
     321                 :             :     int         freeze_min_age;
     322                 :             :     int         freeze_max_age;
     323                 :             :     int         freeze_table_age;
     324                 :             :     int         multixact_freeze_min_age;
     325                 :             :     int         multixact_freeze_max_age;
     326                 :             :     int         multixact_freeze_table_age;
     327                 :             :     int         log_vacuum_min_duration;
     328                 :             :     int         log_analyze_min_duration;
     329                 :             :     float8      vacuum_cost_delay;
     330                 :             :     float8      vacuum_scale_factor;
     331                 :             :     float8      vacuum_ins_scale_factor;
     332                 :             :     float8      analyze_scale_factor;
     333                 :             : } AutoVacOpts;
     334                 :             : 
     335                 :             : /* StdRdOptions->vacuum_index_cleanup values */
     336                 :             : typedef enum StdRdOptIndexCleanup
     337                 :             : {
     338                 :             :     STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO = 0,
     339                 :             :     STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF,
     340                 :             :     STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON,
     341                 :             : } StdRdOptIndexCleanup;
     342                 :             : 
     343                 :             : typedef struct StdRdOptions
     344                 :             : {
     345                 :             :     int32       vl_len_;        /* varlena header (do not touch directly!) */
     346                 :             :     int         fillfactor;     /* page fill factor in percent (0..100) */
     347                 :             :     int         toast_tuple_target; /* target for tuple toasting */
     348                 :             :     AutoVacOpts autovacuum;     /* autovacuum-related options */
     349                 :             :     bool        user_catalog_table; /* use as an additional catalog relation */
     350                 :             :     int         parallel_workers;   /* max number of parallel workers */
     351                 :             :     StdRdOptIndexCleanup vacuum_index_cleanup;  /* controls index vacuuming */
     352                 :             :     pg_ternary  vacuum_truncate;    /* enables vacuum to truncate a relation */
     353                 :             : 
     354                 :             :     /*
     355                 :             :      * Fraction of pages in a relation that vacuum can eagerly scan and fail
     356                 :             :      * to freeze. 0 if disabled, -1 if unspecified.
     357                 :             :      */
     358                 :             :     double      vacuum_max_eager_freeze_failure_rate;
     359                 :             : } StdRdOptions;
     360                 :             : 
     361                 :             : #define HEAP_MIN_FILLFACTOR         10
     362                 :             : #define HEAP_DEFAULT_FILLFACTOR     100
     363                 :             : 
     364                 :             : /*
     365                 :             :  * RelationGetToastTupleTarget
     366                 :             :  *      Returns the relation's toast_tuple_target.  Note multiple eval of argument!
     367                 :             :  */
     368                 :             : #define RelationGetToastTupleTarget(relation, defaulttarg) \
     369                 :             :     ((relation)->rd_options ? \
     370                 :             :      ((StdRdOptions *) (relation)->rd_options)->toast_tuple_target : (defaulttarg))
     371                 :             : 
     372                 :             : /*
     373                 :             :  * RelationGetFillFactor
     374                 :             :  *      Returns the relation's fillfactor.  Note multiple eval of argument!
     375                 :             :  */
     376                 :             : #define RelationGetFillFactor(relation, defaultff) \
     377                 :             :     ((relation)->rd_options ? \
     378                 :             :      ((StdRdOptions *) (relation)->rd_options)->fillfactor : (defaultff))
     379                 :             : 
     380                 :             : /*
     381                 :             :  * RelationGetTargetPageUsage
     382                 :             :  *      Returns the relation's desired space usage per page in bytes.
     383                 :             :  */
     384                 :             : #define RelationGetTargetPageUsage(relation, defaultff) \
     385                 :             :     (BLCKSZ * RelationGetFillFactor(relation, defaultff) / 100)
     386                 :             : 
     387                 :             : /*
     388                 :             :  * RelationGetTargetPageFreeSpace
     389                 :             :  *      Returns the relation's desired freespace per page in bytes.
     390                 :             :  */
     391                 :             : #define RelationGetTargetPageFreeSpace(relation, defaultff) \
     392                 :             :     (BLCKSZ * (100 - RelationGetFillFactor(relation, defaultff)) / 100)
     393                 :             : 
     394                 :             : /*
     395                 :             :  * RelationIsUsedAsCatalogTable
     396                 :             :  *      Returns whether the relation should be treated as a catalog table
     397                 :             :  *      from the pov of logical decoding.  Note multiple eval of argument!
     398                 :             :  */
     399                 :             : #define RelationIsUsedAsCatalogTable(relation)  \
     400                 :             :     ((relation)->rd_options && \
     401                 :             :      ((relation)->rd_rel->relkind == RELKIND_RELATION || \
     402                 :             :       (relation)->rd_rel->relkind == RELKIND_MATVIEW) ? \
     403                 :             :      ((StdRdOptions *) (relation)->rd_options)->user_catalog_table : false)
     404                 :             : 
     405                 :             : /*
     406                 :             :  * RelationGetParallelWorkers
     407                 :             :  *      Returns the relation's parallel_workers reloption setting.
     408                 :             :  *      Note multiple eval of argument!
     409                 :             :  */
     410                 :             : #define RelationGetParallelWorkers(relation, defaultpw) \
     411                 :             :     ((relation)->rd_options ? \
     412                 :             :      ((StdRdOptions *) (relation)->rd_options)->parallel_workers : (defaultpw))
     413                 :             : 
     414                 :             : /* ViewOptions->check_option values */
     415                 :             : typedef enum ViewOptCheckOption
     416                 :             : {
     417                 :             :     VIEW_OPTION_CHECK_OPTION_NOT_SET,
     418                 :             :     VIEW_OPTION_CHECK_OPTION_LOCAL,
     419                 :             :     VIEW_OPTION_CHECK_OPTION_CASCADED,
     420                 :             : } ViewOptCheckOption;
     421                 :             : 
     422                 :             : /*
     423                 :             :  * ViewOptions
     424                 :             :  *      Contents of rd_options for views
     425                 :             :  */
     426                 :             : typedef struct ViewOptions
     427                 :             : {
     428                 :             :     int32       vl_len_;        /* varlena header (do not touch directly!) */
     429                 :             :     bool        security_barrier;
     430                 :             :     bool        security_invoker;
     431                 :             :     ViewOptCheckOption check_option;
     432                 :             : } ViewOptions;
     433                 :             : 
     434                 :             : /*
     435                 :             :  * RelationIsSecurityView
     436                 :             :  *      Returns whether the relation is security view, or not.  Note multiple
     437                 :             :  *      eval of argument!
     438                 :             :  */
     439                 :             : #define RelationIsSecurityView(relation)                                    \
     440                 :             :     (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW),              \
     441                 :             :      (relation)->rd_options ?                                                \
     442                 :             :       ((ViewOptions *) (relation)->rd_options)->security_barrier : false)
     443                 :             : 
     444                 :             : /*
     445                 :             :  * RelationHasSecurityInvoker
     446                 :             :  *      Returns true if the relation has the security_invoker property set.
     447                 :             :  *      Note multiple eval of argument!
     448                 :             :  */
     449                 :             : #define RelationHasSecurityInvoker(relation)                                \
     450                 :             :     (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW),              \
     451                 :             :      (relation)->rd_options ?                                                \
     452                 :             :       ((ViewOptions *) (relation)->rd_options)->security_invoker : false)
     453                 :             : 
     454                 :             : /*
     455                 :             :  * RelationHasCheckOption
     456                 :             :  *      Returns true if the relation is a view defined with either the local
     457                 :             :  *      or the cascaded check option.  Note multiple eval of argument!
     458                 :             :  */
     459                 :             : #define RelationHasCheckOption(relation)                                    \
     460                 :             :     (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW),              \
     461                 :             :      (relation)->rd_options &&                                               \
     462                 :             :      ((ViewOptions *) (relation)->rd_options)->check_option !=                \
     463                 :             :      VIEW_OPTION_CHECK_OPTION_NOT_SET)
     464                 :             : 
     465                 :             : /*
     466                 :             :  * RelationHasLocalCheckOption
     467                 :             :  *      Returns true if the relation is a view defined with the local check
     468                 :             :  *      option.  Note multiple eval of argument!
     469                 :             :  */
     470                 :             : #define RelationHasLocalCheckOption(relation)                               \
     471                 :             :     (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW),              \
     472                 :             :      (relation)->rd_options &&                                               \
     473                 :             :      ((ViewOptions *) (relation)->rd_options)->check_option ==                \
     474                 :             :      VIEW_OPTION_CHECK_OPTION_LOCAL)
     475                 :             : 
     476                 :             : /*
     477                 :             :  * RelationHasCascadedCheckOption
     478                 :             :  *      Returns true if the relation is a view defined with the cascaded check
     479                 :             :  *      option.  Note multiple eval of argument!
     480                 :             :  */
     481                 :             : #define RelationHasCascadedCheckOption(relation)                            \
     482                 :             :     (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW),              \
     483                 :             :      (relation)->rd_options &&                                               \
     484                 :             :      ((ViewOptions *) (relation)->rd_options)->check_option ==                \
     485                 :             :       VIEW_OPTION_CHECK_OPTION_CASCADED)
     486                 :             : 
     487                 :             : /*
     488                 :             :  * RelationIsValid
     489                 :             :  *      True iff relation descriptor is valid.
     490                 :             :  */
     491                 :             : #define RelationIsValid(relation) ((relation) != NULL)
     492                 :             : 
     493                 :             : /*
     494                 :             :  * RelationHasReferenceCountZero
     495                 :             :  *      True iff relation reference count is zero.
     496                 :             :  *
     497                 :             :  * Note:
     498                 :             :  *      Assumes relation descriptor is valid.
     499                 :             :  */
     500                 :             : #define RelationHasReferenceCountZero(relation) \
     501                 :             :         ((bool)((relation)->rd_refcnt == 0))
     502                 :             : 
     503                 :             : /*
     504                 :             :  * RelationGetForm
     505                 :             :  *      Returns pg_class tuple for a relation.
     506                 :             :  *
     507                 :             :  * Note:
     508                 :             :  *      Assumes relation descriptor is valid.
     509                 :             :  */
     510                 :             : #define RelationGetForm(relation) ((relation)->rd_rel)
     511                 :             : 
     512                 :             : /*
     513                 :             :  * RelationGetRelid
     514                 :             :  *      Returns the OID of the relation
     515                 :             :  */
     516                 :             : #define RelationGetRelid(relation) ((relation)->rd_id)
     517                 :             : 
     518                 :             : /*
     519                 :             :  * RelationGetNumberOfAttributes
     520                 :             :  *      Returns the total number of attributes in a relation.
     521                 :             :  */
     522                 :             : #define RelationGetNumberOfAttributes(relation) ((relation)->rd_rel->relnatts)
     523                 :             : 
     524                 :             : /*
     525                 :             :  * IndexRelationGetNumberOfAttributes
     526                 :             :  *      Returns the number of attributes in an index.
     527                 :             :  */
     528                 :             : #define IndexRelationGetNumberOfAttributes(relation) \
     529                 :             :         ((relation)->rd_index->indnatts)
     530                 :             : 
     531                 :             : /*
     532                 :             :  * IndexRelationGetNumberOfKeyAttributes
     533                 :             :  *      Returns the number of key attributes in an index.
     534                 :             :  */
     535                 :             : #define IndexRelationGetNumberOfKeyAttributes(relation) \
     536                 :             :         ((relation)->rd_index->indnkeyatts)
     537                 :             : 
     538                 :             : /*
     539                 :             :  * RelationGetDescr
     540                 :             :  *      Returns tuple descriptor for a relation.
     541                 :             :  */
     542                 :             : #define RelationGetDescr(relation) ((relation)->rd_att)
     543                 :             : 
     544                 :             : /*
     545                 :             :  * RelationGetRelationName
     546                 :             :  *      Returns the rel's name.
     547                 :             :  *
     548                 :             :  * Note that the name is only unique within the containing namespace.
     549                 :             :  */
     550                 :             : #define RelationGetRelationName(relation) \
     551                 :             :     (NameStr((relation)->rd_rel->relname))
     552                 :             : 
     553                 :             : /*
     554                 :             :  * RelationGetNamespace
     555                 :             :  *      Returns the rel's namespace OID.
     556                 :             :  */
     557                 :             : #define RelationGetNamespace(relation) \
     558                 :             :     ((relation)->rd_rel->relnamespace)
     559                 :             : 
     560                 :             : /*
     561                 :             :  * RelationIsMapped
     562                 :             :  *      True if the relation uses the relfilenumber map.  Note multiple eval
     563                 :             :  *      of argument!
     564                 :             :  */
     565                 :             : #define RelationIsMapped(relation) \
     566                 :             :     (RELKIND_HAS_STORAGE((relation)->rd_rel->relkind) && \
     567                 :             :      ((relation)->rd_rel->relfilenode == InvalidRelFileNumber))
     568                 :             : 
     569                 :             : #ifndef FRONTEND
     570                 :             : /*
     571                 :             :  * RelationGetSmgr
     572                 :             :  *      Returns smgr file handle for a relation, opening it if needed.
     573                 :             :  *
     574                 :             :  * Very little code is authorized to touch rel->rd_smgr directly.  Instead
     575                 :             :  * use this function to fetch its value.
     576                 :             :  */
     577                 :             : static inline SMgrRelation
     578                 :    97930669 : RelationGetSmgr(Relation rel)
     579                 :             : {
     580         [ +  + ]:    97930669 :     if (unlikely(rel->rd_smgr == NULL))
     581                 :             :     {
     582                 :     1229673 :         rel->rd_smgr = smgropen(rel->rd_locator, rel->rd_backend);
     583                 :     1229673 :         smgrpin(rel->rd_smgr);
     584                 :             :     }
     585                 :    97930669 :     return rel->rd_smgr;
     586                 :             : }
     587                 :             : 
     588                 :             : /*
     589                 :             :  * RelationCloseSmgr
     590                 :             :  *      Close the relation at the smgr level, if not already done.
     591                 :             :  */
     592                 :             : static inline void
     593                 :     2119199 : RelationCloseSmgr(Relation relation)
     594                 :             : {
     595         [ +  + ]:     2119199 :     if (relation->rd_smgr != NULL)
     596                 :             :     {
     597                 :      286564 :         smgrunpin(relation->rd_smgr);
     598                 :      286564 :         smgrclose(relation->rd_smgr);
     599                 :      286564 :         relation->rd_smgr = NULL;
     600                 :             :     }
     601                 :     2119199 : }
     602                 :             : #endif                          /* !FRONTEND */
     603                 :             : 
     604                 :             : /*
     605                 :             :  * RelationGetTargetBlock
     606                 :             :  *      Fetch relation's current insertion target block.
     607                 :             :  *
     608                 :             :  * Returns InvalidBlockNumber if there is no current target block.  Note
     609                 :             :  * that the target block status is discarded on any smgr-level invalidation,
     610                 :             :  * so there's no need to re-open the smgr handle if it's not currently open.
     611                 :             :  */
     612                 :             : #define RelationGetTargetBlock(relation) \
     613                 :             :     ( (relation)->rd_smgr != NULL ? (relation)->rd_smgr->smgr_targblock : InvalidBlockNumber )
     614                 :             : 
     615                 :             : /*
     616                 :             :  * RelationSetTargetBlock
     617                 :             :  *      Set relation's current insertion target block.
     618                 :             :  */
     619                 :             : #define RelationSetTargetBlock(relation, targblock) \
     620                 :             :     do { \
     621                 :             :         RelationGetSmgr(relation)->smgr_targblock = (targblock); \
     622                 :             :     } while (0)
     623                 :             : 
     624                 :             : /*
     625                 :             :  * RelationIsPermanent
     626                 :             :  *      True if relation is permanent.
     627                 :             :  */
     628                 :             : #define RelationIsPermanent(relation) \
     629                 :             :     ((relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
     630                 :             : 
     631                 :             : /*
     632                 :             :  * RelationNeedsWAL
     633                 :             :  *      True if relation needs WAL.
     634                 :             :  *
     635                 :             :  * Returns false if wal_level = minimal and this relation is created or
     636                 :             :  * truncated in the current transaction.  See "Skipping WAL for New
     637                 :             :  * RelFileLocator" in src/backend/access/transam/README.
     638                 :             :  */
     639                 :             : #define RelationNeedsWAL(relation)                                      \
     640                 :             :     (RelationIsPermanent(relation) && (XLogIsNeeded() ||                \
     641                 :             :       (relation->rd_createSubid == InvalidSubTransactionId &&            \
     642                 :             :        relation->rd_firstRelfilelocatorSubid == InvalidSubTransactionId)))
     643                 :             : 
     644                 :             : /*
     645                 :             :  * RelationUsesLocalBuffers
     646                 :             :  *      True if relation's pages are stored in local buffers.
     647                 :             :  */
     648                 :             : #define RelationUsesLocalBuffers(relation) \
     649                 :             :     ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
     650                 :             : 
     651                 :             : /*
     652                 :             :  * RELATION_IS_LOCAL
     653                 :             :  *      If a rel is either temp or newly created in the current transaction,
     654                 :             :  *      it can be assumed to be accessible only to the current backend.
     655                 :             :  *      This is typically used to decide that we can skip acquiring locks.
     656                 :             :  *
     657                 :             :  * Beware of multiple eval of argument
     658                 :             :  */
     659                 :             : #define RELATION_IS_LOCAL(relation) \
     660                 :             :     ((relation)->rd_islocaltemp || \
     661                 :             :      (relation)->rd_createSubid != InvalidSubTransactionId)
     662                 :             : 
     663                 :             : /*
     664                 :             :  * RELATION_IS_OTHER_TEMP
     665                 :             :  *      Test for a temporary relation that belongs to some other session.
     666                 :             :  *
     667                 :             :  * Reading another session's temp-table data through never works right:
     668                 :             :  * the owning session keeps the data in its private local buffer pool,
     669                 :             :  * which we cannot access.  Existing buffer-manager entry points
     670                 :             :  * (ReadBuffer_common(), StartReadBuffersImpl(), read_stream_begin_impl(),
     671                 :             :  * PrefetchBuffer() and ExtendBufferedRelCommon()) already enforce this; any
     672                 :             :  * new buffer-access entry points must do the same.  Command-level code
     673                 :             :  * (TRUNCATE, ALTER TABLE, VACUUM, CLUSTER, REINDEX, ...) additionally uses
     674                 :             :  * this macro for command-specific error messages.
     675                 :             :  *
     676                 :             :  * Beware of multiple eval of argument
     677                 :             :  */
     678                 :             : #define RELATION_IS_OTHER_TEMP(relation) \
     679                 :             :     ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP && \
     680                 :             :      !(relation)->rd_islocaltemp)
     681                 :             : 
     682                 :             : 
     683                 :             : /*
     684                 :             :  * RelationIsScannable
     685                 :             :  *      Currently can only be false for a materialized view which has not been
     686                 :             :  *      populated by its query.  This is likely to get more complicated later,
     687                 :             :  *      so use a macro which looks like a function.
     688                 :             :  */
     689                 :             : #define RelationIsScannable(relation) ((relation)->rd_rel->relispopulated)
     690                 :             : 
     691                 :             : /*
     692                 :             :  * RelationIsPopulated
     693                 :             :  *      Currently, we don't physically distinguish the "populated" and
     694                 :             :  *      "scannable" properties of matviews, but that may change later.
     695                 :             :  *      Hence, use the appropriate one of these macros in code tests.
     696                 :             :  */
     697                 :             : #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
     698                 :             : 
     699                 :             : /*
     700                 :             :  * RelationIsAccessibleInLogicalDecoding
     701                 :             :  *      True if we need to log enough information to have access via
     702                 :             :  *      decoding snapshot.
     703                 :             :  */
     704                 :             : #define RelationIsAccessibleInLogicalDecoding(relation) \
     705                 :             :     (XLogLogicalInfoActive() && \
     706                 :             :      RelationNeedsWAL(relation) && \
     707                 :             :      (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
     708                 :             : 
     709                 :             : /*
     710                 :             :  * RelationIsLogicallyLogged
     711                 :             :  *      True if we need to log enough information to extract the data from the
     712                 :             :  *      WAL stream.
     713                 :             :  *
     714                 :             :  * We don't log information for unlogged tables (since they don't WAL log
     715                 :             :  * anyway), for foreign tables (since they don't WAL log, either),
     716                 :             :  * and for system tables (their content is hard to make sense of, and
     717                 :             :  * it would complicate decoding slightly for little gain). Note that we *do*
     718                 :             :  * log information for user defined catalog tables since they presumably are
     719                 :             :  * interesting to the user...
     720                 :             :  */
     721                 :             : #define RelationIsLogicallyLogged(relation) \
     722                 :             :     (XLogLogicalInfoActive() && \
     723                 :             :      RelationNeedsWAL(relation) && \
     724                 :             :      (relation)->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&  \
     725                 :             :      !IsCatalogRelation(relation))
     726                 :             : 
     727                 :             : /* routines in utils/cache/relcache.c */
     728                 :             : extern void RelationIncrementReferenceCount(Relation rel);
     729                 :             : extern void RelationDecrementReferenceCount(Relation rel);
     730                 :             : 
     731                 :             : #endif                          /* REL_H */
        

Generated by: LCOV version 2.0-1