1 /*-------------------------------------------------------------------------
4 * POSTGRES disk item pointer definitions.
7 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
10 * src/include/storage/itemptr.h
12 *-------------------------------------------------------------------------
17 #include "storage/block.h"
18 #include "storage/off.h"
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.
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
36 typedef struct ItemPointerData
39 OffsetNumber ip_posid
;
42 /* If compiler understands packed and aligned pragmas, use those */
43 #if defined(pg_attribute_packed) && defined(pg_attribute_aligned)
45 pg_attribute_aligned(2)
49 typedef ItemPointerData
*ItemPointer
;
52 * special values used in heap tuples (t_ctid)
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
63 #define SpecTokenOffsetNumber 0xfffe
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.
69 #define MovedPartitionsOffsetNumber 0xfffd
70 #define MovedPartitionsBlockNumber InvalidBlockNumber
80 * True iff the disk item pointer is not NULL.
82 #define ItemPointerIsValid(pointer) \
83 ((bool) (PointerIsValid(pointer) && ((pointer)->ip_posid != 0)))
86 * ItemPointerGetBlockNumberNoCheck
87 * Returns the block number of a disk item pointer.
89 #define ItemPointerGetBlockNumberNoCheck(pointer) \
91 BlockIdGetBlockNumber(&(pointer)->ip_blkid) \
95 * ItemPointerGetBlockNumber
96 * As above, but verifies that the item pointer looks valid.
98 #define ItemPointerGetBlockNumber(pointer) \
100 AssertMacro(ItemPointerIsValid(pointer)), \
101 ItemPointerGetBlockNumberNoCheck(pointer) \
105 * ItemPointerGetOffsetNumberNoCheck
106 * Returns the offset number of a disk item pointer.
108 #define ItemPointerGetOffsetNumberNoCheck(pointer) \
110 (pointer)->ip_posid \
114 * ItemPointerGetOffsetNumber
115 * As above, but verifies that the item pointer looks valid.
117 #define ItemPointerGetOffsetNumber(pointer) \
119 AssertMacro(ItemPointerIsValid(pointer)), \
120 ItemPointerGetOffsetNumberNoCheck(pointer) \
125 * Sets a disk item pointer to the specified block and offset.
127 #define ItemPointerSet(pointer, blockNumber, offNum) \
129 AssertMacro(PointerIsValid(pointer)), \
130 BlockIdSet(&((pointer)->ip_blkid), blockNumber), \
131 (pointer)->ip_posid = offNum \
135 * ItemPointerSetBlockNumber
136 * Sets a disk item pointer to the specified block.
138 #define ItemPointerSetBlockNumber(pointer, blockNumber) \
140 AssertMacro(PointerIsValid(pointer)), \
141 BlockIdSet(&((pointer)->ip_blkid), blockNumber) \
145 * ItemPointerSetOffsetNumber
146 * Sets a disk item pointer to the specified offset.
148 #define ItemPointerSetOffsetNumber(pointer, offsetNumber) \
150 AssertMacro(PointerIsValid(pointer)), \
151 (pointer)->ip_posid = (offsetNumber) \
156 * Copies the contents of one disk item pointer to another.
158 * Should there ever be padding in an ItemPointer this would need to be handled
159 * differently as it's used as hash key.
161 #define ItemPointerCopy(fromPointer, toPointer) \
163 AssertMacro(PointerIsValid(toPointer)), \
164 AssertMacro(PointerIsValid(fromPointer)), \
165 *(toPointer) = *(fromPointer) \
169 * ItemPointerSetInvalid
170 * Sets a disk item pointer to be invalid.
172 #define ItemPointerSetInvalid(pointer) \
174 AssertMacro(PointerIsValid(pointer)), \
175 BlockIdSet(&((pointer)->ip_blkid), InvalidBlockNumber), \
176 (pointer)->ip_posid = InvalidOffsetNumber \
180 * ItemPointerIndicatesMovedPartitions
181 * True iff the block number indicates the tuple has moved to another
184 #define ItemPointerIndicatesMovedPartitions(pointer) \
186 ItemPointerGetOffsetNumber(pointer) == MovedPartitionsOffsetNumber && \
187 ItemPointerGetBlockNumberNoCheck(pointer) == MovedPartitionsBlockNumber \
191 * ItemPointerSetMovedPartitions
192 * Indicate that the item referenced by the itempointer has moved into a
193 * different partition.
195 #define ItemPointerSetMovedPartitions(pointer) \
196 ItemPointerSet((pointer), MovedPartitionsBlockNumber, MovedPartitionsOffsetNumber)
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
);
208 #endif /* ITEMPTR_H */