1
/*-------------------------------------------------------------------------
4
* This file contains heap tuple accessor and mutator routines, as well
5
* as various tuple utilities.
7
* Some notes about varlenas and this code:
9
* Before Postgres 8.3 varlenas always had a 4-byte length header, and
10
* therefore always needed 4-byte alignment (at least). This wasted space
11
* for short varlenas, for example CHAR(1) took 5 bytes and could need up to
12
* 3 additional padding bytes for alignment.
14
* Now, a short varlena (up to 126 data bytes) is reduced to a 1-byte header
15
* and we don't align it. To hide this from datatype-specific functions that
16
* don't want to deal with it, such a datum is considered "toasted" and will
17
* be expanded back to the normal 4-byte-header format by pg_detoast_datum.
18
* (In performance-critical code paths we can use pg_detoast_datum_packed
19
* and the appropriate access macros to avoid that overhead.) Note that this
20
* conversion is performed directly in heap_form_tuple, without invoking
23
* This change will break any code that assumes it needn't detoast values
24
* that have been put into a tuple but never sent to disk. Hopefully there
25
* are few such places.
27
* Varlenas still have alignment 'i' (or 'd') in pg_type/pg_attribute, since
28
* that's the normal requirement for the untoasted format. But we ignore that
29
* for the 1-byte-header format. This means that the actual start position
30
* of a varlena datum may vary depending on which format it has. To determine
31
* what is stored, we have to require that alignment padding bytes be zero.
32
* (Postgres actually has always zeroed them, but now it's required!) Since
33
* the first byte of a 1-byte-header varlena can never be zero, we can examine
34
* the first byte after the previous datum to tell if it's a pad byte or the
35
* start of a 1-byte-header varlena.
37
* Note that while formerly we could rely on the first varlena column of a
38
* system catalog to be at the offset suggested by the C struct for the
39
* catalog, this is now risky: it's only safe if the preceding field is
40
* word-aligned, so that there will never be any padding.
42
* We don't pack varlenas whose attstorage is 'p', since the data type
43
* isn't expecting to have to detoast values. This is used in particular
44
* by oidvector and int2vector, which are used in the system catalogs
45
* and we'd like to still refer to them via C struct offsets.
48
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
49
* Portions Copyright (c) 1994, Regents of the University of California
55
*-------------------------------------------------------------------------
60
#include "access/heapam.h"
61
#include "access/sysattr.h"
62
#include "access/tuptoaster.h"
63
#include "executor/tuptable.h"
66
/* Does att's datatype allow packing into the 1-byte-header varlena format? */
67
#define ATT_IS_PACKABLE(att) \
68
((att)->attlen == -1 && (att)->attstorage != 'p')
69
/* Use this if it's already known varlena */
70
#define VARLENA_ATT_IS_PACKABLE(att) \
71
((att)->attstorage != 'p')
74
/* ----------------------------------------------------------------
75
* misc support routines
76
* ----------------------------------------------------------------
81
* heap_compute_data_size
82
* Determine size of the data area of a tuple to be constructed
85
heap_compute_data_size(TupleDesc tupleDesc,
91
int numberOfAttributes = tupleDesc->natts;
92
Form_pg_attribute *att = tupleDesc->attrs;
94
for (i = 0; i < numberOfAttributes; i++)
103
if (ATT_IS_PACKABLE(att[i]) &&
104
VARATT_CAN_MAKE_SHORT(DatumGetPointer(val)))
107
* we're anticipating converting to a short varlena header, so
108
* adjust length and don't count any alignment
110
data_length += VARATT_CONVERTED_SHORT_SIZE(DatumGetPointer(val));
114
data_length = att_align_datum(data_length, att[i]->attalign,
115
att[i]->attlen, val);
116
data_length = att_addlength_datum(data_length, att[i]->attlen,
126
* Load data portion of a tuple from values/isnull arrays
128
* We also fill the null bitmap (if any) and set the infomask bits
129
* that reflect the tuple's data contents.
131
* NOTE: it is now REQUIRED that the caller have pre-zeroed the data area.
134
heap_fill_tuple(TupleDesc tupleDesc,
135
Datum *values, bool *isnull,
136
char *data, Size data_size,
137
uint16 *infomask, bits8 *bit)
142
int numberOfAttributes = tupleDesc->natts;
143
Form_pg_attribute *att = tupleDesc->attrs;
145
#ifdef USE_ASSERT_CHECKING
156
/* just to keep compiler quiet */
161
*infomask &= ~(HEAP_HASNULL | HEAP_HASVARWIDTH | HEAP_HASEXTERNAL);
163
for (i = 0; i < numberOfAttributes; i++)
169
if (bitmask != HIGHBIT)
180
*infomask |= HEAP_HASNULL;
188
* XXX we use the att_align macros on the pointer value itself, not on
189
* an offset. This is a bit of a hack.
192
if (att[i]->attbyval)
195
data = (char *) att_align_nominal((long) data, att[i]->attalign);
196
store_att_byval(data, values[i], att[i]->attlen);
197
data_length = att[i]->attlen;
199
else if (att[i]->attlen == -1)
202
Pointer val = DatumGetPointer(values[i]);
204
*infomask |= HEAP_HASVARWIDTH;
205
if (VARATT_IS_EXTERNAL(val))
207
*infomask |= HEAP_HASEXTERNAL;
208
/* no alignment, since it's short by definition */
209
data_length = VARSIZE_EXTERNAL(val);
210
memcpy(data, val, data_length);
212
else if (VARATT_IS_SHORT(val))
214
/* no alignment for short varlenas */
215
data_length = VARSIZE_SHORT(val);
216
memcpy(data, val, data_length);
218
else if (VARLENA_ATT_IS_PACKABLE(att[i]) &&
219
VARATT_CAN_MAKE_SHORT(val))
221
/* convert to short varlena -- no alignment */
222
data_length = VARATT_CONVERTED_SHORT_SIZE(val);
223
SET_VARSIZE_SHORT(data, data_length);
224
memcpy(data + 1, VARDATA(val), data_length - 1);
228
/* full 4-byte header varlena */
229
data = (char *) att_align_nominal((long) data,
231
data_length = VARSIZE(val);
232
memcpy(data, val, data_length);
235
else if (att[i]->attlen == -2)
237
/* cstring ... never needs alignment */
238
*infomask |= HEAP_HASVARWIDTH;
239
Assert(att[i]->attalign == 'c');
240
data_length = strlen(DatumGetCString(values[i])) + 1;
241
memcpy(data, DatumGetPointer(values[i]), data_length);
245
/* fixed-length pass-by-reference */
246
data = (char *) att_align_nominal((long) data, att[i]->attalign);
247
Assert(att[i]->attlen > 0);
248
data_length = att[i]->attlen;
249
memcpy(data, DatumGetPointer(values[i]), data_length);
255
Assert((data - start) == data_size);
259
/* ----------------------------------------------------------------
260
* heap tuple interface
261
* ----------------------------------------------------------------
265
* heap_attisnull - returns TRUE iff tuple attribute is not present
269
heap_attisnull(HeapTuple tup, int attnum)
271
if (attnum > (int) HeapTupleHeaderGetNatts(tup->t_data))
276
if (HeapTupleNoNulls(tup))
278
return att_isnull(attnum - 1, tup->t_data->t_bits);
283
case TableOidAttributeNumber:
284
case SelfItemPointerAttributeNumber:
285
case ObjectIdAttributeNumber:
286
case MinTransactionIdAttributeNumber:
287
case MinCommandIdAttributeNumber:
288
case MaxTransactionIdAttributeNumber:
289
case MaxCommandIdAttributeNumber:
290
/* these are never null */
294
elog(ERROR, "invalid attnum: %d", attnum);
303
* This only gets called from fastgetattr() macro, in cases where
304
* we can't use a cacheoffset and the value is not null.
306
* This caches attribute offsets in the attribute descriptor.
308
* An alternative way to speed things up would be to cache offsets
309
* with the tuple, but that seems more difficult unless you take
310
* the storage hit of actually putting those offsets into the
311
* tuple you send to disk. Yuck.
313
* This scheme will be slightly slower than that, but should
314
* perform well for queries which hit large #'s of tuples. After
315
* you cache the offsets once, examining all the other tuples using
316
* the same attribute descriptor will go much quicker. -cim 5/4/91
318
* NOTE: if you need to change this code, see also heap_deform_tuple.
319
* Also see nocache_index_getattr, which is the same code for index
324
nocachegetattr(HeapTuple tuple,
329
HeapTupleHeader tup = tuple->t_data;
330
Form_pg_attribute *att = tupleDesc->attrs;
331
char *tp; /* ptr to data part of tuple */
332
bits8 *bp = tup->t_bits; /* ptr to null bitmap in tuple */
333
bool slow = false; /* do we have to walk attrs? */
334
int off; /* current offset within data */
336
(void) isnull; /* not used */
341
* 1: No nulls and no variable-width attributes.
342
* 2: Has a null or a var-width AFTER att.
343
* 3: Has nulls or var-widths BEFORE att.
348
/* This is handled in the macro */
357
if (HeapTupleNoNulls(tuple))
360
/* This is handled in the macro */
361
if (att[attnum]->attcacheoff >= 0)
363
return fetchatt(att[attnum],
364
(char *) tup + tup->t_hoff +
365
att[attnum]->attcacheoff);
372
* there's a null somewhere in the tuple
374
* check to see if desired att is null
378
/* This is handled in the macro */
379
if (att_isnull(attnum, bp))
388
* Now check to see if any preceding bits are null...
391
int byte = attnum >> 3;
392
int finalbit = attnum & 0x07;
394
/* check for nulls "before" final bit of last byte */
395
if ((~bp[byte]) & ((1 << finalbit) - 1))
399
/* check for nulls in any "earlier" bytes */
402
for (i = 0; i < byte; i++)
414
tp = (char *) tup + tup->t_hoff;
419
* If we get here, there are no nulls up to and including the target
420
* attribute. If we have a cached offset, we can use it.
422
if (att[attnum]->attcacheoff >= 0)
424
return fetchatt(att[attnum],
425
tp + att[attnum]->attcacheoff);
429
* Otherwise, check for non-fixed-length attrs up to and including
430
* target. If there aren't any, it's safe to cheaply initialize the
431
* cached offsets for these attrs.
433
if (HeapTupleHasVarWidth(tuple))
437
for (j = 0; j <= attnum; j++)
439
if (att[j]->attlen <= 0)
450
int natts = tupleDesc->natts;
454
* If we get here, we have a tuple with no nulls or var-widths up to
455
* and including the target attribute, so we can use the cached offset
456
* ... only we don't have it yet, or we'd not have got here. Since
457
* it's cheap to compute offsets for fixed-width columns, we take the
458
* opportunity to initialize the cached offsets for *all* the leading
459
* fixed-width columns, in hope of avoiding future visits to this
462
att[0]->attcacheoff = 0;
464
/* we might have set some offsets in the slow path previously */
465
while (j < natts && att[j]->attcacheoff > 0)
468
off = att[j - 1]->attcacheoff + att[j - 1]->attlen;
470
for (; j < natts; j++)
472
if (att[j]->attlen <= 0)
475
off = att_align_nominal(off, att[j]->attalign);
477
att[j]->attcacheoff = off;
479
off += att[j]->attlen;
484
off = att[attnum]->attcacheoff;
488
bool usecache = true;
492
* Now we know that we have to walk the tuple CAREFULLY. But we still
493
* might be able to cache some offsets for next time.
495
* Note - This loop is a little tricky. For each non-null attribute,
496
* we have to first account for alignment padding before the attr,
497
* then advance over the attr based on its length. Nulls have no
498
* storage and no alignment padding either. We can use/set
499
* attcacheoff until we reach either a null or a var-width attribute.
502
for (i = 0;; i++) /* loop exit is at "break" */
504
if (HeapTupleHasNulls(tuple) && att_isnull(i, bp))
507
continue; /* this cannot be the target att */
510
/* If we know the next offset, we can skip the rest */
511
if (usecache && att[i]->attcacheoff >= 0)
512
off = att[i]->attcacheoff;
513
else if (att[i]->attlen == -1)
516
* We can only cache the offset for a varlena attribute if the
517
* offset is already suitably aligned, so that there would be
518
* no pad bytes in any case: then the offset will be valid for
519
* either an aligned or unaligned value.
522
off == att_align_nominal(off, att[i]->attalign))
523
att[i]->attcacheoff = off;
526
off = att_align_pointer(off, att[i]->attalign, -1,
533
/* not varlena, so safe to use att_align_nominal */
534
off = att_align_nominal(off, att[i]->attalign);
537
att[i]->attcacheoff = off;
543
off = att_addlength_pointer(off, att[i]->attlen, tp + off);
545
if (usecache && att[i]->attlen <= 0)
550
return fetchatt(att[attnum], tp + off);
556
* Fetch the value of a system attribute for a tuple.
558
* This is a support routine for the heap_getattr macro. The macro
559
* has already determined that the attnum refers to a system attribute.
563
heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
569
/* Currently, no sys attribute ever reads as NULL. */
575
case SelfItemPointerAttributeNumber:
576
/* pass-by-reference datatype */
577
result = PointerGetDatum(&(tup->t_self));
579
case ObjectIdAttributeNumber:
580
result = ObjectIdGetDatum(HeapTupleGetOid(tup));
582
case MinTransactionIdAttributeNumber:
583
result = TransactionIdGetDatum(HeapTupleHeaderGetXmin(tup->t_data));
585
case MaxTransactionIdAttributeNumber:
586
result = TransactionIdGetDatum(HeapTupleHeaderGetXmax(tup->t_data));
588
case MinCommandIdAttributeNumber:
589
case MaxCommandIdAttributeNumber:
592
* cmin and cmax are now both aliases for the same field, which
593
* can in fact also be a combo command id. XXX perhaps we should
594
* return the "real" cmin or cmax if possible, that is if we are
595
* inside the originating transaction?
597
result = CommandIdGetDatum(HeapTupleHeaderGetRawCommandId(tup->t_data));
599
case TableOidAttributeNumber:
600
result = ObjectIdGetDatum(tup->t_tableOid);
603
elog(ERROR, "invalid attnum: %d", attnum);
604
result = 0; /* keep compiler quiet */
613
* returns a copy of an entire tuple
615
* The HeapTuple struct, tuple header, and tuple data are all allocated
616
* as a single palloc() block.
620
heap_copytuple(HeapTuple tuple)
624
if (!HeapTupleIsValid(tuple) || tuple->t_data == NULL)
627
newTuple = (HeapTuple) palloc(HEAPTUPLESIZE + tuple->t_len);
628
newTuple->t_len = tuple->t_len;
629
newTuple->t_self = tuple->t_self;
630
newTuple->t_tableOid = tuple->t_tableOid;
631
newTuple->t_data = (HeapTupleHeader) ((char *) newTuple + HEAPTUPLESIZE);
632
memcpy((char *) newTuple->t_data, (char *) tuple->t_data, tuple->t_len);
637
* heap_copytuple_with_tuple
639
* copy a tuple into a caller-supplied HeapTuple management struct
641
* Note that after calling this function, the "dest" HeapTuple will not be
642
* allocated as a single palloc() block (unlike with heap_copytuple()).
646
heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest)
648
if (!HeapTupleIsValid(src) || src->t_data == NULL)
654
dest->t_len = src->t_len;
655
dest->t_self = src->t_self;
656
dest->t_tableOid = src->t_tableOid;
657
dest->t_data = (HeapTupleHeader) palloc(src->t_len);
658
memcpy((char *) dest->t_data, (char *) src->t_data, src->t_len);
663
* construct a tuple from the given values[] and isnull[] arrays,
664
* which are of the length indicated by tupleDescriptor->natts
666
* The result is allocated in the current memory context.
669
heap_form_tuple(TupleDesc tupleDescriptor,
673
HeapTuple tuple; /* return tuple */
674
HeapTupleHeader td; /* tuple data */
678
bool hasnull = false;
679
Form_pg_attribute *att = tupleDescriptor->attrs;
680
int numberOfAttributes = tupleDescriptor->natts;
683
if (numberOfAttributes > MaxTupleAttributeNumber)
685
(errcode(ERRCODE_TOO_MANY_COLUMNS),
686
errmsg("number of columns (%d) exceeds limit (%d)",
687
numberOfAttributes, MaxTupleAttributeNumber)));
690
* Check for nulls and embedded tuples; expand any toasted attributes in
691
* embedded tuples. This preserves the invariant that toasting can only
694
* We can skip calling toast_flatten_tuple_attribute() if the attribute
695
* couldn't possibly be of composite type. All composite datums are
696
* varlena and have alignment 'd'; furthermore they aren't arrays. Also,
697
* if an attribute is already toasted, it must have been sent to disk
698
* already and so cannot contain toasted attributes.
700
for (i = 0; i < numberOfAttributes; i++)
704
else if (att[i]->attlen == -1 &&
705
att[i]->attalign == 'd' &&
706
att[i]->attndims == 0 &&
707
!VARATT_IS_EXTENDED(DatumGetPointer(values[i])))
709
values[i] = toast_flatten_tuple_attribute(values[i],
716
* Determine total space needed
718
len = offsetof(HeapTupleHeaderData, t_bits);
721
len += BITMAPLEN(numberOfAttributes);
723
if (tupleDescriptor->tdhasoid)
726
hoff = len = MAXALIGN(len); /* align user data safely */
728
data_len = heap_compute_data_size(tupleDescriptor, values, isnull);
733
* Allocate and zero the space needed. Note that the tuple body and
734
* HeapTupleData management structure are allocated in one chunk.
736
tuple = (HeapTuple) palloc0(HEAPTUPLESIZE + len);
737
tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
740
* And fill in the information. Note we fill the Datum fields even though
741
* this tuple may never become a Datum.
744
ItemPointerSetInvalid(&(tuple->t_self));
745
tuple->t_tableOid = InvalidOid;
747
HeapTupleHeaderSetDatumLength(td, len);
748
HeapTupleHeaderSetTypeId(td, tupleDescriptor->tdtypeid);
749
HeapTupleHeaderSetTypMod(td, tupleDescriptor->tdtypmod);
751
HeapTupleHeaderSetNatts(td, numberOfAttributes);
754
if (tupleDescriptor->tdhasoid) /* else leave infomask = 0 */
755
td->t_infomask = HEAP_HASOID;
757
heap_fill_tuple(tupleDescriptor,
763
(hasnull ? td->t_bits : NULL));
771
* construct a tuple from the given values[] and nulls[] arrays
773
* Null attributes are indicated by a 'n' in the appropriate byte
774
* of nulls[]. Non-null attributes are indicated by a ' ' (space).
776
* OLD API with char 'n'/' ' convention for indicating nulls.
777
* This is deprecated and should not be used in new code, but we keep it
778
* around for use by old add-on modules.
781
heap_formtuple(TupleDesc tupleDescriptor,
785
HeapTuple tuple; /* return tuple */
786
int numberOfAttributes = tupleDescriptor->natts;
787
bool *boolNulls = (bool *) palloc(numberOfAttributes * sizeof(bool));
790
for (i = 0; i < numberOfAttributes; i++)
791
boolNulls[i] = (nulls[i] == 'n');
793
tuple = heap_form_tuple(tupleDescriptor, values, boolNulls);
803
* form a new tuple from an old tuple and a set of replacement values.
805
* The replValues, replIsnull, and doReplace arrays must be of the length
806
* indicated by tupleDesc->natts. The new tuple is constructed using the data
807
* from replValues/replIsnull at columns where doReplace is true, and using
808
* the data from the old tuple at columns where doReplace is false.
810
* The result is allocated in the current memory context.
813
heap_modify_tuple(HeapTuple tuple,
819
int numberOfAttributes = tupleDesc->natts;
826
* allocate and fill values and isnull arrays from either the tuple or the
827
* repl information, as appropriate.
829
* NOTE: it's debatable whether to use heap_deform_tuple() here or just
830
* heap_getattr() only the non-replaced colums. The latter could win if
831
* there are many replaced columns and few non-replaced ones. However,
832
* heap_deform_tuple costs only O(N) while the heap_getattr way would cost
833
* O(N^2) if there are many non-replaced columns, so it seems better to
834
* err on the side of linear cost.
836
values = (Datum *) palloc(numberOfAttributes * sizeof(Datum));
837
isnull = (bool *) palloc(numberOfAttributes * sizeof(bool));
839
heap_deform_tuple(tuple, tupleDesc, values, isnull);
841
for (attoff = 0; attoff < numberOfAttributes; attoff++)
843
if (doReplace[attoff])
845
values[attoff] = replValues[attoff];
846
isnull[attoff] = replIsnull[attoff];
851
* create a new tuple from the values and isnull arrays
853
newTuple = heap_form_tuple(tupleDesc, values, isnull);
859
* copy the identification info of the old tuple: t_ctid, t_self, and OID
862
newTuple->t_data->t_ctid = tuple->t_data->t_ctid;
863
newTuple->t_self = tuple->t_self;
864
newTuple->t_tableOid = tuple->t_tableOid;
865
if (tupleDesc->tdhasoid)
866
HeapTupleSetOid(newTuple, HeapTupleGetOid(tuple));
874
* forms a new tuple from an old tuple and a set of replacement values.
875
* returns a new palloc'ed tuple.
877
* OLD API with char 'n'/' ' convention for indicating nulls, and
878
* char 'r'/' ' convention for indicating whether to replace columns.
879
* This is deprecated and should not be used in new code, but we keep it
880
* around for use by old add-on modules.
883
heap_modifytuple(HeapTuple tuple,
890
int numberOfAttributes = tupleDesc->natts;
891
bool *boolNulls = (bool *) palloc(numberOfAttributes * sizeof(bool));
892
bool *boolActions = (bool *) palloc(numberOfAttributes * sizeof(bool));
895
for (attnum = 0; attnum < numberOfAttributes; attnum++)
897
boolNulls[attnum] = (replNulls[attnum] == 'n');
898
boolActions[attnum] = (replActions[attnum] == 'r');
901
result = heap_modify_tuple(tuple, tupleDesc, replValues, boolNulls, boolActions);
911
* Given a tuple, extract data into values/isnull arrays; this is
912
* the inverse of heap_form_tuple.
914
* Storage for the values/isnull arrays is provided by the caller;
915
* it should be sized according to tupleDesc->natts not tuple->t_natts.
917
* Note that for pass-by-reference datatypes, the pointer placed
918
* in the Datum will point into the given tuple.
920
* When all or most of a tuple's fields need to be extracted,
921
* this routine will be significantly quicker than a loop around
922
* heap_getattr; the loop will become O(N^2) as soon as any
923
* noncacheable attribute offsets are involved.
926
heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc,
927
Datum *values, bool *isnull)
929
HeapTupleHeader tup = tuple->t_data;
930
bool hasnulls = HeapTupleHasNulls(tuple);
931
Form_pg_attribute *att = tupleDesc->attrs;
932
int tdesc_natts = tupleDesc->natts;
933
int natts; /* number of atts to extract */
935
char *tp; /* ptr to tuple data */
936
long off; /* offset in tuple data */
937
bits8 *bp = tup->t_bits; /* ptr to null bitmap in tuple */
938
bool slow = false; /* can we use/set attcacheoff? */
940
natts = HeapTupleHeaderGetNatts(tup);
943
* In inheritance situations, it is possible that the given tuple actually
944
* has more fields than the caller is expecting. Don't run off the end of
945
* the caller's arrays.
947
natts = Min(natts, tdesc_natts);
949
tp = (char *) tup + tup->t_hoff;
953
for (attnum = 0; attnum < natts; attnum++)
955
Form_pg_attribute thisatt = att[attnum];
957
if (hasnulls && att_isnull(attnum, bp))
959
values[attnum] = (Datum) 0;
960
isnull[attnum] = true;
961
slow = true; /* can't use attcacheoff anymore */
965
isnull[attnum] = false;
967
if (!slow && thisatt->attcacheoff >= 0)
968
off = thisatt->attcacheoff;
969
else if (thisatt->attlen == -1)
972
* We can only cache the offset for a varlena attribute if the
973
* offset is already suitably aligned, so that there would be no
974
* pad bytes in any case: then the offset will be valid for either
975
* an aligned or unaligned value.
978
off == att_align_nominal(off, thisatt->attalign))
979
thisatt->attcacheoff = off;
982
off = att_align_pointer(off, thisatt->attalign, -1,
989
/* not varlena, so safe to use att_align_nominal */
990
off = att_align_nominal(off, thisatt->attalign);
993
thisatt->attcacheoff = off;
996
values[attnum] = fetchatt(thisatt, tp + off);
998
off = att_addlength_pointer(off, thisatt->attlen, tp + off);
1000
if (thisatt->attlen <= 0)
1001
slow = true; /* can't use attcacheoff anymore */
1005
* If tuple doesn't have all the atts indicated by tupleDesc, read the
1008
for (; attnum < tdesc_natts; attnum++)
1010
values[attnum] = (Datum) 0;
1011
isnull[attnum] = true;
1018
* Given a tuple, extract data into values/nulls arrays; this is
1019
* the inverse of heap_formtuple.
1021
* Storage for the values/nulls arrays is provided by the caller;
1022
* it should be sized according to tupleDesc->natts not tuple->t_natts.
1024
* Note that for pass-by-reference datatypes, the pointer placed
1025
* in the Datum will point into the given tuple.
1027
* When all or most of a tuple's fields need to be extracted,
1028
* this routine will be significantly quicker than a loop around
1029
* heap_getattr; the loop will become O(N^2) as soon as any
1030
* noncacheable attribute offsets are involved.
1032
* OLD API with char 'n'/' ' convention for indicating nulls.
1033
* This is deprecated and should not be used in new code, but we keep it
1034
* around for use by old add-on modules.
1037
heap_deformtuple(HeapTuple tuple,
1038
TupleDesc tupleDesc,
1042
int natts = tupleDesc->natts;
1043
bool *boolNulls = (bool *) palloc(natts * sizeof(bool));
1046
heap_deform_tuple(tuple, tupleDesc, values, boolNulls);
1048
for (attnum = 0; attnum < natts; attnum++)
1049
nulls[attnum] = (boolNulls[attnum] ? 'n' : ' ');
1056
* Given a TupleTableSlot, extract data from the slot's physical tuple
1057
* into its Datum/isnull arrays. Data is extracted up through the
1058
* natts'th column (caller must ensure this is a legal column number).
1060
* This is essentially an incremental version of heap_deform_tuple:
1061
* on each call we extract attributes up to the one needed, without
1062
* re-computing information about previously extracted attributes.
1063
* slot->tts_nvalid is the number of attributes already extracted.
1066
slot_deform_tuple(TupleTableSlot *slot, int natts)
1068
HeapTuple tuple = slot->tts_tuple;
1069
TupleDesc tupleDesc = slot->tts_tupleDescriptor;
1070
Datum *values = slot->tts_values;
1071
bool *isnull = slot->tts_isnull;
1072
HeapTupleHeader tup = tuple->t_data;
1073
bool hasnulls = HeapTupleHasNulls(tuple);
1074
Form_pg_attribute *att = tupleDesc->attrs;
1076
char *tp; /* ptr to tuple data */
1077
long off; /* offset in tuple data */
1078
bits8 *bp = tup->t_bits; /* ptr to null bitmap in tuple */
1079
bool slow; /* can we use/set attcacheoff? */
1082
* Check whether the first call for this tuple, and initialize or restore
1085
attnum = slot->tts_nvalid;
1088
/* Start from the first attribute */
1094
/* Restore state from previous execution */
1095
off = slot->tts_off;
1096
slow = slot->tts_slow;
1099
tp = (char *) tup + tup->t_hoff;
1101
for (; attnum < natts; attnum++)
1103
Form_pg_attribute thisatt = att[attnum];
1105
if (hasnulls && att_isnull(attnum, bp))
1107
values[attnum] = (Datum) 0;
1108
isnull[attnum] = true;
1109
slow = true; /* can't use attcacheoff anymore */
1113
isnull[attnum] = false;
1115
if (!slow && thisatt->attcacheoff >= 0)
1116
off = thisatt->attcacheoff;
1117
else if (thisatt->attlen == -1)
1120
* We can only cache the offset for a varlena attribute if the
1121
* offset is already suitably aligned, so that there would be no
1122
* pad bytes in any case: then the offset will be valid for either
1123
* an aligned or unaligned value.
1126
off == att_align_nominal(off, thisatt->attalign))
1127
thisatt->attcacheoff = off;
1130
off = att_align_pointer(off, thisatt->attalign, -1,
1137
/* not varlena, so safe to use att_align_nominal */
1138
off = att_align_nominal(off, thisatt->attalign);
1141
thisatt->attcacheoff = off;
1144
values[attnum] = fetchatt(thisatt, tp + off);
1146
off = att_addlength_pointer(off, thisatt->attlen, tp + off);
1148
if (thisatt->attlen <= 0)
1149
slow = true; /* can't use attcacheoff anymore */
1153
* Save state for next execution
1155
slot->tts_nvalid = attnum;
1156
slot->tts_off = off;
1157
slot->tts_slow = slow;
1162
* This function fetches an attribute of the slot's current tuple.
1163
* It is functionally equivalent to heap_getattr, but fetches of
1164
* multiple attributes of the same tuple will be optimized better,
1165
* because we avoid O(N^2) behavior from multiple calls of
1166
* nocachegetattr(), even when attcacheoff isn't usable.
1168
* A difference from raw heap_getattr is that attnums beyond the
1169
* slot's tupdesc's last attribute will be considered NULL even
1170
* when the physical tuple is longer than the tupdesc.
1173
slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
1175
HeapTuple tuple = slot->tts_tuple;
1176
TupleDesc tupleDesc = slot->tts_tupleDescriptor;
1177
HeapTupleHeader tup;
1180
* system attributes are handled by heap_getsysattr
1184
if (tuple == NULL) /* internal error */
1185
elog(ERROR, "cannot extract system attribute from virtual tuple");
1186
if (slot->tts_mintuple) /* internal error */
1187
elog(ERROR, "cannot extract system attribute from minimal tuple");
1188
return heap_getsysattr(tuple, attnum, tupleDesc, isnull);
1192
* fast path if desired attribute already cached
1194
if (attnum <= slot->tts_nvalid)
1196
*isnull = slot->tts_isnull[attnum - 1];
1197
return slot->tts_values[attnum - 1];
1201
* return NULL if attnum is out of range according to the tupdesc
1203
if (attnum > tupleDesc->natts)
1210
* otherwise we had better have a physical tuple (tts_nvalid should equal
1211
* natts in all virtual-tuple cases)
1213
if (tuple == NULL) /* internal error */
1214
elog(ERROR, "cannot extract attribute from empty tuple slot");
1217
* return NULL if attnum is out of range according to the tuple
1219
* (We have to check this separately because of various inheritance and
1220
* table-alteration scenarios: the tuple could be either longer or shorter
1221
* than the tupdesc.)
1223
tup = tuple->t_data;
1224
if (attnum > HeapTupleHeaderGetNatts(tup))
1231
* check if target attribute is null: no point in groveling through tuple
1233
if (HeapTupleHasNulls(tuple) && att_isnull(attnum - 1, tup->t_bits))
1240
* If the attribute's column has been dropped, we force a NULL result.
1241
* This case should not happen in normal use, but it could happen if we
1242
* are executing a plan cached before the column was dropped.
1244
if (tupleDesc->attrs[attnum - 1]->attisdropped)
1251
* Extract the attribute, along with any preceding attributes.
1253
slot_deform_tuple(slot, attnum);
1256
* The result is acquired from tts_values array.
1258
*isnull = slot->tts_isnull[attnum - 1];
1259
return slot->tts_values[attnum - 1];
1264
* This function forces all the entries of the slot's Datum/isnull
1265
* arrays to be valid. The caller may then extract data directly
1266
* from those arrays instead of using slot_getattr.
1269
slot_getallattrs(TupleTableSlot *slot)
1271
int tdesc_natts = slot->tts_tupleDescriptor->natts;
1275
/* Quick out if we have 'em all already */
1276
if (slot->tts_nvalid == tdesc_natts)
1280
* otherwise we had better have a physical tuple (tts_nvalid should equal
1281
* natts in all virtual-tuple cases)
1283
tuple = slot->tts_tuple;
1284
if (tuple == NULL) /* internal error */
1285
elog(ERROR, "cannot extract attribute from empty tuple slot");
1288
* load up any slots available from physical tuple
1290
attnum = HeapTupleHeaderGetNatts(tuple->t_data);
1291
attnum = Min(attnum, tdesc_natts);
1293
slot_deform_tuple(slot, attnum);
1296
* If tuple doesn't have all the atts indicated by tupleDesc, read the
1299
for (; attnum < tdesc_natts; attnum++)
1301
slot->tts_values[attnum] = (Datum) 0;
1302
slot->tts_isnull[attnum] = true;
1304
slot->tts_nvalid = tdesc_natts;
1309
* This function forces the entries of the slot's Datum/isnull
1310
* arrays to be valid at least up through the attnum'th entry.
1313
slot_getsomeattrs(TupleTableSlot *slot, int attnum)
1318
/* Quick out if we have 'em all already */
1319
if (slot->tts_nvalid >= attnum)
1322
/* Check for caller error */
1323
if (attnum <= 0 || attnum > slot->tts_tupleDescriptor->natts)
1324
elog(ERROR, "invalid attribute number %d", attnum);
1327
* otherwise we had better have a physical tuple (tts_nvalid should equal
1328
* natts in all virtual-tuple cases)
1330
tuple = slot->tts_tuple;
1331
if (tuple == NULL) /* internal error */
1332
elog(ERROR, "cannot extract attribute from empty tuple slot");
1335
* load up any slots available from physical tuple
1337
attno = HeapTupleHeaderGetNatts(tuple->t_data);
1338
attno = Min(attno, attnum);
1340
slot_deform_tuple(slot, attno);
1343
* If tuple doesn't have all the atts indicated by tupleDesc, read the
1346
for (; attno < attnum; attno++)
1348
slot->tts_values[attno] = (Datum) 0;
1349
slot->tts_isnull[attno] = true;
1351
slot->tts_nvalid = attnum;
1356
* Detect whether an attribute of the slot is null, without
1357
* actually fetching it.
1360
slot_attisnull(TupleTableSlot *slot, int attnum)
1362
HeapTuple tuple = slot->tts_tuple;
1363
TupleDesc tupleDesc = slot->tts_tupleDescriptor;
1366
* system attributes are handled by heap_attisnull
1370
if (tuple == NULL) /* internal error */
1371
elog(ERROR, "cannot extract system attribute from virtual tuple");
1372
if (slot->tts_mintuple) /* internal error */
1373
elog(ERROR, "cannot extract system attribute from minimal tuple");
1374
return heap_attisnull(tuple, attnum);
1378
* fast path if desired attribute already cached
1380
if (attnum <= slot->tts_nvalid)
1381
return slot->tts_isnull[attnum - 1];
1384
* return NULL if attnum is out of range according to the tupdesc
1386
if (attnum > tupleDesc->natts)
1390
* otherwise we had better have a physical tuple (tts_nvalid should equal
1391
* natts in all virtual-tuple cases)
1393
if (tuple == NULL) /* internal error */
1394
elog(ERROR, "cannot extract attribute from empty tuple slot");
1396
/* and let the tuple tell it */
1397
return heap_attisnull(tuple, attnum);
1404
heap_freetuple(HeapTuple htup)
1411
* heap_form_minimal_tuple
1412
* construct a MinimalTuple from the given values[] and isnull[] arrays,
1413
* which are of the length indicated by tupleDescriptor->natts
1415
* This is exactly like heap_form_tuple() except that the result is a
1416
* "minimal" tuple lacking a HeapTupleData header as well as room for system
1419
* The result is allocated in the current memory context.
1422
heap_form_minimal_tuple(TupleDesc tupleDescriptor,
1426
MinimalTuple tuple; /* return tuple */
1430
bool hasnull = false;
1431
Form_pg_attribute *att = tupleDescriptor->attrs;
1432
int numberOfAttributes = tupleDescriptor->natts;
1435
if (numberOfAttributes > MaxTupleAttributeNumber)
1437
(errcode(ERRCODE_TOO_MANY_COLUMNS),
1438
errmsg("number of columns (%d) exceeds limit (%d)",
1439
numberOfAttributes, MaxTupleAttributeNumber)));
1442
* Check for nulls and embedded tuples; expand any toasted attributes in
1443
* embedded tuples. This preserves the invariant that toasting can only
1444
* go one level deep.
1446
* We can skip calling toast_flatten_tuple_attribute() if the attribute
1447
* couldn't possibly be of composite type. All composite datums are
1448
* varlena and have alignment 'd'; furthermore they aren't arrays. Also,
1449
* if an attribute is already toasted, it must have been sent to disk
1450
* already and so cannot contain toasted attributes.
1452
for (i = 0; i < numberOfAttributes; i++)
1456
else if (att[i]->attlen == -1 &&
1457
att[i]->attalign == 'd' &&
1458
att[i]->attndims == 0 &&
1459
!VARATT_IS_EXTENDED(values[i]))
1461
values[i] = toast_flatten_tuple_attribute(values[i],
1468
* Determine total space needed
1470
len = offsetof(MinimalTupleData, t_bits);
1473
len += BITMAPLEN(numberOfAttributes);
1475
if (tupleDescriptor->tdhasoid)
1478
hoff = len = MAXALIGN(len); /* align user data safely */
1480
data_len = heap_compute_data_size(tupleDescriptor, values, isnull);
1485
* Allocate and zero the space needed.
1487
tuple = (MinimalTuple) palloc0(len);
1490
* And fill in the information.
1493
HeapTupleHeaderSetNatts(tuple, numberOfAttributes);
1494
tuple->t_hoff = hoff + MINIMAL_TUPLE_OFFSET;
1496
if (tupleDescriptor->tdhasoid) /* else leave infomask = 0 */
1497
tuple->t_infomask = HEAP_HASOID;
1499
heap_fill_tuple(tupleDescriptor,
1502
(char *) tuple + hoff,
1505
(hasnull ? tuple->t_bits : NULL));
1511
* heap_free_minimal_tuple
1514
heap_free_minimal_tuple(MinimalTuple mtup)
1520
* heap_copy_minimal_tuple
1521
* copy a MinimalTuple
1523
* The result is allocated in the current memory context.
1526
heap_copy_minimal_tuple(MinimalTuple mtup)
1528
MinimalTuple result;
1530
result = (MinimalTuple) palloc(mtup->t_len);
1531
memcpy(result, mtup, mtup->t_len);
1536
* heap_tuple_from_minimal_tuple
1537
* create a HeapTuple by copying from a MinimalTuple;
1538
* system columns are filled with zeroes
1540
* The result is allocated in the current memory context.
1541
* The HeapTuple struct, tuple header, and tuple data are all allocated
1542
* as a single palloc() block.
1545
heap_tuple_from_minimal_tuple(MinimalTuple mtup)
1548
uint32 len = mtup->t_len + MINIMAL_TUPLE_OFFSET;
1550
result = (HeapTuple) palloc(HEAPTUPLESIZE + len);
1551
result->t_len = len;
1552
ItemPointerSetInvalid(&(result->t_self));
1553
result->t_tableOid = InvalidOid;
1554
result->t_data = (HeapTupleHeader) ((char *) result + HEAPTUPLESIZE);
1555
memcpy((char *) result->t_data + MINIMAL_TUPLE_OFFSET, mtup, mtup->t_len);
1556
memset(result->t_data, 0, offsetof(HeapTupleHeaderData, t_infomask2));
1561
* minimal_tuple_from_heap_tuple
1562
* create a MinimalTuple by copying from a HeapTuple
1564
* The result is allocated in the current memory context.
1567
minimal_tuple_from_heap_tuple(HeapTuple htup)
1569
MinimalTuple result;
1572
Assert(htup->t_len > MINIMAL_TUPLE_OFFSET);
1573
len = htup->t_len - MINIMAL_TUPLE_OFFSET;
1574
result = (MinimalTuple) palloc(len);
1575
memcpy(result, (char *) htup->t_data + MINIMAL_TUPLE_OFFSET, len);
1576
result->t_len = len;