1 /*-------------------------------------------------------------------------
2  *
3  * itemptr.h
4  *	  POSTGRES disk item pointer definitions.
5  *
6  *
7  * Portions Copyright (c) 1996-2020, 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 
206 #endif							/* ITEMPTR_H */
207