1 /*-------------------------------------------------------------------------
4 * POSTGRES disk item pointer definitions.
7 * Portions Copyright (c) 1996-2022, 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.
83 ItemPointerIsValid(const ItemPointerData
*pointer
)
85 return PointerIsValid(pointer
) && pointer
->ip_posid
!= 0;
89 * ItemPointerGetBlockNumberNoCheck
90 * Returns the block number of a disk item pointer.
92 static inline BlockNumber
93 ItemPointerGetBlockNumberNoCheck(const ItemPointerData
*pointer
)
95 return BlockIdGetBlockNumber(&pointer
->ip_blkid
);
99 * ItemPointerGetBlockNumber
100 * As above, but verifies that the item pointer looks valid.
102 static inline BlockNumber
103 ItemPointerGetBlockNumber(const ItemPointerData
*pointer
)
105 Assert(ItemPointerIsValid(pointer
));
106 return ItemPointerGetBlockNumberNoCheck(pointer
);
110 * ItemPointerGetOffsetNumberNoCheck
111 * Returns the offset number of a disk item pointer.
113 static inline OffsetNumber
114 ItemPointerGetOffsetNumberNoCheck(const ItemPointerData
*pointer
)
116 return pointer
->ip_posid
;
120 * ItemPointerGetOffsetNumber
121 * As above, but verifies that the item pointer looks valid.
123 static inline OffsetNumber
124 ItemPointerGetOffsetNumber(const ItemPointerData
*pointer
)
126 Assert(ItemPointerIsValid(pointer
));
127 return ItemPointerGetOffsetNumberNoCheck(pointer
);
132 * Sets a disk item pointer to the specified block and offset.
135 ItemPointerSet(ItemPointerData
*pointer
, BlockNumber blockNumber
, OffsetNumber offNum
)
137 Assert(PointerIsValid(pointer
));
138 BlockIdSet(&pointer
->ip_blkid
, blockNumber
);
139 pointer
->ip_posid
= offNum
;
143 * ItemPointerSetBlockNumber
144 * Sets a disk item pointer to the specified block.
147 ItemPointerSetBlockNumber(ItemPointerData
*pointer
, BlockNumber blockNumber
)
149 Assert(PointerIsValid(pointer
));
150 BlockIdSet(&pointer
->ip_blkid
, blockNumber
);
154 * ItemPointerSetOffsetNumber
155 * Sets a disk item pointer to the specified offset.
158 ItemPointerSetOffsetNumber(ItemPointerData
*pointer
, OffsetNumber offsetNumber
)
160 Assert(PointerIsValid(pointer
));
161 pointer
->ip_posid
= offsetNumber
;
166 * Copies the contents of one disk item pointer to another.
168 * Should there ever be padding in an ItemPointer this would need to be handled
169 * differently as it's used as hash key.
172 ItemPointerCopy(const ItemPointerData
*fromPointer
, ItemPointerData
*toPointer
)
174 Assert(PointerIsValid(toPointer
));
175 Assert(PointerIsValid(fromPointer
));
176 *toPointer
= *fromPointer
;
180 * ItemPointerSetInvalid
181 * Sets a disk item pointer to be invalid.
184 ItemPointerSetInvalid(ItemPointerData
*pointer
)
186 Assert(PointerIsValid(pointer
));
187 BlockIdSet(&pointer
->ip_blkid
, InvalidBlockNumber
);
188 pointer
->ip_posid
= InvalidOffsetNumber
;
192 * ItemPointerIndicatesMovedPartitions
193 * True iff the block number indicates the tuple has moved to another
197 ItemPointerIndicatesMovedPartitions(const ItemPointerData
*pointer
)
200 ItemPointerGetOffsetNumber(pointer
) == MovedPartitionsOffsetNumber
&&
201 ItemPointerGetBlockNumberNoCheck(pointer
) == MovedPartitionsBlockNumber
;
205 * ItemPointerSetMovedPartitions
206 * Indicate that the item referenced by the itempointer has moved into a
207 * different partition.
210 ItemPointerSetMovedPartitions(ItemPointerData
*pointer
)
212 ItemPointerSet(pointer
, MovedPartitionsBlockNumber
, MovedPartitionsOffsetNumber
);
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
);
225 #endif /* ITEMPTR_H */