Age Owner TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * itemptr.h
4 : * POSTGRES disk item pointer definitions.
5 : *
6 : *
7 : * Portions Copyright (c) 1996-2023, 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
270 peter 83 GNC 882968955 : ItemPointerIsValid(const ItemPointerData *pointer)
84 : {
85 882968955 : return PointerIsValid(pointer) && pointer->ip_posid != 0;
86 : }
87 :
9720 scrappy 88 ECB : /*
89 : * ItemPointerGetBlockNumberNoCheck
90 : * Returns the block number of a disk item pointer.
91 : */
92 : static inline BlockNumber
270 peter 93 GNC 420755180 : ItemPointerGetBlockNumberNoCheck(const ItemPointerData *pointer)
94 : {
95 420755180 : return BlockIdGetBlockNumber(&pointer->ip_blkid);
96 : }
2203 alvherre 97 ECB :
98 : /*
99 : * ItemPointerGetBlockNumber
100 : * As above, but verifies that the item pointer looks valid.
101 : */
102 : static inline BlockNumber
270 peter 103 GNC 310936156 : ItemPointerGetBlockNumber(const ItemPointerData *pointer)
104 : {
105 310936156 : Assert(ItemPointerIsValid(pointer));
106 310936156 : return ItemPointerGetBlockNumberNoCheck(pointer);
107 : }
9720 scrappy 108 ECB :
109 : /*
2203 alvherre 110 : * ItemPointerGetOffsetNumberNoCheck
9345 bruce 111 : * Returns the offset number of a disk item pointer.
112 : */
113 : static inline OffsetNumber
270 peter 114 GNC 894616525 : ItemPointerGetOffsetNumberNoCheck(const ItemPointerData *pointer)
115 : {
116 894616525 : return pointer->ip_posid;
117 : }
118 :
119 : /*
2203 alvherre 120 ECB : * ItemPointerGetOffsetNumber
121 : * As above, but verifies that the item pointer looks valid.
122 : */
123 : static inline OffsetNumber
270 peter 124 GNC 193253708 : ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
125 : {
126 193253708 : Assert(ItemPointerIsValid(pointer));
127 193253708 : return ItemPointerGetOffsetNumberNoCheck(pointer);
128 : }
129 :
130 : /*
8720 bruce 131 ECB : * ItemPointerSet
132 : * Sets a disk item pointer to the specified block and offset.
9720 scrappy 133 : */
134 : static inline void
270 peter 135 GNC 503005258 : ItemPointerSet(ItemPointerData *pointer, BlockNumber blockNumber, OffsetNumber offNum)
136 : {
137 503005258 : Assert(PointerIsValid(pointer));
138 503005258 : BlockIdSet(&pointer->ip_blkid, blockNumber);
139 503005258 : pointer->ip_posid = offNum;
140 503005258 : }
141 :
142 : /*
8720 bruce 143 ECB : * ItemPointerSetBlockNumber
144 : * Sets a disk item pointer to the specified block.
9720 scrappy 145 : */
146 : static inline void
270 peter 147 GNC 36731902 : ItemPointerSetBlockNumber(ItemPointerData *pointer, BlockNumber blockNumber)
148 : {
149 36731902 : Assert(PointerIsValid(pointer));
150 36731902 : BlockIdSet(&pointer->ip_blkid, blockNumber);
151 36731902 : }
152 :
153 : /*
154 : * ItemPointerSetOffsetNumber
155 : * Sets a disk item pointer to the specified offset.
9720 scrappy 156 ECB : */
157 : static inline void
270 peter 158 GNC 56812113 : ItemPointerSetOffsetNumber(ItemPointerData *pointer, OffsetNumber offsetNumber)
159 : {
160 56812113 : Assert(PointerIsValid(pointer));
161 56812113 : pointer->ip_posid = offsetNumber;
162 56812113 : }
163 :
164 : /*
165 : * ItemPointerCopy
166 : * Copies the contents of one disk item pointer to another.
167 : *
3324 rhaas 168 ECB : * Should there ever be padding in an ItemPointer this would need to be handled
169 : * differently as it's used as hash key.
9720 scrappy 170 : */
171 : static inline void
270 peter 172 GNC 15111946 : ItemPointerCopy(const ItemPointerData *fromPointer, ItemPointerData *toPointer)
173 : {
174 15111946 : Assert(PointerIsValid(toPointer));
175 15111946 : Assert(PointerIsValid(fromPointer));
176 15111946 : *toPointer = *fromPointer;
177 15111946 : }
178 :
179 : /*
180 : * ItemPointerSetInvalid
181 : * Sets a disk item pointer to be invalid.
182 : */
183 : static inline void
184 150959260 : ItemPointerSetInvalid(ItemPointerData *pointer)
185 : {
186 150959260 : Assert(PointerIsValid(pointer));
187 150959260 : BlockIdSet(&pointer->ip_blkid, InvalidBlockNumber);
188 150959260 : pointer->ip_posid = InvalidOffsetNumber;
189 150959260 : }
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 208981 : ItemPointerIndicatesMovedPartitions(const ItemPointerData *pointer)
198 : {
199 : return
200 208992 : ItemPointerGetOffsetNumber(pointer) == MovedPartitionsOffsetNumber &&
201 11 : ItemPointerGetBlockNumberNoCheck(pointer) == MovedPartitionsBlockNumber;
202 : }
1828 andres 203 ECB :
204 : /*
205 : * ItemPointerSetMovedPartitions
206 : * Indicate that the item referenced by the itempointer has moved into a
207 : * different partition.
208 : */
209 : static inline void
270 peter 210 GNC 523 : ItemPointerSetMovedPartitions(ItemPointerData *pointer)
211 : {
212 523 : ItemPointerSet(pointer, MovedPartitionsBlockNumber, MovedPartitionsOffsetNumber);
213 523 : }
1828 andres 214 ECB :
215 : /* ----------------
216 : * externs
9720 scrappy 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
55 peter 231 GNC 21517719 : DatumGetItemPointer(Datum X)
232 : {
233 21517719 : return (ItemPointer) DatumGetPointer(X);
234 : }
235 :
236 : static inline Datum
237 8714 : ItemPointerGetDatum(const ItemPointerData *X)
238 : {
239 8714 : 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 */
|