1 /*------------------------------------------------------------------------- 2 * 3 * itemptr.h 4 * POSTGRES disk item pointer definitions. 5 * 6 * 7 * Portions Copyright (c) 1996-2021, 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 macros 75 * ---------------- 76 */ 77 78 /* 79 * ItemPointerIsValid 80 * True iff the disk item pointer is not NULL. 81 */ 82 #define ItemPointerIsValid(pointer) \ 83 ((bool) (PointerIsValid(pointer) && ((pointer)->ip_posid != 0))) 84 85 /* 86 * ItemPointerGetBlockNumberNoCheck 87 * Returns the block number of a disk item pointer. 88 */ 89 #define ItemPointerGetBlockNumberNoCheck(pointer) \ 90 ( \ 91 BlockIdGetBlockNumber(&(pointer)->ip_blkid) \ 92 ) 93 94 /* 95 * ItemPointerGetBlockNumber 96 * As above, but verifies that the item pointer looks valid. 97 */ 98 #define ItemPointerGetBlockNumber(pointer) \ 99 ( \ 100 AssertMacro(ItemPointerIsValid(pointer)), \ 101 ItemPointerGetBlockNumberNoCheck(pointer) \ 102 ) 103 104 /* 105 * ItemPointerGetOffsetNumberNoCheck 106 * Returns the offset number of a disk item pointer. 107 */ 108 #define ItemPointerGetOffsetNumberNoCheck(pointer) \ 109 ( \ 110 (pointer)->ip_posid \ 111 ) 112 113 /* 114 * ItemPointerGetOffsetNumber 115 * As above, but verifies that the item pointer looks valid. 116 */ 117 #define ItemPointerGetOffsetNumber(pointer) \ 118 ( \ 119 AssertMacro(ItemPointerIsValid(pointer)), \ 120 ItemPointerGetOffsetNumberNoCheck(pointer) \ 121 ) 122 123 /* 124 * ItemPointerSet 125 * Sets a disk item pointer to the specified block and offset. 126 */ 127 #define ItemPointerSet(pointer, blockNumber, offNum) \ 128 ( \ 129 AssertMacro(PointerIsValid(pointer)), \ 130 BlockIdSet(&((pointer)->ip_blkid), blockNumber), \ 131 (pointer)->ip_posid = offNum \ 132 ) 133 134 /* 135 * ItemPointerSetBlockNumber 136 * Sets a disk item pointer to the specified block. 137 */ 138 #define ItemPointerSetBlockNumber(pointer, blockNumber) \ 139 ( \ 140 AssertMacro(PointerIsValid(pointer)), \ 141 BlockIdSet(&((pointer)->ip_blkid), blockNumber) \ 142 ) 143 144 /* 145 * ItemPointerSetOffsetNumber 146 * Sets a disk item pointer to the specified offset. 147 */ 148 #define ItemPointerSetOffsetNumber(pointer, offsetNumber) \ 149 ( \ 150 AssertMacro(PointerIsValid(pointer)), \ 151 (pointer)->ip_posid = (offsetNumber) \ 152 ) 153 154 /* 155 * ItemPointerCopy 156 * Copies the contents of one disk item pointer to another. 157 * 158 * Should there ever be padding in an ItemPointer this would need to be handled 159 * differently as it's used as hash key. 160 */ 161 #define ItemPointerCopy(fromPointer, toPointer) \ 162 ( \ 163 AssertMacro(PointerIsValid(toPointer)), \ 164 AssertMacro(PointerIsValid(fromPointer)), \ 165 *(toPointer) = *(fromPointer) \ 166 ) 167 168 /* 169 * ItemPointerSetInvalid 170 * Sets a disk item pointer to be invalid. 171 */ 172 #define ItemPointerSetInvalid(pointer) \ 173 ( \ 174 AssertMacro(PointerIsValid(pointer)), \ 175 BlockIdSet(&((pointer)->ip_blkid), InvalidBlockNumber), \ 176 (pointer)->ip_posid = InvalidOffsetNumber \ 177 ) 178 179 /* 180 * ItemPointerIndicatesMovedPartitions 181 * True iff the block number indicates the tuple has moved to another 182 * partition. 183 */ 184 #define ItemPointerIndicatesMovedPartitions(pointer) \ 185 ( \ 186 ItemPointerGetOffsetNumber(pointer) == MovedPartitionsOffsetNumber && \ 187 ItemPointerGetBlockNumberNoCheck(pointer) == MovedPartitionsBlockNumber \ 188 ) 189 190 /* 191 * ItemPointerSetMovedPartitions 192 * Indicate that the item referenced by the itempointer has moved into a 193 * different partition. 194 */ 195 #define ItemPointerSetMovedPartitions(pointer) \ 196 ItemPointerSet((pointer), MovedPartitionsBlockNumber, MovedPartitionsOffsetNumber) 197 198 /* ---------------- 199 * externs 200 * ---------------- 201 */ 202 203 extern bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2); 204 extern int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2); 205 extern void ItemPointerInc(ItemPointer pointer); 206 extern void ItemPointerDec(ItemPointer pointer); 207 208 #endif /* ITEMPTR_H */ 209