LCOV - code coverage report
Current view: top level - src/include/access - itup.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 21 21
Test Date: 2026-03-11 20:15:07 Functions: 100.0 % 5 5
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * itup.h
       4              :  *    POSTGRES index tuple 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/itup.h
      11              :  *
      12              :  *-------------------------------------------------------------------------
      13              :  */
      14              : #ifndef ITUP_H
      15              : #define ITUP_H
      16              : 
      17              : #include "access/tupdesc.h"
      18              : #include "access/tupmacs.h"
      19              : #include "storage/bufpage.h"
      20              : #include "storage/itemptr.h"
      21              : 
      22              : /*
      23              :  * Index tuple header structure
      24              :  *
      25              :  * All index tuples start with IndexTupleData.  If the HasNulls bit is set,
      26              :  * this is followed by an IndexAttributeBitMapData.  The index attribute
      27              :  * values follow, beginning at a MAXALIGN boundary.
      28              :  *
      29              :  * Note that the space allocated for the bitmap does not vary with the number
      30              :  * of attributes; that is because we don't have room to store the number of
      31              :  * attributes in the header.  Given the MAXALIGN constraint there's no space
      32              :  * savings to be had anyway, for usual values of INDEX_MAX_KEYS.
      33              :  */
      34              : 
      35              : typedef struct IndexTupleData
      36              : {
      37              :     ItemPointerData t_tid;      /* reference TID to heap tuple */
      38              : 
      39              :     /* ---------------
      40              :      * t_info is laid out in the following fashion:
      41              :      *
      42              :      * 15th (high) bit: has nulls
      43              :      * 14th bit: has var-width attributes
      44              :      * 13th bit: AM-defined meaning
      45              :      * 12-0 bit: size of tuple
      46              :      * ---------------
      47              :      */
      48              : 
      49              :     unsigned short t_info;      /* various info about tuple */
      50              : 
      51              : } IndexTupleData;               /* MORE DATA FOLLOWS AT END OF STRUCT */
      52              : 
      53              : typedef IndexTupleData *IndexTuple;
      54              : 
      55              : typedef struct IndexAttributeBitMapData
      56              : {
      57              :     bits8       bits[(INDEX_MAX_KEYS + 8 - 1) / 8];
      58              : }           IndexAttributeBitMapData;
      59              : 
      60              : typedef IndexAttributeBitMapData * IndexAttributeBitMap;
      61              : 
      62              : /*
      63              :  * t_info manipulation macros
      64              :  */
      65              : #define INDEX_SIZE_MASK 0x1FFF
      66              : #define INDEX_AM_RESERVED_BIT 0x2000    /* reserved for index-AM specific
      67              :                                          * usage */
      68              : #define INDEX_VAR_MASK  0x4000
      69              : #define INDEX_NULL_MASK 0x8000
      70              : 
      71              : static inline Size
      72    118382488 : IndexTupleSize(const IndexTupleData *itup)
      73              : {
      74    118382488 :     return (itup->t_info & INDEX_SIZE_MASK);
      75              : }
      76              : 
      77              : static inline bool
      78    355634681 : IndexTupleHasNulls(const IndexTupleData *itup)
      79              : {
      80    355634681 :     return itup->t_info & INDEX_NULL_MASK;
      81              : }
      82              : 
      83              : static inline bool
      84      4528553 : IndexTupleHasVarwidths(const IndexTupleData *itup)
      85              : {
      86      4528553 :     return itup->t_info & INDEX_VAR_MASK;
      87              : }
      88              : 
      89              : 
      90              : /* routines in indextuple.c */
      91              : extern IndexTuple index_form_tuple(TupleDesc tupleDescriptor,
      92              :                                    const Datum *values, const bool *isnull);
      93              : extern IndexTuple index_form_tuple_context(TupleDesc tupleDescriptor,
      94              :                                            const Datum *values, const bool *isnull,
      95              :                                            MemoryContext context);
      96              : extern Datum nocache_index_getattr(IndexTuple tup, int attnum,
      97              :                                    TupleDesc tupleDesc);
      98              : extern void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor,
      99              :                                Datum *values, bool *isnull);
     100              : extern void index_deform_tuple_internal(TupleDesc tupleDescriptor,
     101              :                                         Datum *values, bool *isnull,
     102              :                                         char *tp, bits8 *bp, int hasnulls);
     103              : extern IndexTuple CopyIndexTuple(IndexTuple source);
     104              : extern IndexTuple index_truncate_tuple(TupleDesc sourceDescriptor,
     105              :                                        IndexTuple source, int leavenatts);
     106              : 
     107              : 
     108              : /*
     109              :  * Takes an infomask as argument (primarily because this needs to be usable
     110              :  * at index_form_tuple time so enough space is allocated).
     111              :  */
     112              : static inline Size
     113    308542716 : IndexInfoFindDataOffset(unsigned short t_info)
     114              : {
     115    308542716 :     if (!(t_info & INDEX_NULL_MASK))
     116    308430579 :         return MAXALIGN(sizeof(IndexTupleData));
     117              :     else
     118       112137 :         return MAXALIGN(sizeof(IndexTupleData) + sizeof(IndexAttributeBitMapData));
     119              : }
     120              : 
     121              : #ifndef FRONTEND
     122              : 
     123              : /* ----------------
     124              :  *      index_getattr
     125              :  *
     126              :  *      This gets called many times, so we macro the cacheable and NULL
     127              :  *      lookups, and call nocache_index_getattr() for the rest.
     128              :  *
     129              :  * ----------------
     130              :  */
     131              : static inline Datum
     132    290075954 : index_getattr(IndexTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
     133              : {
     134              :     Assert(isnull);
     135              :     Assert(attnum > 0);
     136              : 
     137    290075954 :     *isnull = false;
     138              : 
     139    290075954 :     if (!IndexTupleHasNulls(tup))
     140              :     {
     141    289730893 :         CompactAttribute *attr = TupleDescCompactAttr(tupleDesc, attnum - 1);
     142              : 
     143    289730893 :         if (attr->attcacheoff >= 0)
     144              :         {
     145    286254083 :             return fetchatt(attr,
     146              :                             (char *) tup + IndexInfoFindDataOffset(tup->t_info) +
     147              :                             attr->attcacheoff);
     148              :         }
     149              :         else
     150      3476810 :             return nocache_index_getattr(tup, attnum, tupleDesc);
     151              :     }
     152              :     else
     153              :     {
     154       345061 :         if (att_isnull(attnum - 1, (bits8 *) tup + sizeof(IndexTupleData)))
     155              :         {
     156       287763 :             *isnull = true;
     157       287763 :             return (Datum) 0;
     158              :         }
     159              :         else
     160        57298 :             return nocache_index_getattr(tup, attnum, tupleDesc);
     161              :     }
     162              : }
     163              : 
     164              : #endif
     165              : 
     166              : /*
     167              :  * MaxIndexTuplesPerPage is an upper bound on the number of tuples that can
     168              :  * fit on one index page.  An index tuple must have either data or a null
     169              :  * bitmap, so we can safely assume it's at least 1 byte bigger than a bare
     170              :  * IndexTupleData struct.  We arrive at the divisor because each tuple
     171              :  * must be maxaligned, and it must have an associated line pointer.
     172              :  *
     173              :  * To be index-type-independent, this does not account for any special space
     174              :  * on the page, and is thus conservative.
     175              :  *
     176              :  * Note: in btree non-leaf pages, the first tuple has no key (it's implicitly
     177              :  * minus infinity), thus breaking the "at least 1 byte bigger" assumption.
     178              :  * On such a page, N tuples could take one MAXALIGN quantum less space than
     179              :  * estimated here, seemingly allowing one more tuple than estimated here.
     180              :  * But such a page always has at least MAXALIGN special space, so we're safe.
     181              :  */
     182              : #define MaxIndexTuplesPerPage   \
     183              :     ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
     184              :             (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))
     185              : 
     186              : #endif                          /* ITUP_H */
        

Generated by: LCOV version 2.0-1