LCOV - code coverage report
Current view: top level - src/include/utils - rel.h (source / functions) Coverage Total Hit
Test: Code coverage Lines: 100.0 % 13 13
Test Date: 2026-01-26 10:56:24 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                 :             :         int                     vacuum_threshold;
     315                 :             :         int                     vacuum_max_threshold;
     316                 :             :         int                     vacuum_ins_threshold;
     317                 :             :         int                     analyze_threshold;
     318                 :             :         int                     vacuum_cost_limit;
     319                 :             :         int                     freeze_min_age;
     320                 :             :         int                     freeze_max_age;
     321                 :             :         int                     freeze_table_age;
     322                 :             :         int                     multixact_freeze_min_age;
     323                 :             :         int                     multixact_freeze_max_age;
     324                 :             :         int                     multixact_freeze_table_age;
     325                 :             :         int                     log_vacuum_min_duration;
     326                 :             :         int                     log_analyze_min_duration;
     327                 :             :         float8          vacuum_cost_delay;
     328                 :             :         float8          vacuum_scale_factor;
     329                 :             :         float8          vacuum_ins_scale_factor;
     330                 :             :         float8          analyze_scale_factor;
     331                 :             : } AutoVacOpts;
     332                 :             : 
     333                 :             : /* StdRdOptions->vacuum_index_cleanup values */
     334                 :             : typedef enum StdRdOptIndexCleanup
     335                 :             : {
     336                 :             :         STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO = 0,
     337                 :             :         STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF,
     338                 :             :         STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON,
     339                 :             : } StdRdOptIndexCleanup;
     340                 :             : 
     341                 :             : typedef struct StdRdOptions
     342                 :             : {
     343                 :             :         int32           vl_len_;                /* varlena header (do not touch directly!) */
     344                 :             :         int                     fillfactor;             /* page fill factor in percent (0..100) */
     345                 :             :         int                     toast_tuple_target; /* target for tuple toasting */
     346                 :             :         AutoVacOpts autovacuum;         /* autovacuum-related options */
     347                 :             :         bool            user_catalog_table; /* use as an additional catalog relation */
     348                 :             :         int                     parallel_workers;       /* max number of parallel workers */
     349                 :             :         StdRdOptIndexCleanup vacuum_index_cleanup;      /* controls index vacuuming */
     350                 :             :         pg_ternary      vacuum_truncate;        /* enables vacuum to truncate a relation */
     351                 :             : 
     352                 :             :         /*
     353                 :             :          * Fraction of pages in a relation that vacuum can eagerly scan and fail
     354                 :             :          * to freeze. 0 if disabled, -1 if unspecified.
     355                 :             :          */
     356                 :             :         double          vacuum_max_eager_freeze_failure_rate;
     357                 :             : } StdRdOptions;
     358                 :             : 
     359                 :             : #define HEAP_MIN_FILLFACTOR                     10
     360                 :             : #define HEAP_DEFAULT_FILLFACTOR         100
     361                 :             : 
     362                 :             : /*
     363                 :             :  * RelationGetToastTupleTarget
     364                 :             :  *              Returns the relation's toast_tuple_target.  Note multiple eval of argument!
     365                 :             :  */
     366                 :             : #define RelationGetToastTupleTarget(relation, defaulttarg) \
     367                 :             :         ((relation)->rd_options ? \
     368                 :             :          ((StdRdOptions *) (relation)->rd_options)->toast_tuple_target : (defaulttarg))
     369                 :             : 
     370                 :             : /*
     371                 :             :  * RelationGetFillFactor
     372                 :             :  *              Returns the relation's fillfactor.  Note multiple eval of argument!
     373                 :             :  */
     374                 :             : #define RelationGetFillFactor(relation, defaultff) \
     375                 :             :         ((relation)->rd_options ? \
     376                 :             :          ((StdRdOptions *) (relation)->rd_options)->fillfactor : (defaultff))
     377                 :             : 
     378                 :             : /*
     379                 :             :  * RelationGetTargetPageUsage
     380                 :             :  *              Returns the relation's desired space usage per page in bytes.
     381                 :             :  */
     382                 :             : #define RelationGetTargetPageUsage(relation, defaultff) \
     383                 :             :         (BLCKSZ * RelationGetFillFactor(relation, defaultff) / 100)
     384                 :             : 
     385                 :             : /*
     386                 :             :  * RelationGetTargetPageFreeSpace
     387                 :             :  *              Returns the relation's desired freespace per page in bytes.
     388                 :             :  */
     389                 :             : #define RelationGetTargetPageFreeSpace(relation, defaultff) \
     390                 :             :         (BLCKSZ * (100 - RelationGetFillFactor(relation, defaultff)) / 100)
     391                 :             : 
     392                 :             : /*
     393                 :             :  * RelationIsUsedAsCatalogTable
     394                 :             :  *              Returns whether the relation should be treated as a catalog table
     395                 :             :  *              from the pov of logical decoding.  Note multiple eval of argument!
     396                 :             :  */
     397                 :             : #define RelationIsUsedAsCatalogTable(relation)  \
     398                 :             :         ((relation)->rd_options && \
     399                 :             :          ((relation)->rd_rel->relkind == RELKIND_RELATION || \
     400                 :             :           (relation)->rd_rel->relkind == RELKIND_MATVIEW) ? \
     401                 :             :          ((StdRdOptions *) (relation)->rd_options)->user_catalog_table : false)
     402                 :             : 
     403                 :             : /*
     404                 :             :  * RelationGetParallelWorkers
     405                 :             :  *              Returns the relation's parallel_workers reloption setting.
     406                 :             :  *              Note multiple eval of argument!
     407                 :             :  */
     408                 :             : #define RelationGetParallelWorkers(relation, defaultpw) \
     409                 :             :         ((relation)->rd_options ? \
     410                 :             :          ((StdRdOptions *) (relation)->rd_options)->parallel_workers : (defaultpw))
     411                 :             : 
     412                 :             : /* ViewOptions->check_option values */
     413                 :             : typedef enum ViewOptCheckOption
     414                 :             : {
     415                 :             :         VIEW_OPTION_CHECK_OPTION_NOT_SET,
     416                 :             :         VIEW_OPTION_CHECK_OPTION_LOCAL,
     417                 :             :         VIEW_OPTION_CHECK_OPTION_CASCADED,
     418                 :             : } ViewOptCheckOption;
     419                 :             : 
     420                 :             : /*
     421                 :             :  * ViewOptions
     422                 :             :  *              Contents of rd_options for views
     423                 :             :  */
     424                 :             : typedef struct ViewOptions
     425                 :             : {
     426                 :             :         int32           vl_len_;                /* varlena header (do not touch directly!) */
     427                 :             :         bool            security_barrier;
     428                 :             :         bool            security_invoker;
     429                 :             :         ViewOptCheckOption check_option;
     430                 :             : } ViewOptions;
     431                 :             : 
     432                 :             : /*
     433                 :             :  * RelationIsSecurityView
     434                 :             :  *              Returns whether the relation is security view, or not.  Note multiple
     435                 :             :  *              eval of argument!
     436                 :             :  */
     437                 :             : #define RelationIsSecurityView(relation)                                                                        \
     438                 :             :         (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW),                          \
     439                 :             :          (relation)->rd_options ?                                                                                            \
     440                 :             :           ((ViewOptions *) (relation)->rd_options)->security_barrier : false)
     441                 :             : 
     442                 :             : /*
     443                 :             :  * RelationHasSecurityInvoker
     444                 :             :  *              Returns true if the relation has the security_invoker property set.
     445                 :             :  *              Note multiple eval of argument!
     446                 :             :  */
     447                 :             : #define RelationHasSecurityInvoker(relation)                                                            \
     448                 :             :         (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW),                          \
     449                 :             :          (relation)->rd_options ?                                                                                            \
     450                 :             :           ((ViewOptions *) (relation)->rd_options)->security_invoker : false)
     451                 :             : 
     452                 :             : /*
     453                 :             :  * RelationHasCheckOption
     454                 :             :  *              Returns true if the relation is a view defined with either the local
     455                 :             :  *              or the cascaded check option.  Note multiple eval of argument!
     456                 :             :  */
     457                 :             : #define RelationHasCheckOption(relation)                                                                        \
     458                 :             :         (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW),                          \
     459                 :             :          (relation)->rd_options &&                                                                                           \
     460                 :             :          ((ViewOptions *) (relation)->rd_options)->check_option !=                                \
     461                 :             :          VIEW_OPTION_CHECK_OPTION_NOT_SET)
     462                 :             : 
     463                 :             : /*
     464                 :             :  * RelationHasLocalCheckOption
     465                 :             :  *              Returns true if the relation is a view defined with the local check
     466                 :             :  *              option.  Note multiple eval of argument!
     467                 :             :  */
     468                 :             : #define RelationHasLocalCheckOption(relation)                                                           \
     469                 :             :         (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW),                          \
     470                 :             :          (relation)->rd_options &&                                                                                           \
     471                 :             :          ((ViewOptions *) (relation)->rd_options)->check_option ==                                \
     472                 :             :          VIEW_OPTION_CHECK_OPTION_LOCAL)
     473                 :             : 
     474                 :             : /*
     475                 :             :  * RelationHasCascadedCheckOption
     476                 :             :  *              Returns true if the relation is a view defined with the cascaded check
     477                 :             :  *              option.  Note multiple eval of argument!
     478                 :             :  */
     479                 :             : #define RelationHasCascadedCheckOption(relation)                                                        \
     480                 :             :         (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW),                          \
     481                 :             :          (relation)->rd_options &&                                                                                           \
     482                 :             :          ((ViewOptions *) (relation)->rd_options)->check_option ==                                \
     483                 :             :           VIEW_OPTION_CHECK_OPTION_CASCADED)
     484                 :             : 
     485                 :             : /*
     486                 :             :  * RelationIsValid
     487                 :             :  *              True iff relation descriptor is valid.
     488                 :             :  */
     489                 :             : #define RelationIsValid(relation) ((relation) != NULL)
     490                 :             : 
     491                 :             : /*
     492                 :             :  * RelationHasReferenceCountZero
     493                 :             :  *              True iff relation reference count is zero.
     494                 :             :  *
     495                 :             :  * Note:
     496                 :             :  *              Assumes relation descriptor is valid.
     497                 :             :  */
     498                 :             : #define RelationHasReferenceCountZero(relation) \
     499                 :             :                 ((bool)((relation)->rd_refcnt == 0))
     500                 :             : 
     501                 :             : /*
     502                 :             :  * RelationGetForm
     503                 :             :  *              Returns pg_class tuple for a relation.
     504                 :             :  *
     505                 :             :  * Note:
     506                 :             :  *              Assumes relation descriptor is valid.
     507                 :             :  */
     508                 :             : #define RelationGetForm(relation) ((relation)->rd_rel)
     509                 :             : 
     510                 :             : /*
     511                 :             :  * RelationGetRelid
     512                 :             :  *              Returns the OID of the relation
     513                 :             :  */
     514                 :             : #define RelationGetRelid(relation) ((relation)->rd_id)
     515                 :             : 
     516                 :             : /*
     517                 :             :  * RelationGetNumberOfAttributes
     518                 :             :  *              Returns the total number of attributes in a relation.
     519                 :             :  */
     520                 :             : #define RelationGetNumberOfAttributes(relation) ((relation)->rd_rel->relnatts)
     521                 :             : 
     522                 :             : /*
     523                 :             :  * IndexRelationGetNumberOfAttributes
     524                 :             :  *              Returns the number of attributes in an index.
     525                 :             :  */
     526                 :             : #define IndexRelationGetNumberOfAttributes(relation) \
     527                 :             :                 ((relation)->rd_index->indnatts)
     528                 :             : 
     529                 :             : /*
     530                 :             :  * IndexRelationGetNumberOfKeyAttributes
     531                 :             :  *              Returns the number of key attributes in an index.
     532                 :             :  */
     533                 :             : #define IndexRelationGetNumberOfKeyAttributes(relation) \
     534                 :             :                 ((relation)->rd_index->indnkeyatts)
     535                 :             : 
     536                 :             : /*
     537                 :             :  * RelationGetDescr
     538                 :             :  *              Returns tuple descriptor for a relation.
     539                 :             :  */
     540                 :             : #define RelationGetDescr(relation) ((relation)->rd_att)
     541                 :             : 
     542                 :             : /*
     543                 :             :  * RelationGetRelationName
     544                 :             :  *              Returns the rel's name.
     545                 :             :  *
     546                 :             :  * Note that the name is only unique within the containing namespace.
     547                 :             :  */
     548                 :             : #define RelationGetRelationName(relation) \
     549                 :             :         (NameStr((relation)->rd_rel->relname))
     550                 :             : 
     551                 :             : /*
     552                 :             :  * RelationGetNamespace
     553                 :             :  *              Returns the rel's namespace OID.
     554                 :             :  */
     555                 :             : #define RelationGetNamespace(relation) \
     556                 :             :         ((relation)->rd_rel->relnamespace)
     557                 :             : 
     558                 :             : /*
     559                 :             :  * RelationIsMapped
     560                 :             :  *              True if the relation uses the relfilenumber map.  Note multiple eval
     561                 :             :  *              of argument!
     562                 :             :  */
     563                 :             : #define RelationIsMapped(relation) \
     564                 :             :         (RELKIND_HAS_STORAGE((relation)->rd_rel->relkind) && \
     565                 :             :          ((relation)->rd_rel->relfilenode == InvalidRelFileNumber))
     566                 :             : 
     567                 :             : #ifndef FRONTEND
     568                 :             : /*
     569                 :             :  * RelationGetSmgr
     570                 :             :  *              Returns smgr file handle for a relation, opening it if needed.
     571                 :             :  *
     572                 :             :  * Very little code is authorized to touch rel->rd_smgr directly.  Instead
     573                 :             :  * use this function to fetch its value.
     574                 :             :  */
     575                 :             : static inline SMgrRelation
     576                 :    13544473 : RelationGetSmgr(Relation rel)
     577                 :             : {
     578         [ +  + ]:    13544473 :         if (unlikely(rel->rd_smgr == NULL))
     579                 :             :         {
     580                 :       64987 :                 rel->rd_smgr = smgropen(rel->rd_locator, rel->rd_backend);
     581                 :       64987 :                 smgrpin(rel->rd_smgr);
     582                 :       64987 :         }
     583                 :    13544473 :         return rel->rd_smgr;
     584                 :             : }
     585                 :             : 
     586                 :             : /*
     587                 :             :  * RelationCloseSmgr
     588                 :             :  *              Close the relation at the smgr level, if not already done.
     589                 :             :  */
     590                 :             : static inline void
     591                 :      320037 : RelationCloseSmgr(Relation relation)
     592                 :             : {
     593         [ +  + ]:      320037 :         if (relation->rd_smgr != NULL)
     594                 :             :         {
     595                 :       29293 :                 smgrunpin(relation->rd_smgr);
     596                 :       29293 :                 smgrclose(relation->rd_smgr);
     597                 :       29293 :                 relation->rd_smgr = NULL;
     598                 :       29293 :         }
     599                 :      320037 : }
     600                 :             : #endif                                                  /* !FRONTEND */
     601                 :             : 
     602                 :             : /*
     603                 :             :  * RelationGetTargetBlock
     604                 :             :  *              Fetch relation's current insertion target block.
     605                 :             :  *
     606                 :             :  * Returns InvalidBlockNumber if there is no current target block.  Note
     607                 :             :  * that the target block status is discarded on any smgr-level invalidation,
     608                 :             :  * so there's no need to re-open the smgr handle if it's not currently open.
     609                 :             :  */
     610                 :             : #define RelationGetTargetBlock(relation) \
     611                 :             :         ( (relation)->rd_smgr != NULL ? (relation)->rd_smgr->smgr_targblock : InvalidBlockNumber )
     612                 :             : 
     613                 :             : /*
     614                 :             :  * RelationSetTargetBlock
     615                 :             :  *              Set relation's current insertion target block.
     616                 :             :  */
     617                 :             : #define RelationSetTargetBlock(relation, targblock) \
     618                 :             :         do { \
     619                 :             :                 RelationGetSmgr(relation)->smgr_targblock = (targblock); \
     620                 :             :         } while (0)
     621                 :             : 
     622                 :             : /*
     623                 :             :  * RelationIsPermanent
     624                 :             :  *              True if relation is permanent.
     625                 :             :  */
     626                 :             : #define RelationIsPermanent(relation) \
     627                 :             :         ((relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
     628                 :             : 
     629                 :             : /*
     630                 :             :  * RelationNeedsWAL
     631                 :             :  *              True if relation needs WAL.
     632                 :             :  *
     633                 :             :  * Returns false if wal_level = minimal and this relation is created or
     634                 :             :  * truncated in the current transaction.  See "Skipping WAL for New
     635                 :             :  * RelFileLocator" in src/backend/access/transam/README.
     636                 :             :  */
     637                 :             : #define RelationNeedsWAL(relation)                                                                              \
     638                 :             :         (RelationIsPermanent(relation) && (XLogIsNeeded() ||                            \
     639                 :             :           (relation->rd_createSubid == InvalidSubTransactionId &&                    \
     640                 :             :            relation->rd_firstRelfilelocatorSubid == InvalidSubTransactionId)))
     641                 :             : 
     642                 :             : /*
     643                 :             :  * RelationUsesLocalBuffers
     644                 :             :  *              True if relation's pages are stored in local buffers.
     645                 :             :  */
     646                 :             : #define RelationUsesLocalBuffers(relation) \
     647                 :             :         ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
     648                 :             : 
     649                 :             : /*
     650                 :             :  * RELATION_IS_LOCAL
     651                 :             :  *              If a rel is either temp or newly created in the current transaction,
     652                 :             :  *              it can be assumed to be accessible only to the current backend.
     653                 :             :  *              This is typically used to decide that we can skip acquiring locks.
     654                 :             :  *
     655                 :             :  * Beware of multiple eval of argument
     656                 :             :  */
     657                 :             : #define RELATION_IS_LOCAL(relation) \
     658                 :             :         ((relation)->rd_islocaltemp || \
     659                 :             :          (relation)->rd_createSubid != InvalidSubTransactionId)
     660                 :             : 
     661                 :             : /*
     662                 :             :  * RELATION_IS_OTHER_TEMP
     663                 :             :  *              Test for a temporary relation that belongs to some other session.
     664                 :             :  *
     665                 :             :  * Beware of multiple eval of argument
     666                 :             :  */
     667                 :             : #define RELATION_IS_OTHER_TEMP(relation) \
     668                 :             :         ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP && \
     669                 :             :          !(relation)->rd_islocaltemp)
     670                 :             : 
     671                 :             : 
     672                 :             : /*
     673                 :             :  * RelationIsScannable
     674                 :             :  *              Currently can only be false for a materialized view which has not been
     675                 :             :  *              populated by its query.  This is likely to get more complicated later,
     676                 :             :  *              so use a macro which looks like a function.
     677                 :             :  */
     678                 :             : #define RelationIsScannable(relation) ((relation)->rd_rel->relispopulated)
     679                 :             : 
     680                 :             : /*
     681                 :             :  * RelationIsPopulated
     682                 :             :  *              Currently, we don't physically distinguish the "populated" and
     683                 :             :  *              "scannable" properties of matviews, but that may change later.
     684                 :             :  *              Hence, use the appropriate one of these macros in code tests.
     685                 :             :  */
     686                 :             : #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
     687                 :             : 
     688                 :             : /*
     689                 :             :  * RelationIsAccessibleInLogicalDecoding
     690                 :             :  *              True if we need to log enough information to have access via
     691                 :             :  *              decoding snapshot.
     692                 :             :  */
     693                 :             : #define RelationIsAccessibleInLogicalDecoding(relation) \
     694                 :             :         (XLogLogicalInfoActive() && \
     695                 :             :          RelationNeedsWAL(relation) && \
     696                 :             :          (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
     697                 :             : 
     698                 :             : /*
     699                 :             :  * RelationIsLogicallyLogged
     700                 :             :  *              True if we need to log enough information to extract the data from the
     701                 :             :  *              WAL stream.
     702                 :             :  *
     703                 :             :  * We don't log information for unlogged tables (since they don't WAL log
     704                 :             :  * anyway), for foreign tables (since they don't WAL log, either),
     705                 :             :  * and for system tables (their content is hard to make sense of, and
     706                 :             :  * it would complicate decoding slightly for little gain). Note that we *do*
     707                 :             :  * log information for user defined catalog tables since they presumably are
     708                 :             :  * interesting to the user...
     709                 :             :  */
     710                 :             : #define RelationIsLogicallyLogged(relation) \
     711                 :             :         (XLogLogicalInfoActive() && \
     712                 :             :          RelationNeedsWAL(relation) && \
     713                 :             :          (relation)->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&  \
     714                 :             :          !IsCatalogRelation(relation))
     715                 :             : 
     716                 :             : /* routines in utils/cache/relcache.c */
     717                 :             : extern void RelationIncrementReferenceCount(Relation rel);
     718                 :             : extern void RelationDecrementReferenceCount(Relation rel);
     719                 :             : 
     720                 :             : #endif                                                  /* REL_H */
        

Generated by: LCOV version 2.3.2-1