1 /*-------------------------------------------------------------------------
4 * POSTGRES heap tuple definitions.
7 * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
10 * $Id: htup.h,v 1.48 2001/03/25 22:40:58 tgl Exp $
12 *-------------------------------------------------------------------------
17 #include "storage/bufpage.h"
18 #include "storage/relfilenode.h"
20 #define MinHeapTupleBitmapSize 32 /* 8 * 4 */
23 * MaxHeapAttributeNumber limits the number of (user) columns in a table.
24 * The key limit on this value is that the size of the fixed overhead for
25 * a tuple, plus the size of the null-values bitmap (at 1 bit per column),
26 * plus MAXALIGN alignment, must fit into t_hoff which is uint8. On most
27 * machines the absolute upper limit without making t_hoff wider would be
28 * about 1700. Note, however, that depending on column data types you will
29 * likely also be running into the disk-block-based limit on overall tuple
30 * size if you have more than a thousand or so columns. TOAST won't help.
32 #define MaxHeapAttributeNumber 1600 /* 8 * 200 */
35 * This is the on-disk copy of the tuple.
37 * To avoid wasting space, the attributes should be layed out in such a
38 * way to reduce structure padding.
40 typedef struct HeapTupleHeaderData
42 Oid t_oid; /* OID of this tuple -- 4 bytes */
44 CommandId t_cmin; /* insert CID stamp -- 4 bytes each */
45 CommandId t_cmax; /* delete CommandId stamp */
47 TransactionId t_xmin; /* insert XID stamp -- 4 bytes each */
48 TransactionId t_xmax; /* delete XID stamp */
50 ItemPointerData t_ctid; /* current TID of this or newer tuple */
52 int16 t_natts; /* number of attributes */
54 uint16 t_infomask; /* various infos */
56 uint8 t_hoff; /* sizeof() tuple header */
58 /* ^ - 31 bytes - ^ */
60 bits8 t_bits[MinHeapTupleBitmapSize / 8];
61 /* bit map of NULLs */
63 /* MORE DATA FOLLOWS AT END OF STRUCT */
64 } HeapTupleHeaderData;
66 typedef HeapTupleHeaderData *HeapTupleHeader;
69 * XLOG allows to store some information in high 4 bits of log
70 * record xl_info field
72 #define XLOG_HEAP_INSERT 0x00
73 #define XLOG_HEAP_DELETE 0x10
74 #define XLOG_HEAP_UPDATE 0x20
75 #define XLOG_HEAP_MOVE 0x30
76 #define XLOG_HEAP_CLEAN 0x40
77 #define XLOG_HEAP_OPMASK 0x70
79 * When we insert 1st item on new page in INSERT/UPDATE
80 * we can (and we do) restore entire page in redo
82 #define XLOG_HEAP_INIT_PAGE 0x80
85 * All what we need to find changed tuple (18 bytes)
87 * NB: on most machines, sizeof(xl_heaptid) will include some trailing pad
88 * bytes for alignment. We don't want to store the pad space in the XLOG,
89 * so use SizeOfHeapTid for space calculations. Similar comments apply for
90 * the other xl_FOO structs.
92 typedef struct xl_heaptid
95 ItemPointerData tid; /* changed tuple id */
98 #define SizeOfHeapTid (offsetof(xl_heaptid, tid) + SizeOfIptrData)
100 /* This is what we need to know about delete */
101 typedef struct xl_heap_delete
103 xl_heaptid target; /* deleted tuple id */
106 #define SizeOfHeapDelete (offsetof(xl_heap_delete, target) + SizeOfHeapTid)
108 typedef struct xl_heap_header
113 uint8 mask; /* low 8 bits of t_infomask */
116 #define SizeOfHeapHeader (offsetof(xl_heap_header, mask) + sizeof(uint8))
118 /* This is what we need to know about insert */
119 typedef struct xl_heap_insert
121 xl_heaptid target; /* inserted tuple id */
122 /* xl_heap_header & TUPLE DATA FOLLOWS AT END OF STRUCT */
125 #define SizeOfHeapInsert (offsetof(xl_heap_insert, target) + SizeOfHeapTid)
127 /* This is what we need to know about update|move */
128 typedef struct xl_heap_update
130 xl_heaptid target; /* deleted tuple id */
131 ItemPointerData newtid; /* new inserted tuple id */
132 /* NEW TUPLE xl_heap_header (PLUS xmax & xmin IF MOVE OP) */
133 /* and TUPLE DATA FOLLOWS AT END OF STRUCT */
136 #define SizeOfHeapUpdate (offsetof(xl_heap_update, newtid) + SizeOfIptrData)
138 /* This is what we need to know about page cleanup */
139 typedef struct xl_heap_clean
143 /* UNUSED OFFSET NUMBERS FOLLOW AT THE END */
146 #define SizeOfHeapClean (offsetof(xl_heap_clean, block) + sizeof(BlockNumber))
149 * MaxTupleSize is the maximum allowed size of a tuple, including header and
150 * MAXALIGN alignment padding. Basically it's BLCKSZ minus the other stuff
151 * that has to be on a disk page. The "other stuff" includes access-method-
152 * dependent "special space", which we assume will be no more than
153 * MaxSpecialSpace bytes (currently, on heap pages it's actually zero).
155 * NOTE: we do not need to count an ItemId for the tuple because
156 * sizeof(PageHeaderData) includes the first ItemId on the page.
158 #define MaxSpecialSpace 32
160 #define MaxTupleSize \
161 (BLCKSZ - MAXALIGN(sizeof(PageHeaderData) + MaxSpecialSpace))
164 * MaxAttrSize is a somewhat arbitrary upper limit on the declared size of
165 * data fields of char(n) and similar types. It need not have anything
166 * directly to do with the *actual* upper limit of varlena values, which
167 * is currently 1Gb (see struct varattrib in postgres.h). I've set it
168 * at 10Mb which seems like a reasonable number --- tgl 8/6/00.
170 #define MaxAttrSize (10 * 1024 * 1024)
174 * Attribute numbers for the system-defined attributes
176 #define SelfItemPointerAttributeNumber (-1)
177 #define ObjectIdAttributeNumber (-2)
178 #define MinTransactionIdAttributeNumber (-3)
179 #define MinCommandIdAttributeNumber (-4)
180 #define MaxTransactionIdAttributeNumber (-5)
181 #define MaxCommandIdAttributeNumber (-6)
182 #define TableOidAttributeNumber (-7)
183 #define FirstLowInvalidHeapAttributeNumber (-8)
186 * This is the in-memory copy of the tuple.
188 * This new HeapTuple for version >= 6.5 and this is why it was changed:
190 * 1. t_len moved off on-disk tuple data - ItemIdData is used to get len;
191 * 2. t_ctid above is not self tuple TID now - it may point to
192 * updated version of tuple (required by MVCC);
193 * 3. someday someone let tuple to cross block boundaries -
194 * he have to add something below...
197 * Up to now t_data could be NULL, the memory location directly following
198 * HeapTupleData, or pointing into a buffer. Now, it could also point to
199 * a separate allocation that was done in the t_datamcxt memory context.
201 typedef struct HeapTupleData
203 uint32 t_len; /* length of *t_data */
204 ItemPointerData t_self; /* SelfItemPointer */
205 Oid t_tableOid; /* table the tuple came from */
206 MemoryContext t_datamcxt; /* memory context of allocation */
207 HeapTupleHeader t_data; /* -> tuple header and data */
210 typedef HeapTupleData *HeapTuple;
212 #define HEAPTUPLESIZE MAXALIGN(sizeof(HeapTupleData))
219 #define GETSTRUCT(TUP) (((char *)((HeapTuple)(TUP))->t_data) + \
220 ((HeapTuple)(TUP))->t_data->t_hoff)
225 * Computes minimum size of bitmap given number of domains.
227 #define BITMAPLEN(NATTS) \
228 ((((((int)(NATTS) - 1) >> 3) + 4 - (MinHeapTupleBitmapSize >> 3)) \
229 & ~03) + (MinHeapTupleBitmapSize >> 3))
233 * True iff the heap tuple is valid.
235 #define HeapTupleIsValid(tuple) PointerIsValid(tuple)
238 * information stored in t_infomask:
240 #define HEAP_HASNULL 0x0001 /* has null attribute(s) */
241 #define HEAP_HASVARLENA 0x0002 /* has variable length
243 #define HEAP_HASEXTERNAL 0x0004 /* has external stored */
245 #define HEAP_HASCOMPRESSED 0x0008 /* has compressed stored */
247 #define HEAP_HASEXTENDED 0x000C /* the two above combined */
249 #define HEAP_XMAX_UNLOGGED 0x0080 /* to lock tuple for update */
250 /* without logging */
251 #define HEAP_XMIN_COMMITTED 0x0100 /* t_xmin committed */
252 #define HEAP_XMIN_INVALID 0x0200 /* t_xmin invalid/aborted */
253 #define HEAP_XMAX_COMMITTED 0x0400 /* t_xmax committed */
254 #define HEAP_XMAX_INVALID 0x0800 /* t_xmax invalid/aborted */
255 #define HEAP_MARKED_FOR_UPDATE 0x1000 /* marked for UPDATE */
256 #define HEAP_UPDATED 0x2000 /* this is UPDATEd version of row */
257 #define HEAP_MOVED_OFF 0x4000 /* removed or moved to another
259 #define HEAP_MOVED_IN 0x8000 /* moved from another place by
262 #define HEAP_XACT_MASK 0xFFF0 /* */
264 #define HeapTupleNoNulls(tuple) \
265 (!(((HeapTuple) (tuple))->t_data->t_infomask & HEAP_HASNULL))
267 #define HeapTupleAllFixed(tuple) \
268 (!(((HeapTuple) (tuple))->t_data->t_infomask & HEAP_HASVARLENA))
270 #define HeapTupleHasExternal(tuple) \
271 ((((HeapTuple)(tuple))->t_data->t_infomask & HEAP_HASEXTERNAL) != 0)
273 #define HeapTupleHasCompressed(tuple) \
274 ((((HeapTuple)(tuple))->t_data->t_infomask & HEAP_HASCOMPRESSED) != 0)
276 #define HeapTupleHasExtended(tuple) \
277 ((((HeapTuple)(tuple))->t_data->t_infomask & HEAP_HASEXTENDED) != 0)