LCOV - code coverage report
Current view: top level - src/include/access - tupdesc.h (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 100.0 % 6 6
Test Date: 2026-11-11 13:16:13 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * tupdesc.h
       4              :  *    POSTGRES tuple descriptor 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/access/tupdesc.h
      11              :  *
      12              :  *-------------------------------------------------------------------------
      13              :  */
      14              : #ifndef TUPDESC_H
      15              : #define TUPDESC_H
      16              : 
      17              : #include "access/attnum.h"
      18              : #include "access/xlogdefs.h"
      19              : #include "catalog/pg_attribute.h"
      20              : #include "nodes/pg_list.h"
      21              : 
      22              : 
      23              : typedef struct AttrDefault
      24              : {
      25              :     AttrNumber  adnum;
      26              :     char       *adbin;          /* nodeToString representation of expr */
      27              : } AttrDefault;
      28              : 
      29              : typedef struct ConstrCheck
      30              : {
      31              :     char       *ccname;
      32              :     char       *ccbin;          /* nodeToString representation of expr */
      33              :     bool        ccenforced;
      34              :     bool        ccvalid;
      35              :     bool        ccnoinherit;    /* this is a non-inheritable constraint */
      36              : } ConstrCheck;
      37              : 
      38              : /* This structure contains constraints of a tuple */
      39              : typedef struct TupleConstr
      40              : {
      41              :     AttrDefault *defval;        /* array */
      42              :     ConstrCheck *check;         /* array */
      43              :     struct AttrMissing *missing;    /* missing attributes values, NULL if none */
      44              :     uint16      num_defval;
      45              :     uint16      num_check;
      46              :     bool        has_not_null;   /* any not-null, including not valid ones */
      47              :     bool        has_generated_stored;
      48              :     bool        has_generated_virtual;
      49              : } TupleConstr;
      50              : 
      51              : /*
      52              :  * CompactAttribute
      53              :  *      Cut-down version of FormData_pg_attribute for faster access for tasks
      54              :  *      such as tuple deformation.  The fields of this struct are populated
      55              :  *      using the populate_compact_attribute() function, which must be called
      56              :  *      directly after the FormData_pg_attribute struct is populated or
      57              :  *      altered in any way.
      58              :  *
      59              :  * Currently, this struct is 8 bytes.  Any code changes which enlarge this
      60              :  * struct should be considered very carefully.
      61              :  *
      62              :  * Code which must access a TupleDesc's attribute data should always make use
      63              :  * the fields of this struct when required fields are available here.  It's
      64              :  * more efficient to access the memory in CompactAttribute due to it being a
      65              :  * more compact representation of FormData_pg_attribute and also because
      66              :  * accessing the FormData_pg_attribute requires an additional calculations to
      67              :  * obtain the base address of the array within the TupleDesc.
      68              :  */
      69              : typedef struct CompactAttribute
      70              : {
      71              :     int16       attcacheoff;    /* fixed offset into tuple, if known, or -1 */
      72              :     int16       attlen;         /* attr len in bytes or -1 = varlen, -2 =
      73              :                                  * cstring */
      74              :     bool        attbyval;       /* as FormData_pg_attribute.attbyval */
      75              :     uint8       attalignby;     /* alignment requirement in bytes */
      76              :     bool        attispackable:1;    /* FormData_pg_attribute.attstorage !=
      77              :                                      * TYPSTORAGE_PLAIN */
      78              :     bool        atthasmissing:1;    /* as FormData_pg_attribute.atthasmissing */
      79              :     bool        attisdropped:1; /* as FormData_pg_attribute.attisdropped */
      80              :     bool        attgenerated:1; /* FormData_pg_attribute.attgenerated != '\0' */
      81              :     char        attnullability; /* status of not-null constraint, see below */
      82              : } CompactAttribute;
      83              : 
      84              : /* Valid values for CompactAttribute->attnullability */
      85              : #define ATTNULLABLE_UNRESTRICTED 'f'    /* No constraint exists */
      86              : #define ATTNULLABLE_UNKNOWN     'u' /* constraint exists, validity unknown */
      87              : #define ATTNULLABLE_VALID       'v' /* valid constraint exists */
      88              : #define ATTNULLABLE_INVALID     'i' /* constraint exists, marked invalid */
      89              : 
      90              : /*
      91              :  * This struct is passed around within the backend to describe the structure
      92              :  * of tuples.  For tuples coming from on-disk relations, the information is
      93              :  * collected from the pg_attribute, pg_attrdef, and pg_constraint catalogs.
      94              :  * Transient row types (such as the result of a join query) have anonymous
      95              :  * TupleDesc structs that generally omit any constraint info; therefore the
      96              :  * structure is designed to let the constraints be omitted efficiently.
      97              :  *
      98              :  * Note that only user attributes, not system attributes, are mentioned in
      99              :  * TupleDesc.
     100              :  *
     101              :  * If the tupdesc is known to correspond to a named rowtype (such as a table's
     102              :  * rowtype) then tdtypeid identifies that type and tdtypmod is -1.  Otherwise
     103              :  * tdtypeid is RECORDOID, and tdtypmod can be either -1 for a fully anonymous
     104              :  * row type, or a value >= 0 to allow the rowtype to be looked up in the
     105              :  * typcache.c type cache.
     106              :  *
     107              :  * Note that tdtypeid is never the OID of a domain over composite, even if
     108              :  * we are dealing with values that are known (at some higher level) to be of
     109              :  * a domain-over-composite type.  This is because tdtypeid/tdtypmod need to
     110              :  * match up with the type labeling of composite Datums, and those are never
     111              :  * explicitly marked as being of a domain type, either.
     112              :  *
     113              :  * Tuple descriptors that live in caches (relcache or typcache, at present)
     114              :  * are reference-counted: they can be deleted when their reference count goes
     115              :  * to zero.  Tuple descriptors created by the executor need no reference
     116              :  * counting, however: they are simply created in the appropriate memory
     117              :  * context and go away when the context is freed.  We set the tdrefcount
     118              :  * field of such a descriptor to -1, while reference-counted descriptors
     119              :  * always have tdrefcount >= 0.
     120              :  *
     121              :  * Beyond the compact_attrs variable length array, the TupleDesc stores an
     122              :  * array of FormData_pg_attribute.  The TupleDescAttr() function, as defined
     123              :  * below, takes care of calculating the address of the elements of the
     124              :  * FormData_pg_attribute array.
     125              :  *
     126              :  * The array of CompactAttribute is effectively an abbreviated version of the
     127              :  * array of FormData_pg_attribute.  Because CompactAttribute is significantly
     128              :  * smaller than FormData_pg_attribute, code, especially performance-critical
     129              :  * code, should prioritize using the fields from the CompactAttribute over the
     130              :  * equivalent fields in FormData_pg_attribute.
     131              :  *
     132              :  * Any code making changes manually to and fields in the FormData_pg_attribute
     133              :  * array must subsequently call populate_compact_attribute() to flush the
     134              :  * changes out to the corresponding 'compact_attrs' element.
     135              :  *
     136              :  * firstNonCachedOffsetAttr stores the index into the compact_attrs array for
     137              :  * the first attribute that we don't have a known attcacheoff for.
     138              :  *
     139              :  * firstNonGuaranteedAttr stores the index to into the compact_attrs array for
     140              :  * the first attribute that is either NULLable, missing, or !attbyval.  This
     141              :  * can be used in locations as a guarantee that attributes before this will
     142              :  * always exist in tuples.  The !attbyval part isn't required for this, but
     143              :  * including this allows various tuple deforming routines to forego any checks
     144              :  * for !attbyval.
     145              :  *
     146              :  * Once a TupleDesc has been populated, before it is used for any purpose,
     147              :  * TupleDescFinalize() must be called on it.
     148              :  */
     149              : typedef struct TupleDescData
     150              : {
     151              :     int         natts;          /* number of attributes in the tuple */
     152              :     Oid         tdtypeid;       /* composite type ID for tuple type */
     153              :     int32       tdtypmod;       /* typmod for tuple type */
     154              :     int         tdrefcount;     /* reference count, or -1 if not counting */
     155              : 
     156              :     /* ---
     157              :      * Version of the tuple descriptor in aggregate. Used to ensure we never
     158              :      * try to deform datum-style tuples with a different tupledesc than what
     159              :      * was used to form them.  For !RECORDOID descriptors, this is equal to
     160              :      *     TupleDescAttr(td, td->natts - 1)->attversion
     161              :      * but faster to access (due to the constant offset), except when natts=0,
     162              :      * in which case tdversion is 0. The descriptor-wide version is used when
     163              :      * forming tuples and as the fast-path when checking a datum tuple's
     164              :      * version (most of the time it will match, and no per-attribute version
     165              :      * checks are needed).
     166              :      *
     167              :      * See src/backend/catalog/README.attver.md.
     168              :      * ---
     169              :      */
     170              :     XLogRecPtr  tdversion;
     171              : 
     172              :     int         firstNonCachedOffsetAttr;   /* index of first compact_attrs
     173              :                                              * element without an attcacheoff */
     174              :     int         firstNonGuaranteedAttr; /* index of the first nullable,
     175              :                                          * missing, dropped, or !attbyval
     176              :                                          * compact_attrs element. */
     177              :     TupleConstr *constr;        /* constraints, or NULL if none */
     178              :     /* compact_attrs[N] is the compact metadata of Attribute Number N+1 */
     179              :     pg_attribute_counted_by(natts) CompactAttribute compact_attrs[FLEXIBLE_ARRAY_MEMBER];
     180              : }           TupleDescData;
     181              : typedef struct TupleDescData *TupleDesc;
     182              : 
     183              : extern void populate_compact_attribute(TupleDesc tupdesc, int attnum);
     184              : 
     185              : /*
     186              :  * Calculates the base address of the Form_pg_attribute at the end of the
     187              :  * TupleDescData struct.
     188              :  */
     189              : #define TupleDescAttrAddress(desc) \
     190              :     (Form_pg_attribute) ((char *) (desc) + \
     191              :      (offsetof(struct TupleDescData, compact_attrs) + \
     192              :      (desc)->natts * sizeof(CompactAttribute)))
     193              : 
     194              : /* Accessor for the i'th FormData_pg_attribute element of tupdesc. */
     195              : static inline FormData_pg_attribute *
     196    241209901 : TupleDescAttr(TupleDesc tupdesc, int i)
     197              : {
     198    241209901 :     FormData_pg_attribute *attrs = TupleDescAttrAddress(tupdesc);
     199              : 
     200              :     Assert(i >= 0 && i < tupdesc->natts);
     201              : 
     202    241209901 :     return &attrs[i];
     203              : }
     204              : 
     205              : #undef TupleDescAttrAddress
     206              : 
     207              : extern void verify_compact_attribute(TupleDesc, int attnum);
     208              : 
     209              : /*
     210              :  * Accessor for the i'th CompactAttribute element of tupdesc.
     211              :  */
     212              : static inline CompactAttribute *
     213   1311777555 : TupleDescCompactAttr(TupleDesc tupdesc, int i)
     214              : {
     215   1311777555 :     CompactAttribute *cattr = &tupdesc->compact_attrs[i];
     216              : 
     217              : #ifdef USE_ASSERT_CHECKING
     218              : 
     219              :     /* Check that the CompactAttribute is correctly populated */
     220              :     verify_compact_attribute(tupdesc, i);
     221              : #endif
     222              : 
     223   1311777555 :     return cattr;
     224              : }
     225              : 
     226              : extern TupleDesc CreateTemplateTupleDesc(int natts);
     227              : 
     228              : extern TupleDesc CreateTupleDesc(int natts, Form_pg_attribute *attrs);
     229              : 
     230              : extern TupleDesc CreateTupleDescCopy(TupleDesc tupdesc);
     231              : 
     232              : extern TupleDesc CreateTupleDescTruncatedCopy(TupleDesc tupdesc, int natts);
     233              : 
     234              : extern TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc);
     235              : 
     236              : extern Size TupleDescCopySize(TupleDesc src);
     237              : extern void TupleDescCopySized(TupleDesc dst, Size dstsize, TupleDesc src);
     238              : 
     239              : extern void TupleDescCopyEntry(TupleDesc dst, AttrNumber dstAttno,
     240              :                                TupleDesc src, AttrNumber srcAttno);
     241              : 
     242              : extern void TupleDescFinalize(TupleDesc tupdesc);
     243              : extern void FreeTupleDesc(TupleDesc tupdesc);
     244              : 
     245              : extern void IncrTupleDescRefCount(TupleDesc tupdesc);
     246              : extern void DecrTupleDescRefCount(TupleDesc tupdesc);
     247              : 
     248              : extern XLogRecPtr TupleDescGetVersion(TupleDesc tupdesc);
     249              : extern void TupleDescSetVersion(TupleDesc tupdesc, XLogRecPtr version);
     250              : extern XLogRecPtr TupleDescGetAttrVersion(TupleDesc tupdesc, AttrNumber attnum);
     251              : 
     252              : #define PinTupleDesc(tupdesc) \
     253              :     do { \
     254              :         if ((tupdesc)->tdrefcount >= 0) \
     255              :             IncrTupleDescRefCount(tupdesc); \
     256              :     } while (0)
     257              : 
     258              : #define ReleaseTupleDesc(tupdesc) \
     259              :     do { \
     260              :         if ((tupdesc)->tdrefcount >= 0) \
     261              :             DecrTupleDescRefCount(tupdesc); \
     262              :     } while (0)
     263              : 
     264              : extern bool equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2);
     265              : extern bool equalRowTypes(TupleDesc tupdesc1, TupleDesc tupdesc2);
     266              : extern uint32 hashRowType(TupleDesc desc);
     267              : 
     268              : extern void TupleDescInitEntry(TupleDesc desc,
     269              :                                AttrNumber attributeNumber,
     270              :                                const char *attributeName,
     271              :                                Oid oidtypeid,
     272              :                                int32 typmod,
     273              :                                int attdim);
     274              : 
     275              : extern void TupleDescInitBuiltinEntry(TupleDesc desc,
     276              :                                       AttrNumber attributeNumber,
     277              :                                       const char *attributeName,
     278              :                                       Oid oidtypeid,
     279              :                                       int32 typmod,
     280              :                                       int attdim);
     281              : 
     282              : extern void TupleDescInitEntryCollation(TupleDesc desc,
     283              :                                         AttrNumber attributeNumber,
     284              :                                         Oid collationid);
     285              : 
     286              : extern TupleDesc BuildDescFromLists(const List *names, const List *types, const List *typmods, const List *collations);
     287              : 
     288              : extern Node *TupleDescGetDefault(TupleDesc tupdesc, AttrNumber attnum);
     289              : 
     290              : #endif                          /* TUPDESC_H */
        

Generated by: LCOV version 2.0-1