2
0

itup.h 5.2 KB

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