Line data Source code
1 : /*------------------------------------------------------------------------- 2 : * 3 : * itemptr.h 4 : * POSTGRES disk item pointer 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/storage/itemptr.h 11 : * 12 : *------------------------------------------------------------------------- 13 : */ 14 : #ifndef ITEMPTR_H 15 : #define ITEMPTR_H 16 : 17 : #include "storage/block.h" 18 : #include "storage/off.h" 19 : 20 : /* 21 : * ItemPointer: 22 : * 23 : * This is a pointer to an item within a disk page of a known file 24 : * (for example, a cross-link from an index to its parent table). 25 : * ip_blkid tells us which block, ip_posid tells us which entry in 26 : * the linp (ItemIdData) array we want. 27 : * 28 : * Note: because there is an item pointer in each tuple header and index 29 : * tuple header on disk, it's very important not to waste space with 30 : * structure padding bytes. The struct is designed to be six bytes long 31 : * (it contains three int16 fields) but a few compilers will pad it to 32 : * eight bytes unless coerced. We apply appropriate persuasion where 33 : * possible. If your compiler can't be made to play along, you'll waste 34 : * lots of space. 35 : */ 36 : typedef struct ItemPointerData 37 : { 38 : BlockIdData ip_blkid; 39 : OffsetNumber ip_posid; 40 : } 41 : 42 : /* If compiler understands packed and aligned pragmas, use those */ 43 : #if defined(pg_attribute_packed) && defined(pg_attribute_aligned) 44 : pg_attribute_packed() 45 : pg_attribute_aligned(2) 46 : #endif 47 : ItemPointerData; 48 : 49 : typedef ItemPointerData *ItemPointer; 50 : 51 : /* ---------------- 52 : * special values used in heap tuples (t_ctid) 53 : * ---------------- 54 : */ 55 : 56 : /* 57 : * If a heap tuple holds a speculative insertion token rather than a real 58 : * TID, ip_posid is set to SpecTokenOffsetNumber, and the token is stored in 59 : * ip_blkid. SpecTokenOffsetNumber must be higher than MaxOffsetNumber, so 60 : * that it can be distinguished from a valid offset number in a regular item 61 : * pointer. 62 : */ 63 : #define SpecTokenOffsetNumber 0xfffe 64 : 65 : /* 66 : * When a tuple is moved to a different partition by UPDATE, the t_ctid of 67 : * the old tuple version is set to this magic value. 68 : */ 69 : #define MovedPartitionsOffsetNumber 0xfffd 70 : #define MovedPartitionsBlockNumber InvalidBlockNumber 71 : 72 : 73 : /* ---------------- 74 : * support functions 75 : * ---------------- 76 : */ 77 : 78 : /* 79 : * ItemPointerIsValid 80 : * True iff the disk item pointer is not NULL. 81 : */ 82 : static inline bool 83 22546732 : ItemPointerIsValid(const ItemPointerData *pointer) 84 : { 85 22546732 : return PointerIsValid(pointer) && pointer->ip_posid != 0; 86 : } 87 : 88 : /* 89 : * ItemPointerGetBlockNumberNoCheck 90 : * Returns the block number of a disk item pointer. 91 : */ 92 : static inline BlockNumber 93 405922030 : ItemPointerGetBlockNumberNoCheck(const ItemPointerData *pointer) 94 : { 95 405922030 : return BlockIdGetBlockNumber(&pointer->ip_blkid); 96 : } 97 : 98 : /* 99 : * ItemPointerGetBlockNumber 100 : * As above, but verifies that the item pointer looks valid. 101 : */ 102 : static inline BlockNumber 103 255778078 : ItemPointerGetBlockNumber(const ItemPointerData *pointer) 104 : { 105 : Assert(ItemPointerIsValid(pointer)); 106 255778078 : return ItemPointerGetBlockNumberNoCheck(pointer); 107 : } 108 : 109 : /* 110 : * ItemPointerGetOffsetNumberNoCheck 111 : * Returns the offset number of a disk item pointer. 112 : */ 113 : static inline OffsetNumber 114 871490284 : ItemPointerGetOffsetNumberNoCheck(const ItemPointerData *pointer) 115 : { 116 871490284 : return pointer->ip_posid; 117 : } 118 : 119 : /* 120 : * ItemPointerGetOffsetNumber 121 : * As above, but verifies that the item pointer looks valid. 122 : */ 123 : static inline OffsetNumber 124 176546520 : ItemPointerGetOffsetNumber(const ItemPointerData *pointer) 125 : { 126 : Assert(ItemPointerIsValid(pointer)); 127 176546520 : return ItemPointerGetOffsetNumberNoCheck(pointer); 128 : } 129 : 130 : /* 131 : * ItemPointerSet 132 : * Sets a disk item pointer to the specified block and offset. 133 : */ 134 : static inline void 135 470802130 : ItemPointerSet(ItemPointerData *pointer, BlockNumber blockNumber, OffsetNumber offNum) 136 : { 137 : Assert(PointerIsValid(pointer)); 138 470802130 : BlockIdSet(&pointer->ip_blkid, blockNumber); 139 470802130 : pointer->ip_posid = offNum; 140 470802130 : } 141 : 142 : /* 143 : * ItemPointerSetBlockNumber 144 : * Sets a disk item pointer to the specified block. 145 : */ 146 : static inline void 147 40537128 : ItemPointerSetBlockNumber(ItemPointerData *pointer, BlockNumber blockNumber) 148 : { 149 : Assert(PointerIsValid(pointer)); 150 40537128 : BlockIdSet(&pointer->ip_blkid, blockNumber); 151 40537128 : } 152 : 153 : /* 154 : * ItemPointerSetOffsetNumber 155 : * Sets a disk item pointer to the specified offset. 156 : */ 157 : static inline void 158 68949846 : ItemPointerSetOffsetNumber(ItemPointerData *pointer, OffsetNumber offsetNumber) 159 : { 160 : Assert(PointerIsValid(pointer)); 161 68949846 : pointer->ip_posid = offsetNumber; 162 68949846 : } 163 : 164 : /* 165 : * ItemPointerCopy 166 : * Copies the contents of one disk item pointer to another. 167 : * 168 : * Should there ever be padding in an ItemPointer this would need to be handled 169 : * differently as it's used as hash key. 170 : */ 171 : static inline void 172 14539318 : ItemPointerCopy(const ItemPointerData *fromPointer, ItemPointerData *toPointer) 173 : { 174 : Assert(PointerIsValid(toPointer)); 175 : Assert(PointerIsValid(fromPointer)); 176 14539318 : *toPointer = *fromPointer; 177 14539318 : } 178 : 179 : /* 180 : * ItemPointerSetInvalid 181 : * Sets a disk item pointer to be invalid. 182 : */ 183 : static inline void 184 252504160 : ItemPointerSetInvalid(ItemPointerData *pointer) 185 : { 186 : Assert(PointerIsValid(pointer)); 187 252504160 : BlockIdSet(&pointer->ip_blkid, InvalidBlockNumber); 188 252504160 : pointer->ip_posid = InvalidOffsetNumber; 189 252504160 : } 190 : 191 : /* 192 : * ItemPointerIndicatesMovedPartitions 193 : * True iff the block number indicates the tuple has moved to another 194 : * partition. 195 : */ 196 : static inline bool 197 39674 : ItemPointerIndicatesMovedPartitions(const ItemPointerData *pointer) 198 : { 199 : return 200 39696 : ItemPointerGetOffsetNumber(pointer) == MovedPartitionsOffsetNumber && 201 22 : ItemPointerGetBlockNumberNoCheck(pointer) == MovedPartitionsBlockNumber; 202 : } 203 : 204 : /* 205 : * ItemPointerSetMovedPartitions 206 : * Indicate that the item referenced by the itempointer has moved into a 207 : * different partition. 208 : */ 209 : static inline void 210 1186 : ItemPointerSetMovedPartitions(ItemPointerData *pointer) 211 : { 212 1186 : ItemPointerSet(pointer, MovedPartitionsBlockNumber, MovedPartitionsOffsetNumber); 213 1186 : } 214 : 215 : /* ---------------- 216 : * externs 217 : * ---------------- 218 : */ 219 : 220 : extern bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2); 221 : extern int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2); 222 : extern void ItemPointerInc(ItemPointer pointer); 223 : extern void ItemPointerDec(ItemPointer pointer); 224 : 225 : /* ---------------- 226 : * Datum conversion functions 227 : * ---------------- 228 : */ 229 : 230 : static inline ItemPointer 231 42876182 : DatumGetItemPointer(Datum X) 232 : { 233 42876182 : return (ItemPointer) DatumGetPointer(X); 234 : } 235 : 236 : static inline Datum 237 21754 : ItemPointerGetDatum(const ItemPointerData *X) 238 : { 239 21754 : return PointerGetDatum(X); 240 : } 241 : 242 : #define PG_GETARG_ITEMPOINTER(n) DatumGetItemPointer(PG_GETARG_DATUM(n)) 243 : #define PG_RETURN_ITEMPOINTER(x) return ItemPointerGetDatum(x) 244 : 245 : #endif /* ITEMPTR_H */