PostgreSQL Source Code  git master
heaptuple.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * heaptuple.c
4  * This file contains heap tuple accessor and mutator routines, as well
5  * as various tuple utilities.
6  *
7  * Some notes about varlenas and this code:
8  *
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.
13  *
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  * heaptoast.c.
22  *
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.
26  *
27  * Varlenas still have alignment INT (or DOUBLE) 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.
36  *
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.
41  *
42  * We don't pack varlenas whose attstorage is PLAIN, 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.
46  *
47  *
48  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
49  * Portions Copyright (c) 1994, Regents of the University of California
50  *
51  *
52  * IDENTIFICATION
53  * src/backend/access/common/heaptuple.c
54  *
55  *-------------------------------------------------------------------------
56  */
57 
58 #include "postgres.h"
59 
60 #include "access/heaptoast.h"
61 #include "access/sysattr.h"
62 #include "access/tupdesc_details.h"
63 #include "common/hashfn.h"
64 #include "utils/datum.h"
65 #include "utils/expandeddatum.h"
66 #include "utils/hsearch.h"
67 #include "utils/memutils.h"
68 
69 
70 /*
71  * Does att's datatype allow packing into the 1-byte-header varlena format?
72  * While functions that use TupleDescAttr() and assign attstorage =
73  * TYPSTORAGE_PLAIN cannot use packed varlena headers, functions that call
74  * TupleDescInitEntry() use typeForm->typstorage (TYPSTORAGE_EXTENDED) and
75  * can use packed varlena headers, e.g.:
76  * CREATE TABLE test(a VARCHAR(10000) STORAGE PLAIN);
77  * INSERT INTO test VALUES (repeat('A',10));
78  * This can be verified with pageinspect.
79  */
80 #define ATT_IS_PACKABLE(att) \
81  ((att)->attlen == -1 && (att)->attstorage != TYPSTORAGE_PLAIN)
82 /* Use this if it's already known varlena */
83 #define VARLENA_ATT_IS_PACKABLE(att) \
84  ((att)->attstorage != TYPSTORAGE_PLAIN)
85 
86 /*
87  * Setup for caching pass-by-ref missing attributes in a way that survives
88  * tupleDesc destruction.
89  */
90 
91 typedef struct
92 {
93  int len;
96 
97 static HTAB *missing_cache = NULL;
98 
99 static uint32
100 missing_hash(const void *key, Size keysize)
101 {
102  const missing_cache_key *entry = (missing_cache_key *) key;
103 
104  return hash_bytes((const unsigned char *) entry->value, entry->len);
105 }
106 
107 static int
108 missing_match(const void *key1, const void *key2, Size keysize)
109 {
110  const missing_cache_key *entry1 = (missing_cache_key *) key1;
111  const missing_cache_key *entry2 = (missing_cache_key *) key2;
112 
113  if (entry1->len != entry2->len)
114  return entry1->len > entry2->len ? 1 : -1;
115 
116  return memcmp(DatumGetPointer(entry1->value),
117  DatumGetPointer(entry2->value),
118  entry1->len);
119 }
120 
121 static void
123 {
124  HASHCTL hash_ctl;
125 
126  hash_ctl.keysize = sizeof(missing_cache_key);
127  hash_ctl.entrysize = sizeof(missing_cache_key);
128  hash_ctl.hcxt = TopMemoryContext;
129  hash_ctl.hash = missing_hash;
130  hash_ctl.match = missing_match;
131  missing_cache =
132  hash_create("Missing Values Cache",
133  32,
134  &hash_ctl,
136 }
137 
138 /* ----------------------------------------------------------------
139  * misc support routines
140  * ----------------------------------------------------------------
141  */
142 
143 /*
144  * Return the missing value of an attribute, or NULL if there isn't one.
145  */
146 Datum
148  int attnum, bool *isnull)
149 {
150  Form_pg_attribute att;
151 
152  Assert(attnum <= tupleDesc->natts);
153  Assert(attnum > 0);
154 
155  att = TupleDescAttr(tupleDesc, attnum - 1);
156 
157  if (att->atthasmissing)
158  {
159  AttrMissing *attrmiss;
160 
161  Assert(tupleDesc->constr);
162  Assert(tupleDesc->constr->missing);
163 
164  attrmiss = tupleDesc->constr->missing + (attnum - 1);
165 
166  if (attrmiss->am_present)
167  {
169  missing_cache_key *entry;
170  bool found;
171  MemoryContext oldctx;
172 
173  *isnull = false;
174 
175  /* no need to cache by-value attributes */
176  if (att->attbyval)
177  return attrmiss->am_value;
178 
179  /* set up cache if required */
180  if (missing_cache == NULL)
182 
183  /* check if there's a cache entry */
184  Assert(att->attlen > 0 || att->attlen == -1);
185  if (att->attlen > 0)
186  key.len = att->attlen;
187  else
188  key.len = VARSIZE_ANY(attrmiss->am_value);
189  key.value = attrmiss->am_value;
190 
191  entry = hash_search(missing_cache, &key, HASH_ENTER, &found);
192 
193  if (!found)
194  {
195  /* cache miss, so we need a non-transient copy of the datum */
197  entry->value =
198  datumCopy(attrmiss->am_value, false, att->attlen);
199  MemoryContextSwitchTo(oldctx);
200  }
201 
202  return entry->value;
203  }
204  }
205 
206  *isnull = true;
207  return PointerGetDatum(NULL);
208 }
209 
210 /*
211  * heap_compute_data_size
212  * Determine size of the data area of a tuple to be constructed
213  */
214 Size
216  const Datum *values,
217  const bool *isnull)
218 {
219  Size data_length = 0;
220  int i;
221  int numberOfAttributes = tupleDesc->natts;
222 
223  for (i = 0; i < numberOfAttributes; i++)
224  {
225  Datum val;
226  Form_pg_attribute atti;
227 
228  if (isnull[i])
229  continue;
230 
231  val = values[i];
232  atti = TupleDescAttr(tupleDesc, i);
233 
234  if (ATT_IS_PACKABLE(atti) &&
236  {
237  /*
238  * we're anticipating converting to a short varlena header, so
239  * adjust length and don't count any alignment
240  */
242  }
243  else if (atti->attlen == -1 &&
245  {
246  /*
247  * we want to flatten the expanded value so that the constructed
248  * tuple doesn't depend on it
249  */
250  data_length = att_align_nominal(data_length, atti->attalign);
251  data_length += EOH_get_flat_size(DatumGetEOHP(val));
252  }
253  else
254  {
255  data_length = att_align_datum(data_length, atti->attalign,
256  atti->attlen, val);
257  data_length = att_addlength_datum(data_length, atti->attlen,
258  val);
259  }
260  }
261 
262  return data_length;
263 }
264 
265 /*
266  * Per-attribute helper for heap_fill_tuple and other routines building tuples.
267  *
268  * Fill in either a data value or a bit in the null bitmask
269  */
270 static inline void
272  bits8 **bit,
273  int *bitmask,
274  char **dataP,
275  uint16 *infomask,
276  Datum datum,
277  bool isnull)
278 {
279  Size data_length;
280  char *data = *dataP;
281 
282  /*
283  * If we're building a null bitmap, set the appropriate bit for the
284  * current column value here.
285  */
286  if (bit != NULL)
287  {
288  if (*bitmask != HIGHBIT)
289  *bitmask <<= 1;
290  else
291  {
292  *bit += 1;
293  **bit = 0x0;
294  *bitmask = 1;
295  }
296 
297  if (isnull)
298  {
299  *infomask |= HEAP_HASNULL;
300  return;
301  }
302 
303  **bit |= *bitmask;
304  }
305 
306  /*
307  * XXX we use the att_align macros on the pointer value itself, not on an
308  * offset. This is a bit of a hack.
309  */
310  if (att->attbyval)
311  {
312  /* pass-by-value */
313  data = (char *) att_align_nominal(data, att->attalign);
314  store_att_byval(data, datum, att->attlen);
315  data_length = att->attlen;
316  }
317  else if (att->attlen == -1)
318  {
319  /* varlena */
320  Pointer val = DatumGetPointer(datum);
321 
322  *infomask |= HEAP_HASVARWIDTH;
323  if (VARATT_IS_EXTERNAL(val))
324  {
326  {
327  /*
328  * we want to flatten the expanded value so that the
329  * constructed tuple doesn't depend on it
330  */
331  ExpandedObjectHeader *eoh = DatumGetEOHP(datum);
332 
333  data = (char *) att_align_nominal(data,
334  att->attalign);
335  data_length = EOH_get_flat_size(eoh);
336  EOH_flatten_into(eoh, data, data_length);
337  }
338  else
339  {
340  *infomask |= HEAP_HASEXTERNAL;
341  /* no alignment, since it's short by definition */
342  data_length = VARSIZE_EXTERNAL(val);
343  memcpy(data, val, data_length);
344  }
345  }
346  else if (VARATT_IS_SHORT(val))
347  {
348  /* no alignment for short varlenas */
349  data_length = VARSIZE_SHORT(val);
350  memcpy(data, val, data_length);
351  }
352  else if (VARLENA_ATT_IS_PACKABLE(att) &&
354  {
355  /* convert to short varlena -- no alignment */
356  data_length = VARATT_CONVERTED_SHORT_SIZE(val);
357  SET_VARSIZE_SHORT(data, data_length);
358  memcpy(data + 1, VARDATA(val), data_length - 1);
359  }
360  else
361  {
362  /* full 4-byte header varlena */
363  data = (char *) att_align_nominal(data,
364  att->attalign);
365  data_length = VARSIZE(val);
366  memcpy(data, val, data_length);
367  }
368  }
369  else if (att->attlen == -2)
370  {
371  /* cstring ... never needs alignment */
372  *infomask |= HEAP_HASVARWIDTH;
373  Assert(att->attalign == TYPALIGN_CHAR);
374  data_length = strlen(DatumGetCString(datum)) + 1;
375  memcpy(data, DatumGetPointer(datum), data_length);
376  }
377  else
378  {
379  /* fixed-length pass-by-reference */
380  data = (char *) att_align_nominal(data, att->attalign);
381  Assert(att->attlen > 0);
382  data_length = att->attlen;
383  memcpy(data, DatumGetPointer(datum), data_length);
384  }
385 
386  data += data_length;
387  *dataP = data;
388 }
389 
390 /*
391  * heap_fill_tuple
392  * Load data portion of a tuple from values/isnull arrays
393  *
394  * We also fill the null bitmap (if any) and set the infomask bits
395  * that reflect the tuple's data contents.
396  *
397  * NOTE: it is now REQUIRED that the caller have pre-zeroed the data area.
398  */
399 void
401  const Datum *values, const bool *isnull,
402  char *data, Size data_size,
403  uint16 *infomask, bits8 *bit)
404 {
405  bits8 *bitP;
406  int bitmask;
407  int i;
408  int numberOfAttributes = tupleDesc->natts;
409 
410 #ifdef USE_ASSERT_CHECKING
411  char *start = data;
412 #endif
413 
414  if (bit != NULL)
415  {
416  bitP = &bit[-1];
417  bitmask = HIGHBIT;
418  }
419  else
420  {
421  /* just to keep compiler quiet */
422  bitP = NULL;
423  bitmask = 0;
424  }
425 
426  *infomask &= ~(HEAP_HASNULL | HEAP_HASVARWIDTH | HEAP_HASEXTERNAL);
427 
428  for (i = 0; i < numberOfAttributes; i++)
429  {
430  Form_pg_attribute attr = TupleDescAttr(tupleDesc, i);
431 
432  fill_val(attr,
433  bitP ? &bitP : NULL,
434  &bitmask,
435  &data,
436  infomask,
437  values ? values[i] : PointerGetDatum(NULL),
438  isnull ? isnull[i] : true);
439  }
440 
441  Assert((data - start) == data_size);
442 }
443 
444 
445 /* ----------------------------------------------------------------
446  * heap tuple interface
447  * ----------------------------------------------------------------
448  */
449 
450 /* ----------------
451  * heap_attisnull - returns true iff tuple attribute is not present
452  * ----------------
453  */
454 bool
456 {
457  /*
458  * We allow a NULL tupledesc for relations not expected to have missing
459  * values, such as catalog relations and indexes.
460  */
461  Assert(!tupleDesc || attnum <= tupleDesc->natts);
462  if (attnum > (int) HeapTupleHeaderGetNatts(tup->t_data))
463  {
464  if (tupleDesc && TupleDescAttr(tupleDesc, attnum - 1)->atthasmissing)
465  return false;
466  else
467  return true;
468  }
469 
470  if (attnum > 0)
471  {
472  if (HeapTupleNoNulls(tup))
473  return false;
474  return att_isnull(attnum - 1, tup->t_data->t_bits);
475  }
476 
477  switch (attnum)
478  {
485  /* these are never null */
486  break;
487 
488  default:
489  elog(ERROR, "invalid attnum: %d", attnum);
490  }
491 
492  return false;
493 }
494 
495 /* ----------------
496  * nocachegetattr
497  *
498  * This only gets called from fastgetattr(), in cases where we
499  * can't use a cacheoffset and the value is not null.
500  *
501  * This caches attribute offsets in the attribute descriptor.
502  *
503  * An alternative way to speed things up would be to cache offsets
504  * with the tuple, but that seems more difficult unless you take
505  * the storage hit of actually putting those offsets into the
506  * tuple you send to disk. Yuck.
507  *
508  * This scheme will be slightly slower than that, but should
509  * perform well for queries which hit large #'s of tuples. After
510  * you cache the offsets once, examining all the other tuples using
511  * the same attribute descriptor will go much quicker. -cim 5/4/91
512  *
513  * NOTE: if you need to change this code, see also heap_deform_tuple.
514  * Also see nocache_index_getattr, which is the same code for index
515  * tuples.
516  * ----------------
517  */
518 Datum
520  int attnum,
521  TupleDesc tupleDesc)
522 {
523  HeapTupleHeader td = tup->t_data;
524  char *tp; /* ptr to data part of tuple */
525  bits8 *bp = td->t_bits; /* ptr to null bitmap in tuple */
526  bool slow = false; /* do we have to walk attrs? */
527  int off; /* current offset within data */
528 
529  /* ----------------
530  * Three cases:
531  *
532  * 1: No nulls and no variable-width attributes.
533  * 2: Has a null or a var-width AFTER att.
534  * 3: Has nulls or var-widths BEFORE att.
535  * ----------------
536  */
537 
538  attnum--;
539 
540  if (!HeapTupleNoNulls(tup))
541  {
542  /*
543  * there's a null somewhere in the tuple
544  *
545  * check to see if any preceding bits are null...
546  */
547  int byte = attnum >> 3;
548  int finalbit = attnum & 0x07;
549 
550  /* check for nulls "before" final bit of last byte */
551  if ((~bp[byte]) & ((1 << finalbit) - 1))
552  slow = true;
553  else
554  {
555  /* check for nulls in any "earlier" bytes */
556  int i;
557 
558  for (i = 0; i < byte; i++)
559  {
560  if (bp[i] != 0xFF)
561  {
562  slow = true;
563  break;
564  }
565  }
566  }
567  }
568 
569  tp = (char *) td + td->t_hoff;
570 
571  if (!slow)
572  {
573  Form_pg_attribute att;
574 
575  /*
576  * If we get here, there are no nulls up to and including the target
577  * attribute. If we have a cached offset, we can use it.
578  */
579  att = TupleDescAttr(tupleDesc, attnum);
580  if (att->attcacheoff >= 0)
581  return fetchatt(att, tp + att->attcacheoff);
582 
583  /*
584  * Otherwise, check for non-fixed-length attrs up to and including
585  * target. If there aren't any, it's safe to cheaply initialize the
586  * cached offsets for these attrs.
587  */
588  if (HeapTupleHasVarWidth(tup))
589  {
590  int j;
591 
592  for (j = 0; j <= attnum; j++)
593  {
594  if (TupleDescAttr(tupleDesc, j)->attlen <= 0)
595  {
596  slow = true;
597  break;
598  }
599  }
600  }
601  }
602 
603  if (!slow)
604  {
605  int natts = tupleDesc->natts;
606  int j = 1;
607 
608  /*
609  * If we get here, we have a tuple with no nulls or var-widths up to
610  * and including the target attribute, so we can use the cached offset
611  * ... only we don't have it yet, or we'd not have got here. Since
612  * it's cheap to compute offsets for fixed-width columns, we take the
613  * opportunity to initialize the cached offsets for *all* the leading
614  * fixed-width columns, in hope of avoiding future visits to this
615  * routine.
616  */
617  TupleDescAttr(tupleDesc, 0)->attcacheoff = 0;
618 
619  /* we might have set some offsets in the slow path previously */
620  while (j < natts && TupleDescAttr(tupleDesc, j)->attcacheoff > 0)
621  j++;
622 
623  off = TupleDescAttr(tupleDesc, j - 1)->attcacheoff +
624  TupleDescAttr(tupleDesc, j - 1)->attlen;
625 
626  for (; j < natts; j++)
627  {
628  Form_pg_attribute att = TupleDescAttr(tupleDesc, j);
629 
630  if (att->attlen <= 0)
631  break;
632 
633  off = att_align_nominal(off, att->attalign);
634 
635  att->attcacheoff = off;
636 
637  off += att->attlen;
638  }
639 
640  Assert(j > attnum);
641 
642  off = TupleDescAttr(tupleDesc, attnum)->attcacheoff;
643  }
644  else
645  {
646  bool usecache = true;
647  int i;
648 
649  /*
650  * Now we know that we have to walk the tuple CAREFULLY. But we still
651  * might be able to cache some offsets for next time.
652  *
653  * Note - This loop is a little tricky. For each non-null attribute,
654  * we have to first account for alignment padding before the attr,
655  * then advance over the attr based on its length. Nulls have no
656  * storage and no alignment padding either. We can use/set
657  * attcacheoff until we reach either a null or a var-width attribute.
658  */
659  off = 0;
660  for (i = 0;; i++) /* loop exit is at "break" */
661  {
662  Form_pg_attribute att = TupleDescAttr(tupleDesc, i);
663 
664  if (HeapTupleHasNulls(tup) && att_isnull(i, bp))
665  {
666  usecache = false;
667  continue; /* this cannot be the target att */
668  }
669 
670  /* If we know the next offset, we can skip the rest */
671  if (usecache && att->attcacheoff >= 0)
672  off = att->attcacheoff;
673  else if (att->attlen == -1)
674  {
675  /*
676  * We can only cache the offset for a varlena attribute if the
677  * offset is already suitably aligned, so that there would be
678  * no pad bytes in any case: then the offset will be valid for
679  * either an aligned or unaligned value.
680  */
681  if (usecache &&
682  off == att_align_nominal(off, att->attalign))
683  att->attcacheoff = off;
684  else
685  {
686  off = att_align_pointer(off, att->attalign, -1,
687  tp + off);
688  usecache = false;
689  }
690  }
691  else
692  {
693  /* not varlena, so safe to use att_align_nominal */
694  off = att_align_nominal(off, att->attalign);
695 
696  if (usecache)
697  att->attcacheoff = off;
698  }
699 
700  if (i == attnum)
701  break;
702 
703  off = att_addlength_pointer(off, att->attlen, tp + off);
704 
705  if (usecache && att->attlen <= 0)
706  usecache = false;
707  }
708  }
709 
710  return fetchatt(TupleDescAttr(tupleDesc, attnum), tp + off);
711 }
712 
713 /* ----------------
714  * heap_getsysattr
715  *
716  * Fetch the value of a system attribute for a tuple.
717  *
718  * This is a support routine for heap_getattr(). The function has already
719  * determined that the attnum refers to a system attribute.
720  * ----------------
721  */
722 Datum
723 heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
724 {
725  Datum result;
726 
727  Assert(tup);
728 
729  /* Currently, no sys attribute ever reads as NULL. */
730  *isnull = false;
731 
732  switch (attnum)
733  {
735  /* pass-by-reference datatype */
736  result = PointerGetDatum(&(tup->t_self));
737  break;
740  break;
743  break;
746 
747  /*
748  * cmin and cmax are now both aliases for the same field, which
749  * can in fact also be a combo command id. XXX perhaps we should
750  * return the "real" cmin or cmax if possible, that is if we are
751  * inside the originating transaction?
752  */
754  break;
756  result = ObjectIdGetDatum(tup->t_tableOid);
757  break;
758  default:
759  elog(ERROR, "invalid attnum: %d", attnum);
760  result = 0; /* keep compiler quiet */
761  break;
762  }
763  return result;
764 }
765 
766 /* ----------------
767  * heap_copytuple
768  *
769  * returns a copy of an entire tuple
770  *
771  * The HeapTuple struct, tuple header, and tuple data are all allocated
772  * as a single palloc() block.
773  * ----------------
774  */
775 HeapTuple
777 {
778  HeapTuple newTuple;
779 
780  if (!HeapTupleIsValid(tuple) || tuple->t_data == NULL)
781  return NULL;
782 
783  newTuple = (HeapTuple) palloc(HEAPTUPLESIZE + tuple->t_len);
784  newTuple->t_len = tuple->t_len;
785  newTuple->t_self = tuple->t_self;
786  newTuple->t_tableOid = tuple->t_tableOid;
787  newTuple->t_data = (HeapTupleHeader) ((char *) newTuple + HEAPTUPLESIZE);
788  memcpy((char *) newTuple->t_data, (char *) tuple->t_data, tuple->t_len);
789  return newTuple;
790 }
791 
792 /* ----------------
793  * heap_copytuple_with_tuple
794  *
795  * copy a tuple into a caller-supplied HeapTuple management struct
796  *
797  * Note that after calling this function, the "dest" HeapTuple will not be
798  * allocated as a single palloc() block (unlike with heap_copytuple()).
799  * ----------------
800  */
801 void
803 {
804  if (!HeapTupleIsValid(src) || src->t_data == NULL)
805  {
806  dest->t_data = NULL;
807  return;
808  }
809 
810  dest->t_len = src->t_len;
811  dest->t_self = src->t_self;
812  dest->t_tableOid = src->t_tableOid;
813  dest->t_data = (HeapTupleHeader) palloc(src->t_len);
814  memcpy((char *) dest->t_data, (char *) src->t_data, src->t_len);
815 }
816 
817 /*
818  * Expand a tuple which has fewer attributes than required. For each attribute
819  * not present in the sourceTuple, if there is a missing value that will be
820  * used. Otherwise the attribute will be set to NULL.
821  *
822  * The source tuple must have fewer attributes than the required number.
823  *
824  * Only one of targetHeapTuple and targetMinimalTuple may be supplied. The
825  * other argument must be NULL.
826  */
827 static void
828 expand_tuple(HeapTuple *targetHeapTuple,
829  MinimalTuple *targetMinimalTuple,
830  HeapTuple sourceTuple,
831  TupleDesc tupleDesc)
832 {
833  AttrMissing *attrmiss = NULL;
834  int attnum;
835  int firstmissingnum;
836  bool hasNulls = HeapTupleHasNulls(sourceTuple);
837  HeapTupleHeader targetTHeader;
838  HeapTupleHeader sourceTHeader = sourceTuple->t_data;
839  int sourceNatts = HeapTupleHeaderGetNatts(sourceTHeader);
840  int natts = tupleDesc->natts;
841  int sourceNullLen;
842  int targetNullLen;
843  Size sourceDataLen = sourceTuple->t_len - sourceTHeader->t_hoff;
844  Size targetDataLen;
845  Size len;
846  int hoff;
847  bits8 *nullBits = NULL;
848  int bitMask = 0;
849  char *targetData;
850  uint16 *infoMask;
851 
852  Assert((targetHeapTuple && !targetMinimalTuple)
853  || (!targetHeapTuple && targetMinimalTuple));
854 
855  Assert(sourceNatts < natts);
856 
857  sourceNullLen = (hasNulls ? BITMAPLEN(sourceNatts) : 0);
858 
859  targetDataLen = sourceDataLen;
860 
861  if (tupleDesc->constr &&
862  tupleDesc->constr->missing)
863  {
864  /*
865  * If there are missing values we want to put them into the tuple.
866  * Before that we have to compute the extra length for the values
867  * array and the variable length data.
868  */
869  attrmiss = tupleDesc->constr->missing;
870 
871  /*
872  * Find the first item in attrmiss for which we don't have a value in
873  * the source. We can ignore all the missing entries before that.
874  */
875  for (firstmissingnum = sourceNatts;
876  firstmissingnum < natts;
877  firstmissingnum++)
878  {
879  if (attrmiss[firstmissingnum].am_present)
880  break;
881  else
882  hasNulls = true;
883  }
884 
885  /*
886  * Now walk the missing attributes. If there is a missing value make
887  * space for it. Otherwise, it's going to be NULL.
888  */
889  for (attnum = firstmissingnum;
890  attnum < natts;
891  attnum++)
892  {
893  if (attrmiss[attnum].am_present)
894  {
895  Form_pg_attribute att = TupleDescAttr(tupleDesc, attnum);
896 
897  targetDataLen = att_align_datum(targetDataLen,
898  att->attalign,
899  att->attlen,
900  attrmiss[attnum].am_value);
901 
902  targetDataLen = att_addlength_pointer(targetDataLen,
903  att->attlen,
904  attrmiss[attnum].am_value);
905  }
906  else
907  {
908  /* no missing value, so it must be null */
909  hasNulls = true;
910  }
911  }
912  } /* end if have missing values */
913  else
914  {
915  /*
916  * If there are no missing values at all then NULLS must be allowed,
917  * since some of the attributes are known to be absent.
918  */
919  hasNulls = true;
920  }
921 
922  len = 0;
923 
924  if (hasNulls)
925  {
926  targetNullLen = BITMAPLEN(natts);
927  len += targetNullLen;
928  }
929  else
930  targetNullLen = 0;
931 
932  /*
933  * Allocate and zero the space needed. Note that the tuple body and
934  * HeapTupleData management structure are allocated in one chunk.
935  */
936  if (targetHeapTuple)
937  {
938  len += offsetof(HeapTupleHeaderData, t_bits);
939  hoff = len = MAXALIGN(len); /* align user data safely */
940  len += targetDataLen;
941 
942  *targetHeapTuple = (HeapTuple) palloc0(HEAPTUPLESIZE + len);
943  (*targetHeapTuple)->t_data
944  = targetTHeader
945  = (HeapTupleHeader) ((char *) *targetHeapTuple + HEAPTUPLESIZE);
946  (*targetHeapTuple)->t_len = len;
947  (*targetHeapTuple)->t_tableOid = sourceTuple->t_tableOid;
948  (*targetHeapTuple)->t_self = sourceTuple->t_self;
949 
950  targetTHeader->t_infomask = sourceTHeader->t_infomask;
951  targetTHeader->t_hoff = hoff;
952  HeapTupleHeaderSetNatts(targetTHeader, natts);
953  HeapTupleHeaderSetDatumLength(targetTHeader, len);
954  HeapTupleHeaderSetTypeId(targetTHeader, tupleDesc->tdtypeid);
955  HeapTupleHeaderSetTypMod(targetTHeader, tupleDesc->tdtypmod);
956  /* We also make sure that t_ctid is invalid unless explicitly set */
957  ItemPointerSetInvalid(&(targetTHeader->t_ctid));
958  if (targetNullLen > 0)
959  nullBits = (bits8 *) ((char *) (*targetHeapTuple)->t_data
960  + offsetof(HeapTupleHeaderData, t_bits));
961  targetData = (char *) (*targetHeapTuple)->t_data + hoff;
962  infoMask = &(targetTHeader->t_infomask);
963  }
964  else
965  {
967  hoff = len = MAXALIGN(len); /* align user data safely */
968  len += targetDataLen;
969 
970  *targetMinimalTuple = (MinimalTuple) palloc0(len);
971  (*targetMinimalTuple)->t_len = len;
972  (*targetMinimalTuple)->t_hoff = hoff + MINIMAL_TUPLE_OFFSET;
973  (*targetMinimalTuple)->t_infomask = sourceTHeader->t_infomask;
974  /* Same macro works for MinimalTuples */
975  HeapTupleHeaderSetNatts(*targetMinimalTuple, natts);
976  if (targetNullLen > 0)
977  nullBits = (bits8 *) ((char *) *targetMinimalTuple
978  + offsetof(MinimalTupleData, t_bits));
979  targetData = (char *) *targetMinimalTuple + hoff;
980  infoMask = &((*targetMinimalTuple)->t_infomask);
981  }
982 
983  if (targetNullLen > 0)
984  {
985  if (sourceNullLen > 0)
986  {
987  /* if bitmap pre-existed copy in - all is set */
988  memcpy(nullBits,
989  ((char *) sourceTHeader)
990  + offsetof(HeapTupleHeaderData, t_bits),
991  sourceNullLen);
992  nullBits += sourceNullLen - 1;
993  }
994  else
995  {
996  sourceNullLen = BITMAPLEN(sourceNatts);
997  /* Set NOT NULL for all existing attributes */
998  memset(nullBits, 0xff, sourceNullLen);
999 
1000  nullBits += sourceNullLen - 1;
1001 
1002  if (sourceNatts & 0x07)
1003  {
1004  /* build the mask (inverted!) */
1005  bitMask = 0xff << (sourceNatts & 0x07);
1006  /* Voila */
1007  *nullBits = ~bitMask;
1008  }
1009  }
1010 
1011  bitMask = (1 << ((sourceNatts - 1) & 0x07));
1012  } /* End if have null bitmap */
1013 
1014  memcpy(targetData,
1015  ((char *) sourceTuple->t_data) + sourceTHeader->t_hoff,
1016  sourceDataLen);
1017 
1018  targetData += sourceDataLen;
1019 
1020  /* Now fill in the missing values */
1021  for (attnum = sourceNatts; attnum < natts; attnum++)
1022  {
1023 
1024  Form_pg_attribute attr = TupleDescAttr(tupleDesc, attnum);
1025 
1026  if (attrmiss && attrmiss[attnum].am_present)
1027  {
1028  fill_val(attr,
1029  nullBits ? &nullBits : NULL,
1030  &bitMask,
1031  &targetData,
1032  infoMask,
1033  attrmiss[attnum].am_value,
1034  false);
1035  }
1036  else
1037  {
1038  fill_val(attr,
1039  &nullBits,
1040  &bitMask,
1041  &targetData,
1042  infoMask,
1043  (Datum) 0,
1044  true);
1045  }
1046  } /* end loop over missing attributes */
1047 }
1048 
1049 /*
1050  * Fill in the missing values for a minimal HeapTuple
1051  */
1054 {
1055  MinimalTuple minimalTuple;
1056 
1057  expand_tuple(NULL, &minimalTuple, sourceTuple, tupleDesc);
1058  return minimalTuple;
1059 }
1060 
1061 /*
1062  * Fill in the missing values for an ordinary HeapTuple
1063  */
1064 HeapTuple
1065 heap_expand_tuple(HeapTuple sourceTuple, TupleDesc tupleDesc)
1066 {
1067  HeapTuple heapTuple;
1068 
1069  expand_tuple(&heapTuple, NULL, sourceTuple, tupleDesc);
1070  return heapTuple;
1071 }
1072 
1073 /* ----------------
1074  * heap_copy_tuple_as_datum
1075  *
1076  * copy a tuple as a composite-type Datum
1077  * ----------------
1078  */
1079 Datum
1081 {
1082  HeapTupleHeader td;
1083 
1084  /*
1085  * If the tuple contains any external TOAST pointers, we have to inline
1086  * those fields to meet the conventions for composite-type Datums.
1087  */
1088  if (HeapTupleHasExternal(tuple))
1089  return toast_flatten_tuple_to_datum(tuple->t_data,
1090  tuple->t_len,
1091  tupleDesc);
1092 
1093  /*
1094  * Fast path for easy case: just make a palloc'd copy and insert the
1095  * correct composite-Datum header fields (since those may not be set if
1096  * the given tuple came from disk, rather than from heap_form_tuple).
1097  */
1098  td = (HeapTupleHeader) palloc(tuple->t_len);
1099  memcpy((char *) td, (char *) tuple->t_data, tuple->t_len);
1100 
1102  HeapTupleHeaderSetTypeId(td, tupleDesc->tdtypeid);
1103  HeapTupleHeaderSetTypMod(td, tupleDesc->tdtypmod);
1104 
1105  return PointerGetDatum(td);
1106 }
1107 
1108 /*
1109  * heap_form_tuple
1110  * construct a tuple from the given values[] and isnull[] arrays,
1111  * which are of the length indicated by tupleDescriptor->natts
1112  *
1113  * The result is allocated in the current memory context.
1114  */
1115 HeapTuple
1116 heap_form_tuple(TupleDesc tupleDescriptor,
1117  const Datum *values,
1118  const bool *isnull)
1119 {
1120  HeapTuple tuple; /* return tuple */
1121  HeapTupleHeader td; /* tuple data */
1122  Size len,
1123  data_len;
1124  int hoff;
1125  bool hasnull = false;
1126  int numberOfAttributes = tupleDescriptor->natts;
1127  int i;
1128 
1129  if (numberOfAttributes > MaxTupleAttributeNumber)
1130  ereport(ERROR,
1131  (errcode(ERRCODE_TOO_MANY_COLUMNS),
1132  errmsg("number of columns (%d) exceeds limit (%d)",
1133  numberOfAttributes, MaxTupleAttributeNumber)));
1134 
1135  /*
1136  * Check for nulls
1137  */
1138  for (i = 0; i < numberOfAttributes; i++)
1139  {
1140  if (isnull[i])
1141  {
1142  hasnull = true;
1143  break;
1144  }
1145  }
1146 
1147  /*
1148  * Determine total space needed
1149  */
1150  len = offsetof(HeapTupleHeaderData, t_bits);
1151 
1152  if (hasnull)
1153  len += BITMAPLEN(numberOfAttributes);
1154 
1155  hoff = len = MAXALIGN(len); /* align user data safely */
1156 
1157  data_len = heap_compute_data_size(tupleDescriptor, values, isnull);
1158 
1159  len += data_len;
1160 
1161  /*
1162  * Allocate and zero the space needed. Note that the tuple body and
1163  * HeapTupleData management structure are allocated in one chunk.
1164  */
1165  tuple = (HeapTuple) palloc0(HEAPTUPLESIZE + len);
1166  tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
1167 
1168  /*
1169  * And fill in the information. Note we fill the Datum fields even though
1170  * this tuple may never become a Datum. This lets HeapTupleHeaderGetDatum
1171  * identify the tuple type if needed.
1172  */
1173  tuple->t_len = len;
1174  ItemPointerSetInvalid(&(tuple->t_self));
1175  tuple->t_tableOid = InvalidOid;
1176 
1178  HeapTupleHeaderSetTypeId(td, tupleDescriptor->tdtypeid);
1179  HeapTupleHeaderSetTypMod(td, tupleDescriptor->tdtypmod);
1180  /* We also make sure that t_ctid is invalid unless explicitly set */
1181  ItemPointerSetInvalid(&(td->t_ctid));
1182 
1183  HeapTupleHeaderSetNatts(td, numberOfAttributes);
1184  td->t_hoff = hoff;
1185 
1186  heap_fill_tuple(tupleDescriptor,
1187  values,
1188  isnull,
1189  (char *) td + hoff,
1190  data_len,
1191  &td->t_infomask,
1192  (hasnull ? td->t_bits : NULL));
1193 
1194  return tuple;
1195 }
1196 
1197 /*
1198  * heap_modify_tuple
1199  * form a new tuple from an old tuple and a set of replacement values.
1200  *
1201  * The replValues, replIsnull, and doReplace arrays must be of the length
1202  * indicated by tupleDesc->natts. The new tuple is constructed using the data
1203  * from replValues/replIsnull at columns where doReplace is true, and using
1204  * the data from the old tuple at columns where doReplace is false.
1205  *
1206  * The result is allocated in the current memory context.
1207  */
1208 HeapTuple
1210  TupleDesc tupleDesc,
1211  const Datum *replValues,
1212  const bool *replIsnull,
1213  const bool *doReplace)
1214 {
1215  int numberOfAttributes = tupleDesc->natts;
1216  int attoff;
1217  Datum *values;
1218  bool *isnull;
1219  HeapTuple newTuple;
1220 
1221  /*
1222  * allocate and fill values and isnull arrays from either the tuple or the
1223  * repl information, as appropriate.
1224  *
1225  * NOTE: it's debatable whether to use heap_deform_tuple() here or just
1226  * heap_getattr() only the non-replaced columns. The latter could win if
1227  * there are many replaced columns and few non-replaced ones. However,
1228  * heap_deform_tuple costs only O(N) while the heap_getattr way would cost
1229  * O(N^2) if there are many non-replaced columns, so it seems better to
1230  * err on the side of linear cost.
1231  */
1232  values = (Datum *) palloc(numberOfAttributes * sizeof(Datum));
1233  isnull = (bool *) palloc(numberOfAttributes * sizeof(bool));
1234 
1235  heap_deform_tuple(tuple, tupleDesc, values, isnull);
1236 
1237  for (attoff = 0; attoff < numberOfAttributes; attoff++)
1238  {
1239  if (doReplace[attoff])
1240  {
1241  values[attoff] = replValues[attoff];
1242  isnull[attoff] = replIsnull[attoff];
1243  }
1244  }
1245 
1246  /*
1247  * create a new tuple from the values and isnull arrays
1248  */
1249  newTuple = heap_form_tuple(tupleDesc, values, isnull);
1250 
1251  pfree(values);
1252  pfree(isnull);
1253 
1254  /*
1255  * copy the identification info of the old tuple: t_ctid, t_self
1256  */
1257  newTuple->t_data->t_ctid = tuple->t_data->t_ctid;
1258  newTuple->t_self = tuple->t_self;
1259  newTuple->t_tableOid = tuple->t_tableOid;
1260 
1261  return newTuple;
1262 }
1263 
1264 /*
1265  * heap_modify_tuple_by_cols
1266  * form a new tuple from an old tuple and a set of replacement values.
1267  *
1268  * This is like heap_modify_tuple, except that instead of specifying which
1269  * column(s) to replace by a boolean map, an array of target column numbers
1270  * is used. This is often more convenient when a fixed number of columns
1271  * are to be replaced. The replCols, replValues, and replIsnull arrays must
1272  * be of length nCols. Target column numbers are indexed from 1.
1273  *
1274  * The result is allocated in the current memory context.
1275  */
1276 HeapTuple
1278  TupleDesc tupleDesc,
1279  int nCols,
1280  const int *replCols,
1281  const Datum *replValues,
1282  const bool *replIsnull)
1283 {
1284  int numberOfAttributes = tupleDesc->natts;
1285  Datum *values;
1286  bool *isnull;
1287  HeapTuple newTuple;
1288  int i;
1289 
1290  /*
1291  * allocate and fill values and isnull arrays from the tuple, then replace
1292  * selected columns from the input arrays.
1293  */
1294  values = (Datum *) palloc(numberOfAttributes * sizeof(Datum));
1295  isnull = (bool *) palloc(numberOfAttributes * sizeof(bool));
1296 
1297  heap_deform_tuple(tuple, tupleDesc, values, isnull);
1298 
1299  for (i = 0; i < nCols; i++)
1300  {
1301  int attnum = replCols[i];
1302 
1303  if (attnum <= 0 || attnum > numberOfAttributes)
1304  elog(ERROR, "invalid column number %d", attnum);
1305  values[attnum - 1] = replValues[i];
1306  isnull[attnum - 1] = replIsnull[i];
1307  }
1308 
1309  /*
1310  * create a new tuple from the values and isnull arrays
1311  */
1312  newTuple = heap_form_tuple(tupleDesc, values, isnull);
1313 
1314  pfree(values);
1315  pfree(isnull);
1316 
1317  /*
1318  * copy the identification info of the old tuple: t_ctid, t_self
1319  */
1320  newTuple->t_data->t_ctid = tuple->t_data->t_ctid;
1321  newTuple->t_self = tuple->t_self;
1322  newTuple->t_tableOid = tuple->t_tableOid;
1323 
1324  return newTuple;
1325 }
1326 
1327 /*
1328  * heap_deform_tuple
1329  * Given a tuple, extract data into values/isnull arrays; this is
1330  * the inverse of heap_form_tuple.
1331  *
1332  * Storage for the values/isnull arrays is provided by the caller;
1333  * it should be sized according to tupleDesc->natts not
1334  * HeapTupleHeaderGetNatts(tuple->t_data).
1335  *
1336  * Note that for pass-by-reference datatypes, the pointer placed
1337  * in the Datum will point into the given tuple.
1338  *
1339  * When all or most of a tuple's fields need to be extracted,
1340  * this routine will be significantly quicker than a loop around
1341  * heap_getattr; the loop will become O(N^2) as soon as any
1342  * noncacheable attribute offsets are involved.
1343  */
1344 void
1346  Datum *values, bool *isnull)
1347 {
1348  HeapTupleHeader tup = tuple->t_data;
1349  bool hasnulls = HeapTupleHasNulls(tuple);
1350  int tdesc_natts = tupleDesc->natts;
1351  int natts; /* number of atts to extract */
1352  int attnum;
1353  char *tp; /* ptr to tuple data */
1354  uint32 off; /* offset in tuple data */
1355  bits8 *bp = tup->t_bits; /* ptr to null bitmap in tuple */
1356  bool slow = false; /* can we use/set attcacheoff? */
1357 
1358  natts = HeapTupleHeaderGetNatts(tup);
1359 
1360  /*
1361  * In inheritance situations, it is possible that the given tuple actually
1362  * has more fields than the caller is expecting. Don't run off the end of
1363  * the caller's arrays.
1364  */
1365  natts = Min(natts, tdesc_natts);
1366 
1367  tp = (char *) tup + tup->t_hoff;
1368 
1369  off = 0;
1370 
1371  for (attnum = 0; attnum < natts; attnum++)
1372  {
1373  Form_pg_attribute thisatt = TupleDescAttr(tupleDesc, attnum);
1374 
1375  if (hasnulls && att_isnull(attnum, bp))
1376  {
1377  values[attnum] = (Datum) 0;
1378  isnull[attnum] = true;
1379  slow = true; /* can't use attcacheoff anymore */
1380  continue;
1381  }
1382 
1383  isnull[attnum] = false;
1384 
1385  if (!slow && thisatt->attcacheoff >= 0)
1386  off = thisatt->attcacheoff;
1387  else if (thisatt->attlen == -1)
1388  {
1389  /*
1390  * We can only cache the offset for a varlena attribute if the
1391  * offset is already suitably aligned, so that there would be no
1392  * pad bytes in any case: then the offset will be valid for either
1393  * an aligned or unaligned value.
1394  */
1395  if (!slow &&
1396  off == att_align_nominal(off, thisatt->attalign))
1397  thisatt->attcacheoff = off;
1398  else
1399  {
1400  off = att_align_pointer(off, thisatt->attalign, -1,
1401  tp + off);
1402  slow = true;
1403  }
1404  }
1405  else
1406  {
1407  /* not varlena, so safe to use att_align_nominal */
1408  off = att_align_nominal(off, thisatt->attalign);
1409 
1410  if (!slow)
1411  thisatt->attcacheoff = off;
1412  }
1413 
1414  values[attnum] = fetchatt(thisatt, tp + off);
1415 
1416  off = att_addlength_pointer(off, thisatt->attlen, tp + off);
1417 
1418  if (thisatt->attlen <= 0)
1419  slow = true; /* can't use attcacheoff anymore */
1420  }
1421 
1422  /*
1423  * If tuple doesn't have all the atts indicated by tupleDesc, read the
1424  * rest as nulls or missing values as appropriate.
1425  */
1426  for (; attnum < tdesc_natts; attnum++)
1427  values[attnum] = getmissingattr(tupleDesc, attnum + 1, &isnull[attnum]);
1428 }
1429 
1430 /*
1431  * heap_freetuple
1432  */
1433 void
1435 {
1436  pfree(htup);
1437 }
1438 
1439 
1440 /*
1441  * heap_form_minimal_tuple
1442  * construct a MinimalTuple from the given values[] and isnull[] arrays,
1443  * which are of the length indicated by tupleDescriptor->natts
1444  *
1445  * This is exactly like heap_form_tuple() except that the result is a
1446  * "minimal" tuple lacking a HeapTupleData header as well as room for system
1447  * columns.
1448  *
1449  * The result is allocated in the current memory context.
1450  */
1453  const Datum *values,
1454  const bool *isnull)
1455 {
1456  MinimalTuple tuple; /* return tuple */
1457  Size len,
1458  data_len;
1459  int hoff;
1460  bool hasnull = false;
1461  int numberOfAttributes = tupleDescriptor->natts;
1462  int i;
1463 
1464  if (numberOfAttributes > MaxTupleAttributeNumber)
1465  ereport(ERROR,
1466  (errcode(ERRCODE_TOO_MANY_COLUMNS),
1467  errmsg("number of columns (%d) exceeds limit (%d)",
1468  numberOfAttributes, MaxTupleAttributeNumber)));
1469 
1470  /*
1471  * Check for nulls
1472  */
1473  for (i = 0; i < numberOfAttributes; i++)
1474  {
1475  if (isnull[i])
1476  {
1477  hasnull = true;
1478  break;
1479  }
1480  }
1481 
1482  /*
1483  * Determine total space needed
1484  */
1486 
1487  if (hasnull)
1488  len += BITMAPLEN(numberOfAttributes);
1489 
1490  hoff = len = MAXALIGN(len); /* align user data safely */
1491 
1492  data_len = heap_compute_data_size(tupleDescriptor, values, isnull);
1493 
1494  len += data_len;
1495 
1496  /*
1497  * Allocate and zero the space needed.
1498  */
1499  tuple = (MinimalTuple) palloc0(len);
1500 
1501  /*
1502  * And fill in the information.
1503  */
1504  tuple->t_len = len;
1505  HeapTupleHeaderSetNatts(tuple, numberOfAttributes);
1506  tuple->t_hoff = hoff + MINIMAL_TUPLE_OFFSET;
1507 
1508  heap_fill_tuple(tupleDescriptor,
1509  values,
1510  isnull,
1511  (char *) tuple + hoff,
1512  data_len,
1513  &tuple->t_infomask,
1514  (hasnull ? tuple->t_bits : NULL));
1515 
1516  return tuple;
1517 }
1518 
1519 /*
1520  * heap_free_minimal_tuple
1521  */
1522 void
1524 {
1525  pfree(mtup);
1526 }
1527 
1528 /*
1529  * heap_copy_minimal_tuple
1530  * copy a MinimalTuple
1531  *
1532  * The result is allocated in the current memory context.
1533  */
1536 {
1537  MinimalTuple result;
1538 
1539  result = (MinimalTuple) palloc(mtup->t_len);
1540  memcpy(result, mtup, mtup->t_len);
1541  return result;
1542 }
1543 
1544 /*
1545  * heap_tuple_from_minimal_tuple
1546  * create a HeapTuple by copying from a MinimalTuple;
1547  * system columns are filled with zeroes
1548  *
1549  * The result is allocated in the current memory context.
1550  * The HeapTuple struct, tuple header, and tuple data are all allocated
1551  * as a single palloc() block.
1552  */
1553 HeapTuple
1555 {
1556  HeapTuple result;
1558 
1559  result = (HeapTuple) palloc(HEAPTUPLESIZE + len);
1560  result->t_len = len;
1561  ItemPointerSetInvalid(&(result->t_self));
1562  result->t_tableOid = InvalidOid;
1563  result->t_data = (HeapTupleHeader) ((char *) result + HEAPTUPLESIZE);
1564  memcpy((char *) result->t_data + MINIMAL_TUPLE_OFFSET, mtup, mtup->t_len);
1565  memset(result->t_data, 0, offsetof(HeapTupleHeaderData, t_infomask2));
1566  return result;
1567 }
1568 
1569 /*
1570  * minimal_tuple_from_heap_tuple
1571  * create a MinimalTuple by copying from a HeapTuple
1572  *
1573  * The result is allocated in the current memory context.
1574  */
1577 {
1578  MinimalTuple result;
1579  uint32 len;
1580 
1582  len = htup->t_len - MINIMAL_TUPLE_OFFSET;
1583  result = (MinimalTuple) palloc(len);
1584  memcpy(result, (char *) htup->t_data + MINIMAL_TUPLE_OFFSET, len);
1585  result->t_len = len;
1586  return result;
1587 }
1588 
1589 /*
1590  * This mainly exists so JIT can inline the definition, but it's also
1591  * sometimes useful in debugging sessions.
1592  */
1593 size_t
1594 varsize_any(void *p)
1595 {
1596  return VARSIZE_ANY(p);
1597 }
static Datum values[MAXATTR]
Definition: bootstrap.c:151
#define Min(x, y)
Definition: c.h:958
#define MAXALIGN(LEN)
Definition: c.h:765
char * Pointer
Definition: c.h:476
#define Assert(condition)
Definition: c.h:812
uint8 bits8
Definition: c.h:492
uint16_t uint16
Definition: c.h:484
uint32_t uint32
Definition: c.h:485
#define HIGHBIT
Definition: c.h:1108
size_t Size
Definition: c.h:559
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:132
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:955
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:352
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define ereport(elevel,...)
Definition: elog.h:149
ExpandedObjectHeader * DatumGetEOHP(Datum d)
Definition: expandeddatum.c:29
void EOH_flatten_into(ExpandedObjectHeader *eohptr, void *result, Size allocated_size)
Definition: expandeddatum.c:81
Size EOH_get_flat_size(ExpandedObjectHeader *eohptr)
Definition: expandeddatum.c:75
uint32 hash_bytes(const unsigned char *k, int keylen)
Definition: hashfn.c:146
return str start
for(;;)
Datum toast_flatten_tuple_to_datum(HeapTupleHeader tup, uint32 tup_len, TupleDesc tupleDesc)
Definition: heaptoast.c:449
Size heap_compute_data_size(TupleDesc tupleDesc, const Datum *values, const bool *isnull)
Definition: heaptuple.c:215
static uint32 missing_hash(const void *key, Size keysize)
Definition: heaptuple.c:100
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition: heaptuple.c:1209
void heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest)
Definition: heaptuple.c:802
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:776
static void init_missing_cache()
Definition: heaptuple.c:122
size_t varsize_any(void *p)
Definition: heaptuple.c:1594
MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup)
Definition: heaptuple.c:1576
Datum heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: heaptuple.c:723
MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1452
#define VARLENA_ATT_IS_PACKABLE(att)
Definition: heaptuple.c:83
HeapTuple heap_modify_tuple_by_cols(HeapTuple tuple, TupleDesc tupleDesc, int nCols, const int *replCols, const Datum *replValues, const bool *replIsnull)
Definition: heaptuple.c:1277
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1116
void heap_free_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1523
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
Definition: heaptuple.c:455
Datum nocachegetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc)
Definition: heaptuple.c:519
Datum getmissingattr(TupleDesc tupleDesc, int attnum, bool *isnull)
Definition: heaptuple.c:147
HeapTuple heap_expand_tuple(HeapTuple sourceTuple, TupleDesc tupleDesc)
Definition: heaptuple.c:1065
#define ATT_IS_PACKABLE(att)
Definition: heaptuple.c:80
void heap_fill_tuple(TupleDesc tupleDesc, const Datum *values, const bool *isnull, char *data, Size data_size, uint16 *infomask, bits8 *bit)
Definition: heaptuple.c:400
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:1345
static int missing_match(const void *key1, const void *key2, Size keysize)
Definition: heaptuple.c:108
MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1535
Datum heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc)
Definition: heaptuple.c:1080
static HTAB * missing_cache
Definition: heaptuple.c:97
static void expand_tuple(HeapTuple *targetHeapTuple, MinimalTuple *targetMinimalTuple, HeapTuple sourceTuple, TupleDesc tupleDesc)
Definition: heaptuple.c:828
HeapTuple heap_tuple_from_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1554
MinimalTuple minimal_expand_tuple(HeapTuple sourceTuple, TupleDesc tupleDesc)
Definition: heaptuple.c:1053
static void fill_val(Form_pg_attribute att, bits8 **bit, int *bitmask, char **dataP, uint16 *infomask, Datum datum, bool isnull)
Definition: heaptuple.c:271
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1434
@ HASH_ENTER
Definition: hsearch.h:114
#define HASH_CONTEXT
Definition: hsearch.h:102
#define HASH_ELEM
Definition: hsearch.h:95
#define HASH_COMPARE
Definition: hsearch.h:99
#define HASH_FUNCTION
Definition: hsearch.h:98
#define HEAPTUPLESIZE
Definition: htup.h:73
HeapTupleData * HeapTuple
Definition: htup.h:71
MinimalTupleData * MinimalTuple
Definition: htup.h:27
HeapTupleHeaderData * HeapTupleHeader
Definition: htup.h:23
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define HEAP_HASVARWIDTH
Definition: htup_details.h:191
#define MINIMAL_TUPLE_OFFSET
Definition: htup_details.h:617
#define HeapTupleHeaderSetTypMod(tup, typmod)
Definition: htup_details.h:471
#define HeapTupleHeaderGetNatts(tup)
Definition: htup_details.h:529
#define HEAP_HASNULL
Definition: htup_details.h:190
#define SizeofMinimalTupleHeader
Definition: htup_details.h:647
#define HeapTupleHasVarWidth(tuple)
Definition: htup_details.h:665
#define BITMAPLEN(NATTS)
Definition: htup_details.h:545
#define HeapTupleHasExternal(tuple)
Definition: htup_details.h:671
#define MaxTupleAttributeNumber
Definition: htup_details.h:34
#define HeapTupleNoNulls(tuple)
Definition: htup_details.h:662
#define HEAP_HASEXTERNAL
Definition: htup_details.h:192
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:304
#define HeapTupleHeaderSetNatts(tup, natts)
Definition: htup_details.h:532
#define HeapTupleHeaderSetDatumLength(tup, len)
Definition: htup_details.h:453
#define HeapTupleHeaderGetRawXmax(tup)
Definition: htup_details.h:371
#define HeapTupleHeaderGetRawCommandId(tup)
Definition: htup_details.h:387
#define HeapTupleHasNulls(tuple)
Definition: htup_details.h:659
#define HeapTupleHeaderSetTypeId(tup, typeid)
Definition: htup_details.h:461
long val
Definition: informix.c:689
int j
Definition: isn.c:73
int i
Definition: isn.c:72
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
static void ItemPointerSetInvalid(ItemPointerData *pointer)
Definition: itemptr.h:184
void pfree(void *pointer)
Definition: mcxt.c:1521
MemoryContext TopMemoryContext
Definition: mcxt.c:149
void * palloc0(Size size)
Definition: mcxt.c:1347
void * palloc(Size size)
Definition: mcxt.c:1317
int16 attnum
Definition: pg_attribute.h:74
int16 attlen
Definition: pg_attribute.h:59
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:209
const void size_t len
const void * data
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
static char * DatumGetCString(Datum X)
Definition: postgres.h:335
static Datum TransactionIdGetDatum(TransactionId X)
Definition: postgres.h:272
uintptr_t Datum
Definition: postgres.h:64
static Datum CommandIdGetDatum(CommandId X)
Definition: postgres.h:302
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
#define InvalidOid
Definition: postgres_ext.h:36
MemoryContextSwitchTo(old_ctx)
Size keysize
Definition: hsearch.h:75
HashValueFunc hash
Definition: hsearch.h:78
Size entrysize
Definition: hsearch.h:76
HashCompareFunc match
Definition: hsearch.h:80
MemoryContext hcxt
Definition: hsearch.h:86
Definition: dynahash.c:220
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
HeapTupleHeader t_data
Definition: htup.h:68
Oid t_tableOid
Definition: htup.h:66
ItemPointerData t_ctid
Definition: htup_details.h:161
bits8 t_bits[FLEXIBLE_ARRAY_MEMBER]
Definition: htup_details.h:178
bits8 t_bits[FLEXIBLE_ARRAY_MEMBER]
Definition: htup_details.h:640
struct AttrMissing * missing
Definition: tupdesc.h:41
TupleConstr * constr
Definition: tupdesc.h:85
int32 tdtypmod
Definition: tupdesc.h:83
Oid tdtypeid
Definition: tupdesc.h:82
#define MinTransactionIdAttributeNumber
Definition: sysattr.h:22
#define MaxCommandIdAttributeNumber
Definition: sysattr.h:25
#define MaxTransactionIdAttributeNumber
Definition: sysattr.h:24
#define TableOidAttributeNumber
Definition: sysattr.h:26
#define SelfItemPointerAttributeNumber
Definition: sysattr.h:21
#define MinCommandIdAttributeNumber
Definition: sysattr.h:23
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
#define att_align_pointer(cur_offset, attalign, attlen, attptr)
Definition: tupmacs.h:107
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:129
#define att_align_datum(cur_offset, attalign, attlen, attdatum)
Definition: tupmacs.h:86
static bool att_isnull(int ATT, const bits8 *BITS)
Definition: tupmacs.h:26
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:157
#define fetchatt(A, T)
Definition: tupmacs.h:46
#define att_addlength_datum(cur_offset, attlen, attdatum)
Definition: tupmacs.h:145
static void store_att_byval(void *T, Datum newdatum, int attlen)
Definition: tupmacs.h:183
#define VARSIZE_SHORT(PTR)
Definition: varatt.h:281
#define SET_VARSIZE_SHORT(PTR, len)
Definition: varatt.h:306
#define VARATT_CAN_MAKE_SHORT(PTR)
Definition: varatt.h:258
#define VARATT_IS_EXTERNAL_EXPANDED(PTR)
Definition: varatt.h:298
#define VARATT_IS_SHORT(PTR)
Definition: varatt.h:302
#define VARSIZE_ANY(PTR)
Definition: varatt.h:311
#define VARDATA(PTR)
Definition: varatt.h:278
#define VARSIZE_EXTERNAL(PTR)
Definition: varatt.h:285
#define VARSIZE(PTR)
Definition: varatt.h:279
#define VARATT_CONVERTED_SHORT_SIZE(PTR)
Definition: varatt.h:261
#define VARATT_IS_EXTERNAL(PTR)
Definition: varatt.h:289
Datum bit(PG_FUNCTION_ARGS)
Definition: varbit.c:391