LCOV - code coverage report
Current view: top level - src/include/access - itup.h (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 14 14 100.0 %
Date: 2024-04-19 02:11:33 Functions: 2 2 100.0 %
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-2024, 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             : #define IndexTupleSize(itup)        ((Size) ((itup)->t_info & INDEX_SIZE_MASK))
      72             : #define IndexTupleHasNulls(itup)    ((((IndexTuple) (itup))->t_info & INDEX_NULL_MASK))
      73             : #define IndexTupleHasVarwidths(itup) ((((IndexTuple) (itup))->t_info & INDEX_VAR_MASK))
      74             : 
      75             : 
      76             : /* routines in indextuple.c */
      77             : extern IndexTuple index_form_tuple(TupleDesc tupleDescriptor,
      78             :                                    const Datum *values, const bool *isnull);
      79             : extern IndexTuple index_form_tuple_context(TupleDesc tupleDescriptor,
      80             :                                            const Datum *values, const bool *isnull,
      81             :                                            MemoryContext context);
      82             : extern Datum nocache_index_getattr(IndexTuple tup, int attnum,
      83             :                                    TupleDesc tupleDesc);
      84             : extern void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor,
      85             :                                Datum *values, bool *isnull);
      86             : extern void index_deform_tuple_internal(TupleDesc tupleDescriptor,
      87             :                                         Datum *values, bool *isnull,
      88             :                                         char *tp, bits8 *bp, int hasnulls);
      89             : extern IndexTuple CopyIndexTuple(IndexTuple source);
      90             : extern IndexTuple index_truncate_tuple(TupleDesc sourceDescriptor,
      91             :                                        IndexTuple source, int leavenatts);
      92             : 
      93             : 
      94             : /*
      95             :  * Takes an infomask as argument (primarily because this needs to be usable
      96             :  * at index_form_tuple time so enough space is allocated).
      97             :  */
      98             : static inline Size
      99   493301030 : IndexInfoFindDataOffset(unsigned short t_info)
     100             : {
     101   493301030 :     if (!(t_info & INDEX_NULL_MASK))
     102   493078936 :         return MAXALIGN(sizeof(IndexTupleData));
     103             :     else
     104      222094 :         return MAXALIGN(sizeof(IndexTupleData) + sizeof(IndexAttributeBitMapData));
     105             : }
     106             : 
     107             : #ifndef FRONTEND
     108             : 
     109             : /* ----------------
     110             :  *      index_getattr
     111             :  *
     112             :  *      This gets called many times, so we macro the cacheable and NULL
     113             :  *      lookups, and call nocache_index_getattr() for the rest.
     114             :  *
     115             :  * ----------------
     116             :  */
     117             : static inline Datum
     118   459723264 : index_getattr(IndexTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
     119             : {
     120             :     Assert(PointerIsValid(isnull));
     121             :     Assert(attnum > 0);
     122             : 
     123   459723264 :     *isnull = false;
     124             : 
     125   459723264 :     if (!IndexTupleHasNulls(tup))
     126             :     {
     127   458992070 :         if (TupleDescAttr(tupleDesc, attnum - 1)->attcacheoff >= 0)
     128             :         {
     129   453515066 :             return fetchatt(TupleDescAttr(tupleDesc, attnum - 1),
     130             :                             (char *) tup + IndexInfoFindDataOffset(tup->t_info)
     131             :                             + TupleDescAttr(tupleDesc, attnum - 1)->attcacheoff);
     132             :         }
     133             :         else
     134     5477004 :             return nocache_index_getattr(tup, attnum, tupleDesc);
     135             :     }
     136             :     else
     137             :     {
     138      731194 :         if (att_isnull(attnum - 1, (bits8 *) tup + sizeof(IndexTupleData)))
     139             :         {
     140      618284 :             *isnull = true;
     141      618284 :             return (Datum) NULL;
     142             :         }
     143             :         else
     144      112910 :             return nocache_index_getattr(tup, attnum, tupleDesc);
     145             :     }
     146             : }
     147             : 
     148             : #endif
     149             : 
     150             : /*
     151             :  * MaxIndexTuplesPerPage is an upper bound on the number of tuples that can
     152             :  * fit on one index page.  An index tuple must have either data or a null
     153             :  * bitmap, so we can safely assume it's at least 1 byte bigger than a bare
     154             :  * IndexTupleData struct.  We arrive at the divisor because each tuple
     155             :  * must be maxaligned, and it must have an associated line pointer.
     156             :  *
     157             :  * To be index-type-independent, this does not account for any special space
     158             :  * on the page, and is thus conservative.
     159             :  *
     160             :  * Note: in btree non-leaf pages, the first tuple has no key (it's implicitly
     161             :  * minus infinity), thus breaking the "at least 1 byte bigger" assumption.
     162             :  * On such a page, N tuples could take one MAXALIGN quantum less space than
     163             :  * estimated here, seemingly allowing one more tuple than estimated here.
     164             :  * But such a page always has at least MAXALIGN special space, so we're safe.
     165             :  */
     166             : #define MaxIndexTuplesPerPage   \
     167             :     ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
     168             :             (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))
     169             : 
     170             : #endif                          /* ITUP_H */

Generated by: LCOV version 1.14