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

Generated by: LCOV version 2.0-1