OSDN Git Service

Re-run pgindent with updated list of typedefs. (Updated README should
[pg-rex/syncrep.git] / src / include / access / htup.h
1 /*-------------------------------------------------------------------------
2  *
3  * htup.h
4  *        POSTGRES heap tuple definitions.
5  *
6  *
7  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * $PostgreSQL: pgsql/src/include/access/htup.h,v 1.97 2007/11/15 22:25:16 momjian Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14 #ifndef HTUP_H
15 #define HTUP_H
16
17 #include "storage/itemptr.h"
18 #include "storage/relfilenode.h"
19
20 /*
21  * MaxTupleAttributeNumber limits the number of (user) columns in a tuple.
22  * The key limit on this value is that the size of the fixed overhead for
23  * a tuple, plus the size of the null-values bitmap (at 1 bit per column),
24  * plus MAXALIGN alignment, must fit into t_hoff which is uint8.  On most
25  * machines the upper limit without making t_hoff wider would be a little
26  * over 1700.  We use round numbers here and for MaxHeapAttributeNumber
27  * so that alterations in HeapTupleHeaderData layout won't change the
28  * supported max number of columns.
29  */
30 #define MaxTupleAttributeNumber 1664    /* 8 * 208 */
31
32 /*
33  * MaxHeapAttributeNumber limits the number of (user) columns in a table.
34  * This should be somewhat less than MaxTupleAttributeNumber.  It must be
35  * at least one less, else we will fail to do UPDATEs on a maximal-width
36  * table (because UPDATE has to form working tuples that include CTID).
37  * In practice we want some additional daylight so that we can gracefully
38  * support operations that add hidden "resjunk" columns, for example
39  * SELECT * FROM wide_table ORDER BY foo, bar, baz.
40  * In any case, depending on column data types you will likely be running
41  * into the disk-block-based limit on overall tuple size if you have more
42  * than a thousand or so columns.  TOAST won't help.
43  */
44 #define MaxHeapAttributeNumber  1600    /* 8 * 200 */
45
46 /*
47  * Heap tuple header.  To avoid wasting space, the fields should be
48  * laid out in such a way as to avoid structure padding.
49  *
50  * Datums of composite types (row types) share the same general structure
51  * as on-disk tuples, so that the same routines can be used to build and
52  * examine them.  However the requirements are slightly different: a Datum
53  * does not need any transaction visibility information, and it does need
54  * a length word and some embedded type information.  We can achieve this
55  * by overlaying the xmin/cmin/xmax/cmax/xvac fields of a heap tuple
56  * with the fields needed in the Datum case.  Typically, all tuples built
57  * in-memory will be initialized with the Datum fields; but when a tuple is
58  * about to be inserted in a table, the transaction fields will be filled,
59  * overwriting the datum fields.
60  *
61  * The overall structure of a heap tuple looks like:
62  *                      fixed fields (HeapTupleHeaderData struct)
63  *                      nulls bitmap (if HEAP_HASNULL is set in t_infomask)
64  *                      alignment padding (as needed to make user data MAXALIGN'd)
65  *                      object ID (if HEAP_HASOID is set in t_infomask)
66  *                      user data fields
67  *
68  * We store five "virtual" fields Xmin, Cmin, Xmax, Cmax, and Xvac in three
69  * physical fields.  Xmin and Xmax are always really stored, but Cmin, Cmax
70  * and Xvac share a field.      This works because we know that Cmin and Cmax
71  * are only interesting for the lifetime of the inserting and deleting
72  * transaction respectively.  If a tuple is inserted and deleted in the same
73  * transaction, we store a "combo" command id that can be mapped to the real
74  * cmin and cmax, but only by use of local state within the originating
75  * backend.  See combocid.c for more details.  Meanwhile, Xvac is only set
76  * by VACUUM FULL, which does not have any command sub-structure and so does
77  * not need either Cmin or Cmax.  (This requires that VACUUM FULL never try
78  * to move a tuple whose Cmin or Cmax is still interesting, ie, an insert-
79  * in-progress or delete-in-progress tuple.)
80  *
81  * A word about t_ctid: whenever a new tuple is stored on disk, its t_ctid
82  * is initialized with its own TID (location).  If the tuple is ever updated,
83  * its t_ctid is changed to point to the replacement version of the tuple.
84  * Thus, a tuple is the latest version of its row iff XMAX is invalid or
85  * t_ctid points to itself (in which case, if XMAX is valid, the tuple is
86  * either locked or deleted).  One can follow the chain of t_ctid links
87  * to find the newest version of the row.  Beware however that VACUUM might
88  * erase the pointed-to (newer) tuple before erasing the pointing (older)
89  * tuple.  Hence, when following a t_ctid link, it is necessary to check
90  * to see if the referenced slot is empty or contains an unrelated tuple.
91  * Check that the referenced tuple has XMIN equal to the referencing tuple's
92  * XMAX to verify that it is actually the descendant version and not an
93  * unrelated tuple stored into a slot recently freed by VACUUM.  If either
94  * check fails, one may assume that there is no live descendant version.
95  *
96  * Following the fixed header fields, the nulls bitmap is stored (beginning
97  * at t_bits).  The bitmap is *not* stored if t_infomask shows that there
98  * are no nulls in the tuple.  If an OID field is present (as indicated by
99  * t_infomask), then it is stored just before the user data, which begins at
100  * the offset shown by t_hoff.  Note that t_hoff must be a multiple of
101  * MAXALIGN.
102  */
103
104 typedef struct HeapTupleFields
105 {
106         TransactionId t_xmin;           /* inserting xact ID */
107         TransactionId t_xmax;           /* deleting or locking xact ID */
108
109         union
110         {
111                 CommandId       t_cid;          /* inserting or deleting command ID, or both */
112                 TransactionId t_xvac;   /* VACUUM FULL xact ID */
113         }                       t_field3;
114 } HeapTupleFields;
115
116 typedef struct DatumTupleFields
117 {
118         int32           datum_len_;             /* varlena header (do not touch directly!) */
119
120         int32           datum_typmod;   /* -1, or identifier of a record type */
121
122         Oid                     datum_typeid;   /* composite type OID, or RECORDOID */
123
124         /*
125          * Note: field ordering is chosen with thought that Oid might someday
126          * widen to 64 bits.
127          */
128 } DatumTupleFields;
129
130 typedef struct HeapTupleHeaderData
131 {
132         union
133         {
134                 HeapTupleFields t_heap;
135                 DatumTupleFields t_datum;
136         }                       t_choice;
137
138         ItemPointerData t_ctid;         /* current TID of this or newer tuple */
139
140         /* Fields below here must match MinimalTupleData! */
141
142         uint16          t_infomask2;    /* number of attributes + various flags */
143
144         uint16          t_infomask;             /* various flag bits, see below */
145
146         uint8           t_hoff;                 /* sizeof header incl. bitmap, padding */
147
148         /* ^ - 23 bytes - ^ */
149
150         bits8           t_bits[1];              /* bitmap of NULLs -- VARIABLE LENGTH */
151
152         /* MORE DATA FOLLOWS AT END OF STRUCT */
153 } HeapTupleHeaderData;
154
155 typedef HeapTupleHeaderData *HeapTupleHeader;
156
157 /*
158  * information stored in t_infomask:
159  */
160 #define HEAP_HASNULL                    0x0001  /* has null attribute(s) */
161 #define HEAP_HASVARWIDTH                0x0002  /* has variable-width attribute(s) */
162 #define HEAP_HASEXTERNAL                0x0004  /* has external stored attribute(s) */
163 #define HEAP_HASOID                             0x0008  /* has an object-id field */
164 /* bit 0x0010 is available */
165 #define HEAP_COMBOCID                   0x0020  /* t_cid is a combo cid */
166 #define HEAP_XMAX_EXCL_LOCK             0x0040  /* xmax is exclusive locker */
167 #define HEAP_XMAX_SHARED_LOCK   0x0080  /* xmax is shared locker */
168 /* if either LOCK bit is set, xmax hasn't deleted the tuple, only locked it */
169 #define HEAP_IS_LOCKED  (HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_SHARED_LOCK)
170 #define HEAP_XMIN_COMMITTED             0x0100  /* t_xmin committed */
171 #define HEAP_XMIN_INVALID               0x0200  /* t_xmin invalid/aborted */
172 #define HEAP_XMAX_COMMITTED             0x0400  /* t_xmax committed */
173 #define HEAP_XMAX_INVALID               0x0800  /* t_xmax invalid/aborted */
174 #define HEAP_XMAX_IS_MULTI              0x1000  /* t_xmax is a MultiXactId */
175 #define HEAP_UPDATED                    0x2000  /* this is UPDATEd version of row */
176 #define HEAP_MOVED_OFF                  0x4000  /* moved to another place by VACUUM
177                                                                                  * FULL */
178 #define HEAP_MOVED_IN                   0x8000  /* moved from another place by VACUUM
179                                                                                  * FULL */
180 #define HEAP_MOVED (HEAP_MOVED_OFF | HEAP_MOVED_IN)
181
182 #define HEAP_XACT_MASK                  0xFFE0  /* visibility-related bits */
183
184 /*
185  * information stored in t_infomask2:
186  */
187 #define HEAP_NATTS_MASK                 0x07FF  /* 11 bits for number of attributes */
188 /* bits 0x3800 are available */
189 #define HEAP_HOT_UPDATED                0x4000  /* tuple was HOT-updated */
190 #define HEAP_ONLY_TUPLE                 0x8000  /* this is heap-only tuple */
191
192 #define HEAP2_XACT_MASK                 0xC000  /* visibility-related bits */
193
194 /*
195  * HeapTupleHeader accessor macros
196  *
197  * Note: beware of multiple evaluations of "tup" argument.      But the Set
198  * macros evaluate their other argument only once.
199  */
200
201 #define HeapTupleHeaderGetXmin(tup) \
202 ( \
203         (tup)->t_choice.t_heap.t_xmin \
204 )
205
206 #define HeapTupleHeaderSetXmin(tup, xid) \
207 ( \
208         (tup)->t_choice.t_heap.t_xmin = (xid) \
209 )
210
211 #define HeapTupleHeaderGetXmax(tup) \
212 ( \
213         (tup)->t_choice.t_heap.t_xmax \
214 )
215
216 #define HeapTupleHeaderSetXmax(tup, xid) \
217 ( \
218         (tup)->t_choice.t_heap.t_xmax = (xid) \
219 )
220
221 /*
222  * HeapTupleHeaderGetRawCommandId will give you what's in the header whether
223  * it is useful or not.  Most code should use HeapTupleHeaderGetCmin or
224  * HeapTupleHeaderGetCmax instead, but note that those Assert that you can
225  * get a legitimate result, ie you are in the originating transaction!
226  */
227 #define HeapTupleHeaderGetRawCommandId(tup) \
228 ( \
229         (tup)->t_choice.t_heap.t_field3.t_cid \
230 )
231
232 /* SetCmin is reasonably simple since we never need a combo CID */
233 #define HeapTupleHeaderSetCmin(tup, cid) \
234 do { \
235         Assert(!((tup)->t_infomask & HEAP_MOVED)); \
236         (tup)->t_choice.t_heap.t_field3.t_cid = (cid); \
237         (tup)->t_infomask &= ~HEAP_COMBOCID; \
238 } while (0)
239
240 /* SetCmax must be used after HeapTupleHeaderAdjustCmax; see combocid.c */
241 #define HeapTupleHeaderSetCmax(tup, cid, iscombo) \
242 do { \
243         Assert(!((tup)->t_infomask & HEAP_MOVED)); \
244         (tup)->t_choice.t_heap.t_field3.t_cid = (cid); \
245         if (iscombo) \
246                 (tup)->t_infomask |= HEAP_COMBOCID; \
247         else \
248                 (tup)->t_infomask &= ~HEAP_COMBOCID; \
249 } while (0)
250
251 #define HeapTupleHeaderGetXvac(tup) \
252 ( \
253         ((tup)->t_infomask & HEAP_MOVED) ? \
254                 (tup)->t_choice.t_heap.t_field3.t_xvac \
255         : \
256                 InvalidTransactionId \
257 )
258
259 #define HeapTupleHeaderSetXvac(tup, xid) \
260 do { \
261         Assert((tup)->t_infomask & HEAP_MOVED); \
262         (tup)->t_choice.t_heap.t_field3.t_xvac = (xid); \
263 } while (0)
264
265 #define HeapTupleHeaderGetDatumLength(tup) \
266         VARSIZE(tup)
267
268 #define HeapTupleHeaderSetDatumLength(tup, len) \
269         SET_VARSIZE(tup, len)
270
271 #define HeapTupleHeaderGetTypeId(tup) \
272 ( \
273         (tup)->t_choice.t_datum.datum_typeid \
274 )
275
276 #define HeapTupleHeaderSetTypeId(tup, typeid) \
277 ( \
278         (tup)->t_choice.t_datum.datum_typeid = (typeid) \
279 )
280
281 #define HeapTupleHeaderGetTypMod(tup) \
282 ( \
283         (tup)->t_choice.t_datum.datum_typmod \
284 )
285
286 #define HeapTupleHeaderSetTypMod(tup, typmod) \
287 ( \
288         (tup)->t_choice.t_datum.datum_typmod = (typmod) \
289 )
290
291 #define HeapTupleHeaderGetOid(tup) \
292 ( \
293         ((tup)->t_infomask & HEAP_HASOID) ? \
294                 *((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) \
295         : \
296                 InvalidOid \
297 )
298
299 #define HeapTupleHeaderSetOid(tup, oid) \
300 do { \
301         Assert((tup)->t_infomask & HEAP_HASOID); \
302         *((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) = (oid); \
303 } while (0)
304
305 /*
306  * Note that we stop considering a tuple HOT-updated as soon as it is known
307  * aborted or the would-be updating transaction is known aborted.  For best
308  * efficiency, check tuple visibility before using this macro, so that the
309  * INVALID bits will be as up to date as possible.
310  */
311 #define HeapTupleHeaderIsHotUpdated(tup) \
312 ( \
313         ((tup)->t_infomask2 & HEAP_HOT_UPDATED) != 0 && \
314         ((tup)->t_infomask & (HEAP_XMIN_INVALID | HEAP_XMAX_INVALID)) == 0 \
315 )
316
317 #define HeapTupleHeaderSetHotUpdated(tup) \
318 ( \
319         (tup)->t_infomask2 |= HEAP_HOT_UPDATED \
320 )
321
322 #define HeapTupleHeaderClearHotUpdated(tup) \
323 ( \
324         (tup)->t_infomask2 &= ~HEAP_HOT_UPDATED \
325 )
326
327 #define HeapTupleHeaderIsHeapOnly(tup) \
328 ( \
329   (tup)->t_infomask2 & HEAP_ONLY_TUPLE \
330 )
331
332 #define HeapTupleHeaderSetHeapOnly(tup) \
333 ( \
334   (tup)->t_infomask2 |= HEAP_ONLY_TUPLE \
335 )
336
337 #define HeapTupleHeaderClearHeapOnly(tup) \
338 ( \
339   (tup)->t_infomask2 &= ~HEAP_ONLY_TUPLE \
340 )
341
342 #define HeapTupleHeaderGetNatts(tup) \
343         ((tup)->t_infomask2 & HEAP_NATTS_MASK)
344
345 #define HeapTupleHeaderSetNatts(tup, natts) \
346 ( \
347         (tup)->t_infomask2 = ((tup)->t_infomask2 & ~HEAP_NATTS_MASK) | (natts) \
348 )
349
350
351 /*
352  * BITMAPLEN(NATTS) -
353  *              Computes size of null bitmap given number of data columns.
354  */
355 #define BITMAPLEN(NATTS)        (((int)(NATTS) + 7) / 8)
356
357 /*
358  * MaxHeapTupleSize is the maximum allowed size of a heap tuple, including
359  * header and MAXALIGN alignment padding.  Basically it's BLCKSZ minus the
360  * other stuff that has to be on a disk page.  Since heap pages use no
361  * "special space", there's no deduction for that.
362  *
363  * NOTE: we do not need to count an ItemId for the tuple because
364  * sizeof(PageHeaderData) includes the first ItemId on the page.  But beware
365  * of assuming that, say, you can fit 2 tuples of size MaxHeapTupleSize/2
366  * on the same page.
367  */
368 #define MaxHeapTupleSize  (BLCKSZ - MAXALIGN(sizeof(PageHeaderData)))
369
370 /*
371  * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can
372  * fit on one heap page.  (Note that indexes could have more, because they
373  * use a smaller tuple header.)  We arrive at the divisor because each tuple
374  * must be maxaligned, and it must have an associated item pointer.
375  *
376  * Note: with HOT, there could theoretically be more line pointers (not actual
377  * tuples) than this on a heap page.  However we constrain the number of line
378  * pointers to this anyway, to avoid excessive line-pointer bloat and not
379  * require increases in the size of work arrays.
380  */
381 #define MaxHeapTuplesPerPage    \
382         ((int) ((BLCKSZ - offsetof(PageHeaderData, pd_linp)) / \
383                         (MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData))))
384
385 /*
386  * MaxAttrSize is a somewhat arbitrary upper limit on the declared size of
387  * data fields of char(n) and similar types.  It need not have anything
388  * directly to do with the *actual* upper limit of varlena values, which
389  * is currently 1Gb (see TOAST structures in postgres.h).  I've set it
390  * at 10Mb which seems like a reasonable number --- tgl 8/6/00.
391  */
392 #define MaxAttrSize             (10 * 1024 * 1024)
393
394
395 /*
396  * Attribute numbers for the system-defined attributes
397  */
398 #define SelfItemPointerAttributeNumber                  (-1)
399 #define ObjectIdAttributeNumber                                 (-2)
400 #define MinTransactionIdAttributeNumber                 (-3)
401 #define MinCommandIdAttributeNumber                             (-4)
402 #define MaxTransactionIdAttributeNumber                 (-5)
403 #define MaxCommandIdAttributeNumber                             (-6)
404 #define TableOidAttributeNumber                                 (-7)
405 #define FirstLowInvalidHeapAttributeNumber              (-8)
406
407
408 /*
409  * MinimalTuple is an alternative representation that is used for transient
410  * tuples inside the executor, in places where transaction status information
411  * is not required, the tuple rowtype is known, and shaving off a few bytes
412  * is worthwhile because we need to store many tuples.  The representation
413  * is chosen so that tuple access routines can work with either full or
414  * minimal tuples via a HeapTupleData pointer structure.  The access routines
415  * see no difference, except that they must not access the transaction status
416  * or t_ctid fields because those aren't there.
417  *
418  * For the most part, MinimalTuples should be accessed via TupleTableSlot
419  * routines.  These routines will prevent access to the "system columns"
420  * and thereby prevent accidental use of the nonexistent fields.
421  *
422  * MinimalTupleData contains a length word, some padding, and fields matching
423  * HeapTupleHeaderData beginning with t_infomask2. The padding is chosen so
424  * that offsetof(t_infomask2) is the same modulo MAXIMUM_ALIGNOF in both
425  * structs.   This makes data alignment rules equivalent in both cases.
426  *
427  * When a minimal tuple is accessed via a HeapTupleData pointer, t_data is
428  * set to point MINIMAL_TUPLE_OFFSET bytes before the actual start of the
429  * minimal tuple --- that is, where a full tuple matching the minimal tuple's
430  * data would start.  This trick is what makes the structs seem equivalent.
431  *
432  * Note that t_hoff is computed the same as in a full tuple, hence it includes
433  * the MINIMAL_TUPLE_OFFSET distance.  t_len does not include that, however.
434  */
435 #define MINIMAL_TUPLE_OFFSET \
436         ((offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) / MAXIMUM_ALIGNOF * MAXIMUM_ALIGNOF)
437 #define MINIMAL_TUPLE_PADDING \
438         ((offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) % MAXIMUM_ALIGNOF)
439
440 typedef struct MinimalTupleData
441 {
442         uint32          t_len;                  /* actual length of minimal tuple */
443
444         char            mt_padding[MINIMAL_TUPLE_PADDING];
445
446         /* Fields below here must match HeapTupleHeaderData! */
447
448         uint16          t_infomask2;    /* number of attributes + various flags */
449
450         uint16          t_infomask;             /* various flag bits, see below */
451
452         uint8           t_hoff;                 /* sizeof header incl. bitmap, padding */
453
454         /* ^ - 23 bytes - ^ */
455
456         bits8           t_bits[1];              /* bitmap of NULLs -- VARIABLE LENGTH */
457
458         /* MORE DATA FOLLOWS AT END OF STRUCT */
459 } MinimalTupleData;
460
461 typedef MinimalTupleData *MinimalTuple;
462
463
464 /*
465  * HeapTupleData is an in-memory data structure that points to a tuple.
466  *
467  * There are several ways in which this data structure is used:
468  *
469  * * Pointer to a tuple in a disk buffer: t_data points directly into the
470  *       buffer (which the code had better be holding a pin on, but this is not
471  *       reflected in HeapTupleData itself).
472  *
473  * * Pointer to nothing: t_data is NULL.  This is used as a failure indication
474  *       in some functions.
475  *
476  * * Part of a palloc'd tuple: the HeapTupleData itself and the tuple
477  *       form a single palloc'd chunk.  t_data points to the memory location
478  *       immediately following the HeapTupleData struct (at offset HEAPTUPLESIZE).
479  *       This is the output format of heap_form_tuple and related routines.
480  *
481  * * Separately allocated tuple: t_data points to a palloc'd chunk that
482  *       is not adjacent to the HeapTupleData.  (This case is deprecated since
483  *       it's difficult to tell apart from case #1.  It should be used only in
484  *       limited contexts where the code knows that case #1 will never apply.)
485  *
486  * * Separately allocated minimal tuple: t_data points MINIMAL_TUPLE_OFFSET
487  *       bytes before the start of a MinimalTuple.      As with the previous case,
488  *       this can't be told apart from case #1 by inspection; code setting up
489  *       or destroying this representation has to know what it's doing.
490  *
491  * t_len should always be valid, except in the pointer-to-nothing case.
492  * t_self and t_tableOid should be valid if the HeapTupleData points to
493  * a disk buffer, or if it represents a copy of a tuple on disk.  They
494  * should be explicitly set invalid in manufactured tuples.
495  */
496 typedef struct HeapTupleData
497 {
498         uint32          t_len;                  /* length of *t_data */
499         ItemPointerData t_self;         /* SelfItemPointer */
500         Oid                     t_tableOid;             /* table the tuple came from */
501         HeapTupleHeader t_data;         /* -> tuple header and data */
502 } HeapTupleData;
503
504 typedef HeapTupleData *HeapTuple;
505
506 #define HEAPTUPLESIZE   MAXALIGN(sizeof(HeapTupleData))
507
508 /*
509  * GETSTRUCT - given a HeapTuple pointer, return address of the user data
510  */
511 #define GETSTRUCT(TUP) ((char *) ((TUP)->t_data) + (TUP)->t_data->t_hoff)
512
513 /*
514  * Accessor macros to be used with HeapTuple pointers.
515  */
516 #define HeapTupleIsValid(tuple) PointerIsValid(tuple)
517
518 #define HeapTupleHasNulls(tuple) \
519                 (((tuple)->t_data->t_infomask & HEAP_HASNULL) != 0)
520
521 #define HeapTupleNoNulls(tuple) \
522                 (!((tuple)->t_data->t_infomask & HEAP_HASNULL))
523
524 #define HeapTupleHasVarWidth(tuple) \
525                 (((tuple)->t_data->t_infomask & HEAP_HASVARWIDTH) != 0)
526
527 #define HeapTupleAllFixed(tuple) \
528                 (!((tuple)->t_data->t_infomask & HEAP_HASVARWIDTH))
529
530 #define HeapTupleHasExternal(tuple) \
531                 (((tuple)->t_data->t_infomask & HEAP_HASEXTERNAL) != 0)
532
533 #define HeapTupleIsHotUpdated(tuple) \
534                 HeapTupleHeaderIsHotUpdated((tuple)->t_data)
535
536 #define HeapTupleSetHotUpdated(tuple) \
537                 HeapTupleHeaderSetHotUpdated((tuple)->t_data)
538
539 #define HeapTupleClearHotUpdated(tuple) \
540                 HeapTupleHeaderClearHotUpdated((tuple)->t_data)
541
542 #define HeapTupleIsHeapOnly(tuple) \
543                 HeapTupleHeaderIsHeapOnly((tuple)->t_data)
544
545 #define HeapTupleSetHeapOnly(tuple) \
546                 HeapTupleHeaderSetHeapOnly((tuple)->t_data)
547
548 #define HeapTupleClearHeapOnly(tuple) \
549                 HeapTupleHeaderClearHeapOnly((tuple)->t_data)
550
551 #define HeapTupleGetOid(tuple) \
552                 HeapTupleHeaderGetOid((tuple)->t_data)
553
554 #define HeapTupleSetOid(tuple, oid) \
555                 HeapTupleHeaderSetOid((tuple)->t_data, (oid))
556
557
558 /*
559  * WAL record definitions for heapam.c's WAL operations
560  *
561  * XLOG allows to store some information in high 4 bits of log
562  * record xl_info field.  We use 3 for opcode and one for init bit.
563  */
564 #define XLOG_HEAP_INSERT                0x00
565 #define XLOG_HEAP_DELETE                0x10
566 #define XLOG_HEAP_UPDATE                0x20
567 #define XLOG_HEAP_MOVE                  0x30
568 #define XLOG_HEAP_HOT_UPDATE    0x40
569 #define XLOG_HEAP_NEWPAGE               0x50
570 #define XLOG_HEAP_LOCK                  0x60
571 #define XLOG_HEAP_INPLACE               0x70
572
573 #define XLOG_HEAP_OPMASK                0x70
574 /*
575  * When we insert 1st item on new page in INSERT/UPDATE
576  * we can (and we do) restore entire page in redo
577  */
578 #define XLOG_HEAP_INIT_PAGE             0x80
579 /*
580  * We ran out of opcodes, so heapam.c now has a second RmgrId.  These opcodes
581  * are associated with RM_HEAP2_ID, but are not logically different from
582  * the ones above associated with RM_HEAP_ID.  We apply XLOG_HEAP_OPMASK,
583  * although currently XLOG_HEAP_INIT_PAGE is not used for any of these.
584  */
585 #define XLOG_HEAP2_FREEZE               0x00
586 #define XLOG_HEAP2_CLEAN                0x10
587 #define XLOG_HEAP2_CLEAN_MOVE   0x20
588
589 /*
590  * All what we need to find changed tuple
591  *
592  * NB: on most machines, sizeof(xl_heaptid) will include some trailing pad
593  * bytes for alignment.  We don't want to store the pad space in the XLOG,
594  * so use SizeOfHeapTid for space calculations.  Similar comments apply for
595  * the other xl_FOO structs.
596  */
597 typedef struct xl_heaptid
598 {
599         RelFileNode node;
600         ItemPointerData tid;            /* changed tuple id */
601 } xl_heaptid;
602
603 #define SizeOfHeapTid           (offsetof(xl_heaptid, tid) + SizeOfIptrData)
604
605 /* This is what we need to know about delete */
606 typedef struct xl_heap_delete
607 {
608         xl_heaptid      target;                 /* deleted tuple id */
609 } xl_heap_delete;
610
611 #define SizeOfHeapDelete        (offsetof(xl_heap_delete, target) + SizeOfHeapTid)
612
613 /*
614  * We don't store the whole fixed part (HeapTupleHeaderData) of an inserted
615  * or updated tuple in WAL; we can save a few bytes by reconstructing the
616  * fields that are available elsewhere in the WAL record, or perhaps just
617  * plain needn't be reconstructed.  These are the fields we must store.
618  * NOTE: t_hoff could be recomputed, but we may as well store it because
619  * it will come for free due to alignment considerations.
620  */
621 typedef struct xl_heap_header
622 {
623         uint16          t_infomask2;
624         uint16          t_infomask;
625         uint8           t_hoff;
626 } xl_heap_header;
627
628 #define SizeOfHeapHeader        (offsetof(xl_heap_header, t_hoff) + sizeof(uint8))
629
630 /* This is what we need to know about insert */
631 typedef struct xl_heap_insert
632 {
633         xl_heaptid      target;                 /* inserted tuple id */
634         /* xl_heap_header & TUPLE DATA FOLLOWS AT END OF STRUCT */
635 } xl_heap_insert;
636
637 #define SizeOfHeapInsert        (offsetof(xl_heap_insert, target) + SizeOfHeapTid)
638
639 /* This is what we need to know about update|move|hot_update */
640 typedef struct xl_heap_update
641 {
642         xl_heaptid      target;                 /* deleted tuple id */
643         ItemPointerData newtid;         /* new inserted tuple id */
644         /* NEW TUPLE xl_heap_header (PLUS xmax & xmin IF MOVE OP) */
645         /* and TUPLE DATA FOLLOWS AT END OF STRUCT */
646 } xl_heap_update;
647
648 #define SizeOfHeapUpdate        (offsetof(xl_heap_update, newtid) + SizeOfIptrData)
649
650 /*
651  * This is what we need to know about vacuum page cleanup/redirect
652  *
653  * The array of OffsetNumbers following the fixed part of the record contains:
654  *      * for each redirected item: the item offset, then the offset redirected to
655  *      * for each now-dead item: the item offset
656  *      * for each now-unused item: the item offset
657  * The total number of OffsetNumbers is therefore 2*nredirected+ndead+nunused.
658  * Note that nunused is not explicitly stored, but may be found by reference
659  * to the total record length.
660  *
661  * If the opcode is CLEAN_MOVE instead of CLEAN, then each redirection pair
662  * should be interpreted as physically moving the "to" item pointer to the
663  * "from" slot, rather than placing a redirection item in the "from" slot.
664  * The moved pointers should be replaced by LP_UNUSED items (there will not
665  * be explicit entries in the "now-unused" list for this).      Also, the
666  * HEAP_ONLY bit in the moved tuples must be turned off.
667  */
668 typedef struct xl_heap_clean
669 {
670         RelFileNode node;
671         BlockNumber block;
672         uint16          nredirected;
673         uint16          ndead;
674         /* OFFSET NUMBERS FOLLOW */
675 } xl_heap_clean;
676
677 #define SizeOfHeapClean (offsetof(xl_heap_clean, ndead) + sizeof(uint16))
678
679 /* This is for replacing a page's contents in toto */
680 /* NB: this is used for indexes as well as heaps */
681 typedef struct xl_heap_newpage
682 {
683         RelFileNode node;
684         BlockNumber blkno;                      /* location of new page */
685         /* entire page contents follow at end of record */
686 } xl_heap_newpage;
687
688 #define SizeOfHeapNewpage       (offsetof(xl_heap_newpage, blkno) + sizeof(BlockNumber))
689
690 /* This is what we need to know about lock */
691 typedef struct xl_heap_lock
692 {
693         xl_heaptid      target;                 /* locked tuple id */
694         TransactionId locking_xid;      /* might be a MultiXactId not xid */
695         bool            xid_is_mxact;   /* is it? */
696         bool            shared_lock;    /* shared or exclusive row lock? */
697 } xl_heap_lock;
698
699 #define SizeOfHeapLock  (offsetof(xl_heap_lock, shared_lock) + sizeof(bool))
700
701 /* This is what we need to know about in-place update */
702 typedef struct xl_heap_inplace
703 {
704         xl_heaptid      target;                 /* updated tuple id */
705         /* TUPLE DATA FOLLOWS AT END OF STRUCT */
706 } xl_heap_inplace;
707
708 #define SizeOfHeapInplace       (offsetof(xl_heap_inplace, target) + SizeOfHeapTid)
709
710 /* This is what we need to know about tuple freezing during vacuum */
711 typedef struct xl_heap_freeze
712 {
713         RelFileNode node;
714         BlockNumber block;
715         TransactionId cutoff_xid;
716         /* TUPLE OFFSET NUMBERS FOLLOW AT THE END */
717 } xl_heap_freeze;
718
719 #define SizeOfHeapFreeze (offsetof(xl_heap_freeze, cutoff_xid) + sizeof(TransactionId))
720
721 /* HeapTupleHeader functions implemented in utils/time/combocid.c */
722 extern CommandId HeapTupleHeaderGetCmin(HeapTupleHeader tup);
723 extern CommandId HeapTupleHeaderGetCmax(HeapTupleHeader tup);
724 extern void HeapTupleHeaderAdjustCmax(HeapTupleHeader tup,
725                                                   CommandId *cmax,
726                                                   bool *iscombo);
727
728 #endif   /* HTUP_H */