PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
heaptuple.c File Reference
#include "postgres.h"
#include "access/heaptoast.h"
#include "access/sysattr.h"
#include "access/tupdesc_details.h"
#include "common/hashfn.h"
#include "utils/datum.h"
#include "utils/expandeddatum.h"
#include "utils/hsearch.h"
#include "utils/memutils.h"
Include dependency graph for heaptuple.c:

Go to the source code of this file.

Data Structures

struct  missing_cache_key
 

Macros

#define ATT_IS_PACKABLE(att)    ((att)->attlen == -1 && (att)->attstorage != TYPSTORAGE_PLAIN)
 
#define VARLENA_ATT_IS_PACKABLE(att)    ((att)->attstorage != TYPSTORAGE_PLAIN)
 
#define COMPACT_ATTR_IS_PACKABLE(att)    ((att)->attlen == -1 && (att)->attispackable)
 

Functions

static uint32 missing_hash (const void *key, Size keysize)
 
static int missing_match (const void *key1, const void *key2, Size keysize)
 
static void init_missing_cache ()
 
Datum getmissingattr (TupleDesc tupleDesc, int attnum, bool *isnull)
 
Size heap_compute_data_size (TupleDesc tupleDesc, const Datum *values, const bool *isnull)
 
static void fill_val (CompactAttribute *att, bits8 **bit, int *bitmask, char **dataP, uint16 *infomask, Datum datum, bool isnull)
 
void heap_fill_tuple (TupleDesc tupleDesc, const Datum *values, const bool *isnull, char *data, Size data_size, uint16 *infomask, bits8 *bit)
 
bool heap_attisnull (HeapTuple tup, int attnum, TupleDesc tupleDesc)
 
Datum nocachegetattr (HeapTuple tup, int attnum, TupleDesc tupleDesc)
 
Datum heap_getsysattr (HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
 
HeapTuple heap_copytuple (HeapTuple tuple)
 
void heap_copytuple_with_tuple (HeapTuple src, HeapTuple dest)
 
static void expand_tuple (HeapTuple *targetHeapTuple, MinimalTuple *targetMinimalTuple, HeapTuple sourceTuple, TupleDesc tupleDesc)
 
MinimalTuple minimal_expand_tuple (HeapTuple sourceTuple, TupleDesc tupleDesc)
 
HeapTuple heap_expand_tuple (HeapTuple sourceTuple, TupleDesc tupleDesc)
 
Datum heap_copy_tuple_as_datum (HeapTuple tuple, TupleDesc tupleDesc)
 
HeapTuple heap_form_tuple (TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
 
HeapTuple heap_modify_tuple (HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
 
HeapTuple heap_modify_tuple_by_cols (HeapTuple tuple, TupleDesc tupleDesc, int nCols, const int *replCols, const Datum *replValues, const bool *replIsnull)
 
void heap_deform_tuple (HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
 
void heap_freetuple (HeapTuple htup)
 
MinimalTuple heap_form_minimal_tuple (TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
 
void heap_free_minimal_tuple (MinimalTuple mtup)
 
MinimalTuple heap_copy_minimal_tuple (MinimalTuple mtup)
 
HeapTuple heap_tuple_from_minimal_tuple (MinimalTuple mtup)
 
MinimalTuple minimal_tuple_from_heap_tuple (HeapTuple htup)
 
size_t varsize_any (void *p)
 

Variables

static HTABmissing_cache = NULL
 

Macro Definition Documentation

◆ ATT_IS_PACKABLE

#define ATT_IS_PACKABLE (   att)     ((att)->attlen == -1 && (att)->attstorage != TYPSTORAGE_PLAIN)

Definition at line 80 of file heaptuple.c.

◆ COMPACT_ATTR_IS_PACKABLE

#define COMPACT_ATTR_IS_PACKABLE (   att)     ((att)->attlen == -1 && (att)->attispackable)

Definition at line 87 of file heaptuple.c.

◆ VARLENA_ATT_IS_PACKABLE

#define VARLENA_ATT_IS_PACKABLE (   att)     ((att)->attstorage != TYPSTORAGE_PLAIN)

Definition at line 83 of file heaptuple.c.

Function Documentation

◆ expand_tuple()

static void expand_tuple ( HeapTuple targetHeapTuple,
MinimalTuple targetMinimalTuple,
HeapTuple  sourceTuple,
TupleDesc  tupleDesc 
)
static

Definition at line 830 of file heaptuple.c.

834{
835 AttrMissing *attrmiss = NULL;
836 int attnum;
837 int firstmissingnum;
838 bool hasNulls = HeapTupleHasNulls(sourceTuple);
839 HeapTupleHeader targetTHeader;
840 HeapTupleHeader sourceTHeader = sourceTuple->t_data;
841 int sourceNatts = HeapTupleHeaderGetNatts(sourceTHeader);
842 int natts = tupleDesc->natts;
843 int sourceNullLen;
844 int targetNullLen;
845 Size sourceDataLen = sourceTuple->t_len - sourceTHeader->t_hoff;
846 Size targetDataLen;
847 Size len;
848 int hoff;
849 bits8 *nullBits = NULL;
850 int bitMask = 0;
851 char *targetData;
852 uint16 *infoMask;
853
854 Assert((targetHeapTuple && !targetMinimalTuple)
855 || (!targetHeapTuple && targetMinimalTuple));
856
857 Assert(sourceNatts < natts);
858
859 sourceNullLen = (hasNulls ? BITMAPLEN(sourceNatts) : 0);
860
861 targetDataLen = sourceDataLen;
862
863 if (tupleDesc->constr &&
864 tupleDesc->constr->missing)
865 {
866 /*
867 * If there are missing values we want to put them into the tuple.
868 * Before that we have to compute the extra length for the values
869 * array and the variable length data.
870 */
871 attrmiss = tupleDesc->constr->missing;
872
873 /*
874 * Find the first item in attrmiss for which we don't have a value in
875 * the source. We can ignore all the missing entries before that.
876 */
877 for (firstmissingnum = sourceNatts;
878 firstmissingnum < natts;
879 firstmissingnum++)
880 {
881 if (attrmiss[firstmissingnum].am_present)
882 break;
883 else
884 hasNulls = true;
885 }
886
887 /*
888 * Now walk the missing attributes. If there is a missing value make
889 * space for it. Otherwise, it's going to be NULL.
890 */
891 for (attnum = firstmissingnum;
892 attnum < natts;
893 attnum++)
894 {
895 if (attrmiss[attnum].am_present)
896 {
898
899 targetDataLen = att_datum_alignby(targetDataLen,
900 att->attalignby,
901 att->attlen,
902 attrmiss[attnum].am_value);
903
904 targetDataLen = att_addlength_pointer(targetDataLen,
905 att->attlen,
906 attrmiss[attnum].am_value);
907 }
908 else
909 {
910 /* no missing value, so it must be null */
911 hasNulls = true;
912 }
913 }
914 } /* end if have missing values */
915 else
916 {
917 /*
918 * If there are no missing values at all then NULLS must be allowed,
919 * since some of the attributes are known to be absent.
920 */
921 hasNulls = true;
922 }
923
924 len = 0;
925
926 if (hasNulls)
927 {
928 targetNullLen = BITMAPLEN(natts);
929 len += targetNullLen;
930 }
931 else
932 targetNullLen = 0;
933
934 /*
935 * Allocate and zero the space needed. Note that the tuple body and
936 * HeapTupleData management structure are allocated in one chunk.
937 */
938 if (targetHeapTuple)
939 {
940 len += offsetof(HeapTupleHeaderData, t_bits);
941 hoff = len = MAXALIGN(len); /* align user data safely */
942 len += targetDataLen;
943
944 *targetHeapTuple = (HeapTuple) palloc0(HEAPTUPLESIZE + len);
945 (*targetHeapTuple)->t_data
946 = targetTHeader
947 = (HeapTupleHeader) ((char *) *targetHeapTuple + HEAPTUPLESIZE);
948 (*targetHeapTuple)->t_len = len;
949 (*targetHeapTuple)->t_tableOid = sourceTuple->t_tableOid;
950 (*targetHeapTuple)->t_self = sourceTuple->t_self;
951
952 targetTHeader->t_infomask = sourceTHeader->t_infomask;
953 targetTHeader->t_hoff = hoff;
954 HeapTupleHeaderSetNatts(targetTHeader, natts);
955 HeapTupleHeaderSetDatumLength(targetTHeader, len);
956 HeapTupleHeaderSetTypeId(targetTHeader, tupleDesc->tdtypeid);
957 HeapTupleHeaderSetTypMod(targetTHeader, tupleDesc->tdtypmod);
958 /* We also make sure that t_ctid is invalid unless explicitly set */
959 ItemPointerSetInvalid(&(targetTHeader->t_ctid));
960 if (targetNullLen > 0)
961 nullBits = (bits8 *) ((char *) (*targetHeapTuple)->t_data
962 + offsetof(HeapTupleHeaderData, t_bits));
963 targetData = (char *) (*targetHeapTuple)->t_data + hoff;
964 infoMask = &(targetTHeader->t_infomask);
965 }
966 else
967 {
969 hoff = len = MAXALIGN(len); /* align user data safely */
970 len += targetDataLen;
971
972 *targetMinimalTuple = (MinimalTuple) palloc0(len);
973 (*targetMinimalTuple)->t_len = len;
974 (*targetMinimalTuple)->t_hoff = hoff + MINIMAL_TUPLE_OFFSET;
975 (*targetMinimalTuple)->t_infomask = sourceTHeader->t_infomask;
976 /* Same macro works for MinimalTuples */
977 HeapTupleHeaderSetNatts(*targetMinimalTuple, natts);
978 if (targetNullLen > 0)
979 nullBits = (bits8 *) ((char *) *targetMinimalTuple
980 + offsetof(MinimalTupleData, t_bits));
981 targetData = (char *) *targetMinimalTuple + hoff;
982 infoMask = &((*targetMinimalTuple)->t_infomask);
983 }
984
985 if (targetNullLen > 0)
986 {
987 if (sourceNullLen > 0)
988 {
989 /* if bitmap pre-existed copy in - all is set */
990 memcpy(nullBits,
991 ((char *) sourceTHeader)
992 + offsetof(HeapTupleHeaderData, t_bits),
993 sourceNullLen);
994 nullBits += sourceNullLen - 1;
995 }
996 else
997 {
998 sourceNullLen = BITMAPLEN(sourceNatts);
999 /* Set NOT NULL for all existing attributes */
1000 memset(nullBits, 0xff, sourceNullLen);
1001
1002 nullBits += sourceNullLen - 1;
1003
1004 if (sourceNatts & 0x07)
1005 {
1006 /* build the mask (inverted!) */
1007 bitMask = 0xff << (sourceNatts & 0x07);
1008 /* Voila */
1009 *nullBits = ~bitMask;
1010 }
1011 }
1012
1013 bitMask = (1 << ((sourceNatts - 1) & 0x07));
1014 } /* End if have null bitmap */
1015
1016 memcpy(targetData,
1017 ((char *) sourceTuple->t_data) + sourceTHeader->t_hoff,
1018 sourceDataLen);
1019
1020 targetData += sourceDataLen;
1021
1022 /* Now fill in the missing values */
1023 for (attnum = sourceNatts; attnum < natts; attnum++)
1024 {
1025 CompactAttribute *attr = TupleDescCompactAttr(tupleDesc, attnum);
1026
1027 if (attrmiss && attrmiss[attnum].am_present)
1028 {
1029 fill_val(attr,
1030 nullBits ? &nullBits : NULL,
1031 &bitMask,
1032 &targetData,
1033 infoMask,
1034 attrmiss[attnum].am_value,
1035 false);
1036 }
1037 else
1038 {
1039 fill_val(attr,
1040 &nullBits,
1041 &bitMask,
1042 &targetData,
1043 infoMask,
1044 (Datum) 0,
1045 true);
1046 }
1047 } /* end loop over missing attributes */
1048}
#define MAXALIGN(LEN)
Definition: c.h:765
#define Assert(condition)
Definition: c.h:812
uint8 bits8
Definition: c.h:492
uint16_t uint16
Definition: c.h:484
size_t Size
Definition: c.h:559
static void fill_val(CompactAttribute *att, bits8 **bit, int *bitmask, char **dataP, uint16 *infomask, Datum datum, bool isnull)
Definition: heaptuple.c:275
#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 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 SizeofMinimalTupleHeader
Definition: htup_details.h:647
#define BITMAPLEN(NATTS)
Definition: htup_details.h:545
#define HeapTupleHeaderSetNatts(tup, natts)
Definition: htup_details.h:532
#define HeapTupleHeaderSetDatumLength(tup, len)
Definition: htup_details.h:453
#define HeapTupleHasNulls(tuple)
Definition: htup_details.h:659
#define HeapTupleHeaderSetTypeId(tup, typeid)
Definition: htup_details.h:461
static void ItemPointerSetInvalid(ItemPointerData *pointer)
Definition: itemptr.h:184
void * palloc0(Size size)
Definition: mcxt.c:1347
int16 attnum
Definition: pg_attribute.h:74
const void size_t len
uintptr_t Datum
Definition: postgres.h:64
uint8 attalignby
Definition: tupdesc.h:78
int16 attlen
Definition: tupdesc.h:69
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
struct AttrMissing * missing
Definition: tupdesc.h:41
TupleConstr * constr
Definition: tupdesc.h:133
int32 tdtypmod
Definition: tupdesc.h:131
Oid tdtypeid
Definition: tupdesc.h:130
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:169
#define att_datum_alignby(cur_offset, attalignby, attlen, attdatum)
Definition: tupmacs.h:98
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:185

References AttrMissing::am_value, Assert, att_addlength_pointer, att_datum_alignby, CompactAttribute::attalignby, CompactAttribute::attlen, attnum, BITMAPLEN, TupleDescData::constr, fill_val(), HeapTupleHasNulls, HeapTupleHeaderGetNatts, HeapTupleHeaderSetDatumLength, HeapTupleHeaderSetNatts, HeapTupleHeaderSetTypeId, HeapTupleHeaderSetTypMod, HEAPTUPLESIZE, ItemPointerSetInvalid(), len, MAXALIGN, MINIMAL_TUPLE_OFFSET, TupleConstr::missing, TupleDescData::natts, palloc0(), SizeofMinimalTupleHeader, HeapTupleHeaderData::t_ctid, HeapTupleData::t_data, HeapTupleHeaderData::t_hoff, HeapTupleHeaderData::t_infomask, HeapTupleData::t_len, HeapTupleData::t_self, HeapTupleData::t_tableOid, TupleDescData::tdtypeid, TupleDescData::tdtypmod, and TupleDescCompactAttr().

Referenced by heap_expand_tuple(), and minimal_expand_tuple().

◆ fill_val()

static void fill_val ( CompactAttribute att,
bits8 **  bit,
int *  bitmask,
char **  dataP,
uint16 infomask,
Datum  datum,
bool  isnull 
)
inlinestatic

Definition at line 275 of file heaptuple.c.

282{
283 Size data_length;
284 char *data = *dataP;
285
286 /*
287 * If we're building a null bitmap, set the appropriate bit for the
288 * current column value here.
289 */
290 if (bit != NULL)
291 {
292 if (*bitmask != HIGHBIT)
293 *bitmask <<= 1;
294 else
295 {
296 *bit += 1;
297 **bit = 0x0;
298 *bitmask = 1;
299 }
300
301 if (isnull)
302 {
303 *infomask |= HEAP_HASNULL;
304 return;
305 }
306
307 **bit |= *bitmask;
308 }
309
310 /*
311 * XXX we use the att_nominal_alignby macro on the pointer value itself,
312 * not on an offset. This is a bit of a hack.
313 */
314 if (att->attbyval)
315 {
316 /* pass-by-value */
317 data = (char *) att_nominal_alignby(data, att->attalignby);
318 store_att_byval(data, datum, att->attlen);
319 data_length = att->attlen;
320 }
321 else if (att->attlen == -1)
322 {
323 /* varlena */
324 Pointer val = DatumGetPointer(datum);
325
326 *infomask |= HEAP_HASVARWIDTH;
328 {
330 {
331 /*
332 * we want to flatten the expanded value so that the
333 * constructed tuple doesn't depend on it
334 */
336
337 data = (char *) att_nominal_alignby(data, att->attalignby);
338 data_length = EOH_get_flat_size(eoh);
339 EOH_flatten_into(eoh, data, data_length);
340 }
341 else
342 {
343 *infomask |= HEAP_HASEXTERNAL;
344 /* no alignment, since it's short by definition */
345 data_length = VARSIZE_EXTERNAL(val);
346 memcpy(data, val, data_length);
347 }
348 }
349 else if (VARATT_IS_SHORT(val))
350 {
351 /* no alignment for short varlenas */
352 data_length = VARSIZE_SHORT(val);
353 memcpy(data, val, data_length);
354 }
355 else if (att->attispackable && VARATT_CAN_MAKE_SHORT(val))
356 {
357 /* convert to short varlena -- no alignment */
358 data_length = VARATT_CONVERTED_SHORT_SIZE(val);
359 SET_VARSIZE_SHORT(data, data_length);
360 memcpy(data + 1, VARDATA(val), data_length - 1);
361 }
362 else
363 {
364 /* full 4-byte header varlena */
365 data = (char *) att_nominal_alignby(data, att->attalignby);
366 data_length = VARSIZE(val);
367 memcpy(data, val, data_length);
368 }
369 }
370 else if (att->attlen == -2)
371 {
372 /* cstring ... never needs alignment */
373 *infomask |= HEAP_HASVARWIDTH;
374 Assert(att->attalignby == sizeof(char));
375 data_length = strlen(DatumGetCString(datum)) + 1;
376 memcpy(data, DatumGetPointer(datum), data_length);
377 }
378 else
379 {
380 /* fixed-length pass-by-reference */
381 data = (char *) att_nominal_alignby(data, att->attalignby);
382 Assert(att->attlen > 0);
383 data_length = att->attlen;
384 memcpy(data, DatumGetPointer(datum), data_length);
385 }
386
387 data += data_length;
388 *dataP = data;
389}
char * Pointer
Definition: c.h:476
#define HIGHBIT
Definition: c.h:1108
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
#define HEAP_HASVARWIDTH
Definition: htup_details.h:191
#define HEAP_HASNULL
Definition: htup_details.h:190
#define HEAP_HASEXTERNAL
Definition: htup_details.h:192
long val
Definition: informix.c:689
const void * data
static char * DatumGetCString(Datum X)
Definition: postgres.h:335
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
bool attispackable
Definition: tupdesc.h:72
#define att_nominal_alignby(cur_offset, attalignby)
Definition: tupmacs.h:165
static void store_att_byval(void *T, Datum newdatum, int attlen)
Definition: tupmacs.h:211
#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 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

References Assert, att_nominal_alignby, CompactAttribute::attalignby, CompactAttribute::attbyval, CompactAttribute::attispackable, CompactAttribute::attlen, bit(), data, DatumGetCString(), DatumGetEOHP(), DatumGetPointer(), EOH_flatten_into(), EOH_get_flat_size(), HEAP_HASEXTERNAL, HEAP_HASNULL, HEAP_HASVARWIDTH, HIGHBIT, SET_VARSIZE_SHORT, store_att_byval(), val, VARATT_CAN_MAKE_SHORT, VARATT_CONVERTED_SHORT_SIZE, VARATT_IS_EXTERNAL, VARATT_IS_EXTERNAL_EXPANDED, VARATT_IS_SHORT, VARDATA, VARSIZE, VARSIZE_EXTERNAL, and VARSIZE_SHORT.

Referenced by expand_tuple(), and heap_fill_tuple().

◆ getmissingattr()

Datum getmissingattr ( TupleDesc  tupleDesc,
int  attnum,
bool *  isnull 
)

Definition at line 151 of file heaptuple.c.

153{
154 CompactAttribute *att;
155
156 Assert(attnum <= tupleDesc->natts);
157 Assert(attnum > 0);
158
159 att = TupleDescCompactAttr(tupleDesc, attnum - 1);
160
161 if (att->atthasmissing)
162 {
163 AttrMissing *attrmiss;
164
165 Assert(tupleDesc->constr);
166 Assert(tupleDesc->constr->missing);
167
168 attrmiss = tupleDesc->constr->missing + (attnum - 1);
169
170 if (attrmiss->am_present)
171 {
173 missing_cache_key *entry;
174 bool found;
175 MemoryContext oldctx;
176
177 *isnull = false;
178
179 /* no need to cache by-value attributes */
180 if (att->attbyval)
181 return attrmiss->am_value;
182
183 /* set up cache if required */
184 if (missing_cache == NULL)
186
187 /* check if there's a cache entry */
188 Assert(att->attlen > 0 || att->attlen == -1);
189 if (att->attlen > 0)
190 key.len = att->attlen;
191 else
192 key.len = VARSIZE_ANY(attrmiss->am_value);
193 key.value = attrmiss->am_value;
194
195 entry = hash_search(missing_cache, &key, HASH_ENTER, &found);
196
197 if (!found)
198 {
199 /* cache miss, so we need a non-transient copy of the datum */
201 entry->value =
202 datumCopy(attrmiss->am_value, false, att->attlen);
203 MemoryContextSwitchTo(oldctx);
204 }
205
206 return entry->value;
207 }
208 }
209
210 *isnull = true;
211 return PointerGetDatum(NULL);
212}
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
static void init_missing_cache()
Definition: heaptuple.c:126
static HTAB * missing_cache
Definition: heaptuple.c:101
@ HASH_ENTER
Definition: hsearch.h:114
MemoryContext TopMemoryContext
Definition: mcxt.c:149
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
MemoryContextSwitchTo(old_ctx)
bool atthasmissing
Definition: tupdesc.h:74
#define VARSIZE_ANY(PTR)
Definition: varatt.h:311

References AttrMissing::am_present, AttrMissing::am_value, Assert, CompactAttribute::attbyval, CompactAttribute::atthasmissing, CompactAttribute::attlen, attnum, TupleDescData::constr, datumCopy(), HASH_ENTER, hash_search(), init_missing_cache(), sort-test::key, MemoryContextSwitchTo(), TupleConstr::missing, missing_cache, PointerGetDatum(), TopMemoryContext, TupleDescCompactAttr(), missing_cache_key::value, and VARSIZE_ANY.

Referenced by heap_getattr().

◆ heap_attisnull()

bool heap_attisnull ( HeapTuple  tup,
int  attnum,
TupleDesc  tupleDesc 
)

Definition at line 456 of file heaptuple.c.

457{
458 /*
459 * We allow a NULL tupledesc for relations not expected to have missing
460 * values, such as catalog relations and indexes.
461 */
462 Assert(!tupleDesc || attnum <= tupleDesc->natts);
463 if (attnum > (int) HeapTupleHeaderGetNatts(tup->t_data))
464 {
465 if (tupleDesc &&
466 TupleDescCompactAttr(tupleDesc, attnum - 1)->atthasmissing)
467 return false;
468 else
469 return true;
470 }
471
472 if (attnum > 0)
473 {
474 if (HeapTupleNoNulls(tup))
475 return false;
476 return att_isnull(attnum - 1, tup->t_data->t_bits);
477 }
478
479 switch (attnum)
480 {
487 /* these are never null */
488 break;
489
490 default:
491 elog(ERROR, "invalid attnum: %d", attnum);
492 }
493
494 return false;
495}
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define HeapTupleNoNulls(tuple)
Definition: htup_details.h:662
bits8 t_bits[FLEXIBLE_ARRAY_MEMBER]
Definition: htup_details.h:178
#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
static bool att_isnull(int ATT, const bits8 *BITS)
Definition: tupmacs.h:26

References Assert, att_isnull(), attnum, elog, ERROR, HeapTupleHeaderGetNatts, HeapTupleNoNulls, MaxCommandIdAttributeNumber, MaxTransactionIdAttributeNumber, MinCommandIdAttributeNumber, MinTransactionIdAttributeNumber, SelfItemPointerAttributeNumber, HeapTupleHeaderData::t_bits, HeapTupleData::t_data, TableOidAttributeNumber, and TupleDescCompactAttr().

Referenced by AlterPublicationOptions(), AlterPublicationSchemas(), build_function_result_tupdesc_t(), check_index_is_clusterable(), CheckIndexCompatible(), ExecEvalRowNullInt(), ExecuteCallStmt(), fmgr_info_cxt_security(), fmgr_symbol(), get_func_result_name(), index_drop(), inline_function(), inline_set_returning_function(), IsIndexUsableForReplicaIdentityFull(), pg_get_indexdef_worker(), pg_get_partkeydef_worker(), pg_get_statisticsobj_worker(), pg_get_statisticsobjdef_expressions(), RelationGetDummyIndexExpressions(), RelationGetIndexExpressions(), RelationGetIndexList(), RelationGetIndexPredicate(), statext_is_kind_built(), and transformFkeyCheckAttrs().

◆ heap_compute_data_size()

Size heap_compute_data_size ( TupleDesc  tupleDesc,
const Datum values,
const bool *  isnull 
)

Definition at line 219 of file heaptuple.c.

222{
223 Size data_length = 0;
224 int i;
225 int numberOfAttributes = tupleDesc->natts;
226
227 for (i = 0; i < numberOfAttributes; i++)
228 {
229 Datum val;
230 CompactAttribute *atti;
231
232 if (isnull[i])
233 continue;
234
235 val = values[i];
236 atti = TupleDescCompactAttr(tupleDesc, i);
237
238 if (COMPACT_ATTR_IS_PACKABLE(atti) &&
240 {
241 /*
242 * we're anticipating converting to a short varlena header, so
243 * adjust length and don't count any alignment
244 */
246 }
247 else if (atti->attlen == -1 &&
249 {
250 /*
251 * we want to flatten the expanded value so that the constructed
252 * tuple doesn't depend on it
253 */
254 data_length = att_nominal_alignby(data_length, atti->attalignby);
255 data_length += EOH_get_flat_size(DatumGetEOHP(val));
256 }
257 else
258 {
259 data_length = att_datum_alignby(data_length, atti->attalignby,
260 atti->attlen, val);
261 data_length = att_addlength_datum(data_length, atti->attlen,
262 val);
263 }
264 }
265
266 return data_length;
267}
static Datum values[MAXATTR]
Definition: bootstrap.c:151
#define COMPACT_ATTR_IS_PACKABLE(att)
Definition: heaptuple.c:87
int i
Definition: isn.c:72
#define att_addlength_datum(cur_offset, attlen, attdatum)
Definition: tupmacs.h:173

References att_addlength_datum, att_datum_alignby, att_nominal_alignby, CompactAttribute::attalignby, CompactAttribute::attlen, COMPACT_ATTR_IS_PACKABLE, DatumGetEOHP(), DatumGetPointer(), EOH_get_flat_size(), i, TupleDescData::natts, TupleDescCompactAttr(), val, values, VARATT_CAN_MAKE_SHORT, VARATT_CONVERTED_SHORT_SIZE, and VARATT_IS_EXTERNAL_EXPANDED.

Referenced by brin_form_tuple(), ER_get_flat_size(), heap_form_minimal_tuple(), heap_form_tuple(), heap_toast_insert_or_update(), index_form_tuple_context(), spgFormLeafTuple(), SpGistGetLeafTupleSize(), and toast_flatten_tuple_to_datum().

◆ heap_copy_minimal_tuple()

MinimalTuple heap_copy_minimal_tuple ( MinimalTuple  mtup)

Definition at line 1536 of file heaptuple.c.

1537{
1538 MinimalTuple result;
1539
1540 result = (MinimalTuple) palloc(mtup->t_len);
1541 memcpy(result, mtup, mtup->t_len);
1542 return result;
1543}
void * palloc(Size size)
Definition: mcxt.c:1317

References palloc(), and MinimalTupleData::t_len.

Referenced by gm_readnext_tuple(), tts_minimal_copy_minimal_tuple(), tts_minimal_materialize(), tuplesort_gettupleslot(), and tuplestore_gettupleslot().

◆ heap_copy_tuple_as_datum()

Datum heap_copy_tuple_as_datum ( HeapTuple  tuple,
TupleDesc  tupleDesc 
)

Definition at line 1081 of file heaptuple.c.

1082{
1083 HeapTupleHeader td;
1084
1085 /*
1086 * If the tuple contains any external TOAST pointers, we have to inline
1087 * those fields to meet the conventions for composite-type Datums.
1088 */
1089 if (HeapTupleHasExternal(tuple))
1091 tuple->t_len,
1092 tupleDesc);
1093
1094 /*
1095 * Fast path for easy case: just make a palloc'd copy and insert the
1096 * correct composite-Datum header fields (since those may not be set if
1097 * the given tuple came from disk, rather than from heap_form_tuple).
1098 */
1099 td = (HeapTupleHeader) palloc(tuple->t_len);
1100 memcpy((char *) td, (char *) tuple->t_data, tuple->t_len);
1101
1103 HeapTupleHeaderSetTypeId(td, tupleDesc->tdtypeid);
1104 HeapTupleHeaderSetTypMod(td, tupleDesc->tdtypmod);
1105
1106 return PointerGetDatum(td);
1107}
Datum toast_flatten_tuple_to_datum(HeapTupleHeader tup, uint32 tup_len, TupleDesc tupleDesc)
Definition: heaptoast.c:449
#define HeapTupleHasExternal(tuple)
Definition: htup_details.h:671

References HeapTupleHasExternal, HeapTupleHeaderSetDatumLength, HeapTupleHeaderSetTypeId, HeapTupleHeaderSetTypMod, palloc(), PointerGetDatum(), HeapTupleData::t_data, HeapTupleData::t_len, TupleDescData::tdtypeid, TupleDescData::tdtypmod, and toast_flatten_tuple_to_datum().

Referenced by ExecEvalConvertRowtype(), ExecFetchSlotHeapTupleDatum(), PLyGenericObject_ToComposite(), PLyMapping_ToComposite(), PLySequence_ToComposite(), serialize_expr_stats(), and SPI_returntuple().

◆ heap_copytuple()

HeapTuple heap_copytuple ( HeapTuple  tuple)

Definition at line 778 of file heaptuple.c.

779{
780 HeapTuple newTuple;
781
782 if (!HeapTupleIsValid(tuple) || tuple->t_data == NULL)
783 return NULL;
784
785 newTuple = (HeapTuple) palloc(HEAPTUPLESIZE + tuple->t_len);
786 newTuple->t_len = tuple->t_len;
787 newTuple->t_self = tuple->t_self;
788 newTuple->t_tableOid = tuple->t_tableOid;
789 newTuple->t_data = (HeapTupleHeader) ((char *) newTuple + HEAPTUPLESIZE);
790 memcpy((char *) newTuple->t_data, (char *) tuple->t_data, tuple->t_len);
791 return newTuple;
792}
#define HeapTupleIsValid(tuple)
Definition: htup.h:78

References HeapTupleIsValid, HEAPTUPLESIZE, palloc(), HeapTupleData::t_data, HeapTupleData::t_len, HeapTupleData::t_self, and HeapTupleData::t_tableOid.

Referenced by AlterConstraintNamespaces(), AlterDomainValidateConstraint(), AlterExtensionNamespace(), AlterSequence(), AlterTypeOwner(), ATExecAlterConstrRecurse(), ATExecValidateConstraint(), CatalogCacheCreateEntry(), changeDependenciesOf(), changeDependenciesOn(), changeDependencyFor(), ConstraintSetParentConstraint(), CopyStatistics(), CreateTriggerFiringOn(), DefineIndex(), dropconstraint_internal(), EnableDisableTrigger(), ExecForceStoreHeapTuple(), expanded_record_set_tuple(), findDomainNotNullConstraint(), findNotNullConstraintAttnum(), get_catalog_object_by_oid_extended(), GetDatabaseTuple(), GetDatabaseTupleByOid(), index_concurrently_swap(), make_expanded_record_from_datum(), MarkInheritDetached(), MergeConstraintsIntoExisting(), MergeWithExistingConstraint(), RelationInitIndexAccessInfo(), RemoveInheritance(), rename_policy(), RenameEnumLabel(), RenameTableSpace(), renametrig_internal(), RenumberEnumType(), ResetSequence(), rewrite_heap_tuple(), ScanPgRelation(), SearchSysCacheCopy(), SearchSysCacheCopyAttName(), SearchSysCacheCopyAttNum(), SearchSysCacheLockedCopy1(), shdepChangeDep(), SPI_copytuple(), statext_expressions_load(), systable_inplace_update_begin(), TriggerSetParentTrigger(), tts_buffer_heap_copy_heap_tuple(), tts_buffer_heap_materialize(), tts_heap_copy_heap_tuple(), tts_heap_materialize(), and tuplesort_putheaptuple().

◆ heap_copytuple_with_tuple()

void heap_copytuple_with_tuple ( HeapTuple  src,
HeapTuple  dest 
)

Definition at line 804 of file heaptuple.c.

805{
806 if (!HeapTupleIsValid(src) || src->t_data == NULL)
807 {
808 dest->t_data = NULL;
809 return;
810 }
811
812 dest->t_len = src->t_len;
813 dest->t_self = src->t_self;
814 dest->t_tableOid = src->t_tableOid;
815 dest->t_data = (HeapTupleHeader) palloc(src->t_len);
816 memcpy((char *) dest->t_data, (char *) src->t_data, src->t_len);
817}

References generate_unaccent_rules::dest, HeapTupleIsValid, palloc(), HeapTupleData::t_data, HeapTupleData::t_len, HeapTupleData::t_self, and HeapTupleData::t_tableOid.

◆ heap_deform_tuple()

void heap_deform_tuple ( HeapTuple  tuple,
TupleDesc  tupleDesc,
Datum values,
bool *  isnull 
)

Definition at line 1346 of file heaptuple.c.

1348{
1349 HeapTupleHeader tup = tuple->t_data;
1350 bool hasnulls = HeapTupleHasNulls(tuple);
1351 int tdesc_natts = tupleDesc->natts;
1352 int natts; /* number of atts to extract */
1353 int attnum;
1354 char *tp; /* ptr to tuple data */
1355 uint32 off; /* offset in tuple data */
1356 bits8 *bp = tup->t_bits; /* ptr to null bitmap in tuple */
1357 bool slow = false; /* can we use/set attcacheoff? */
1358
1359 natts = HeapTupleHeaderGetNatts(tup);
1360
1361 /*
1362 * In inheritance situations, it is possible that the given tuple actually
1363 * has more fields than the caller is expecting. Don't run off the end of
1364 * the caller's arrays.
1365 */
1366 natts = Min(natts, tdesc_natts);
1367
1368 tp = (char *) tup + tup->t_hoff;
1369
1370 off = 0;
1371
1372 for (attnum = 0; attnum < natts; attnum++)
1373 {
1374 CompactAttribute *thisatt = TupleDescCompactAttr(tupleDesc, attnum);
1375
1376 if (hasnulls && att_isnull(attnum, bp))
1377 {
1378 values[attnum] = (Datum) 0;
1379 isnull[attnum] = true;
1380 slow = true; /* can't use attcacheoff anymore */
1381 continue;
1382 }
1383
1384 isnull[attnum] = false;
1385
1386 if (!slow && thisatt->attcacheoff >= 0)
1387 off = thisatt->attcacheoff;
1388 else if (thisatt->attlen == -1)
1389 {
1390 /*
1391 * We can only cache the offset for a varlena attribute if the
1392 * offset is already suitably aligned, so that there would be no
1393 * pad bytes in any case: then the offset will be valid for either
1394 * an aligned or unaligned value.
1395 */
1396 if (!slow &&
1397 off == att_nominal_alignby(off, thisatt->attalignby))
1398 thisatt->attcacheoff = off;
1399 else
1400 {
1401 off = att_pointer_alignby(off, thisatt->attalignby, -1,
1402 tp + off);
1403 slow = true;
1404 }
1405 }
1406 else
1407 {
1408 /* not varlena, so safe to use att_nominal_alignby */
1409 off = att_nominal_alignby(off, thisatt->attalignby);
1410
1411 if (!slow)
1412 thisatt->attcacheoff = off;
1413 }
1414
1415 values[attnum] = fetchatt(thisatt, tp + off);
1416
1417 off = att_addlength_pointer(off, thisatt->attlen, tp + off);
1418
1419 if (thisatt->attlen <= 0)
1420 slow = true; /* can't use attcacheoff anymore */
1421 }
1422
1423 /*
1424 * If tuple doesn't have all the atts indicated by tupleDesc, read the
1425 * rest as nulls or missing values as appropriate.
1426 */
1427 for (; attnum < tdesc_natts; attnum++)
1428 values[attnum] = getmissingattr(tupleDesc, attnum + 1, &isnull[attnum]);
1429}
#define Min(x, y)
Definition: c.h:958
uint32_t uint32
Definition: c.h:485
for(;;)
Datum getmissingattr(TupleDesc tupleDesc, int attnum, bool *isnull)
Definition: heaptuple.c:151
int32 attcacheoff
Definition: tupdesc.h:68
#define att_pointer_alignby(cur_offset, attalignby, attlen, attptr)
Definition: tupmacs.h:129
#define fetchatt(A, T)
Definition: tupmacs.h:47

References att_addlength_pointer, att_isnull(), att_nominal_alignby, att_pointer_alignby, CompactAttribute::attalignby, CompactAttribute::attcacheoff, CompactAttribute::attlen, attnum, fetchatt, for(), HeapTupleHasNulls, HeapTupleHeaderGetNatts, Min, TupleDescData::natts, HeapTupleHeaderData::t_bits, HeapTupleData::t_data, HeapTupleHeaderData::t_hoff, TupleDescCompactAttr(), and values.

Referenced by attribute_statistics_update(), deconstruct_expanded_record(), exec_move_row(), ExecEvalFieldStoreDeForm(), ExecForceStoreHeapTuple(), ExecForceStoreMinimalTuple(), ExecStoreHeapTupleDatum(), execute_attr_map_tuple(), ExtractReplicaIdentity(), hash_record(), hash_record_extended(), heap_modify_tuple(), heap_modify_tuple_by_cols(), heap_toast_delete(), heap_toast_insert_or_update(), hstore_from_record(), hstore_populate_record(), make_tuple_indirect(), populate_record(), record_cmp(), record_eq(), record_image_cmp(), record_image_eq(), record_out(), record_send(), reform_and_rewrite_tuple(), ReorderBufferToastReplace(), RI_Initial_Check(), RI_PartitionRemove_Check(), SPI_modifytuple(), toast_flatten_tuple(), and toast_flatten_tuple_to_datum().

◆ heap_expand_tuple()

HeapTuple heap_expand_tuple ( HeapTuple  sourceTuple,
TupleDesc  tupleDesc 
)

Definition at line 1066 of file heaptuple.c.

1067{
1068 HeapTuple heapTuple;
1069
1070 expand_tuple(&heapTuple, NULL, sourceTuple, tupleDesc);
1071 return heapTuple;
1072}
static void expand_tuple(HeapTuple *targetHeapTuple, MinimalTuple *targetMinimalTuple, HeapTuple sourceTuple, TupleDesc tupleDesc)
Definition: heaptuple.c:830

References expand_tuple().

◆ heap_fill_tuple()

void heap_fill_tuple ( TupleDesc  tupleDesc,
const Datum values,
const bool *  isnull,
char *  data,
Size  data_size,
uint16 infomask,
bits8 bit 
)

Definition at line 401 of file heaptuple.c.

405{
406 bits8 *bitP;
407 int bitmask;
408 int i;
409 int numberOfAttributes = tupleDesc->natts;
410
411#ifdef USE_ASSERT_CHECKING
412 char *start = data;
413#endif
414
415 if (bit != NULL)
416 {
417 bitP = &bit[-1];
418 bitmask = HIGHBIT;
419 }
420 else
421 {
422 /* just to keep compiler quiet */
423 bitP = NULL;
424 bitmask = 0;
425 }
426
428
429 for (i = 0; i < numberOfAttributes; i++)
430 {
431 CompactAttribute *attr = TupleDescCompactAttr(tupleDesc, i);
432
433 fill_val(attr,
434 bitP ? &bitP : NULL,
435 &bitmask,
436 &data,
437 infomask,
438 values ? values[i] : PointerGetDatum(NULL),
439 isnull ? isnull[i] : true);
440 }
441
442 Assert((data - start) == data_size);
443}
return str start

References Assert, bit(), data, fill_val(), HEAP_HASEXTERNAL, HEAP_HASNULL, HEAP_HASVARWIDTH, HIGHBIT, i, TupleDescData::natts, PointerGetDatum(), start, TupleDescCompactAttr(), and values.

Referenced by brin_form_tuple(), ER_flatten_into(), heap_form_minimal_tuple(), heap_form_tuple(), heap_toast_insert_or_update(), index_form_tuple_context(), spgFormLeafTuple(), and toast_flatten_tuple_to_datum().

◆ heap_form_minimal_tuple()

MinimalTuple heap_form_minimal_tuple ( TupleDesc  tupleDescriptor,
const Datum values,
const bool *  isnull 
)

Definition at line 1453 of file heaptuple.c.

1456{
1457 MinimalTuple tuple; /* return tuple */
1458 Size len,
1459 data_len;
1460 int hoff;
1461 bool hasnull = false;
1462 int numberOfAttributes = tupleDescriptor->natts;
1463 int i;
1464
1465 if (numberOfAttributes > MaxTupleAttributeNumber)
1466 ereport(ERROR,
1467 (errcode(ERRCODE_TOO_MANY_COLUMNS),
1468 errmsg("number of columns (%d) exceeds limit (%d)",
1469 numberOfAttributes, MaxTupleAttributeNumber)));
1470
1471 /*
1472 * Check for nulls
1473 */
1474 for (i = 0; i < numberOfAttributes; i++)
1475 {
1476 if (isnull[i])
1477 {
1478 hasnull = true;
1479 break;
1480 }
1481 }
1482
1483 /*
1484 * Determine total space needed
1485 */
1487
1488 if (hasnull)
1489 len += BITMAPLEN(numberOfAttributes);
1490
1491 hoff = len = MAXALIGN(len); /* align user data safely */
1492
1493 data_len = heap_compute_data_size(tupleDescriptor, values, isnull);
1494
1495 len += data_len;
1496
1497 /*
1498 * Allocate and zero the space needed.
1499 */
1500 tuple = (MinimalTuple) palloc0(len);
1501
1502 /*
1503 * And fill in the information.
1504 */
1505 tuple->t_len = len;
1506 HeapTupleHeaderSetNatts(tuple, numberOfAttributes);
1507 tuple->t_hoff = hoff + MINIMAL_TUPLE_OFFSET;
1508
1509 heap_fill_tuple(tupleDescriptor,
1510 values,
1511 isnull,
1512 (char *) tuple + hoff,
1513 data_len,
1514 &tuple->t_infomask,
1515 (hasnull ? tuple->t_bits : NULL));
1516
1517 return tuple;
1518}
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ereport(elevel,...)
Definition: elog.h:149
Size heap_compute_data_size(TupleDesc tupleDesc, const Datum *values, const bool *isnull)
Definition: heaptuple.c:219
void heap_fill_tuple(TupleDesc tupleDesc, const Datum *values, const bool *isnull, char *data, Size data_size, uint16 *infomask, bits8 *bit)
Definition: heaptuple.c:401
#define MaxTupleAttributeNumber
Definition: htup_details.h:34
bits8 t_bits[FLEXIBLE_ARRAY_MEMBER]
Definition: htup_details.h:640

References BITMAPLEN, ereport, errcode(), errmsg(), ERROR, heap_compute_data_size(), heap_fill_tuple(), HeapTupleHeaderSetNatts, i, len, MAXALIGN, MaxTupleAttributeNumber, MINIMAL_TUPLE_OFFSET, TupleDescData::natts, palloc0(), SizeofMinimalTupleHeader, MinimalTupleData::t_bits, MinimalTupleData::t_hoff, MinimalTupleData::t_infomask, MinimalTupleData::t_len, and values.

Referenced by tts_minimal_materialize(), tts_virtual_copy_minimal_tuple(), and tuplestore_putvalues().

◆ heap_form_tuple()

HeapTuple heap_form_tuple ( TupleDesc  tupleDescriptor,
const Datum values,
const bool *  isnull 
)

Definition at line 1117 of file heaptuple.c.

1120{
1121 HeapTuple tuple; /* return tuple */
1122 HeapTupleHeader td; /* tuple data */
1123 Size len,
1124 data_len;
1125 int hoff;
1126 bool hasnull = false;
1127 int numberOfAttributes = tupleDescriptor->natts;
1128 int i;
1129
1130 if (numberOfAttributes > MaxTupleAttributeNumber)
1131 ereport(ERROR,
1132 (errcode(ERRCODE_TOO_MANY_COLUMNS),
1133 errmsg("number of columns (%d) exceeds limit (%d)",
1134 numberOfAttributes, MaxTupleAttributeNumber)));
1135
1136 /*
1137 * Check for nulls
1138 */
1139 for (i = 0; i < numberOfAttributes; i++)
1140 {
1141 if (isnull[i])
1142 {
1143 hasnull = true;
1144 break;
1145 }
1146 }
1147
1148 /*
1149 * Determine total space needed
1150 */
1151 len = offsetof(HeapTupleHeaderData, t_bits);
1152
1153 if (hasnull)
1154 len += BITMAPLEN(numberOfAttributes);
1155
1156 hoff = len = MAXALIGN(len); /* align user data safely */
1157
1158 data_len = heap_compute_data_size(tupleDescriptor, values, isnull);
1159
1160 len += data_len;
1161
1162 /*
1163 * Allocate and zero the space needed. Note that the tuple body and
1164 * HeapTupleData management structure are allocated in one chunk.
1165 */
1166 tuple = (HeapTuple) palloc0(HEAPTUPLESIZE + len);
1167 tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
1168
1169 /*
1170 * And fill in the information. Note we fill the Datum fields even though
1171 * this tuple may never become a Datum. This lets HeapTupleHeaderGetDatum
1172 * identify the tuple type if needed.
1173 */
1174 tuple->t_len = len;
1175 ItemPointerSetInvalid(&(tuple->t_self));
1176 tuple->t_tableOid = InvalidOid;
1177
1179 HeapTupleHeaderSetTypeId(td, tupleDescriptor->tdtypeid);
1180 HeapTupleHeaderSetTypMod(td, tupleDescriptor->tdtypmod);
1181 /* We also make sure that t_ctid is invalid unless explicitly set */
1183
1184 HeapTupleHeaderSetNatts(td, numberOfAttributes);
1185 td->t_hoff = hoff;
1186
1187 heap_fill_tuple(tupleDescriptor,
1188 values,
1189 isnull,
1190 (char *) td + hoff,
1191 data_len,
1192 &td->t_infomask,
1193 (hasnull ? td->t_bits : NULL));
1194
1195 return tuple;
1196}
#define InvalidOid
Definition: postgres_ext.h:36

References BITMAPLEN, ereport, errcode(), errmsg(), ERROR, heap_compute_data_size(), heap_fill_tuple(), HeapTupleHeaderSetDatumLength, HeapTupleHeaderSetNatts, HeapTupleHeaderSetTypeId, HeapTupleHeaderSetTypMod, HEAPTUPLESIZE, i, InvalidOid, ItemPointerSetInvalid(), len, MAXALIGN, MaxTupleAttributeNumber, TupleDescData::natts, palloc0(), HeapTupleHeaderData::t_bits, HeapTupleHeaderData::t_ctid, HeapTupleData::t_data, HeapTupleHeaderData::t_hoff, HeapTupleHeaderData::t_infomask, HeapTupleData::t_len, HeapTupleData::t_self, HeapTupleData::t_tableOid, TupleDescData::tdtypeid, TupleDescData::tdtypmod, and values.

Referenced by aclexplode(), AddEnumLabel(), AddRoleMems(), AddSubscriptionRelState(), AggregateCreate(), AlterSetting(), brin_metapage_info(), bt_page_print_tuples(), BuildTupleFromCStrings(), CastCreate(), CollationCreate(), ConversionCreate(), copy_replication_slot(), CreateAccessMethod(), CreateComments(), CreateConstraintEntry(), createdb(), CreateForeignDataWrapper(), CreateForeignServer(), CreateForeignTable(), CreateOpFamily(), CreatePolicy(), CreateProceduralLanguage(), CreatePublication(), CreateRole(), CreateSharedComments(), CreateStatistics(), CreateSubscription(), CreateTableSpace(), CreateTransform(), CreateTriggerFiringOn(), CreateUserMapping(), DefineOpClass(), DefineSequence(), DefineTSConfiguration(), DefineTSDictionary(), DefineTSParser(), DefineTSTemplate(), each_object_field_end(), elements_array_element_end(), ExecEvalFieldStoreForm(), ExecEvalRow(), execute_attr_map_tuple(), expanded_record_get_tuple(), ExtractReplicaIdentity(), file_acquire_sample_rows(), fill_hba_line(), fill_ident_line(), gin_leafpage_items(), gin_metapage_info(), gin_page_opaque_info(), gist_page_opaque_info(), gistFetchTuple(), hash_bitmap_info(), hash_metapage_info(), hash_page_items(), hash_page_stats(), heap_modify_tuple(), heap_modify_tuple_by_cols(), heap_page_items(), heap_tuple_infomask_flags(), hstore_each(), hstore_populate_record(), injection_points_stats_fixed(), insert_event_trigger_tuple(), InsertExtensionTuple(), InsertOneTuple(), InsertPgClassTuple(), InsertRule(), inv_truncate(), inv_write(), LargeObjectCreate(), make_tuple_from_result_row(), make_tuple_from_row(), make_tuple_indirect(), NamespaceCreate(), OperatorCreate(), OperatorShellMake(), page_header(), ParameterAclCreate(), pg_available_wal_summaries(), pg_backup_stop(), pg_buffercache_pages(), pg_buffercache_summary(), pg_control_checkpoint(), pg_control_init(), pg_control_recovery(), pg_control_system(), pg_create_logical_replication_slot(), pg_create_physical_replication_slot(), pg_get_catalog_foreign_keys(), pg_get_logical_snapshot_info(), pg_get_logical_snapshot_meta(), pg_get_object_address(), pg_get_publication_tables(), pg_get_sequence_data(), pg_get_wal_record_info(), pg_get_wal_summarizer_state(), pg_identify_object(), pg_identify_object_as_address(), pg_input_error_info(), pg_last_committed_xact(), pg_lock_status(), pg_partition_tree(), pg_prepared_xact(), pg_replication_slot_advance(), pg_sequence_parameters(), pg_split_walfile_name(), pg_stat_file(), pg_stat_get_archiver(), pg_stat_get_backend_subxact(), pg_stat_get_replication_slot(), pg_stat_get_subscription_stats(), pg_stat_get_wal(), pg_stat_get_wal_receiver(), pg_stat_statements_info(), pg_stats_ext_mcvlist_items(), pg_timezone_abbrevs(), pg_visibility(), pg_visibility_map(), pg_visibility_map_rel(), pg_visibility_map_summary(), pg_visibility_rel(), pg_wal_summary_contents(), pg_walfile_name_offset(), pg_xact_commit_timestamp_origin(), pgstatginindex_internal(), pgstathashindex(), pgstattuple_approx_internal(), plperl_build_tuple_result(), PLyGenericObject_ToComposite(), PLyMapping_ToComposite(), PLySequence_ToComposite(), populate_record(), ProcedureCreate(), publication_add_relation(), publication_add_schema(), RangeCreate(), record_in(), record_recv(), recordExtensionInitPrivWorker(), reform_and_rewrite_tuple(), ReorderBufferToastReplace(), replorigin_create(), report_corruption_internal(), serialize_expr_stats(), SetDefaultACL(), SetSecurityLabel(), SetSharedSecurityLabel(), shdepAddDependency(), shdepChangeDep(), SPI_modifytuple(), ssl_extension_info(), statext_store(), StoreAttrDefault(), storeGettuple(), storeOperators(), StorePartitionKey(), storeProcedures(), StoreSingleInheritance(), test_enc_conversion(), test_predtest(), toast_build_flattened_tuple(), toast_flatten_tuple(), toast_save_datum(), tsvector_unnest(), tts_buffer_heap_materialize(), tts_heap_materialize(), tts_virtual_copy_heap_tuple(), TypeCreate(), TypeShellMake(), update_attstats(), UpdateIndexRelation(), and upsert_pg_statistic().

◆ heap_free_minimal_tuple()

void heap_free_minimal_tuple ( MinimalTuple  mtup)

◆ heap_freetuple()

void heap_freetuple ( HeapTuple  htup)

Definition at line 1435 of file heaptuple.c.

1436{
1437 pfree(htup);
1438}

References pfree().

Referenced by acquire_inherited_sample_rows(), acquire_sample_rows(), AddEnumLabel(), AddSubscriptionRelState(), AfterTriggerExecute(), AlterCollation(), AlterDatabaseOwner(), AlterDatabaseRefreshColl(), AlterDomainDefault(), AlterDomainNotNull(), AlterDomainValidateConstraint(), AlterEventTrigger(), AlterEventTriggerOwner(), AlterEventTriggerOwner_oid(), AlterForeignDataWrapper(), AlterForeignDataWrapperOwner(), AlterForeignDataWrapperOwner_oid(), AlterForeignServer(), AlterForeignServerOwner(), AlterForeignServerOwner_oid(), AlterFunction(), AlterObjectRename_internal(), AlterPolicy(), AlterPublication(), AlterPublicationOwner(), AlterPublicationOwner_oid(), AlterRelationNamespaceInternal(), AlterRole(), AlterSchemaOwner_internal(), AlterStatistics(), AlterSubscription(), AlterSubscriptionOwner(), AlterSubscriptionOwner_oid(), AlterTableSpaceOptions(), AlterTSDictionary(), AlterTypeNamespaceInternal(), AlterUserMapping(), analyze_row_processor(), ATExecAddColumn(), ATExecAddIdentity(), ATExecAddOf(), ATExecAlterColumnGenericOptions(), ATExecAlterColumnType(), ATExecAlterConstrRecurse(), ATExecChangeOwner(), ATExecDropColumn(), ATExecDropExpression(), ATExecDropIdentity(), ATExecDropNotNull(), ATExecDropOf(), ATExecForceNoForceRowSecurity(), ATExecGenericOptions(), ATExecSetAccessMethodNoStorage(), ATExecSetCompression(), ATExecSetIdentity(), ATExecSetOptions(), ATExecSetRelOptions(), ATExecSetRowSecurity(), ATExecSetStatistics(), ATExecSetStorage(), ATExecValidateConstraint(), build_tuplestore_recursively(), CastCreate(), CatalogCacheCreateEntry(), CatalogTuplesMultiInsertWithInfo(), change_owner_fix_column_acls(), changeDependenciesOf(), changeDependenciesOn(), changeDependencyFor(), clear_subscription_skip_lsn(), CollationCreate(), ConversionCreate(), copy_table_data(), CopyStatistics(), create_toast_table(), CreateAccessMethod(), CreateComments(), CreateForeignDataWrapper(), CreateForeignServer(), CreateForeignTable(), CreateOpFamily(), CreatePolicy(), CreatePublication(), CreateSharedComments(), CreateStatistics(), CreateSubscription(), CreateTableSpace(), CreateTransform(), CreateTriggerFiringOn(), CreateUserMapping(), crosstab(), DefineIndex(), DefineOpClass(), DefineSequence(), DefineTSConfiguration(), DefineTSDictionary(), DefineTSParser(), DefineTSTemplate(), DetachPartitionFinalize(), DisableSubscription(), dropconstraint_internal(), dropdb(), EnableDisableRule(), EnableDisableTrigger(), EventTriggerOnLogin(), examine_attribute(), examine_expression(), ExecBRDeleteTriggers(), ExecBRInsertTriggers(), ExecBRUpdateTriggers(), ExecIRDeleteTriggers(), ExecIRInsertTriggers(), ExecIRUpdateTriggers(), ExecReScanAgg(), ExecReScanIndexScan(), ExecScanSubPlan(), ExecSetParamPlan(), expanded_record_set_tuple(), ExtractReplicaIdentity(), file_acquire_sample_rows(), heap_delete(), heap_insert(), heap_update(), index_build(), index_concurrently_swap(), index_constraint_create(), index_update_stats(), insert_event_trigger_tuple(), InsertExtensionTuple(), InsertOneTuple(), InsertPgClassTuple(), InsertRule(), inv_truncate(), inv_write(), LargeObjectCreate(), mark_index_clustered(), MarkInheritDetached(), MergeAttributesIntoExisting(), MergeConstraintsIntoExisting(), OperatorShellMake(), ParameterAclCreate(), PLyGenericObject_ToComposite(), PLyMapping_ToComposite(), PLySequence_ToComposite(), ProcedureCreate(), publication_add_relation(), publication_add_schema(), RangeCreate(), raw_heap_insert(), record_in(), record_recv(), reform_and_rewrite_tuple(), relation_mark_replica_identity(), relation_statistics_update(), RelationBuildDesc(), RelationClearMissing(), RelationInitPhysicalAddr(), RelationReloadIndexInfo(), RelationReloadNailed(), RelationSetNewRelfilenumber(), RemoveConstraintById(), RemoveInheritance(), RemoveRoleFromObjectPolicy(), renameatt_internal(), RenameConstraintById(), RenameEnumLabel(), RenameRelationInternal(), RenameRewriteRule(), RenameSchema(), RenameTypeInternal(), RenumberEnumType(), replorigin_create(), ResetRelRewrite(), rewrite_heap_dead_tuple(), rewrite_heap_tuple(), set_attnotnull(), SetDatabaseHasLoginEventTriggers(), SetIndexStorageProperties(), SetMatViewPopulatedState(), SetRelationHasSubclass(), SetRelationNumChecks(), SetRelationRuleStatus(), SetRelationTableSpace(), SetSecurityLabel(), SetSharedSecurityLabel(), shdepAddDependency(), shdepChangeDep(), SPI_freetuple(), statext_store(), StoreAttrDefault(), storeOperators(), StorePartitionBound(), storeProcedures(), StoreSingleInheritance(), swap_relation_files(), table_recheck_autovac(), toast_save_datum(), TriggerSetParentTrigger(), tts_buffer_heap_clear(), tts_buffer_heap_store_tuple(), tts_heap_clear(), TypeShellMake(), update_attstats(), update_default_partition_oid(), update_relispartition(), UpdateIndexRelation(), UpdateTwoPhaseState(), upsert_pg_statistic(), vac_update_datfrozenxid(), validatePartitionedIndex(), and xpath_table().

◆ heap_getsysattr()

Datum heap_getsysattr ( HeapTuple  tup,
int  attnum,
TupleDesc  tupleDesc,
bool *  isnull 
)

Definition at line 725 of file heaptuple.c.

726{
727 Datum result;
728
729 Assert(tup);
730
731 /* Currently, no sys attribute ever reads as NULL. */
732 *isnull = false;
733
734 switch (attnum)
735 {
737 /* pass-by-reference datatype */
738 result = PointerGetDatum(&(tup->t_self));
739 break;
742 break;
745 break;
748
749 /*
750 * cmin and cmax are now both aliases for the same field, which
751 * can in fact also be a combo command id. XXX perhaps we should
752 * return the "real" cmin or cmax if possible, that is if we are
753 * inside the originating transaction?
754 */
756 break;
758 result = ObjectIdGetDatum(tup->t_tableOid);
759 break;
760 default:
761 elog(ERROR, "invalid attnum: %d", attnum);
762 result = 0; /* keep compiler quiet */
763 break;
764 }
765 return result;
766}
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:304
#define HeapTupleHeaderGetRawXmax(tup)
Definition: htup_details.h:371
#define HeapTupleHeaderGetRawCommandId(tup)
Definition: htup_details.h:387
static Datum TransactionIdGetDatum(TransactionId X)
Definition: postgres.h:272
static Datum CommandIdGetDatum(CommandId X)
Definition: postgres.h:302
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252

References Assert, attnum, CommandIdGetDatum(), elog, ERROR, HeapTupleHeaderGetRawCommandId, HeapTupleHeaderGetRawXmax, HeapTupleHeaderGetRawXmin, MaxCommandIdAttributeNumber, MaxTransactionIdAttributeNumber, MinCommandIdAttributeNumber, MinTransactionIdAttributeNumber, ObjectIdGetDatum(), PointerGetDatum(), SelfItemPointerAttributeNumber, HeapTupleData::t_data, HeapTupleData::t_self, HeapTupleData::t_tableOid, TableOidAttributeNumber, and TransactionIdGetDatum().

Referenced by expanded_record_fetch_field(), heap_getattr(), tts_buffer_heap_getsysattr(), and tts_heap_getsysattr().

◆ heap_modify_tuple()

HeapTuple heap_modify_tuple ( HeapTuple  tuple,
TupleDesc  tupleDesc,
const Datum replValues,
const bool *  replIsnull,
const bool *  doReplace 
)

Definition at line 1210 of file heaptuple.c.

1215{
1216 int numberOfAttributes = tupleDesc->natts;
1217 int attoff;
1218 Datum *values;
1219 bool *isnull;
1220 HeapTuple newTuple;
1221
1222 /*
1223 * allocate and fill values and isnull arrays from either the tuple or the
1224 * repl information, as appropriate.
1225 *
1226 * NOTE: it's debatable whether to use heap_deform_tuple() here or just
1227 * heap_getattr() only the non-replaced columns. The latter could win if
1228 * there are many replaced columns and few non-replaced ones. However,
1229 * heap_deform_tuple costs only O(N) while the heap_getattr way would cost
1230 * O(N^2) if there are many non-replaced columns, so it seems better to
1231 * err on the side of linear cost.
1232 */
1233 values = (Datum *) palloc(numberOfAttributes * sizeof(Datum));
1234 isnull = (bool *) palloc(numberOfAttributes * sizeof(bool));
1235
1236 heap_deform_tuple(tuple, tupleDesc, values, isnull);
1237
1238 for (attoff = 0; attoff < numberOfAttributes; attoff++)
1239 {
1240 if (doReplace[attoff])
1241 {
1242 values[attoff] = replValues[attoff];
1243 isnull[attoff] = replIsnull[attoff];
1244 }
1245 }
1246
1247 /*
1248 * create a new tuple from the values and isnull arrays
1249 */
1250 newTuple = heap_form_tuple(tupleDesc, values, isnull);
1251
1252 pfree(values);
1253 pfree(isnull);
1254
1255 /*
1256 * copy the identification info of the old tuple: t_ctid, t_self
1257 */
1258 newTuple->t_data->t_ctid = tuple->t_data->t_ctid;
1259 newTuple->t_self = tuple->t_self;
1260 newTuple->t_tableOid = tuple->t_tableOid;
1261
1262 return newTuple;
1263}
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1117
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:1346

References heap_deform_tuple(), heap_form_tuple(), TupleDescData::natts, palloc(), pfree(), HeapTupleHeaderData::t_ctid, HeapTupleData::t_data, HeapTupleData::t_self, HeapTupleData::t_tableOid, and values.

Referenced by AddRoleMems(), AggregateCreate(), AlterCollation(), AlterDatabase(), AlterDatabaseOwner(), AlterDatabaseRefreshColl(), AlterDomainDefault(), AlterForeignDataWrapper(), AlterForeignDataWrapperOwner_internal(), AlterForeignServer(), AlterForeignServerOwner_internal(), AlterFunction(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), AlterOperator(), AlterPolicy(), AlterPublicationOptions(), AlterRole(), AlterSchemaOwner_internal(), AlterSetting(), AlterStatistics(), AlterSubscription(), AlterTableSpaceOptions(), AlterTSDictionary(), AlterTypeOwnerInternal(), AlterTypeRecurse(), AlterUserMapping(), ApplyExtensionUpdates(), ATExecAlterColumnGenericOptions(), ATExecAlterColumnType(), ATExecChangeOwner(), ATExecGenericOptions(), ATExecSetOptions(), ATExecSetRelOptions(), ATExecSetStatistics(), change_owner_fix_column_acls(), clear_subscription_skip_lsn(), CreateComments(), CreateProceduralLanguage(), CreateSharedComments(), CreateTransform(), DelRoleMems(), DetachPartitionFinalize(), DisableSubscription(), ExecGrant_Attribute(), ExecGrant_common(), ExecGrant_Largeobject(), ExecGrant_Parameter(), ExecGrant_Relation(), extension_config_remove(), index_concurrently_swap(), InsertRule(), inv_truncate(), inv_write(), MakeConfigurationMapping(), movedb(), OperatorCreate(), pg_extension_config_dump(), plperl_modify_tuple(), PLy_modify_tuple(), ProcedureCreate(), recordExtensionInitPrivWorker(), RelationClearMissing(), RemoveAttributeById(), RemoveRoleFromInitPriv(), RemoveRoleFromObjectPolicy(), RenameRole(), ReplaceRoleInInitPriv(), SetAttrMissing(), SetDefaultACL(), SetSecurityLabel(), SetSharedSecurityLabel(), StoreAttrDefault(), StorePartitionBound(), TypeCreate(), update_attstats(), UpdateSubscriptionRelState(), UpdateTwoPhaseState(), and upsert_pg_statistic().

◆ heap_modify_tuple_by_cols()

HeapTuple heap_modify_tuple_by_cols ( HeapTuple  tuple,
TupleDesc  tupleDesc,
int  nCols,
const int *  replCols,
const Datum replValues,
const bool *  replIsnull 
)

Definition at line 1278 of file heaptuple.c.

1284{
1285 int numberOfAttributes = tupleDesc->natts;
1286 Datum *values;
1287 bool *isnull;
1288 HeapTuple newTuple;
1289 int i;
1290
1291 /*
1292 * allocate and fill values and isnull arrays from the tuple, then replace
1293 * selected columns from the input arrays.
1294 */
1295 values = (Datum *) palloc(numberOfAttributes * sizeof(Datum));
1296 isnull = (bool *) palloc(numberOfAttributes * sizeof(bool));
1297
1298 heap_deform_tuple(tuple, tupleDesc, values, isnull);
1299
1300 for (i = 0; i < nCols; i++)
1301 {
1302 int attnum = replCols[i];
1303
1304 if (attnum <= 0 || attnum > numberOfAttributes)
1305 elog(ERROR, "invalid column number %d", attnum);
1306 values[attnum - 1] = replValues[i];
1307 isnull[attnum - 1] = replIsnull[i];
1308 }
1309
1310 /*
1311 * create a new tuple from the values and isnull arrays
1312 */
1313 newTuple = heap_form_tuple(tupleDesc, values, isnull);
1314
1315 pfree(values);
1316 pfree(isnull);
1317
1318 /*
1319 * copy the identification info of the old tuple: t_ctid, t_self
1320 */
1321 newTuple->t_data->t_ctid = tuple->t_data->t_ctid;
1322 newTuple->t_self = tuple->t_self;
1323 newTuple->t_tableOid = tuple->t_tableOid;
1324
1325 return newTuple;
1326}

References attnum, elog, ERROR, heap_deform_tuple(), heap_form_tuple(), i, TupleDescData::natts, palloc(), pfree(), HeapTupleHeaderData::t_ctid, HeapTupleData::t_data, HeapTupleData::t_self, HeapTupleData::t_tableOid, and values.

Referenced by autoinc(), insert_username(), moddatetime(), relation_statistics_update(), and tsvector_update_trigger().

◆ heap_tuple_from_minimal_tuple()

HeapTuple heap_tuple_from_minimal_tuple ( MinimalTuple  mtup)

Definition at line 1555 of file heaptuple.c.

1556{
1557 HeapTuple result;
1559
1560 result = (HeapTuple) palloc(HEAPTUPLESIZE + len);
1561 result->t_len = len;
1562 ItemPointerSetInvalid(&(result->t_self));
1563 result->t_tableOid = InvalidOid;
1564 result->t_data = (HeapTupleHeader) ((char *) result + HEAPTUPLESIZE);
1565 memcpy((char *) result->t_data + MINIMAL_TUPLE_OFFSET, mtup, mtup->t_len);
1566 memset(result->t_data, 0, offsetof(HeapTupleHeaderData, t_infomask2));
1567 return result;
1568}

References HEAPTUPLESIZE, InvalidOid, ItemPointerSetInvalid(), len, MINIMAL_TUPLE_OFFSET, palloc(), HeapTupleData::t_data, HeapTupleData::t_len, MinimalTupleData::t_len, HeapTupleData::t_self, and HeapTupleData::t_tableOid.

Referenced by tts_minimal_copy_heap_tuple().

◆ init_missing_cache()

static void init_missing_cache ( )
static

Definition at line 126 of file heaptuple.c.

127{
128 HASHCTL hash_ctl;
129
130 hash_ctl.keysize = sizeof(missing_cache_key);
131 hash_ctl.entrysize = sizeof(missing_cache_key);
132 hash_ctl.hcxt = TopMemoryContext;
133 hash_ctl.hash = missing_hash;
134 hash_ctl.match = missing_match;
136 hash_create("Missing Values Cache",
137 32,
138 &hash_ctl,
140}
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:352
static uint32 missing_hash(const void *key, Size keysize)
Definition: heaptuple.c:104
static int missing_match(const void *key1, const void *key2, Size keysize)
Definition: heaptuple.c:112
#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
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

References HASHCTL::entrysize, HASHCTL::hash, HASH_COMPARE, HASH_CONTEXT, hash_create(), HASH_ELEM, HASH_FUNCTION, HASHCTL::hcxt, HASHCTL::keysize, HASHCTL::match, missing_cache, missing_hash(), missing_match(), and TopMemoryContext.

Referenced by getmissingattr().

◆ minimal_expand_tuple()

MinimalTuple minimal_expand_tuple ( HeapTuple  sourceTuple,
TupleDesc  tupleDesc 
)

Definition at line 1054 of file heaptuple.c.

1055{
1056 MinimalTuple minimalTuple;
1057
1058 expand_tuple(NULL, &minimalTuple, sourceTuple, tupleDesc);
1059 return minimalTuple;
1060}

References expand_tuple().

◆ minimal_tuple_from_heap_tuple()

MinimalTuple minimal_tuple_from_heap_tuple ( HeapTuple  htup)

Definition at line 1577 of file heaptuple.c.

1578{
1579 MinimalTuple result;
1580 uint32 len;
1581
1583 len = htup->t_len - MINIMAL_TUPLE_OFFSET;
1584 result = (MinimalTuple) palloc(len);
1585 memcpy(result, (char *) htup->t_data + MINIMAL_TUPLE_OFFSET, len);
1586 result->t_len = len;
1587 return result;
1588}

References Assert, len, MINIMAL_TUPLE_OFFSET, palloc(), HeapTupleData::t_data, HeapTupleData::t_len, and MinimalTupleData::t_len.

Referenced by copytup_heap(), tts_buffer_heap_copy_minimal_tuple(), and tts_heap_copy_minimal_tuple().

◆ missing_hash()

static uint32 missing_hash ( const void *  key,
Size  keysize 
)
static

Definition at line 104 of file heaptuple.c.

105{
106 const missing_cache_key *entry = (missing_cache_key *) key;
107
108 return hash_bytes((const unsigned char *) entry->value, entry->len);
109}
uint32 hash_bytes(const unsigned char *k, int keylen)
Definition: hashfn.c:146

References hash_bytes(), sort-test::key, missing_cache_key::len, and missing_cache_key::value.

Referenced by init_missing_cache().

◆ missing_match()

static int missing_match ( const void *  key1,
const void *  key2,
Size  keysize 
)
static

Definition at line 112 of file heaptuple.c.

113{
114 const missing_cache_key *entry1 = (missing_cache_key *) key1;
115 const missing_cache_key *entry2 = (missing_cache_key *) key2;
116
117 if (entry1->len != entry2->len)
118 return entry1->len > entry2->len ? 1 : -1;
119
120 return memcmp(DatumGetPointer(entry1->value),
121 DatumGetPointer(entry2->value),
122 entry1->len);
123}

References DatumGetPointer(), missing_cache_key::len, and missing_cache_key::value.

Referenced by init_missing_cache().

◆ nocachegetattr()

Datum nocachegetattr ( HeapTuple  tup,
int  attnum,
TupleDesc  tupleDesc 
)

Definition at line 521 of file heaptuple.c.

524{
525 HeapTupleHeader td = tup->t_data;
526 char *tp; /* ptr to data part of tuple */
527 bits8 *bp = td->t_bits; /* ptr to null bitmap in tuple */
528 bool slow = false; /* do we have to walk attrs? */
529 int off; /* current offset within data */
530
531 /* ----------------
532 * Three cases:
533 *
534 * 1: No nulls and no variable-width attributes.
535 * 2: Has a null or a var-width AFTER att.
536 * 3: Has nulls or var-widths BEFORE att.
537 * ----------------
538 */
539
540 attnum--;
541
542 if (!HeapTupleNoNulls(tup))
543 {
544 /*
545 * there's a null somewhere in the tuple
546 *
547 * check to see if any preceding bits are null...
548 */
549 int byte = attnum >> 3;
550 int finalbit = attnum & 0x07;
551
552 /* check for nulls "before" final bit of last byte */
553 if ((~bp[byte]) & ((1 << finalbit) - 1))
554 slow = true;
555 else
556 {
557 /* check for nulls in any "earlier" bytes */
558 int i;
559
560 for (i = 0; i < byte; i++)
561 {
562 if (bp[i] != 0xFF)
563 {
564 slow = true;
565 break;
566 }
567 }
568 }
569 }
570
571 tp = (char *) td + td->t_hoff;
572
573 if (!slow)
574 {
575 CompactAttribute *att;
576
577 /*
578 * If we get here, there are no nulls up to and including the target
579 * attribute. If we have a cached offset, we can use it.
580 */
581 att = TupleDescCompactAttr(tupleDesc, attnum);
582 if (att->attcacheoff >= 0)
583 return fetchatt(att, tp + att->attcacheoff);
584
585 /*
586 * Otherwise, check for non-fixed-length attrs up to and including
587 * target. If there aren't any, it's safe to cheaply initialize the
588 * cached offsets for these attrs.
589 */
590 if (HeapTupleHasVarWidth(tup))
591 {
592 int j;
593
594 for (j = 0; j <= attnum; j++)
595 {
596 if (TupleDescCompactAttr(tupleDesc, j)->attlen <= 0)
597 {
598 slow = true;
599 break;
600 }
601 }
602 }
603 }
604
605 if (!slow)
606 {
607 int natts = tupleDesc->natts;
608 int j = 1;
609
610 /*
611 * If we get here, we have a tuple with no nulls or var-widths up to
612 * and including the target attribute, so we can use the cached offset
613 * ... only we don't have it yet, or we'd not have got here. Since
614 * it's cheap to compute offsets for fixed-width columns, we take the
615 * opportunity to initialize the cached offsets for *all* the leading
616 * fixed-width columns, in hope of avoiding future visits to this
617 * routine.
618 */
619 TupleDescCompactAttr(tupleDesc, 0)->attcacheoff = 0;
620
621 /* we might have set some offsets in the slow path previously */
622 while (j < natts && TupleDescCompactAttr(tupleDesc, j)->attcacheoff > 0)
623 j++;
624
625 off = TupleDescCompactAttr(tupleDesc, j - 1)->attcacheoff +
626 TupleDescCompactAttr(tupleDesc, j - 1)->attlen;
627
628 for (; j < natts; j++)
629 {
630 CompactAttribute *att = TupleDescCompactAttr(tupleDesc, j);
631
632 if (att->attlen <= 0)
633 break;
634
635 off = att_nominal_alignby(off, att->attalignby);
636
637 att->attcacheoff = off;
638
639 off += att->attlen;
640 }
641
642 Assert(j > attnum);
643
644 off = TupleDescCompactAttr(tupleDesc, attnum)->attcacheoff;
645 }
646 else
647 {
648 bool usecache = true;
649 int i;
650
651 /*
652 * Now we know that we have to walk the tuple CAREFULLY. But we still
653 * might be able to cache some offsets for next time.
654 *
655 * Note - This loop is a little tricky. For each non-null attribute,
656 * we have to first account for alignment padding before the attr,
657 * then advance over the attr based on its length. Nulls have no
658 * storage and no alignment padding either. We can use/set
659 * attcacheoff until we reach either a null or a var-width attribute.
660 */
661 off = 0;
662 for (i = 0;; i++) /* loop exit is at "break" */
663 {
664 CompactAttribute *att = TupleDescCompactAttr(tupleDesc, i);
665
666 if (HeapTupleHasNulls(tup) && att_isnull(i, bp))
667 {
668 usecache = false;
669 continue; /* this cannot be the target att */
670 }
671
672 /* If we know the next offset, we can skip the rest */
673 if (usecache && att->attcacheoff >= 0)
674 off = att->attcacheoff;
675 else if (att->attlen == -1)
676 {
677 /*
678 * We can only cache the offset for a varlena attribute if the
679 * offset is already suitably aligned, so that there would be
680 * no pad bytes in any case: then the offset will be valid for
681 * either an aligned or unaligned value.
682 */
683 if (usecache &&
684 off == att_nominal_alignby(off, att->attalignby))
685 att->attcacheoff = off;
686 else
687 {
688 off = att_pointer_alignby(off, att->attalignby, -1,
689 tp + off);
690 usecache = false;
691 }
692 }
693 else
694 {
695 /* not varlena, so safe to use att_nominal_alignby */
696 off = att_nominal_alignby(off, att->attalignby);
697
698 if (usecache)
699 att->attcacheoff = off;
700 }
701
702 if (i == attnum)
703 break;
704
705 off = att_addlength_pointer(off, att->attlen, tp + off);
706
707 if (usecache && att->attlen <= 0)
708 usecache = false;
709 }
710 }
711
712 return fetchatt(TupleDescCompactAttr(tupleDesc, attnum), tp + off);
713}
#define HeapTupleHasVarWidth(tuple)
Definition: htup_details.h:665
int j
Definition: isn.c:73
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
int16 attlen
Definition: pg_attribute.h:59

References Assert, att_addlength_pointer, att_isnull(), att_nominal_alignby, att_pointer_alignby, CompactAttribute::attalignby, CompactAttribute::attcacheoff, CompactAttribute::attlen, attlen, attnum, fetchatt, HeapTupleHasNulls, HeapTupleHasVarWidth, HeapTupleNoNulls, i, if(), j, TupleDescData::natts, HeapTupleHeaderData::t_bits, HeapTupleData::t_data, HeapTupleHeaderData::t_hoff, and TupleDescCompactAttr().

Referenced by fastgetattr().

◆ varsize_any()

size_t varsize_any ( void *  p)

Definition at line 1595 of file heaptuple.c.

1596{
1597 return VARSIZE_ANY(p);
1598}

References VARSIZE_ANY.

Variable Documentation

◆ missing_cache

HTAB* missing_cache = NULL
static

Definition at line 101 of file heaptuple.c.

Referenced by getmissingattr(), and init_missing_cache().