14 #ifndef HTUP_DETAILS_H
15 #define HTUP_DETAILS_H
34 #define MaxTupleAttributeNumber 1664
48 #define MaxHeapAttributeNumber 1600
166 #define FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK2 2
169 #define FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK 3
172 #define FIELDNO_HEAPTUPLEHEADERDATA_HOFF 4
177 #define FIELDNO_HEAPTUPLEHEADERDATA_BITS 5
185 #define SizeofHeapTupleHeader offsetof(HeapTupleHeaderData, t_bits)
190 #define HEAP_HASNULL 0x0001
191 #define HEAP_HASVARWIDTH 0x0002
192 #define HEAP_HASEXTERNAL 0x0004
193 #define HEAP_HASOID_OLD 0x0008
194 #define HEAP_XMAX_KEYSHR_LOCK 0x0010
195 #define HEAP_COMBOCID 0x0020
196 #define HEAP_XMAX_EXCL_LOCK 0x0040
197 #define HEAP_XMAX_LOCK_ONLY 0x0080
200 #define HEAP_XMAX_SHR_LOCK (HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_KEYSHR_LOCK)
202 #define HEAP_LOCK_MASK (HEAP_XMAX_SHR_LOCK | HEAP_XMAX_EXCL_LOCK | \
203 HEAP_XMAX_KEYSHR_LOCK)
204 #define HEAP_XMIN_COMMITTED 0x0100
205 #define HEAP_XMIN_INVALID 0x0200
206 #define HEAP_XMIN_FROZEN (HEAP_XMIN_COMMITTED|HEAP_XMIN_INVALID)
207 #define HEAP_XMAX_COMMITTED 0x0400
208 #define HEAP_XMAX_INVALID 0x0800
209 #define HEAP_XMAX_IS_MULTI 0x1000
210 #define HEAP_UPDATED 0x2000
211 #define HEAP_MOVED_OFF 0x4000
214 #define HEAP_MOVED_IN 0x8000
217 #define HEAP_MOVED (HEAP_MOVED_OFF | HEAP_MOVED_IN)
219 #define HEAP_XACT_MASK 0xFFF0
231 #define HEAP_XMAX_IS_LOCKED_ONLY(infomask) \
232 (((infomask) & HEAP_XMAX_LOCK_ONLY) || \
233 (((infomask) & (HEAP_XMAX_IS_MULTI | HEAP_LOCK_MASK)) == HEAP_XMAX_EXCL_LOCK))
253 #define HEAP_LOCKED_UPGRADED(infomask) \
255 ((infomask) & HEAP_XMAX_IS_MULTI) != 0 && \
256 ((infomask) & HEAP_XMAX_LOCK_ONLY) != 0 && \
257 (((infomask) & (HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_KEYSHR_LOCK)) == 0) \
263 #define HEAP_XMAX_IS_SHR_LOCKED(infomask) \
264 (((infomask) & HEAP_LOCK_MASK) == HEAP_XMAX_SHR_LOCK)
265 #define HEAP_XMAX_IS_EXCL_LOCKED(infomask) \
266 (((infomask) & HEAP_LOCK_MASK) == HEAP_XMAX_EXCL_LOCK)
267 #define HEAP_XMAX_IS_KEYSHR_LOCKED(infomask) \
268 (((infomask) & HEAP_LOCK_MASK) == HEAP_XMAX_KEYSHR_LOCK)
271 #define HEAP_XMAX_BITS (HEAP_XMAX_COMMITTED | HEAP_XMAX_INVALID | \
272 HEAP_XMAX_IS_MULTI | HEAP_LOCK_MASK | HEAP_XMAX_LOCK_ONLY)
277 #define HEAP_NATTS_MASK 0x07FF
279 #define HEAP_KEYS_UPDATED 0x2000
281 #define HEAP_HOT_UPDATED 0x4000
282 #define HEAP_ONLY_TUPLE 0x8000
284 #define HEAP2_XACT_MASK 0xE000
292 #define HEAP_TUPLE_HAS_MATCH HEAP_ONLY_TUPLE
309 #define HeapTupleHeaderGetRawXmin(tup) \
311 (tup)->t_choice.t_heap.t_xmin \
314 #define HeapTupleHeaderGetXmin(tup) \
316 HeapTupleHeaderXminFrozen(tup) ? \
317 FrozenTransactionId : HeapTupleHeaderGetRawXmin(tup) \
320 #define HeapTupleHeaderSetXmin(tup, xid) \
322 (tup)->t_choice.t_heap.t_xmin = (xid) \
325 #define HeapTupleHeaderXminCommitted(tup) \
327 ((tup)->t_infomask & HEAP_XMIN_COMMITTED) != 0 \
330 #define HeapTupleHeaderXminInvalid(tup) \
332 ((tup)->t_infomask & (HEAP_XMIN_COMMITTED|HEAP_XMIN_INVALID)) == \
336 #define HeapTupleHeaderXminFrozen(tup) \
338 ((tup)->t_infomask & (HEAP_XMIN_FROZEN)) == HEAP_XMIN_FROZEN \
341 #define HeapTupleHeaderSetXminCommitted(tup) \
343 AssertMacro(!HeapTupleHeaderXminInvalid(tup)), \
344 ((tup)->t_infomask |= HEAP_XMIN_COMMITTED) \
347 #define HeapTupleHeaderSetXminInvalid(tup) \
349 AssertMacro(!HeapTupleHeaderXminCommitted(tup)), \
350 ((tup)->t_infomask |= HEAP_XMIN_INVALID) \
353 #define HeapTupleHeaderSetXminFrozen(tup) \
355 AssertMacro(!HeapTupleHeaderXminInvalid(tup)), \
356 ((tup)->t_infomask |= HEAP_XMIN_FROZEN) \
366 #define HeapTupleHeaderGetUpdateXid(tup) \
368 (!((tup)->t_infomask & HEAP_XMAX_INVALID) && \
369 ((tup)->t_infomask & HEAP_XMAX_IS_MULTI) && \
370 !((tup)->t_infomask & HEAP_XMAX_LOCK_ONLY)) ? \
371 HeapTupleGetUpdateXid(tup) \
373 HeapTupleHeaderGetRawXmax(tup) \
376 #define HeapTupleHeaderGetRawXmax(tup) \
378 (tup)->t_choice.t_heap.t_xmax \
381 #define HeapTupleHeaderSetXmax(tup, xid) \
383 (tup)->t_choice.t_heap.t_xmax = (xid) \
392 #define HeapTupleHeaderGetRawCommandId(tup) \
394 (tup)->t_choice.t_heap.t_field3.t_cid \
398 #define HeapTupleHeaderSetCmin(tup, cid) \
400 Assert(!((tup)->t_infomask & HEAP_MOVED)); \
401 (tup)->t_choice.t_heap.t_field3.t_cid = (cid); \
402 (tup)->t_infomask &= ~HEAP_COMBOCID; \
406 #define HeapTupleHeaderSetCmax(tup, cid, iscombo) \
408 Assert(!((tup)->t_infomask & HEAP_MOVED)); \
409 (tup)->t_choice.t_heap.t_field3.t_cid = (cid); \
411 (tup)->t_infomask |= HEAP_COMBOCID; \
413 (tup)->t_infomask &= ~HEAP_COMBOCID; \
416 #define HeapTupleHeaderGetXvac(tup) \
418 ((tup)->t_infomask & HEAP_MOVED) ? \
419 (tup)->t_choice.t_heap.t_field3.t_xvac \
421 InvalidTransactionId \
424 #define HeapTupleHeaderSetXvac(tup, xid) \
426 Assert((tup)->t_infomask & HEAP_MOVED); \
427 (tup)->t_choice.t_heap.t_field3.t_xvac = (xid); \
431 "invalid speculative token constant");
433 #define HeapTupleHeaderIsSpeculative(tup) \
435 (ItemPointerGetOffsetNumberNoCheck(&(tup)->t_ctid) == SpecTokenOffsetNumber) \
438 #define HeapTupleHeaderGetSpeculativeToken(tup) \
440 AssertMacro(HeapTupleHeaderIsSpeculative(tup)), \
441 ItemPointerGetBlockNumber(&(tup)->t_ctid) \
444 #define HeapTupleHeaderSetSpeculativeToken(tup, token) \
446 ItemPointerSet(&(tup)->t_ctid, token, SpecTokenOffsetNumber) \
449 #define HeapTupleHeaderIndicatesMovedPartitions(tup) \
450 ItemPointerIndicatesMovedPartitions(&(tup)->t_ctid)
452 #define HeapTupleHeaderSetMovedPartitions(tup) \
453 ItemPointerSetMovedPartitions(&(tup)->t_ctid)
455 #define HeapTupleHeaderGetDatumLength(tup) \
458 #define HeapTupleHeaderSetDatumLength(tup, len) \
459 SET_VARSIZE(tup, len)
461 #define HeapTupleHeaderGetTypeId(tup) \
463 (tup)->t_choice.t_datum.datum_typeid \
466 #define HeapTupleHeaderSetTypeId(tup, typeid) \
468 (tup)->t_choice.t_datum.datum_typeid = (typeid) \
471 #define HeapTupleHeaderGetTypMod(tup) \
473 (tup)->t_choice.t_datum.datum_typmod \
476 #define HeapTupleHeaderSetTypMod(tup, typmod) \
478 (tup)->t_choice.t_datum.datum_typmod = (typmod) \
487 #define HeapTupleHeaderIsHotUpdated(tup) \
489 ((tup)->t_infomask2 & HEAP_HOT_UPDATED) != 0 && \
490 ((tup)->t_infomask & HEAP_XMAX_INVALID) == 0 && \
491 !HeapTupleHeaderXminInvalid(tup) \
494 #define HeapTupleHeaderSetHotUpdated(tup) \
496 (tup)->t_infomask2 |= HEAP_HOT_UPDATED \
499 #define HeapTupleHeaderClearHotUpdated(tup) \
501 (tup)->t_infomask2 &= ~HEAP_HOT_UPDATED \
504 #define HeapTupleHeaderIsHeapOnly(tup) \
506 ((tup)->t_infomask2 & HEAP_ONLY_TUPLE) != 0 \
509 #define HeapTupleHeaderSetHeapOnly(tup) \
511 (tup)->t_infomask2 |= HEAP_ONLY_TUPLE \
514 #define HeapTupleHeaderClearHeapOnly(tup) \
516 (tup)->t_infomask2 &= ~HEAP_ONLY_TUPLE \
519 #define HeapTupleHeaderHasMatch(tup) \
521 ((tup)->t_infomask2 & HEAP_TUPLE_HAS_MATCH) != 0 \
524 #define HeapTupleHeaderSetMatch(tup) \
526 (tup)->t_infomask2 |= HEAP_TUPLE_HAS_MATCH \
529 #define HeapTupleHeaderClearMatch(tup) \
531 (tup)->t_infomask2 &= ~HEAP_TUPLE_HAS_MATCH \
534 #define HeapTupleHeaderGetNatts(tup) \
535 ((tup)->t_infomask2 & HEAP_NATTS_MASK)
537 #define HeapTupleHeaderSetNatts(tup, natts) \
539 (tup)->t_infomask2 = ((tup)->t_infomask2 & ~HEAP_NATTS_MASK) | (natts) \
542 #define HeapTupleHeaderHasExternal(tup) \
543 (((tup)->t_infomask & HEAP_HASEXTERNAL) != 0)
550 #define BITMAPLEN(NATTS) (((int)(NATTS) + 7) / 8)
563 #define MaxHeapTupleSize (BLCKSZ - MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData)))
564 #define MinHeapTupleSize MAXALIGN(SizeofHeapTupleHeader)
577 #define MaxHeapTuplesPerPage \
578 ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
579 (MAXALIGN(SizeofHeapTupleHeader) + sizeof(ItemIdData))))
588 #define MaxAttrSize (10 * 1024 * 1024)
622 #define MINIMAL_TUPLE_OFFSET \
623 ((offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) / MAXIMUM_ALIGNOF * MAXIMUM_ALIGNOF)
624 #define MINIMAL_TUPLE_PADDING \
625 ((offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) % MAXIMUM_ALIGNOF)
626 #define MINIMAL_TUPLE_DATA_OFFSET \
627 offsetof(MinimalTupleData, t_infomask2)
652 #define SizeofMinimalTupleHeader offsetof(MinimalTupleData, t_bits)
658 #define GETSTRUCT(TUP) ((char *) ((TUP)->t_data) + (TUP)->t_data->t_hoff)
664 #define HeapTupleHasNulls(tuple) \
665 (((tuple)->t_data->t_infomask & HEAP_HASNULL) != 0)
667 #define HeapTupleNoNulls(tuple) \
668 (!((tuple)->t_data->t_infomask & HEAP_HASNULL))
670 #define HeapTupleHasVarWidth(tuple) \
671 (((tuple)->t_data->t_infomask & HEAP_HASVARWIDTH) != 0)
673 #define HeapTupleAllFixed(tuple) \
674 (!((tuple)->t_data->t_infomask & HEAP_HASVARWIDTH))
676 #define HeapTupleHasExternal(tuple) \
677 (((tuple)->t_data->t_infomask & HEAP_HASEXTERNAL) != 0)
679 #define HeapTupleIsHotUpdated(tuple) \
680 HeapTupleHeaderIsHotUpdated((tuple)->t_data)
682 #define HeapTupleSetHotUpdated(tuple) \
683 HeapTupleHeaderSetHotUpdated((tuple)->t_data)
685 #define HeapTupleClearHotUpdated(tuple) \
686 HeapTupleHeaderClearHotUpdated((tuple)->t_data)
688 #define HeapTupleIsHeapOnly(tuple) \
689 HeapTupleHeaderIsHeapOnly((tuple)->t_data)
691 #define HeapTupleSetHeapOnly(tuple) \
692 HeapTupleHeaderSetHeapOnly((tuple)->t_data)
694 #define HeapTupleClearHeapOnly(tuple) \
695 HeapTupleHeaderClearHeapOnly((tuple)->t_data)
710 int attnum,
bool *isnull);
764 if (att->attcacheoff >= 0)
static Datum values[MAXATTR]
#define FLEXIBLE_ARRAY_MEMBER
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
struct HeapTupleFields HeapTupleFields
#define HeapTupleHeaderGetNatts(tup)
void heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest)
HeapTuple heap_copytuple(HeapTuple tuple)
size_t varsize_any(void *p)
MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup)
Datum heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
void heap_free_minimal_tuple(MinimalTuple mtup)
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
Datum nocachegetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc)
#define HeapTupleNoNulls(tuple)
Datum getmissingattr(TupleDesc tupleDesc, int attnum, bool *isnull)
HeapTuple heap_expand_tuple(HeapTuple sourceTuple, TupleDesc tupleDesc)
struct DatumTupleFields DatumTupleFields
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup)
Size heap_compute_data_size(TupleDesc tupleDesc, Datum *values, bool *isnull)
#define MINIMAL_TUPLE_PADDING
Datum heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc)
StaticAssertDecl(MaxOffsetNumber< SpecTokenOffsetNumber, "invalid speculative token constant")
void heap_fill_tuple(TupleDesc tupleDesc, Datum *values, bool *isnull, char *data, Size data_size, uint16 *infomask, bits8 *bit)
HeapTuple heap_tuple_from_minimal_tuple(MinimalTuple mtup)
MinimalTuple minimal_expand_tuple(HeapTuple sourceTuple, TupleDesc tupleDesc)
HeapTuple heap_modify_tuple_by_cols(HeapTuple tuple, TupleDesc tupleDesc, int nCols, int *replCols, Datum *replValues, bool *replIsnull)
static Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
void heap_freetuple(HeapTuple htup)
#define SpecTokenOffsetNumber
Assert(fmt[strlen(fmt) - 1] !='\n')
FormData_pg_attribute * Form_pg_attribute
union HeapTupleFields::@44 t_field3
char mt_padding[MINIMAL_TUPLE_PADDING]
bits8 t_bits[FLEXIBLE_ARRAY_MEMBER]
#define TupleDescAttr(tupdesc, i)
static bool att_isnull(int ATT, const bits8 *BITS)
Datum bit(PG_FUNCTION_ARGS)