1/*-------------------------------------------------------------------------
4 * POSTGRES index tuple definitions.
7 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
10 * src/include/access/itup.h
12 *-------------------------------------------------------------------------
23 * Index tuple header structure
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.
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.
40 * t_info is laid out in the following fashion:
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
49 unsigned short t_info;
/* various info about tuple */
63 * t_info manipulation macros
65 #define INDEX_SIZE_MASK 0x1FFF
66 #define INDEX_AM_RESERVED_BIT 0x2000 /* reserved for index-AM specific
68 #define INDEX_VAR_MASK 0x4000
69#define INDEX_NULL_MASK 0x8000
90/* routines in indextuple.c */
102 char *tp,
bits8 *bp,
int hasnulls);
109 * Takes an infomask as argument (primarily because this needs to be usable
110 * at index_form_tuple time so enough space is allocated).
126 * This gets called many times, so we macro the cacheable and NULL
127 * lookups, and call nocache_index_getattr() for the rest.
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.
173 * To be index-type-independent, this does not account for any special space
174 * on the page, and is thus conservative.
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.
182#define MaxIndexTuplesPerPage \
183 ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
184 (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))
static Datum values[MAXATTR]
Assert(PointerIsAligned(start, uint64))
void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor, Datum *values, bool *isnull)
IndexTuple index_truncate_tuple(TupleDesc sourceDescriptor, IndexTuple source, int leavenatts)
struct IndexAttributeBitMapData IndexAttributeBitMapData
static bool IndexTupleHasVarwidths(const IndexTupleData *itup)
IndexTupleData * IndexTuple
IndexTuple CopyIndexTuple(IndexTuple source)
static bool IndexTupleHasNulls(const IndexTupleData *itup)
static Datum index_getattr(IndexTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
IndexAttributeBitMapData * IndexAttributeBitMap
void index_deform_tuple_internal(TupleDesc tupleDescriptor, Datum *values, bool *isnull, char *tp, bits8 *bp, int hasnulls)
IndexTuple index_form_tuple_context(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull, MemoryContext context)
struct IndexTupleData IndexTupleData
static Size IndexTupleSize(const IndexTupleData *itup)
Datum nocache_index_getattr(IndexTuple tup, int attnum, TupleDesc tupleDesc)
IndexTuple index_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
static Size IndexInfoFindDataOffset(unsigned short t_info)
static rewind_source * source
bits8 bits[(INDEX_MAX_KEYS+8 - 1)/8]
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
static bool att_isnull(int ATT, const bits8 *BITS)