1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * itemptr.h |
4 | * POSTGRES disk item pointer definitions. |
5 | * |
6 | * |
7 | * Portions Copyright (c) 1996-2019, 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 | * blkid tells us which block, posid tells us which entry in the linp |
26 | * (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 | |
206 | #endif /* ITEMPTR_H */ |
207 | |