Force a checkpoint in CREATE DATABASE before starting to copy the files,
[PostgreSQL.git] / src / backend / access / common / heaptuple.c
blobf27ce02e6e2d771f1bb34e4a93b716a9a9748cfc
1 /*-------------------------------------------------------------------------
3 * heaptuple.c
4 * This file contains heap tuple accessor and mutator routines, as well
5 * as various tuple utilities.
7 * NOTE: there is massive duplication of code in this module to
8 * support both the convention that a null is marked by a bool TRUE,
9 * and the convention that a null is marked by a char 'n'. The latter
10 * convention is deprecated but it'll probably be a long time before
11 * we can get rid of it entirely.
14 * Some notes about varlenas and this code:
16 * Before Postgres 8.3 varlenas always had a 4-byte length header, and
17 * therefore always needed 4-byte alignment (at least). This wasted space
18 * for short varlenas, for example CHAR(1) took 5 bytes and could need up to
19 * 3 additional padding bytes for alignment.
21 * Now, a short varlena (up to 126 data bytes) is reduced to a 1-byte header
22 * and we don't align it. To hide this from datatype-specific functions that
23 * don't want to deal with it, such a datum is considered "toasted" and will
24 * be expanded back to the normal 4-byte-header format by pg_detoast_datum.
25 * (In performance-critical code paths we can use pg_detoast_datum_packed
26 * and the appropriate access macros to avoid that overhead.) Note that this
27 * conversion is performed directly in heap_form_tuple (or heap_formtuple),
28 * without explicitly invoking the toaster.
30 * This change will break any code that assumes it needn't detoast values
31 * that have been put into a tuple but never sent to disk. Hopefully there
32 * are few such places.
34 * Varlenas still have alignment 'i' (or 'd') in pg_type/pg_attribute, since
35 * that's the normal requirement for the untoasted format. But we ignore that
36 * for the 1-byte-header format. This means that the actual start position
37 * of a varlena datum may vary depending on which format it has. To determine
38 * what is stored, we have to require that alignment padding bytes be zero.
39 * (Postgres actually has always zeroed them, but now it's required!) Since
40 * the first byte of a 1-byte-header varlena can never be zero, we can examine
41 * the first byte after the previous datum to tell if it's a pad byte or the
42 * start of a 1-byte-header varlena.
44 * Note that while formerly we could rely on the first varlena column of a
45 * system catalog to be at the offset suggested by the C struct for the
46 * catalog, this is now risky: it's only safe if the preceding field is
47 * word-aligned, so that there will never be any padding.
49 * We don't pack varlenas whose attstorage is 'p', since the data type
50 * isn't expecting to have to detoast values. This is used in particular
51 * by oidvector and int2vector, which are used in the system catalogs
52 * and we'd like to still refer to them via C struct offsets.
55 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
56 * Portions Copyright (c) 1994, Regents of the University of California
59 * IDENTIFICATION
60 * $PostgreSQL$
62 *-------------------------------------------------------------------------
65 #include "postgres.h"
67 #include "access/heapam.h"
68 #include "access/sysattr.h"
69 #include "access/tuptoaster.h"
70 #include "executor/tuptable.h"
73 /* Does att's datatype allow packing into the 1-byte-header varlena format? */
74 #define ATT_IS_PACKABLE(att) \
75 ((att)->attlen == -1 && (att)->attstorage != 'p')
76 /* Use this if it's already known varlena */
77 #define VARLENA_ATT_IS_PACKABLE(att) \
78 ((att)->attstorage != 'p')
81 /* ----------------------------------------------------------------
82 * misc support routines
83 * ----------------------------------------------------------------
88 * heap_compute_data_size
89 * Determine size of the data area of a tuple to be constructed
91 Size
92 heap_compute_data_size(TupleDesc tupleDesc,
93 Datum *values,
94 bool *isnull)
96 Size data_length = 0;
97 int i;
98 int numberOfAttributes = tupleDesc->natts;
99 Form_pg_attribute *att = tupleDesc->attrs;
101 for (i = 0; i < numberOfAttributes; i++)
103 Datum val;
105 if (isnull[i])
106 continue;
108 val = values[i];
110 if (ATT_IS_PACKABLE(att[i]) &&
111 VARATT_CAN_MAKE_SHORT(DatumGetPointer(val)))
114 * we're anticipating converting to a short varlena header, so
115 * adjust length and don't count any alignment
117 data_length += VARATT_CONVERTED_SHORT_SIZE(DatumGetPointer(val));
119 else
121 data_length = att_align_datum(data_length, att[i]->attalign,
122 att[i]->attlen, val);
123 data_length = att_addlength_datum(data_length, att[i]->attlen,
124 val);
128 return data_length;
131 /* ----------------
132 * ComputeDataSize
134 * Determine size of the data area of a tuple to be constructed
136 * OLD API with char 'n'/' ' convention for indicating nulls
137 * ----------------
139 static Size
140 ComputeDataSize(TupleDesc tupleDesc,
141 Datum *values,
142 char *nulls)
144 Size data_length = 0;
145 int i;
146 int numberOfAttributes = tupleDesc->natts;
147 Form_pg_attribute *att = tupleDesc->attrs;
149 for (i = 0; i < numberOfAttributes; i++)
151 Datum val;
153 if (nulls[i] != ' ')
154 continue;
156 val = values[i];
158 if (ATT_IS_PACKABLE(att[i]) &&
159 VARATT_CAN_MAKE_SHORT(DatumGetPointer(val)))
162 * we're anticipating converting to a short varlena header, so
163 * adjust length and don't count any alignment
165 data_length += VARATT_CONVERTED_SHORT_SIZE(DatumGetPointer(val));
167 else
169 data_length = att_align_datum(data_length, att[i]->attalign,
170 att[i]->attlen, val);
171 data_length = att_addlength_datum(data_length, att[i]->attlen,
172 val);
176 return data_length;
180 * heap_fill_tuple
181 * Load data portion of a tuple from values/isnull arrays
183 * We also fill the null bitmap (if any) and set the infomask bits
184 * that reflect the tuple's data contents.
186 * NOTE: it is now REQUIRED that the caller have pre-zeroed the data area.
188 void
189 heap_fill_tuple(TupleDesc tupleDesc,
190 Datum *values, bool *isnull,
191 char *data, Size data_size,
192 uint16 *infomask, bits8 *bit)
194 bits8 *bitP;
195 int bitmask;
196 int i;
197 int numberOfAttributes = tupleDesc->natts;
198 Form_pg_attribute *att = tupleDesc->attrs;
200 #ifdef USE_ASSERT_CHECKING
201 char *start = data;
202 #endif
204 if (bit != NULL)
206 bitP = &bit[-1];
207 bitmask = HIGHBIT;
209 else
211 /* just to keep compiler quiet */
212 bitP = NULL;
213 bitmask = 0;
216 *infomask &= ~(HEAP_HASNULL | HEAP_HASVARWIDTH | HEAP_HASEXTERNAL);
218 for (i = 0; i < numberOfAttributes; i++)
220 Size data_length;
222 if (bit != NULL)
224 if (bitmask != HIGHBIT)
225 bitmask <<= 1;
226 else
228 bitP += 1;
229 *bitP = 0x0;
230 bitmask = 1;
233 if (isnull[i])
235 *infomask |= HEAP_HASNULL;
236 continue;
239 *bitP |= bitmask;
243 * XXX we use the att_align macros on the pointer value itself, not on
244 * an offset. This is a bit of a hack.
247 if (att[i]->attbyval)
249 /* pass-by-value */
250 data = (char *) att_align_nominal((long) data, att[i]->attalign);
251 store_att_byval(data, values[i], att[i]->attlen);
252 data_length = att[i]->attlen;
254 else if (att[i]->attlen == -1)
256 /* varlena */
257 Pointer val = DatumGetPointer(values[i]);
259 *infomask |= HEAP_HASVARWIDTH;
260 if (VARATT_IS_EXTERNAL(val))
262 *infomask |= HEAP_HASEXTERNAL;
263 /* no alignment, since it's short by definition */
264 data_length = VARSIZE_EXTERNAL(val);
265 memcpy(data, val, data_length);
267 else if (VARATT_IS_SHORT(val))
269 /* no alignment for short varlenas */
270 data_length = VARSIZE_SHORT(val);
271 memcpy(data, val, data_length);
273 else if (VARLENA_ATT_IS_PACKABLE(att[i]) &&
274 VARATT_CAN_MAKE_SHORT(val))
276 /* convert to short varlena -- no alignment */
277 data_length = VARATT_CONVERTED_SHORT_SIZE(val);
278 SET_VARSIZE_SHORT(data, data_length);
279 memcpy(data + 1, VARDATA(val), data_length - 1);
281 else
283 /* full 4-byte header varlena */
284 data = (char *) att_align_nominal((long) data,
285 att[i]->attalign);
286 data_length = VARSIZE(val);
287 memcpy(data, val, data_length);
290 else if (att[i]->attlen == -2)
292 /* cstring ... never needs alignment */
293 *infomask |= HEAP_HASVARWIDTH;
294 Assert(att[i]->attalign == 'c');
295 data_length = strlen(DatumGetCString(values[i])) + 1;
296 memcpy(data, DatumGetPointer(values[i]), data_length);
298 else
300 /* fixed-length pass-by-reference */
301 data = (char *) att_align_nominal((long) data, att[i]->attalign);
302 Assert(att[i]->attlen > 0);
303 data_length = att[i]->attlen;
304 memcpy(data, DatumGetPointer(values[i]), data_length);
307 data += data_length;
310 Assert((data - start) == data_size);
313 /* ----------------
314 * DataFill
316 * Load data portion of a tuple from values/nulls arrays
318 * OLD API with char 'n'/' ' convention for indicating nulls
319 * ----------------
321 static void
322 DataFill(TupleDesc tupleDesc,
323 Datum *values, char *nulls,
324 char *data, Size data_size,
325 uint16 *infomask, bits8 *bit)
327 bits8 *bitP;
328 int bitmask;
329 int i;
330 int numberOfAttributes = tupleDesc->natts;
331 Form_pg_attribute *att = tupleDesc->attrs;
333 #ifdef USE_ASSERT_CHECKING
334 char *start = data;
335 #endif
337 if (bit != NULL)
339 bitP = &bit[-1];
340 bitmask = HIGHBIT;
342 else
344 /* just to keep compiler quiet */
345 bitP = NULL;
346 bitmask = 0;
349 *infomask &= ~(HEAP_HASNULL | HEAP_HASVARWIDTH | HEAP_HASEXTERNAL);
351 for (i = 0; i < numberOfAttributes; i++)
353 Size data_length;
355 if (bit != NULL)
357 if (bitmask != HIGHBIT)
358 bitmask <<= 1;
359 else
361 bitP += 1;
362 *bitP = 0x0;
363 bitmask = 1;
366 if (nulls[i] == 'n')
368 *infomask |= HEAP_HASNULL;
369 continue;
372 *bitP |= bitmask;
376 * XXX we use the att_align macros on the pointer value itself, not on
377 * an offset. This is a bit of a hack.
380 if (att[i]->attbyval)
382 /* pass-by-value */
383 data = (char *) att_align_nominal((long) data, att[i]->attalign);
384 store_att_byval(data, values[i], att[i]->attlen);
385 data_length = att[i]->attlen;
387 else if (att[i]->attlen == -1)
389 /* varlena */
390 Pointer val = DatumGetPointer(values[i]);
392 *infomask |= HEAP_HASVARWIDTH;
393 if (VARATT_IS_EXTERNAL(val))
395 *infomask |= HEAP_HASEXTERNAL;
396 /* no alignment, since it's short by definition */
397 data_length = VARSIZE_EXTERNAL(val);
398 memcpy(data, val, data_length);
400 else if (VARATT_IS_SHORT(val))
402 /* no alignment for short varlenas */
403 data_length = VARSIZE_SHORT(val);
404 memcpy(data, val, data_length);
406 else if (VARLENA_ATT_IS_PACKABLE(att[i]) &&
407 VARATT_CAN_MAKE_SHORT(val))
409 /* convert to short varlena -- no alignment */
410 data_length = VARATT_CONVERTED_SHORT_SIZE(val);
411 SET_VARSIZE_SHORT(data, data_length);
412 memcpy(data + 1, VARDATA(val), data_length - 1);
414 else
416 /* full 4-byte header varlena */
417 data = (char *) att_align_nominal((long) data,
418 att[i]->attalign);
419 data_length = VARSIZE(val);
420 memcpy(data, val, data_length);
423 else if (att[i]->attlen == -2)
425 /* cstring ... never needs alignment */
426 *infomask |= HEAP_HASVARWIDTH;
427 Assert(att[i]->attalign == 'c');
428 data_length = strlen(DatumGetCString(values[i])) + 1;
429 memcpy(data, DatumGetPointer(values[i]), data_length);
431 else
433 /* fixed-length pass-by-reference */
434 data = (char *) att_align_nominal((long) data, att[i]->attalign);
435 Assert(att[i]->attlen > 0);
436 data_length = att[i]->attlen;
437 memcpy(data, DatumGetPointer(values[i]), data_length);
440 data += data_length;
443 Assert((data - start) == data_size);
446 /* ----------------------------------------------------------------
447 * heap tuple interface
448 * ----------------------------------------------------------------
451 /* ----------------
452 * heap_attisnull - returns TRUE iff tuple attribute is not present
453 * ----------------
455 bool
456 heap_attisnull(HeapTuple tup, int attnum)
458 if (attnum > (int) HeapTupleHeaderGetNatts(tup->t_data))
459 return true;
461 if (attnum > 0)
463 if (HeapTupleNoNulls(tup))
464 return false;
465 return att_isnull(attnum - 1, tup->t_data->t_bits);
468 switch (attnum)
470 case TableOidAttributeNumber:
471 case SelfItemPointerAttributeNumber:
472 case ObjectIdAttributeNumber:
473 case MinTransactionIdAttributeNumber:
474 case MinCommandIdAttributeNumber:
475 case MaxTransactionIdAttributeNumber:
476 case MaxCommandIdAttributeNumber:
477 /* these are never null */
478 break;
480 default:
481 elog(ERROR, "invalid attnum: %d", attnum);
484 return false;
487 /* ----------------
488 * nocachegetattr
490 * This only gets called from fastgetattr() macro, in cases where
491 * we can't use a cacheoffset and the value is not null.
493 * This caches attribute offsets in the attribute descriptor.
495 * An alternative way to speed things up would be to cache offsets
496 * with the tuple, but that seems more difficult unless you take
497 * the storage hit of actually putting those offsets into the
498 * tuple you send to disk. Yuck.
500 * This scheme will be slightly slower than that, but should
501 * perform well for queries which hit large #'s of tuples. After
502 * you cache the offsets once, examining all the other tuples using
503 * the same attribute descriptor will go much quicker. -cim 5/4/91
505 * NOTE: if you need to change this code, see also heap_deform_tuple.
506 * Also see nocache_index_getattr, which is the same code for index
507 * tuples.
508 * ----------------
510 Datum
511 nocachegetattr(HeapTuple tuple,
512 int attnum,
513 TupleDesc tupleDesc,
514 bool *isnull)
516 HeapTupleHeader tup = tuple->t_data;
517 Form_pg_attribute *att = tupleDesc->attrs;
518 char *tp; /* ptr to data part of tuple */
519 bits8 *bp = tup->t_bits; /* ptr to null bitmap in tuple */
520 bool slow = false; /* do we have to walk attrs? */
521 int off; /* current offset within data */
523 (void) isnull; /* not used */
525 /* ----------------
526 * Three cases:
528 * 1: No nulls and no variable-width attributes.
529 * 2: Has a null or a var-width AFTER att.
530 * 3: Has nulls or var-widths BEFORE att.
531 * ----------------
534 #ifdef IN_MACRO
535 /* This is handled in the macro */
536 Assert(attnum > 0);
538 if (isnull)
539 *isnull = false;
540 #endif
542 attnum--;
544 if (HeapTupleNoNulls(tuple))
546 #ifdef IN_MACRO
547 /* This is handled in the macro */
548 if (att[attnum]->attcacheoff >= 0)
550 return fetchatt(att[attnum],
551 (char *) tup + tup->t_hoff +
552 att[attnum]->attcacheoff);
554 #endif
556 else
559 * there's a null somewhere in the tuple
561 * check to see if desired att is null
564 #ifdef IN_MACRO
565 /* This is handled in the macro */
566 if (att_isnull(attnum, bp))
568 if (isnull)
569 *isnull = true;
570 return (Datum) NULL;
572 #endif
575 * Now check to see if any preceding bits are null...
578 int byte = attnum >> 3;
579 int finalbit = attnum & 0x07;
581 /* check for nulls "before" final bit of last byte */
582 if ((~bp[byte]) & ((1 << finalbit) - 1))
583 slow = true;
584 else
586 /* check for nulls in any "earlier" bytes */
587 int i;
589 for (i = 0; i < byte; i++)
591 if (bp[i] != 0xFF)
593 slow = true;
594 break;
601 tp = (char *) tup + tup->t_hoff;
603 if (!slow)
606 * If we get here, there are no nulls up to and including the target
607 * attribute. If we have a cached offset, we can use it.
609 if (att[attnum]->attcacheoff >= 0)
611 return fetchatt(att[attnum],
612 tp + att[attnum]->attcacheoff);
616 * Otherwise, check for non-fixed-length attrs up to and including
617 * target. If there aren't any, it's safe to cheaply initialize the
618 * cached offsets for these attrs.
620 if (HeapTupleHasVarWidth(tuple))
622 int j;
624 for (j = 0; j <= attnum; j++)
626 if (att[j]->attlen <= 0)
628 slow = true;
629 break;
635 if (!slow)
637 int natts = tupleDesc->natts;
638 int j = 1;
641 * If we get here, we have a tuple with no nulls or var-widths up to
642 * and including the target attribute, so we can use the cached offset
643 * ... only we don't have it yet, or we'd not have got here. Since
644 * it's cheap to compute offsets for fixed-width columns, we take the
645 * opportunity to initialize the cached offsets for *all* the leading
646 * fixed-width columns, in hope of avoiding future visits to this
647 * routine.
649 att[0]->attcacheoff = 0;
651 /* we might have set some offsets in the slow path previously */
652 while (j < natts && att[j]->attcacheoff > 0)
653 j++;
655 off = att[j - 1]->attcacheoff + att[j - 1]->attlen;
657 for (; j < natts; j++)
659 if (att[j]->attlen <= 0)
660 break;
662 off = att_align_nominal(off, att[j]->attalign);
664 att[j]->attcacheoff = off;
666 off += att[j]->attlen;
669 Assert(j > attnum);
671 off = att[attnum]->attcacheoff;
673 else
675 bool usecache = true;
676 int i;
679 * Now we know that we have to walk the tuple CAREFULLY. But we still
680 * might be able to cache some offsets for next time.
682 * Note - This loop is a little tricky. For each non-null attribute,
683 * we have to first account for alignment padding before the attr,
684 * then advance over the attr based on its length. Nulls have no
685 * storage and no alignment padding either. We can use/set
686 * attcacheoff until we reach either a null or a var-width attribute.
688 off = 0;
689 for (i = 0;; i++) /* loop exit is at "break" */
691 if (HeapTupleHasNulls(tuple) && att_isnull(i, bp))
693 usecache = false;
694 continue; /* this cannot be the target att */
697 /* If we know the next offset, we can skip the rest */
698 if (usecache && att[i]->attcacheoff >= 0)
699 off = att[i]->attcacheoff;
700 else if (att[i]->attlen == -1)
703 * We can only cache the offset for a varlena attribute if the
704 * offset is already suitably aligned, so that there would be
705 * no pad bytes in any case: then the offset will be valid for
706 * either an aligned or unaligned value.
708 if (usecache &&
709 off == att_align_nominal(off, att[i]->attalign))
710 att[i]->attcacheoff = off;
711 else
713 off = att_align_pointer(off, att[i]->attalign, -1,
714 tp + off);
715 usecache = false;
718 else
720 /* not varlena, so safe to use att_align_nominal */
721 off = att_align_nominal(off, att[i]->attalign);
723 if (usecache)
724 att[i]->attcacheoff = off;
727 if (i == attnum)
728 break;
730 off = att_addlength_pointer(off, att[i]->attlen, tp + off);
732 if (usecache && att[i]->attlen <= 0)
733 usecache = false;
737 return fetchatt(att[attnum], tp + off);
740 /* ----------------
741 * heap_getsysattr
743 * Fetch the value of a system attribute for a tuple.
745 * This is a support routine for the heap_getattr macro. The macro
746 * has already determined that the attnum refers to a system attribute.
747 * ----------------
749 Datum
750 heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
752 Datum result;
754 Assert(tup);
756 /* Currently, no sys attribute ever reads as NULL. */
757 if (isnull)
758 *isnull = false;
760 switch (attnum)
762 case SelfItemPointerAttributeNumber:
763 /* pass-by-reference datatype */
764 result = PointerGetDatum(&(tup->t_self));
765 break;
766 case ObjectIdAttributeNumber:
767 result = ObjectIdGetDatum(HeapTupleGetOid(tup));
768 break;
769 case MinTransactionIdAttributeNumber:
770 result = TransactionIdGetDatum(HeapTupleHeaderGetXmin(tup->t_data));
771 break;
772 case MaxTransactionIdAttributeNumber:
773 result = TransactionIdGetDatum(HeapTupleHeaderGetXmax(tup->t_data));
774 break;
775 case MinCommandIdAttributeNumber:
776 case MaxCommandIdAttributeNumber:
779 * cmin and cmax are now both aliases for the same field, which
780 * can in fact also be a combo command id. XXX perhaps we should
781 * return the "real" cmin or cmax if possible, that is if we are
782 * inside the originating transaction?
784 result = CommandIdGetDatum(HeapTupleHeaderGetRawCommandId(tup->t_data));
785 break;
786 case TableOidAttributeNumber:
787 result = ObjectIdGetDatum(tup->t_tableOid);
788 break;
789 default:
790 elog(ERROR, "invalid attnum: %d", attnum);
791 result = 0; /* keep compiler quiet */
792 break;
794 return result;
797 /* ----------------
798 * heap_copytuple
800 * returns a copy of an entire tuple
802 * The HeapTuple struct, tuple header, and tuple data are all allocated
803 * as a single palloc() block.
804 * ----------------
806 HeapTuple
807 heap_copytuple(HeapTuple tuple)
809 HeapTuple newTuple;
811 if (!HeapTupleIsValid(tuple) || tuple->t_data == NULL)
812 return NULL;
814 newTuple = (HeapTuple) palloc(HEAPTUPLESIZE + tuple->t_len);
815 newTuple->t_len = tuple->t_len;
816 newTuple->t_self = tuple->t_self;
817 newTuple->t_tableOid = tuple->t_tableOid;
818 newTuple->t_data = (HeapTupleHeader) ((char *) newTuple + HEAPTUPLESIZE);
819 memcpy((char *) newTuple->t_data, (char *) tuple->t_data, tuple->t_len);
820 return newTuple;
823 /* ----------------
824 * heap_copytuple_with_tuple
826 * copy a tuple into a caller-supplied HeapTuple management struct
828 * Note that after calling this function, the "dest" HeapTuple will not be
829 * allocated as a single palloc() block (unlike with heap_copytuple()).
830 * ----------------
832 void
833 heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest)
835 if (!HeapTupleIsValid(src) || src->t_data == NULL)
837 dest->t_data = NULL;
838 return;
841 dest->t_len = src->t_len;
842 dest->t_self = src->t_self;
843 dest->t_tableOid = src->t_tableOid;
844 dest->t_data = (HeapTupleHeader) palloc(src->t_len);
845 memcpy((char *) dest->t_data, (char *) src->t_data, src->t_len);
849 * heap_form_tuple
850 * construct a tuple from the given values[] and isnull[] arrays,
851 * which are of the length indicated by tupleDescriptor->natts
853 * The result is allocated in the current memory context.
855 HeapTuple
856 heap_form_tuple(TupleDesc tupleDescriptor,
857 Datum *values,
858 bool *isnull)
860 HeapTuple tuple; /* return tuple */
861 HeapTupleHeader td; /* tuple data */
862 Size len,
863 data_len;
864 int hoff;
865 bool hasnull = false;
866 Form_pg_attribute *att = tupleDescriptor->attrs;
867 int numberOfAttributes = tupleDescriptor->natts;
868 int i;
870 if (numberOfAttributes > MaxTupleAttributeNumber)
871 ereport(ERROR,
872 (errcode(ERRCODE_TOO_MANY_COLUMNS),
873 errmsg("number of columns (%d) exceeds limit (%d)",
874 numberOfAttributes, MaxTupleAttributeNumber)));
877 * Check for nulls and embedded tuples; expand any toasted attributes in
878 * embedded tuples. This preserves the invariant that toasting can only
879 * go one level deep.
881 * We can skip calling toast_flatten_tuple_attribute() if the attribute
882 * couldn't possibly be of composite type. All composite datums are
883 * varlena and have alignment 'd'; furthermore they aren't arrays. Also,
884 * if an attribute is already toasted, it must have been sent to disk
885 * already and so cannot contain toasted attributes.
887 for (i = 0; i < numberOfAttributes; i++)
889 if (isnull[i])
890 hasnull = true;
891 else if (att[i]->attlen == -1 &&
892 att[i]->attalign == 'd' &&
893 att[i]->attndims == 0 &&
894 !VARATT_IS_EXTENDED(DatumGetPointer(values[i])))
896 values[i] = toast_flatten_tuple_attribute(values[i],
897 att[i]->atttypid,
898 att[i]->atttypmod);
903 * Determine total space needed
905 len = offsetof(HeapTupleHeaderData, t_bits);
907 if (hasnull)
908 len += BITMAPLEN(numberOfAttributes);
910 if (tupleDescriptor->tdhasoid)
911 len += sizeof(Oid);
913 hoff = len = MAXALIGN(len); /* align user data safely */
915 data_len = heap_compute_data_size(tupleDescriptor, values, isnull);
917 len += data_len;
920 * Allocate and zero the space needed. Note that the tuple body and
921 * HeapTupleData management structure are allocated in one chunk.
923 tuple = (HeapTuple) palloc0(HEAPTUPLESIZE + len);
924 tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
927 * And fill in the information. Note we fill the Datum fields even though
928 * this tuple may never become a Datum.
930 tuple->t_len = len;
931 ItemPointerSetInvalid(&(tuple->t_self));
932 tuple->t_tableOid = InvalidOid;
934 HeapTupleHeaderSetDatumLength(td, len);
935 HeapTupleHeaderSetTypeId(td, tupleDescriptor->tdtypeid);
936 HeapTupleHeaderSetTypMod(td, tupleDescriptor->tdtypmod);
938 HeapTupleHeaderSetNatts(td, numberOfAttributes);
939 td->t_hoff = hoff;
941 if (tupleDescriptor->tdhasoid) /* else leave infomask = 0 */
942 td->t_infomask = HEAP_HASOID;
944 heap_fill_tuple(tupleDescriptor,
945 values,
946 isnull,
947 (char *) td + hoff,
948 data_len,
949 &td->t_infomask,
950 (hasnull ? td->t_bits : NULL));
952 return tuple;
955 /* ----------------
956 * heap_formtuple
958 * construct a tuple from the given values[] and nulls[] arrays
960 * Null attributes are indicated by a 'n' in the appropriate byte
961 * of nulls[]. Non-null attributes are indicated by a ' ' (space).
963 * OLD API with char 'n'/' ' convention for indicating nulls
964 * ----------------
966 HeapTuple
967 heap_formtuple(TupleDesc tupleDescriptor,
968 Datum *values,
969 char *nulls)
971 HeapTuple tuple; /* return tuple */
972 HeapTupleHeader td; /* tuple data */
973 Size len,
974 data_len;
975 int hoff;
976 bool hasnull = false;
977 Form_pg_attribute *att = tupleDescriptor->attrs;
978 int numberOfAttributes = tupleDescriptor->natts;
979 int i;
981 if (numberOfAttributes > MaxTupleAttributeNumber)
982 ereport(ERROR,
983 (errcode(ERRCODE_TOO_MANY_COLUMNS),
984 errmsg("number of columns (%d) exceeds limit (%d)",
985 numberOfAttributes, MaxTupleAttributeNumber)));
988 * Check for nulls and embedded tuples; expand any toasted attributes in
989 * embedded tuples. This preserves the invariant that toasting can only
990 * go one level deep.
992 * We can skip calling toast_flatten_tuple_attribute() if the attribute
993 * couldn't possibly be of composite type. All composite datums are
994 * varlena and have alignment 'd'; furthermore they aren't arrays. Also,
995 * if an attribute is already toasted, it must have been sent to disk
996 * already and so cannot contain toasted attributes.
998 for (i = 0; i < numberOfAttributes; i++)
1000 if (nulls[i] != ' ')
1001 hasnull = true;
1002 else if (att[i]->attlen == -1 &&
1003 att[i]->attalign == 'd' &&
1004 att[i]->attndims == 0 &&
1005 !VARATT_IS_EXTENDED(DatumGetPointer(values[i])))
1007 values[i] = toast_flatten_tuple_attribute(values[i],
1008 att[i]->atttypid,
1009 att[i]->atttypmod);
1014 * Determine total space needed
1016 len = offsetof(HeapTupleHeaderData, t_bits);
1018 if (hasnull)
1019 len += BITMAPLEN(numberOfAttributes);
1021 if (tupleDescriptor->tdhasoid)
1022 len += sizeof(Oid);
1024 hoff = len = MAXALIGN(len); /* align user data safely */
1026 data_len = ComputeDataSize(tupleDescriptor, values, nulls);
1028 len += data_len;
1031 * Allocate and zero the space needed. Note that the tuple body and
1032 * HeapTupleData management structure are allocated in one chunk.
1034 tuple = (HeapTuple) palloc0(HEAPTUPLESIZE + len);
1035 tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
1038 * And fill in the information. Note we fill the Datum fields even though
1039 * this tuple may never become a Datum.
1041 tuple->t_len = len;
1042 ItemPointerSetInvalid(&(tuple->t_self));
1043 tuple->t_tableOid = InvalidOid;
1045 HeapTupleHeaderSetDatumLength(td, len);
1046 HeapTupleHeaderSetTypeId(td, tupleDescriptor->tdtypeid);
1047 HeapTupleHeaderSetTypMod(td, tupleDescriptor->tdtypmod);
1049 HeapTupleHeaderSetNatts(td, numberOfAttributes);
1050 td->t_hoff = hoff;
1052 if (tupleDescriptor->tdhasoid) /* else leave infomask = 0 */
1053 td->t_infomask = HEAP_HASOID;
1055 DataFill(tupleDescriptor,
1056 values,
1057 nulls,
1058 (char *) td + hoff,
1059 data_len,
1060 &td->t_infomask,
1061 (hasnull ? td->t_bits : NULL));
1063 return tuple;
1068 * heap_modify_tuple
1069 * form a new tuple from an old tuple and a set of replacement values.
1071 * The replValues, replIsnull, and doReplace arrays must be of the length
1072 * indicated by tupleDesc->natts. The new tuple is constructed using the data
1073 * from replValues/replIsnull at columns where doReplace is true, and using
1074 * the data from the old tuple at columns where doReplace is false.
1076 * The result is allocated in the current memory context.
1078 HeapTuple
1079 heap_modify_tuple(HeapTuple tuple,
1080 TupleDesc tupleDesc,
1081 Datum *replValues,
1082 bool *replIsnull,
1083 bool *doReplace)
1085 int numberOfAttributes = tupleDesc->natts;
1086 int attoff;
1087 Datum *values;
1088 bool *isnull;
1089 HeapTuple newTuple;
1092 * allocate and fill values and isnull arrays from either the tuple or the
1093 * repl information, as appropriate.
1095 * NOTE: it's debatable whether to use heap_deform_tuple() here or just
1096 * heap_getattr() only the non-replaced colums. The latter could win if
1097 * there are many replaced columns and few non-replaced ones. However,
1098 * heap_deform_tuple costs only O(N) while the heap_getattr way would cost
1099 * O(N^2) if there are many non-replaced columns, so it seems better to
1100 * err on the side of linear cost.
1102 values = (Datum *) palloc(numberOfAttributes * sizeof(Datum));
1103 isnull = (bool *) palloc(numberOfAttributes * sizeof(bool));
1105 heap_deform_tuple(tuple, tupleDesc, values, isnull);
1107 for (attoff = 0; attoff < numberOfAttributes; attoff++)
1109 if (doReplace[attoff])
1111 values[attoff] = replValues[attoff];
1112 isnull[attoff] = replIsnull[attoff];
1117 * create a new tuple from the values and isnull arrays
1119 newTuple = heap_form_tuple(tupleDesc, values, isnull);
1121 pfree(values);
1122 pfree(isnull);
1125 * copy the identification info of the old tuple: t_ctid, t_self, and OID
1126 * (if any)
1128 newTuple->t_data->t_ctid = tuple->t_data->t_ctid;
1129 newTuple->t_self = tuple->t_self;
1130 newTuple->t_tableOid = tuple->t_tableOid;
1131 if (tupleDesc->tdhasoid)
1132 HeapTupleSetOid(newTuple, HeapTupleGetOid(tuple));
1134 return newTuple;
1137 /* ----------------
1138 * heap_modifytuple
1140 * forms a new tuple from an old tuple and a set of replacement values.
1141 * returns a new palloc'ed tuple.
1143 * OLD API with char 'n'/' ' convention for indicating nulls, and
1144 * char 'r'/' ' convention for indicating whether to replace columns.
1145 * ----------------
1147 HeapTuple
1148 heap_modifytuple(HeapTuple tuple,
1149 TupleDesc tupleDesc,
1150 Datum *replValues,
1151 char *replNulls,
1152 char *replActions)
1154 int numberOfAttributes = tupleDesc->natts;
1155 int attoff;
1156 Datum *values;
1157 char *nulls;
1158 HeapTuple newTuple;
1161 * allocate and fill values and nulls arrays from either the tuple or the
1162 * repl information, as appropriate.
1164 * NOTE: it's debatable whether to use heap_deformtuple() here or just
1165 * heap_getattr() only the non-replaced colums. The latter could win if
1166 * there are many replaced columns and few non-replaced ones. However,
1167 * heap_deformtuple costs only O(N) while the heap_getattr way would cost
1168 * O(N^2) if there are many non-replaced columns, so it seems better to
1169 * err on the side of linear cost.
1171 values = (Datum *) palloc(numberOfAttributes * sizeof(Datum));
1172 nulls = (char *) palloc(numberOfAttributes * sizeof(char));
1174 heap_deformtuple(tuple, tupleDesc, values, nulls);
1176 for (attoff = 0; attoff < numberOfAttributes; attoff++)
1178 if (replActions[attoff] == 'r')
1180 values[attoff] = replValues[attoff];
1181 nulls[attoff] = replNulls[attoff];
1183 else if (replActions[attoff] != ' ')
1184 elog(ERROR, "unrecognized replace flag: %d",
1185 (int) replActions[attoff]);
1189 * create a new tuple from the values and nulls arrays
1191 newTuple = heap_formtuple(tupleDesc, values, nulls);
1193 pfree(values);
1194 pfree(nulls);
1197 * copy the identification info of the old tuple: t_ctid, t_self, and OID
1198 * (if any)
1200 newTuple->t_data->t_ctid = tuple->t_data->t_ctid;
1201 newTuple->t_self = tuple->t_self;
1202 newTuple->t_tableOid = tuple->t_tableOid;
1203 if (tupleDesc->tdhasoid)
1204 HeapTupleSetOid(newTuple, HeapTupleGetOid(tuple));
1206 return newTuple;
1210 * heap_deform_tuple
1211 * Given a tuple, extract data into values/isnull arrays; this is
1212 * the inverse of heap_form_tuple.
1214 * Storage for the values/isnull arrays is provided by the caller;
1215 * it should be sized according to tupleDesc->natts not tuple->t_natts.
1217 * Note that for pass-by-reference datatypes, the pointer placed
1218 * in the Datum will point into the given tuple.
1220 * When all or most of a tuple's fields need to be extracted,
1221 * this routine will be significantly quicker than a loop around
1222 * heap_getattr; the loop will become O(N^2) as soon as any
1223 * noncacheable attribute offsets are involved.
1225 void
1226 heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc,
1227 Datum *values, bool *isnull)
1229 HeapTupleHeader tup = tuple->t_data;
1230 bool hasnulls = HeapTupleHasNulls(tuple);
1231 Form_pg_attribute *att = tupleDesc->attrs;
1232 int tdesc_natts = tupleDesc->natts;
1233 int natts; /* number of atts to extract */
1234 int attnum;
1235 char *tp; /* ptr to tuple data */
1236 long off; /* offset in tuple data */
1237 bits8 *bp = tup->t_bits; /* ptr to null bitmap in tuple */
1238 bool slow = false; /* can we use/set attcacheoff? */
1240 natts = HeapTupleHeaderGetNatts(tup);
1243 * In inheritance situations, it is possible that the given tuple actually
1244 * has more fields than the caller is expecting. Don't run off the end of
1245 * the caller's arrays.
1247 natts = Min(natts, tdesc_natts);
1249 tp = (char *) tup + tup->t_hoff;
1251 off = 0;
1253 for (attnum = 0; attnum < natts; attnum++)
1255 Form_pg_attribute thisatt = att[attnum];
1257 if (hasnulls && att_isnull(attnum, bp))
1259 values[attnum] = (Datum) 0;
1260 isnull[attnum] = true;
1261 slow = true; /* can't use attcacheoff anymore */
1262 continue;
1265 isnull[attnum] = false;
1267 if (!slow && thisatt->attcacheoff >= 0)
1268 off = thisatt->attcacheoff;
1269 else if (thisatt->attlen == -1)
1272 * We can only cache the offset for a varlena attribute if the
1273 * offset is already suitably aligned, so that there would be no
1274 * pad bytes in any case: then the offset will be valid for either
1275 * an aligned or unaligned value.
1277 if (!slow &&
1278 off == att_align_nominal(off, thisatt->attalign))
1279 thisatt->attcacheoff = off;
1280 else
1282 off = att_align_pointer(off, thisatt->attalign, -1,
1283 tp + off);
1284 slow = true;
1287 else
1289 /* not varlena, so safe to use att_align_nominal */
1290 off = att_align_nominal(off, thisatt->attalign);
1292 if (!slow)
1293 thisatt->attcacheoff = off;
1296 values[attnum] = fetchatt(thisatt, tp + off);
1298 off = att_addlength_pointer(off, thisatt->attlen, tp + off);
1300 if (thisatt->attlen <= 0)
1301 slow = true; /* can't use attcacheoff anymore */
1305 * If tuple doesn't have all the atts indicated by tupleDesc, read the
1306 * rest as null
1308 for (; attnum < tdesc_natts; attnum++)
1310 values[attnum] = (Datum) 0;
1311 isnull[attnum] = true;
1315 /* ----------------
1316 * heap_deformtuple
1318 * Given a tuple, extract data into values/nulls arrays; this is
1319 * the inverse of heap_formtuple.
1321 * Storage for the values/nulls arrays is provided by the caller;
1322 * it should be sized according to tupleDesc->natts not tuple->t_natts.
1324 * Note that for pass-by-reference datatypes, the pointer placed
1325 * in the Datum will point into the given tuple.
1327 * When all or most of a tuple's fields need to be extracted,
1328 * this routine will be significantly quicker than a loop around
1329 * heap_getattr; the loop will become O(N^2) as soon as any
1330 * noncacheable attribute offsets are involved.
1332 * OLD API with char 'n'/' ' convention for indicating nulls
1333 * ----------------
1335 void
1336 heap_deformtuple(HeapTuple tuple,
1337 TupleDesc tupleDesc,
1338 Datum *values,
1339 char *nulls)
1341 HeapTupleHeader tup = tuple->t_data;
1342 bool hasnulls = HeapTupleHasNulls(tuple);
1343 Form_pg_attribute *att = tupleDesc->attrs;
1344 int tdesc_natts = tupleDesc->natts;
1345 int natts; /* number of atts to extract */
1346 int attnum;
1347 char *tp; /* ptr to tuple data */
1348 long off; /* offset in tuple data */
1349 bits8 *bp = tup->t_bits; /* ptr to null bitmap in tuple */
1350 bool slow = false; /* can we use/set attcacheoff? */
1352 natts = HeapTupleHeaderGetNatts(tup);
1355 * In inheritance situations, it is possible that the given tuple actually
1356 * has more fields than the caller is expecting. Don't run off the end of
1357 * the caller's arrays.
1359 natts = Min(natts, tdesc_natts);
1361 tp = (char *) tup + tup->t_hoff;
1363 off = 0;
1365 for (attnum = 0; attnum < natts; attnum++)
1367 Form_pg_attribute thisatt = att[attnum];
1369 if (hasnulls && att_isnull(attnum, bp))
1371 values[attnum] = (Datum) 0;
1372 nulls[attnum] = 'n';
1373 slow = true; /* can't use attcacheoff anymore */
1374 continue;
1377 nulls[attnum] = ' ';
1379 if (!slow && thisatt->attcacheoff >= 0)
1380 off = thisatt->attcacheoff;
1381 else if (thisatt->attlen == -1)
1384 * We can only cache the offset for a varlena attribute if the
1385 * offset is already suitably aligned, so that there would be no
1386 * pad bytes in any case: then the offset will be valid for either
1387 * an aligned or unaligned value.
1389 if (!slow &&
1390 off == att_align_nominal(off, thisatt->attalign))
1391 thisatt->attcacheoff = off;
1392 else
1394 off = att_align_pointer(off, thisatt->attalign, -1,
1395 tp + off);
1396 slow = true;
1399 else
1401 /* not varlena, so safe to use att_align_nominal */
1402 off = att_align_nominal(off, thisatt->attalign);
1404 if (!slow)
1405 thisatt->attcacheoff = off;
1408 values[attnum] = fetchatt(thisatt, tp + off);
1410 off = att_addlength_pointer(off, thisatt->attlen, tp + off);
1412 if (thisatt->attlen <= 0)
1413 slow = true; /* can't use attcacheoff anymore */
1417 * If tuple doesn't have all the atts indicated by tupleDesc, read the
1418 * rest as null
1420 for (; attnum < tdesc_natts; attnum++)
1422 values[attnum] = (Datum) 0;
1423 nulls[attnum] = 'n';
1428 * slot_deform_tuple
1429 * Given a TupleTableSlot, extract data from the slot's physical tuple
1430 * into its Datum/isnull arrays. Data is extracted up through the
1431 * natts'th column (caller must ensure this is a legal column number).
1433 * This is essentially an incremental version of heap_deform_tuple:
1434 * on each call we extract attributes up to the one needed, without
1435 * re-computing information about previously extracted attributes.
1436 * slot->tts_nvalid is the number of attributes already extracted.
1438 static void
1439 slot_deform_tuple(TupleTableSlot *slot, int natts)
1441 HeapTuple tuple = slot->tts_tuple;
1442 TupleDesc tupleDesc = slot->tts_tupleDescriptor;
1443 Datum *values = slot->tts_values;
1444 bool *isnull = slot->tts_isnull;
1445 HeapTupleHeader tup = tuple->t_data;
1446 bool hasnulls = HeapTupleHasNulls(tuple);
1447 Form_pg_attribute *att = tupleDesc->attrs;
1448 int attnum;
1449 char *tp; /* ptr to tuple data */
1450 long off; /* offset in tuple data */
1451 bits8 *bp = tup->t_bits; /* ptr to null bitmap in tuple */
1452 bool slow; /* can we use/set attcacheoff? */
1455 * Check whether the first call for this tuple, and initialize or restore
1456 * loop state.
1458 attnum = slot->tts_nvalid;
1459 if (attnum == 0)
1461 /* Start from the first attribute */
1462 off = 0;
1463 slow = false;
1465 else
1467 /* Restore state from previous execution */
1468 off = slot->tts_off;
1469 slow = slot->tts_slow;
1472 tp = (char *) tup + tup->t_hoff;
1474 for (; attnum < natts; attnum++)
1476 Form_pg_attribute thisatt = att[attnum];
1478 if (hasnulls && att_isnull(attnum, bp))
1480 values[attnum] = (Datum) 0;
1481 isnull[attnum] = true;
1482 slow = true; /* can't use attcacheoff anymore */
1483 continue;
1486 isnull[attnum] = false;
1488 if (!slow && thisatt->attcacheoff >= 0)
1489 off = thisatt->attcacheoff;
1490 else if (thisatt->attlen == -1)
1493 * We can only cache the offset for a varlena attribute if the
1494 * offset is already suitably aligned, so that there would be no
1495 * pad bytes in any case: then the offset will be valid for either
1496 * an aligned or unaligned value.
1498 if (!slow &&
1499 off == att_align_nominal(off, thisatt->attalign))
1500 thisatt->attcacheoff = off;
1501 else
1503 off = att_align_pointer(off, thisatt->attalign, -1,
1504 tp + off);
1505 slow = true;
1508 else
1510 /* not varlena, so safe to use att_align_nominal */
1511 off = att_align_nominal(off, thisatt->attalign);
1513 if (!slow)
1514 thisatt->attcacheoff = off;
1517 values[attnum] = fetchatt(thisatt, tp + off);
1519 off = att_addlength_pointer(off, thisatt->attlen, tp + off);
1521 if (thisatt->attlen <= 0)
1522 slow = true; /* can't use attcacheoff anymore */
1526 * Save state for next execution
1528 slot->tts_nvalid = attnum;
1529 slot->tts_off = off;
1530 slot->tts_slow = slow;
1534 * slot_getattr
1535 * This function fetches an attribute of the slot's current tuple.
1536 * It is functionally equivalent to heap_getattr, but fetches of
1537 * multiple attributes of the same tuple will be optimized better,
1538 * because we avoid O(N^2) behavior from multiple calls of
1539 * nocachegetattr(), even when attcacheoff isn't usable.
1541 * A difference from raw heap_getattr is that attnums beyond the
1542 * slot's tupdesc's last attribute will be considered NULL even
1543 * when the physical tuple is longer than the tupdesc.
1545 Datum
1546 slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
1548 HeapTuple tuple = slot->tts_tuple;
1549 TupleDesc tupleDesc = slot->tts_tupleDescriptor;
1550 HeapTupleHeader tup;
1553 * system attributes are handled by heap_getsysattr
1555 if (attnum <= 0)
1557 if (tuple == NULL) /* internal error */
1558 elog(ERROR, "cannot extract system attribute from virtual tuple");
1559 if (slot->tts_mintuple) /* internal error */
1560 elog(ERROR, "cannot extract system attribute from minimal tuple");
1561 return heap_getsysattr(tuple, attnum, tupleDesc, isnull);
1565 * fast path if desired attribute already cached
1567 if (attnum <= slot->tts_nvalid)
1569 *isnull = slot->tts_isnull[attnum - 1];
1570 return slot->tts_values[attnum - 1];
1574 * return NULL if attnum is out of range according to the tupdesc
1576 if (attnum > tupleDesc->natts)
1578 *isnull = true;
1579 return (Datum) 0;
1583 * otherwise we had better have a physical tuple (tts_nvalid should equal
1584 * natts in all virtual-tuple cases)
1586 if (tuple == NULL) /* internal error */
1587 elog(ERROR, "cannot extract attribute from empty tuple slot");
1590 * return NULL if attnum is out of range according to the tuple
1592 * (We have to check this separately because of various inheritance and
1593 * table-alteration scenarios: the tuple could be either longer or shorter
1594 * than the tupdesc.)
1596 tup = tuple->t_data;
1597 if (attnum > HeapTupleHeaderGetNatts(tup))
1599 *isnull = true;
1600 return (Datum) 0;
1604 * check if target attribute is null: no point in groveling through tuple
1606 if (HeapTupleHasNulls(tuple) && att_isnull(attnum - 1, tup->t_bits))
1608 *isnull = true;
1609 return (Datum) 0;
1613 * If the attribute's column has been dropped, we force a NULL result.
1614 * This case should not happen in normal use, but it could happen if we
1615 * are executing a plan cached before the column was dropped.
1617 if (tupleDesc->attrs[attnum - 1]->attisdropped)
1619 *isnull = true;
1620 return (Datum) 0;
1624 * Extract the attribute, along with any preceding attributes.
1626 slot_deform_tuple(slot, attnum);
1629 * The result is acquired from tts_values array.
1631 *isnull = slot->tts_isnull[attnum - 1];
1632 return slot->tts_values[attnum - 1];
1636 * slot_getallattrs
1637 * This function forces all the entries of the slot's Datum/isnull
1638 * arrays to be valid. The caller may then extract data directly
1639 * from those arrays instead of using slot_getattr.
1641 void
1642 slot_getallattrs(TupleTableSlot *slot)
1644 int tdesc_natts = slot->tts_tupleDescriptor->natts;
1645 int attnum;
1646 HeapTuple tuple;
1648 /* Quick out if we have 'em all already */
1649 if (slot->tts_nvalid == tdesc_natts)
1650 return;
1653 * otherwise we had better have a physical tuple (tts_nvalid should equal
1654 * natts in all virtual-tuple cases)
1656 tuple = slot->tts_tuple;
1657 if (tuple == NULL) /* internal error */
1658 elog(ERROR, "cannot extract attribute from empty tuple slot");
1661 * load up any slots available from physical tuple
1663 attnum = HeapTupleHeaderGetNatts(tuple->t_data);
1664 attnum = Min(attnum, tdesc_natts);
1666 slot_deform_tuple(slot, attnum);
1669 * If tuple doesn't have all the atts indicated by tupleDesc, read the
1670 * rest as null
1672 for (; attnum < tdesc_natts; attnum++)
1674 slot->tts_values[attnum] = (Datum) 0;
1675 slot->tts_isnull[attnum] = true;
1677 slot->tts_nvalid = tdesc_natts;
1681 * slot_getsomeattrs
1682 * This function forces the entries of the slot's Datum/isnull
1683 * arrays to be valid at least up through the attnum'th entry.
1685 void
1686 slot_getsomeattrs(TupleTableSlot *slot, int attnum)
1688 HeapTuple tuple;
1689 int attno;
1691 /* Quick out if we have 'em all already */
1692 if (slot->tts_nvalid >= attnum)
1693 return;
1695 /* Check for caller error */
1696 if (attnum <= 0 || attnum > slot->tts_tupleDescriptor->natts)
1697 elog(ERROR, "invalid attribute number %d", attnum);
1700 * otherwise we had better have a physical tuple (tts_nvalid should equal
1701 * natts in all virtual-tuple cases)
1703 tuple = slot->tts_tuple;
1704 if (tuple == NULL) /* internal error */
1705 elog(ERROR, "cannot extract attribute from empty tuple slot");
1708 * load up any slots available from physical tuple
1710 attno = HeapTupleHeaderGetNatts(tuple->t_data);
1711 attno = Min(attno, attnum);
1713 slot_deform_tuple(slot, attno);
1716 * If tuple doesn't have all the atts indicated by tupleDesc, read the
1717 * rest as null
1719 for (; attno < attnum; attno++)
1721 slot->tts_values[attno] = (Datum) 0;
1722 slot->tts_isnull[attno] = true;
1724 slot->tts_nvalid = attnum;
1728 * slot_attisnull
1729 * Detect whether an attribute of the slot is null, without
1730 * actually fetching it.
1732 bool
1733 slot_attisnull(TupleTableSlot *slot, int attnum)
1735 HeapTuple tuple = slot->tts_tuple;
1736 TupleDesc tupleDesc = slot->tts_tupleDescriptor;
1739 * system attributes are handled by heap_attisnull
1741 if (attnum <= 0)
1743 if (tuple == NULL) /* internal error */
1744 elog(ERROR, "cannot extract system attribute from virtual tuple");
1745 if (slot->tts_mintuple) /* internal error */
1746 elog(ERROR, "cannot extract system attribute from minimal tuple");
1747 return heap_attisnull(tuple, attnum);
1751 * fast path if desired attribute already cached
1753 if (attnum <= slot->tts_nvalid)
1754 return slot->tts_isnull[attnum - 1];
1757 * return NULL if attnum is out of range according to the tupdesc
1759 if (attnum > tupleDesc->natts)
1760 return true;
1763 * otherwise we had better have a physical tuple (tts_nvalid should equal
1764 * natts in all virtual-tuple cases)
1766 if (tuple == NULL) /* internal error */
1767 elog(ERROR, "cannot extract attribute from empty tuple slot");
1769 /* and let the tuple tell it */
1770 return heap_attisnull(tuple, attnum);
1774 * heap_freetuple
1776 void
1777 heap_freetuple(HeapTuple htup)
1779 pfree(htup);
1784 * heap_form_minimal_tuple
1785 * construct a MinimalTuple from the given values[] and isnull[] arrays,
1786 * which are of the length indicated by tupleDescriptor->natts
1788 * This is exactly like heap_form_tuple() except that the result is a
1789 * "minimal" tuple lacking a HeapTupleData header as well as room for system
1790 * columns.
1792 * The result is allocated in the current memory context.
1794 MinimalTuple
1795 heap_form_minimal_tuple(TupleDesc tupleDescriptor,
1796 Datum *values,
1797 bool *isnull)
1799 MinimalTuple tuple; /* return tuple */
1800 Size len,
1801 data_len;
1802 int hoff;
1803 bool hasnull = false;
1804 Form_pg_attribute *att = tupleDescriptor->attrs;
1805 int numberOfAttributes = tupleDescriptor->natts;
1806 int i;
1808 if (numberOfAttributes > MaxTupleAttributeNumber)
1809 ereport(ERROR,
1810 (errcode(ERRCODE_TOO_MANY_COLUMNS),
1811 errmsg("number of columns (%d) exceeds limit (%d)",
1812 numberOfAttributes, MaxTupleAttributeNumber)));
1815 * Check for nulls and embedded tuples; expand any toasted attributes in
1816 * embedded tuples. This preserves the invariant that toasting can only
1817 * go one level deep.
1819 * We can skip calling toast_flatten_tuple_attribute() if the attribute
1820 * couldn't possibly be of composite type. All composite datums are
1821 * varlena and have alignment 'd'; furthermore they aren't arrays. Also,
1822 * if an attribute is already toasted, it must have been sent to disk
1823 * already and so cannot contain toasted attributes.
1825 for (i = 0; i < numberOfAttributes; i++)
1827 if (isnull[i])
1828 hasnull = true;
1829 else if (att[i]->attlen == -1 &&
1830 att[i]->attalign == 'd' &&
1831 att[i]->attndims == 0 &&
1832 !VARATT_IS_EXTENDED(values[i]))
1834 values[i] = toast_flatten_tuple_attribute(values[i],
1835 att[i]->atttypid,
1836 att[i]->atttypmod);
1841 * Determine total space needed
1843 len = offsetof(MinimalTupleData, t_bits);
1845 if (hasnull)
1846 len += BITMAPLEN(numberOfAttributes);
1848 if (tupleDescriptor->tdhasoid)
1849 len += sizeof(Oid);
1851 hoff = len = MAXALIGN(len); /* align user data safely */
1853 data_len = heap_compute_data_size(tupleDescriptor, values, isnull);
1855 len += data_len;
1858 * Allocate and zero the space needed.
1860 tuple = (MinimalTuple) palloc0(len);
1863 * And fill in the information.
1865 tuple->t_len = len;
1866 HeapTupleHeaderSetNatts(tuple, numberOfAttributes);
1867 tuple->t_hoff = hoff + MINIMAL_TUPLE_OFFSET;
1869 if (tupleDescriptor->tdhasoid) /* else leave infomask = 0 */
1870 tuple->t_infomask = HEAP_HASOID;
1872 heap_fill_tuple(tupleDescriptor,
1873 values,
1874 isnull,
1875 (char *) tuple + hoff,
1876 data_len,
1877 &tuple->t_infomask,
1878 (hasnull ? tuple->t_bits : NULL));
1880 return tuple;
1884 * heap_free_minimal_tuple
1886 void
1887 heap_free_minimal_tuple(MinimalTuple mtup)
1889 pfree(mtup);
1893 * heap_copy_minimal_tuple
1894 * copy a MinimalTuple
1896 * The result is allocated in the current memory context.
1898 MinimalTuple
1899 heap_copy_minimal_tuple(MinimalTuple mtup)
1901 MinimalTuple result;
1903 result = (MinimalTuple) palloc(mtup->t_len);
1904 memcpy(result, mtup, mtup->t_len);
1905 return result;
1909 * heap_tuple_from_minimal_tuple
1910 * create a HeapTuple by copying from a MinimalTuple;
1911 * system columns are filled with zeroes
1913 * The result is allocated in the current memory context.
1914 * The HeapTuple struct, tuple header, and tuple data are all allocated
1915 * as a single palloc() block.
1917 HeapTuple
1918 heap_tuple_from_minimal_tuple(MinimalTuple mtup)
1920 HeapTuple result;
1921 uint32 len = mtup->t_len + MINIMAL_TUPLE_OFFSET;
1923 result = (HeapTuple) palloc(HEAPTUPLESIZE + len);
1924 result->t_len = len;
1925 ItemPointerSetInvalid(&(result->t_self));
1926 result->t_tableOid = InvalidOid;
1927 result->t_data = (HeapTupleHeader) ((char *) result + HEAPTUPLESIZE);
1928 memcpy((char *) result->t_data + MINIMAL_TUPLE_OFFSET, mtup, mtup->t_len);
1929 memset(result->t_data, 0, offsetof(HeapTupleHeaderData, t_infomask2));
1930 return result;
1934 * minimal_tuple_from_heap_tuple
1935 * create a MinimalTuple by copying from a HeapTuple
1937 * The result is allocated in the current memory context.
1939 MinimalTuple
1940 minimal_tuple_from_heap_tuple(HeapTuple htup)
1942 MinimalTuple result;
1943 uint32 len;
1945 Assert(htup->t_len > MINIMAL_TUPLE_OFFSET);
1946 len = htup->t_len - MINIMAL_TUPLE_OFFSET;
1947 result = (MinimalTuple) palloc(len);
1948 memcpy(result, (char *) htup->t_data + MINIMAL_TUPLE_OFFSET, len);
1949 result->t_len = len;
1950 return result;
1954 /* ----------------
1955 * heap_addheader
1957 * This routine forms a HeapTuple by copying the given structure (tuple
1958 * data) and adding a generic header. Note that the tuple data is
1959 * presumed to contain no null fields and no varlena fields.
1961 * This routine is really only useful for certain system tables that are
1962 * known to be fixed-width and null-free. Currently it is only used for
1963 * pg_attribute tuples.
1964 * ----------------
1966 HeapTuple
1967 heap_addheader(int natts, /* max domain index */
1968 bool withoid, /* reserve space for oid */
1969 Size structlen, /* its length */
1970 void *structure) /* pointer to the struct */
1972 HeapTuple tuple;
1973 HeapTupleHeader td;
1974 Size len;
1975 int hoff;
1977 AssertArg(natts > 0);
1979 /* header needs no null bitmap */
1980 hoff = offsetof(HeapTupleHeaderData, t_bits);
1981 if (withoid)
1982 hoff += sizeof(Oid);
1983 hoff = MAXALIGN(hoff);
1984 len = hoff + structlen;
1986 tuple = (HeapTuple) palloc0(HEAPTUPLESIZE + len);
1987 tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
1989 tuple->t_len = len;
1990 ItemPointerSetInvalid(&(tuple->t_self));
1991 tuple->t_tableOid = InvalidOid;
1993 /* we don't bother to fill the Datum fields */
1995 HeapTupleHeaderSetNatts(td, natts);
1996 td->t_hoff = hoff;
1998 if (withoid) /* else leave infomask = 0 */
1999 td->t_infomask = HEAP_HASOID;
2001 memcpy((char *) td + hoff, structure, structlen);
2003 return tuple;