Fix xslt_process() to ensure that it inserts a NULL terminator after the
[PostgreSQL.git] / src / backend / access / common / heaptuple.c
bloba86716e3af90ee85f1ff59a74ab7e3e35f5d3320
1 /*-------------------------------------------------------------------------
3 * heaptuple.c
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
21 * tuptoaster.c.
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
52 * IDENTIFICATION
53 * $PostgreSQL$
55 *-------------------------------------------------------------------------
58 #include "postgres.h"
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
84 Size
85 heap_compute_data_size(TupleDesc tupleDesc,
86 Datum *values,
87 bool *isnull)
89 Size data_length = 0;
90 int i;
91 int numberOfAttributes = tupleDesc->natts;
92 Form_pg_attribute *att = tupleDesc->attrs;
94 for (i = 0; i < numberOfAttributes; i++)
96 Datum val;
98 if (isnull[i])
99 continue;
101 val = values[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));
112 else
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,
117 val);
121 return data_length;
125 * heap_fill_tuple
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.
133 void
134 heap_fill_tuple(TupleDesc tupleDesc,
135 Datum *values, bool *isnull,
136 char *data, Size data_size,
137 uint16 *infomask, bits8 *bit)
139 bits8 *bitP;
140 int bitmask;
141 int i;
142 int numberOfAttributes = tupleDesc->natts;
143 Form_pg_attribute *att = tupleDesc->attrs;
145 #ifdef USE_ASSERT_CHECKING
146 char *start = data;
147 #endif
149 if (bit != NULL)
151 bitP = &bit[-1];
152 bitmask = HIGHBIT;
154 else
156 /* just to keep compiler quiet */
157 bitP = NULL;
158 bitmask = 0;
161 *infomask &= ~(HEAP_HASNULL | HEAP_HASVARWIDTH | HEAP_HASEXTERNAL);
163 for (i = 0; i < numberOfAttributes; i++)
165 Size data_length;
167 if (bit != NULL)
169 if (bitmask != HIGHBIT)
170 bitmask <<= 1;
171 else
173 bitP += 1;
174 *bitP = 0x0;
175 bitmask = 1;
178 if (isnull[i])
180 *infomask |= HEAP_HASNULL;
181 continue;
184 *bitP |= bitmask;
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)
194 /* pass-by-value */
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)
201 /* varlena */
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);
226 else
228 /* full 4-byte header varlena */
229 data = (char *) att_align_nominal((long) data,
230 att[i]->attalign);
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);
243 else
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);
252 data += data_length;
255 Assert((data - start) == data_size);
259 /* ----------------------------------------------------------------
260 * heap tuple interface
261 * ----------------------------------------------------------------
264 /* ----------------
265 * heap_attisnull - returns TRUE iff tuple attribute is not present
266 * ----------------
268 bool
269 heap_attisnull(HeapTuple tup, int attnum)
271 if (attnum > (int) HeapTupleHeaderGetNatts(tup->t_data))
272 return true;
274 if (attnum > 0)
276 if (HeapTupleNoNulls(tup))
277 return false;
278 return att_isnull(attnum - 1, tup->t_data->t_bits);
281 switch (attnum)
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 */
291 break;
293 default:
294 elog(ERROR, "invalid attnum: %d", attnum);
297 return false;
300 /* ----------------
301 * nocachegetattr
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
320 * tuples.
321 * ----------------
323 Datum
324 nocachegetattr(HeapTuple tuple,
325 int attnum,
326 TupleDesc tupleDesc,
327 bool *isnull)
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 */
338 /* ----------------
339 * Three cases:
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.
344 * ----------------
347 #ifdef IN_MACRO
348 /* This is handled in the macro */
349 Assert(attnum > 0);
351 if (isnull)
352 *isnull = false;
353 #endif
355 attnum--;
357 if (HeapTupleNoNulls(tuple))
359 #ifdef IN_MACRO
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);
367 #endif
369 else
372 * there's a null somewhere in the tuple
374 * check to see if desired att is null
377 #ifdef IN_MACRO
378 /* This is handled in the macro */
379 if (att_isnull(attnum, bp))
381 if (isnull)
382 *isnull = true;
383 return (Datum) NULL;
385 #endif
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))
396 slow = true;
397 else
399 /* check for nulls in any "earlier" bytes */
400 int i;
402 for (i = 0; i < byte; i++)
404 if (bp[i] != 0xFF)
406 slow = true;
407 break;
414 tp = (char *) tup + tup->t_hoff;
416 if (!slow)
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))
435 int j;
437 for (j = 0; j <= attnum; j++)
439 if (att[j]->attlen <= 0)
441 slow = true;
442 break;
448 if (!slow)
450 int natts = tupleDesc->natts;
451 int j = 1;
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
460 * routine.
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)
466 j++;
468 off = att[j - 1]->attcacheoff + att[j - 1]->attlen;
470 for (; j < natts; j++)
472 if (att[j]->attlen <= 0)
473 break;
475 off = att_align_nominal(off, att[j]->attalign);
477 att[j]->attcacheoff = off;
479 off += att[j]->attlen;
482 Assert(j > attnum);
484 off = att[attnum]->attcacheoff;
486 else
488 bool usecache = true;
489 int i;
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.
501 off = 0;
502 for (i = 0;; i++) /* loop exit is at "break" */
504 if (HeapTupleHasNulls(tuple) && att_isnull(i, bp))
506 usecache = false;
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.
521 if (usecache &&
522 off == att_align_nominal(off, att[i]->attalign))
523 att[i]->attcacheoff = off;
524 else
526 off = att_align_pointer(off, att[i]->attalign, -1,
527 tp + off);
528 usecache = false;
531 else
533 /* not varlena, so safe to use att_align_nominal */
534 off = att_align_nominal(off, att[i]->attalign);
536 if (usecache)
537 att[i]->attcacheoff = off;
540 if (i == attnum)
541 break;
543 off = att_addlength_pointer(off, att[i]->attlen, tp + off);
545 if (usecache && att[i]->attlen <= 0)
546 usecache = false;
550 return fetchatt(att[attnum], tp + off);
553 /* ----------------
554 * heap_getsysattr
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.
560 * ----------------
562 Datum
563 heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
565 Datum result;
567 Assert(tup);
569 /* Currently, no sys attribute ever reads as NULL. */
570 if (isnull)
571 *isnull = false;
573 switch (attnum)
575 case SelfItemPointerAttributeNumber:
576 /* pass-by-reference datatype */
577 result = PointerGetDatum(&(tup->t_self));
578 break;
579 case ObjectIdAttributeNumber:
580 result = ObjectIdGetDatum(HeapTupleGetOid(tup));
581 break;
582 case MinTransactionIdAttributeNumber:
583 result = TransactionIdGetDatum(HeapTupleHeaderGetXmin(tup->t_data));
584 break;
585 case MaxTransactionIdAttributeNumber:
586 result = TransactionIdGetDatum(HeapTupleHeaderGetXmax(tup->t_data));
587 break;
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));
598 break;
599 case TableOidAttributeNumber:
600 result = ObjectIdGetDatum(tup->t_tableOid);
601 break;
602 default:
603 elog(ERROR, "invalid attnum: %d", attnum);
604 result = 0; /* keep compiler quiet */
605 break;
607 return result;
610 /* ----------------
611 * heap_copytuple
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.
617 * ----------------
619 HeapTuple
620 heap_copytuple(HeapTuple tuple)
622 HeapTuple newTuple;
624 if (!HeapTupleIsValid(tuple) || tuple->t_data == NULL)
625 return 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);
633 return newTuple;
636 /* ----------------
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()).
643 * ----------------
645 void
646 heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest)
648 if (!HeapTupleIsValid(src) || src->t_data == NULL)
650 dest->t_data = NULL;
651 return;
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);
662 * heap_form_tuple
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.
668 HeapTuple
669 heap_form_tuple(TupleDesc tupleDescriptor,
670 Datum *values,
671 bool *isnull)
673 HeapTuple tuple; /* return tuple */
674 HeapTupleHeader td; /* tuple data */
675 Size len,
676 data_len;
677 int hoff;
678 bool hasnull = false;
679 Form_pg_attribute *att = tupleDescriptor->attrs;
680 int numberOfAttributes = tupleDescriptor->natts;
681 int i;
683 if (numberOfAttributes > MaxTupleAttributeNumber)
684 ereport(ERROR,
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
692 * go one level deep.
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++)
702 if (isnull[i])
703 hasnull = true;
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],
710 att[i]->atttypid,
711 att[i]->atttypmod);
716 * Determine total space needed
718 len = offsetof(HeapTupleHeaderData, t_bits);
720 if (hasnull)
721 len += BITMAPLEN(numberOfAttributes);
723 if (tupleDescriptor->tdhasoid)
724 len += sizeof(Oid);
726 hoff = len = MAXALIGN(len); /* align user data safely */
728 data_len = heap_compute_data_size(tupleDescriptor, values, isnull);
730 len += data_len;
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.
743 tuple->t_len = len;
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);
752 td->t_hoff = hoff;
754 if (tupleDescriptor->tdhasoid) /* else leave infomask = 0 */
755 td->t_infomask = HEAP_HASOID;
757 heap_fill_tuple(tupleDescriptor,
758 values,
759 isnull,
760 (char *) td + hoff,
761 data_len,
762 &td->t_infomask,
763 (hasnull ? td->t_bits : NULL));
765 return tuple;
769 * heap_formtuple
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.
780 HeapTuple
781 heap_formtuple(TupleDesc tupleDescriptor,
782 Datum *values,
783 char *nulls)
785 HeapTuple tuple; /* return tuple */
786 int numberOfAttributes = tupleDescriptor->natts;
787 bool *boolNulls = (bool *) palloc(numberOfAttributes * sizeof(bool));
788 int i;
790 for (i = 0; i < numberOfAttributes; i++)
791 boolNulls[i] = (nulls[i] == 'n');
793 tuple = heap_form_tuple(tupleDescriptor, values, boolNulls);
795 pfree(boolNulls);
797 return tuple;
802 * heap_modify_tuple
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.
812 HeapTuple
813 heap_modify_tuple(HeapTuple tuple,
814 TupleDesc tupleDesc,
815 Datum *replValues,
816 bool *replIsnull,
817 bool *doReplace)
819 int numberOfAttributes = tupleDesc->natts;
820 int attoff;
821 Datum *values;
822 bool *isnull;
823 HeapTuple newTuple;
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);
855 pfree(values);
856 pfree(isnull);
859 * copy the identification info of the old tuple: t_ctid, t_self, and OID
860 * (if any)
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));
868 return newTuple;
872 * heap_modifytuple
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.
882 HeapTuple
883 heap_modifytuple(HeapTuple tuple,
884 TupleDesc tupleDesc,
885 Datum *replValues,
886 char *replNulls,
887 char *replActions)
889 HeapTuple result;
890 int numberOfAttributes = tupleDesc->natts;
891 bool *boolNulls = (bool *) palloc(numberOfAttributes * sizeof(bool));
892 bool *boolActions = (bool *) palloc(numberOfAttributes * sizeof(bool));
893 int attnum;
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);
903 pfree(boolNulls);
904 pfree(boolActions);
906 return result;
910 * heap_deform_tuple
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.
925 void
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 */
934 int attnum;
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;
951 off = 0;
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 */
962 continue;
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.
977 if (!slow &&
978 off == att_align_nominal(off, thisatt->attalign))
979 thisatt->attcacheoff = off;
980 else
982 off = att_align_pointer(off, thisatt->attalign, -1,
983 tp + off);
984 slow = true;
987 else
989 /* not varlena, so safe to use att_align_nominal */
990 off = att_align_nominal(off, thisatt->attalign);
992 if (!slow)
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
1006 * rest as null
1008 for (; attnum < tdesc_natts; attnum++)
1010 values[attnum] = (Datum) 0;
1011 isnull[attnum] = true;
1016 * heap_deformtuple
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.
1036 void
1037 heap_deformtuple(HeapTuple tuple,
1038 TupleDesc tupleDesc,
1039 Datum *values,
1040 char *nulls)
1042 int natts = tupleDesc->natts;
1043 bool *boolNulls = (bool *) palloc(natts * sizeof(bool));
1044 int attnum;
1046 heap_deform_tuple(tuple, tupleDesc, values, boolNulls);
1048 for (attnum = 0; attnum < natts; attnum++)
1049 nulls[attnum] = (boolNulls[attnum] ? 'n' : ' ');
1051 pfree(boolNulls);
1055 * slot_deform_tuple
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.
1065 static void
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;
1075 int attnum;
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
1083 * loop state.
1085 attnum = slot->tts_nvalid;
1086 if (attnum == 0)
1088 /* Start from the first attribute */
1089 off = 0;
1090 slow = false;
1092 else
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 */
1110 continue;
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.
1125 if (!slow &&
1126 off == att_align_nominal(off, thisatt->attalign))
1127 thisatt->attcacheoff = off;
1128 else
1130 off = att_align_pointer(off, thisatt->attalign, -1,
1131 tp + off);
1132 slow = true;
1135 else
1137 /* not varlena, so safe to use att_align_nominal */
1138 off = att_align_nominal(off, thisatt->attalign);
1140 if (!slow)
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;
1161 * slot_getattr
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.
1172 Datum
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
1182 if (attnum <= 0)
1184 if (tuple == NULL) /* internal error */
1185 elog(ERROR, "cannot extract system attribute from virtual tuple");
1186 if (tuple == &(slot->tts_minhdr)) /* 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)
1205 *isnull = true;
1206 return (Datum) 0;
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))
1226 *isnull = true;
1227 return (Datum) 0;
1231 * check if target attribute is null: no point in groveling through tuple
1233 if (HeapTupleHasNulls(tuple) && att_isnull(attnum - 1, tup->t_bits))
1235 *isnull = true;
1236 return (Datum) 0;
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)
1246 *isnull = true;
1247 return (Datum) 0;
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];
1263 * slot_getallattrs
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.
1268 void
1269 slot_getallattrs(TupleTableSlot *slot)
1271 int tdesc_natts = slot->tts_tupleDescriptor->natts;
1272 int attnum;
1273 HeapTuple tuple;
1275 /* Quick out if we have 'em all already */
1276 if (slot->tts_nvalid == tdesc_natts)
1277 return;
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
1297 * rest as null
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;
1308 * slot_getsomeattrs
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.
1312 void
1313 slot_getsomeattrs(TupleTableSlot *slot, int attnum)
1315 HeapTuple tuple;
1316 int attno;
1318 /* Quick out if we have 'em all already */
1319 if (slot->tts_nvalid >= attnum)
1320 return;
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
1344 * rest as null
1346 for (; attno < attnum; attno++)
1348 slot->tts_values[attno] = (Datum) 0;
1349 slot->tts_isnull[attno] = true;
1351 slot->tts_nvalid = attnum;
1355 * slot_attisnull
1356 * Detect whether an attribute of the slot is null, without
1357 * actually fetching it.
1359 bool
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
1368 if (attnum <= 0)
1370 if (tuple == NULL) /* internal error */
1371 elog(ERROR, "cannot extract system attribute from virtual tuple");
1372 if (tuple == &(slot->tts_minhdr)) /* 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)
1387 return true;
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);
1401 * heap_freetuple
1403 void
1404 heap_freetuple(HeapTuple htup)
1406 pfree(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
1417 * columns.
1419 * The result is allocated in the current memory context.
1421 MinimalTuple
1422 heap_form_minimal_tuple(TupleDesc tupleDescriptor,
1423 Datum *values,
1424 bool *isnull)
1426 MinimalTuple tuple; /* return tuple */
1427 Size len,
1428 data_len;
1429 int hoff;
1430 bool hasnull = false;
1431 Form_pg_attribute *att = tupleDescriptor->attrs;
1432 int numberOfAttributes = tupleDescriptor->natts;
1433 int i;
1435 if (numberOfAttributes > MaxTupleAttributeNumber)
1436 ereport(ERROR,
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++)
1454 if (isnull[i])
1455 hasnull = true;
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],
1462 att[i]->atttypid,
1463 att[i]->atttypmod);
1468 * Determine total space needed
1470 len = offsetof(MinimalTupleData, t_bits);
1472 if (hasnull)
1473 len += BITMAPLEN(numberOfAttributes);
1475 if (tupleDescriptor->tdhasoid)
1476 len += sizeof(Oid);
1478 hoff = len = MAXALIGN(len); /* align user data safely */
1480 data_len = heap_compute_data_size(tupleDescriptor, values, isnull);
1482 len += data_len;
1485 * Allocate and zero the space needed.
1487 tuple = (MinimalTuple) palloc0(len);
1490 * And fill in the information.
1492 tuple->t_len = len;
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,
1500 values,
1501 isnull,
1502 (char *) tuple + hoff,
1503 data_len,
1504 &tuple->t_infomask,
1505 (hasnull ? tuple->t_bits : NULL));
1507 return tuple;
1511 * heap_free_minimal_tuple
1513 void
1514 heap_free_minimal_tuple(MinimalTuple mtup)
1516 pfree(mtup);
1520 * heap_copy_minimal_tuple
1521 * copy a MinimalTuple
1523 * The result is allocated in the current memory context.
1525 MinimalTuple
1526 heap_copy_minimal_tuple(MinimalTuple mtup)
1528 MinimalTuple result;
1530 result = (MinimalTuple) palloc(mtup->t_len);
1531 memcpy(result, mtup, mtup->t_len);
1532 return result;
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.
1544 HeapTuple
1545 heap_tuple_from_minimal_tuple(MinimalTuple mtup)
1547 HeapTuple result;
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));
1557 return result;
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.
1566 MinimalTuple
1567 minimal_tuple_from_heap_tuple(HeapTuple htup)
1569 MinimalTuple result;
1570 uint32 len;
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;
1577 return result;