itup.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*-------------------------------------------------------------------------
  2. *
  3. * itup.h
  4. * POSTGRES index tuple definitions.
  5. *
  6. *
  7. * Portions Copyright (c) 1996-2016, 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: unused
  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. /* bit 0x2000 is not used at present */
  57. #define INDEX_VAR_MASK 0x4000
  58. #define INDEX_NULL_MASK 0x8000
  59. #define IndexTupleSize(itup) ((Size) (((IndexTuple) (itup))->t_info & INDEX_SIZE_MASK))
  60. #define IndexTupleDSize(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. (tupleDesc)->attrs[(attnum)-1]->attcacheoff >= 0 ? \
  93. ( \
  94. fetchatt((tupleDesc)->attrs[(attnum)-1], \
  95. (char *) (tup) + IndexInfoFindDataOffset((tup)->t_info) \
  96. + (tupleDesc)->attrs[(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 item pointer.
  120. */
  121. #define MinIndexTupleSize MAXALIGN(sizeof(IndexTupleData) + 1)
  122. #define MaxIndexTuplesPerPage \
  123. ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
  124. (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))
  125. /* routines in indextuple.c */
  126. extern IndexTuple index_form_tuple(TupleDesc tupleDescriptor,
  127. Datum *values, bool *isnull);
  128. extern Datum nocache_index_getattr(IndexTuple tup, int attnum,
  129. TupleDesc tupleDesc);
  130. extern void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor,
  131. Datum *values, bool *isnull);
  132. extern IndexTuple CopyIndexTuple(IndexTuple source);
  133. #endif /* ITUP_H */