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 */
36typedef 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
47ItemPointerData;
48
49typedef 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
203extern bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2);
204extern int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2);
205
206#endif /* ITEMPTR_H */
207