PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
heaptuple.c File Reference
#include "postgres.h"
#include "access/sysattr.h"
#include "access/tuptoaster.h"
#include "executor/tuptable.h"
#include "utils/expandeddatum.h"
Include dependency graph for heaptuple.c:

Go to the source code of this file.

Macros

#define ATT_IS_PACKABLE(att)   ((att)->attlen == -1 && (att)->attstorage != 'p')
 
#define VARLENA_ATT_IS_PACKABLE(att)   ((att)->attstorage != 'p')
 

Functions

Size heap_compute_data_size (TupleDesc tupleDesc, Datum *values, bool *isnull)
 
void heap_fill_tuple (TupleDesc tupleDesc, Datum *values, bool *isnull, char *data, Size data_size, uint16 *infomask, bits8 *bit)
 
bool heap_attisnull (HeapTuple tup, int attnum)
 
Datum nocachegetattr (HeapTuple tuple, 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)
 
Datum heap_copy_tuple_as_datum (HeapTuple tuple, TupleDesc tupleDesc)
 
HeapTuple heap_form_tuple (TupleDesc tupleDescriptor, Datum *values, bool *isnull)
 
HeapTuple heap_modify_tuple (HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
 
HeapTuple heap_modify_tuple_by_cols (HeapTuple tuple, TupleDesc tupleDesc, int nCols, int *replCols, Datum *replValues, bool *replIsnull)
 
void heap_deform_tuple (HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
 
static void slot_deform_tuple (TupleTableSlot *slot, int natts)
 
Datum slot_getattr (TupleTableSlot *slot, int attnum, bool *isnull)
 
void slot_getallattrs (TupleTableSlot *slot)
 
void slot_getsomeattrs (TupleTableSlot *slot, int attnum)
 
bool slot_attisnull (TupleTableSlot *slot, int attnum)
 
void heap_freetuple (HeapTuple htup)
 
MinimalTuple heap_form_minimal_tuple (TupleDesc tupleDescriptor, Datum *values, 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)
 

Macro Definition Documentation

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

Definition at line 67 of file heaptuple.c.

Referenced by heap_compute_data_size().

#define VARLENA_ATT_IS_PACKABLE (   att)    ((att)->attstorage != 'p')

Definition at line 70 of file heaptuple.c.

Referenced by heap_fill_tuple().

Function Documentation

bool heap_attisnull ( HeapTuple  tup,
int  attnum 
)

Definition at line 297 of file heaptuple.c.

References att_isnull, elog, ERROR, HeapTupleHeaderGetNatts, HeapTupleNoNulls, MaxCommandIdAttributeNumber, MaxTransactionIdAttributeNumber, MinCommandIdAttributeNumber, MinTransactionIdAttributeNumber, ObjectIdAttributeNumber, SelfItemPointerAttributeNumber, HeapTupleHeaderData::t_bits, HeapTupleData::t_data, and TableOidAttributeNumber.

Referenced by AlterDomainNotNull(), ATRewriteTable(), build_function_result_tupdesc_t(), check_index_is_clusterable(), CheckIndexCompatible(), ExecEvalRowNullInt(), fmgr_info_cxt_security(), get_func_result_name(), index_drop(), inline_function(), inline_set_returning_function(), pg_attribute_aclcheck_all(), pg_get_indexdef_worker(), pg_get_partkeydef_worker(), RelationGetIndexExpressions(), RelationGetIndexList(), RelationGetIndexPredicate(), ri_NullCheck(), slot_attisnull(), statext_is_kind_built(), and transformFkeyCheckAttrs().

298 {
299  if (attnum > (int) HeapTupleHeaderGetNatts(tup->t_data))
300  return true;
301 
302  if (attnum > 0)
303  {
304  if (HeapTupleNoNulls(tup))
305  return false;
306  return att_isnull(attnum - 1, tup->t_data->t_bits);
307  }
308 
309  switch (attnum)
310  {
318  /* these are never null */
319  break;
320 
321  default:
322  elog(ERROR, "invalid attnum: %d", attnum);
323  }
324 
325  return false;
326 }
bits8 t_bits[FLEXIBLE_ARRAY_MEMBER]
Definition: htup_details.h:163
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
#define att_isnull(ATT, BITS)
Definition: tupmacs.h:21
#define MinCommandIdAttributeNumber
Definition: sysattr.h:24
HeapTupleHeader t_data
Definition: htup.h:67
#define ERROR
Definition: elog.h:43
#define HeapTupleHeaderGetNatts(tup)
Definition: htup_details.h:532
#define TableOidAttributeNumber
Definition: sysattr.h:27
#define HeapTupleNoNulls(tuple)
Definition: htup_details.h:665
#define MaxCommandIdAttributeNumber
Definition: sysattr.h:26
#define MaxTransactionIdAttributeNumber
Definition: sysattr.h:25
#define SelfItemPointerAttributeNumber
Definition: sysattr.h:21
#define elog
Definition: elog.h:219
#define MinTransactionIdAttributeNumber
Definition: sysattr.h:23
Size heap_compute_data_size ( TupleDesc  tupleDesc,
Datum values,
bool isnull 
)

Definition at line 85 of file heaptuple.c.

References att_addlength_datum, att_align_datum, att_align_nominal, ATT_IS_PACKABLE, tupleDesc::attrs, DatumGetEOHP(), DatumGetPointer, EOH_get_flat_size(), i, tupleDesc::natts, val, VARATT_CAN_MAKE_SHORT, VARATT_CONVERTED_SHORT_SIZE, and VARATT_IS_EXTERNAL_EXPANDED.

Referenced by brin_form_tuple(), heap_form_minimal_tuple(), heap_form_tuple(), index_form_tuple(), toast_flatten_tuple_to_datum(), and toast_insert_or_update().

88 {
89  Size data_length = 0;
90  int i;
91  int numberOfAttributes = tupleDesc->natts;
92  Form_pg_attribute *att = tupleDesc->attrs;
93 
94  for (i = 0; i < numberOfAttributes; i++)
95  {
96  Datum val;
97  Form_pg_attribute atti;
98 
99  if (isnull[i])
100  continue;
101 
102  val = values[i];
103  atti = att[i];
104 
105  if (ATT_IS_PACKABLE(atti) &&
107  {
108  /*
109  * we're anticipating converting to a short varlena header, so
110  * adjust length and don't count any alignment
111  */
112  data_length += VARATT_CONVERTED_SHORT_SIZE(DatumGetPointer(val));
113  }
114  else if (atti->attlen == -1 &&
116  {
117  /*
118  * we want to flatten the expanded value so that the constructed
119  * tuple doesn't depend on it
120  */
121  data_length = att_align_nominal(data_length, atti->attalign);
122  data_length += EOH_get_flat_size(DatumGetEOHP(val));
123  }
124  else
125  {
126  data_length = att_align_datum(data_length, atti->attalign,
127  atti->attlen, val);
128  data_length = att_addlength_datum(data_length, atti->attlen,
129  val);
130  }
131  }
132 
133  return data_length;
134 }
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:144
#define VARATT_IS_EXTERNAL_EXPANDED(PTR)
Definition: postgres.h:323
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int natts
Definition: tupdesc.h:73
#define att_align_datum(cur_offset, attalign, attlen, attdatum)
Definition: tupmacs.h:101
#define VARATT_CAN_MAKE_SHORT(PTR)
Definition: postgres.h:271
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
Size EOH_get_flat_size(ExpandedObjectHeader *eohptr)
Definition: expandeddatum.c:75
ExpandedObjectHeader * DatumGetEOHP(Datum d)
Definition: expandeddatum.c:29
#define VARATT_CONVERTED_SHORT_SIZE(PTR)
Definition: postgres.h:274
uintptr_t Datum
Definition: postgres.h:372
size_t Size
Definition: c.h:356
#define DatumGetPointer(X)
Definition: postgres.h:555
static Datum values[MAXATTR]
Definition: bootstrap.c:163
#define att_addlength_datum(cur_offset, attlen, attdatum)
Definition: tupmacs.h:160
#define ATT_IS_PACKABLE(att)
Definition: heaptuple.c:67
int i
long val
Definition: informix.c:689
MinimalTuple heap_copy_minimal_tuple ( MinimalTuple  mtup)

Definition at line 1479 of file heaptuple.c.

References palloc(), result, and MinimalTupleData::t_len.

Referenced by ExecCopySlotMinimalTuple(), tuplesort_gettupleslot(), and tuplestore_gettupleslot().

1480 {
1482 
1483  result = (MinimalTuple) palloc(mtup->t_len);
1484  memcpy(result, mtup, mtup->t_len);
1485  return result;
1486 }
return result
Definition: formatting.c:1633
MinimalTupleData * MinimalTuple
Definition: htup.h:27
void * palloc(Size size)
Definition: mcxt.c:849
Datum heap_copy_tuple_as_datum ( HeapTuple  tuple,
TupleDesc  tupleDesc 
)

Definition at line 656 of file heaptuple.c.

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

Referenced by exec_eval_datum(), ExecEvalConvertRowtype(), ExecFetchSlotTupleDatum(), PLyGenericObject_ToComposite(), PLyMapping_ToComposite(), PLySequence_ToComposite(), and SPI_returntuple().

657 {
658  HeapTupleHeader td;
659 
660  /*
661  * If the tuple contains any external TOAST pointers, we have to inline
662  * those fields to meet the conventions for composite-type Datums.
663  */
664  if (HeapTupleHasExternal(tuple))
665  return toast_flatten_tuple_to_datum(tuple->t_data,
666  tuple->t_len,
667  tupleDesc);
668 
669  /*
670  * Fast path for easy case: just make a palloc'd copy and insert the
671  * correct composite-Datum header fields (since those may not be set if
672  * the given tuple came from disk, rather than from heap_form_tuple).
673  */
674  td = (HeapTupleHeader) palloc(tuple->t_len);
675  memcpy((char *) td, (char *) tuple->t_data, tuple->t_len);
676 
678  HeapTupleHeaderSetTypeId(td, tupleDesc->tdtypeid);
679  HeapTupleHeaderSetTypMod(td, tupleDesc->tdtypmod);
680 
681  return PointerGetDatum(td);
682 }
Oid tdtypeid
Definition: tupdesc.h:77
#define HeapTupleHeaderSetTypeId(tup, typeid)
Definition: htup_details.h:450
#define PointerGetDatum(X)
Definition: postgres.h:562
HeapTupleHeaderData * HeapTupleHeader
Definition: htup.h:23
int32 tdtypmod
Definition: tupdesc.h:78
#define HeapTupleHeaderSetDatumLength(tup, len)
Definition: htup_details.h:442
HeapTupleHeader t_data
Definition: htup.h:67
uint32 t_len
Definition: htup.h:64
Datum toast_flatten_tuple_to_datum(HeapTupleHeader tup, uint32 tup_len, TupleDesc tupleDesc)
Definition: tuptoaster.c:1187
#define HeapTupleHeaderSetTypMod(tup, typmod)
Definition: htup_details.h:460
#define HeapTupleHasExternal(tuple)
Definition: htup_details.h:674
void * palloc(Size size)
Definition: mcxt.c:849
HeapTuple heap_copytuple ( HeapTuple  tuple)

Definition at line 608 of file heaptuple.c.

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

Referenced by acquire_sample_rows(), AlterConstraintNamespaces(), AlterDomainValidateConstraint(), AlterExtensionNamespace(), AlterSequence(), AlterTypeOwner(), ATExecAlterConstraint(), ATExecDropConstraint(), ATExecValidateConstraint(), changeDependencyFor(), copytup_cluster(), EnableDisableTrigger(), EvalPlanQualFetch(), EvalPlanQualFetchRowMarks(), exec_move_row(), ExecCopySlotTuple(), ExecLockRows(), form_tuple_array(), gather_merge_readnext(), get_catalog_object_by_oid(), get_tuple_from_datum(), GetDatabaseTuple(), GetDatabaseTupleByOid(), GetTupleForTrigger(), index_update_stats(), MergeConstraintsIntoExisting(), MergeWithExistingConstraint(), RelationInitIndexAccessInfo(), RemoveInheritance(), rename_policy(), RenameEnumLabel(), RenameTableSpace(), renametrig(), RenumberEnumType(), reorderqueue_push(), ResetSequence(), rewrite_heap_tuple(), ScanPgRelation(), SearchSysCacheCopy(), SearchSysCacheCopyAttName(), shdepChangeDep(), SPI_copytuple(), and TQRemapTuple().

609 {
610  HeapTuple newTuple;
611 
612  if (!HeapTupleIsValid(tuple) || tuple->t_data == NULL)
613  return NULL;
614 
615  newTuple = (HeapTuple) palloc(HEAPTUPLESIZE + tuple->t_len);
616  newTuple->t_len = tuple->t_len;
617  newTuple->t_self = tuple->t_self;
618  newTuple->t_tableOid = tuple->t_tableOid;
619  newTuple->t_data = (HeapTupleHeader) ((char *) newTuple + HEAPTUPLESIZE);
620  memcpy((char *) newTuple->t_data, (char *) tuple->t_data, tuple->t_len);
621  return newTuple;
622 }
HeapTupleData * HeapTuple
Definition: htup.h:70
HeapTupleHeaderData * HeapTupleHeader
Definition: htup.h:23
HeapTupleHeader t_data
Definition: htup.h:67
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
Oid t_tableOid
Definition: htup.h:66
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
void * palloc(Size size)
Definition: mcxt.c:849
#define HEAPTUPLESIZE
Definition: htup.h:72
void heap_copytuple_with_tuple ( HeapTuple  src,
HeapTuple  dest 
)

Definition at line 634 of file heaptuple.c.

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

Referenced by CatalogCacheCreateEntry(), and SearchCatCacheList().

635 {
636  if (!HeapTupleIsValid(src) || src->t_data == NULL)
637  {
638  dest->t_data = NULL;
639  return;
640  }
641 
642  dest->t_len = src->t_len;
643  dest->t_self = src->t_self;
644  dest->t_tableOid = src->t_tableOid;
645  dest->t_data = (HeapTupleHeader) palloc(src->t_len);
646  memcpy((char *) dest->t_data, (char *) src->t_data, src->t_len);
647 }
HeapTupleHeaderData * HeapTupleHeader
Definition: htup.h:23
HeapTupleHeader t_data
Definition: htup.h:67
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
Oid t_tableOid
Definition: htup.h:66
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
void * palloc(Size size)
Definition: mcxt.c:849
void heap_deform_tuple ( HeapTuple  tuple,
TupleDesc  tupleDesc,
Datum values,
bool isnull 
)

Definition at line 933 of file heaptuple.c.

References att_addlength_pointer, att_align_nominal, att_align_pointer, att_isnull, tupleDesc::attrs, fetchatt, HeapTupleHasNulls, HeapTupleHeaderGetNatts, Min, tupleDesc::natts, HeapTupleHeaderData::t_bits, HeapTupleData::t_data, and HeapTupleHeaderData::t_hoff.

Referenced by ATRewriteTable(), CopyTo(), do_convert_tuple(), ExecEvalFieldStoreDeForm(), ExtractReplicaIdentity(), heap_modify_tuple(), heap_modify_tuple_by_cols(), hstore_from_record(), hstore_populate_record(), logicalrep_write_tuple(), make_tuple_indirect(), populate_record(), record_cmp(), record_eq(), record_image_cmp(), record_image_eq(), record_out(), record_send(), reform_and_rewrite_tuple(), ReorderBufferToastReplace(), SPI_modifytuple(), toast_delete(), toast_flatten_tuple(), toast_flatten_tuple_to_datum(), toast_insert_or_update(), TQExamineRecord(), TQRemapTuple(), and tuple_equals_slot().

935 {
936  HeapTupleHeader tup = tuple->t_data;
937  bool hasnulls = HeapTupleHasNulls(tuple);
938  Form_pg_attribute *att = tupleDesc->attrs;
939  int tdesc_natts = tupleDesc->natts;
940  int natts; /* number of atts to extract */
941  int attnum;
942  char *tp; /* ptr to tuple data */
943  long off; /* offset in tuple data */
944  bits8 *bp = tup->t_bits; /* ptr to null bitmap in tuple */
945  bool slow = false; /* can we use/set attcacheoff? */
946 
947  natts = HeapTupleHeaderGetNatts(tup);
948 
949  /*
950  * In inheritance situations, it is possible that the given tuple actually
951  * has more fields than the caller is expecting. Don't run off the end of
952  * the caller's arrays.
953  */
954  natts = Min(natts, tdesc_natts);
955 
956  tp = (char *) tup + tup->t_hoff;
957 
958  off = 0;
959 
960  for (attnum = 0; attnum < natts; attnum++)
961  {
962  Form_pg_attribute thisatt = att[attnum];
963 
964  if (hasnulls && att_isnull(attnum, bp))
965  {
966  values[attnum] = (Datum) 0;
967  isnull[attnum] = true;
968  slow = true; /* can't use attcacheoff anymore */
969  continue;
970  }
971 
972  isnull[attnum] = false;
973 
974  if (!slow && thisatt->attcacheoff >= 0)
975  off = thisatt->attcacheoff;
976  else if (thisatt->attlen == -1)
977  {
978  /*
979  * We can only cache the offset for a varlena attribute if the
980  * offset is already suitably aligned, so that there would be no
981  * pad bytes in any case: then the offset will be valid for either
982  * an aligned or unaligned value.
983  */
984  if (!slow &&
985  off == att_align_nominal(off, thisatt->attalign))
986  thisatt->attcacheoff = off;
987  else
988  {
989  off = att_align_pointer(off, thisatt->attalign, -1,
990  tp + off);
991  slow = true;
992  }
993  }
994  else
995  {
996  /* not varlena, so safe to use att_align_nominal */
997  off = att_align_nominal(off, thisatt->attalign);
998 
999  if (!slow)
1000  thisatt->attcacheoff = off;
1001  }
1002 
1003  values[attnum] = fetchatt(thisatt, tp + off);
1004 
1005  off = att_addlength_pointer(off, thisatt->attlen, tp + off);
1006 
1007  if (thisatt->attlen <= 0)
1008  slow = true; /* can't use attcacheoff anymore */
1009  }
1010 
1011  /*
1012  * If tuple doesn't have all the atts indicated by tupleDesc, read the
1013  * rest as null
1014  */
1015  for (; attnum < tdesc_natts; attnum++)
1016  {
1017  values[attnum] = (Datum) 0;
1018  isnull[attnum] = true;
1019  }
1020 }
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:144
bits8 t_bits[FLEXIBLE_ARRAY_MEMBER]
Definition: htup_details.h:163
#define att_isnull(ATT, BITS)
Definition: tupmacs.h:21
#define Min(x, y)
Definition: c.h:806
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int natts
Definition: tupdesc.h:73
#define fetchatt(A, T)
Definition: tupmacs.h:37
HeapTupleHeader t_data
Definition: htup.h:67
#define HeapTupleHeaderGetNatts(tup)
Definition: htup_details.h:532
#define HeapTupleHasNulls(tuple)
Definition: htup_details.h:662
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:172
uint8 bits8
Definition: c.h:275
uintptr_t Datum
Definition: postgres.h:372
#define att_align_pointer(cur_offset, attalign, attlen, attptr)
Definition: tupmacs.h:122
static Datum values[MAXATTR]
Definition: bootstrap.c:163
void heap_fill_tuple ( TupleDesc  tupleDesc,
Datum values,
bool isnull,
char *  data,
Size  data_size,
uint16 infomask,
bits8 bit 
)

Definition at line 146 of file heaptuple.c.

References Assert, att_align_nominal, tupleDesc::attrs, DatumGetCString, DatumGetEOHP(), DatumGetPointer, EOH_flatten_into(), EOH_get_flat_size(), HEAP_HASEXTERNAL, HEAP_HASNULL, HEAP_HASVARWIDTH, HIGHBIT, i, tupleDesc::natts, NULL, 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, VARLENA_ATT_IS_PACKABLE, VARSIZE, VARSIZE_EXTERNAL, and VARSIZE_SHORT.

Referenced by brin_form_tuple(), heap_form_minimal_tuple(), heap_form_tuple(), index_form_tuple(), toast_flatten_tuple_to_datum(), and toast_insert_or_update().

150 {
151  bits8 *bitP;
152  int bitmask;
153  int i;
154  int numberOfAttributes = tupleDesc->natts;
155  Form_pg_attribute *att = tupleDesc->attrs;
156 
157 #ifdef USE_ASSERT_CHECKING
158  char *start = data;
159 #endif
160 
161  if (bit != NULL)
162  {
163  bitP = &bit[-1];
164  bitmask = HIGHBIT;
165  }
166  else
167  {
168  /* just to keep compiler quiet */
169  bitP = NULL;
170  bitmask = 0;
171  }
172 
173  *infomask &= ~(HEAP_HASNULL | HEAP_HASVARWIDTH | HEAP_HASEXTERNAL);
174 
175  for (i = 0; i < numberOfAttributes; i++)
176  {
177  Size data_length;
178 
179  if (bit != NULL)
180  {
181  if (bitmask != HIGHBIT)
182  bitmask <<= 1;
183  else
184  {
185  bitP += 1;
186  *bitP = 0x0;
187  bitmask = 1;
188  }
189 
190  if (isnull[i])
191  {
192  *infomask |= HEAP_HASNULL;
193  continue;
194  }
195 
196  *bitP |= bitmask;
197  }
198 
199  /*
200  * XXX we use the att_align macros on the pointer value itself, not on
201  * an offset. This is a bit of a hack.
202  */
203 
204  if (att[i]->attbyval)
205  {
206  /* pass-by-value */
207  data = (char *) att_align_nominal(data, att[i]->attalign);
208  store_att_byval(data, values[i], att[i]->attlen);
209  data_length = att[i]->attlen;
210  }
211  else if (att[i]->attlen == -1)
212  {
213  /* varlena */
215 
216  *infomask |= HEAP_HASVARWIDTH;
217  if (VARATT_IS_EXTERNAL(val))
218  {
220  {
221  /*
222  * we want to flatten the expanded value so that the
223  * constructed tuple doesn't depend on it
224  */
226 
227  data = (char *) att_align_nominal(data,
228  att[i]->attalign);
229  data_length = EOH_get_flat_size(eoh);
230  EOH_flatten_into(eoh, data, data_length);
231  }
232  else
233  {
234  *infomask |= HEAP_HASEXTERNAL;
235  /* no alignment, since it's short by definition */
236  data_length = VARSIZE_EXTERNAL(val);
237  memcpy(data, val, data_length);
238  }
239  }
240  else if (VARATT_IS_SHORT(val))
241  {
242  /* no alignment for short varlenas */
243  data_length = VARSIZE_SHORT(val);
244  memcpy(data, val, data_length);
245  }
246  else if (VARLENA_ATT_IS_PACKABLE(att[i]) &&
248  {
249  /* convert to short varlena -- no alignment */
250  data_length = VARATT_CONVERTED_SHORT_SIZE(val);
251  SET_VARSIZE_SHORT(data, data_length);
252  memcpy(data + 1, VARDATA(val), data_length - 1);
253  }
254  else
255  {
256  /* full 4-byte header varlena */
257  data = (char *) att_align_nominal(data,
258  att[i]->attalign);
259  data_length = VARSIZE(val);
260  memcpy(data, val, data_length);
261  }
262  }
263  else if (att[i]->attlen == -2)
264  {
265  /* cstring ... never needs alignment */
266  *infomask |= HEAP_HASVARWIDTH;
267  Assert(att[i]->attalign == 'c');
268  data_length = strlen(DatumGetCString(values[i])) + 1;
269  memcpy(data, DatumGetPointer(values[i]), data_length);
270  }
271  else
272  {
273  /* fixed-length pass-by-reference */
274  data = (char *) att_align_nominal(data, att[i]->attalign);
275  Assert(att[i]->attlen > 0);
276  data_length = att[i]->attlen;
277  memcpy(data, DatumGetPointer(values[i]), data_length);
278  }
279 
280  data += data_length;
281  }
282 
283  Assert((data - start) == data_size);
284 }
#define SET_VARSIZE_SHORT(PTR, len)
Definition: postgres.h:329
#define VARDATA(PTR)
Definition: postgres.h:303
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:144
#define VARATT_IS_EXTERNAL_EXPANDED(PTR)
Definition: postgres.h:323
#define VARSIZE(PTR)
Definition: postgres.h:304
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int natts
Definition: tupdesc.h:73
#define VARATT_IS_EXTERNAL(PTR)
Definition: postgres.h:314
char * Pointer
Definition: c.h:245
#define HEAP_HASNULL
Definition: htup_details.h:175
#define DatumGetCString(X)
Definition: postgres.h:572
#define VARATT_IS_SHORT(PTR)
Definition: postgres.h:325
#define VARATT_CAN_MAKE_SHORT(PTR)
Definition: postgres.h:271
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
Size EOH_get_flat_size(ExpandedObjectHeader *eohptr)
Definition: expandeddatum.c:75
#define HEAP_HASVARWIDTH
Definition: htup_details.h:176
#define HIGHBIT
Definition: c.h:972
#define VARSIZE_SHORT(PTR)
Definition: postgres.h:306
ExpandedObjectHeader * DatumGetEOHP(Datum d)
Definition: expandeddatum.c:29
#define VARATT_CONVERTED_SHORT_SIZE(PTR)
Definition: postgres.h:274
#define store_att_byval(T, newdatum, attlen)
Definition: tupmacs.h:222
uint8 bits8
Definition: c.h:275
#define VARLENA_ATT_IS_PACKABLE(att)
Definition: heaptuple.c:70
void EOH_flatten_into(ExpandedObjectHeader *eohptr, void *result, Size allocated_size)
Definition: expandeddatum.c:81
#define NULL
Definition: c.h:229
Datum bit(PG_FUNCTION_ARGS)
Definition: varbit.c:361
#define Assert(condition)
Definition: c.h:675
size_t Size
Definition: c.h:356
#define DatumGetPointer(X)
Definition: postgres.h:555
static Datum values[MAXATTR]
Definition: bootstrap.c:163
int i
#define HEAP_HASEXTERNAL
Definition: htup_details.h:177
long val
Definition: informix.c:689
#define VARSIZE_EXTERNAL(PTR)
Definition: postgres.h:310
MinimalTuple heap_form_minimal_tuple ( TupleDesc  tupleDescriptor,
Datum values,
bool isnull 
)

Definition at line 1390 of file heaptuple.c.

References BITMAPLEN, ereport, errcode(), errmsg(), ERROR, heap_compute_data_size(), heap_fill_tuple(), HEAP_HASOID, HeapTupleHeaderSetNatts, i, MAXALIGN, MaxTupleAttributeNumber, MINIMAL_TUPLE_OFFSET, tupleDesc::natts, NULL, palloc0(), SizeofMinimalTupleHeader, MinimalTupleData::t_bits, MinimalTupleData::t_hoff, MinimalTupleData::t_infomask, MinimalTupleData::t_len, and tupleDesc::tdhasoid.

Referenced by ExecCopySlotMinimalTuple(), and tuplestore_putvalues().

1393 {
1394  MinimalTuple tuple; /* return tuple */
1395  Size len,
1396  data_len;
1397  int hoff;
1398  bool hasnull = false;
1399  int numberOfAttributes = tupleDescriptor->natts;
1400  int i;
1401 
1402  if (numberOfAttributes > MaxTupleAttributeNumber)
1403  ereport(ERROR,
1404  (errcode(ERRCODE_TOO_MANY_COLUMNS),
1405  errmsg("number of columns (%d) exceeds limit (%d)",
1406  numberOfAttributes, MaxTupleAttributeNumber)));
1407 
1408  /*
1409  * Check for nulls
1410  */
1411  for (i = 0; i < numberOfAttributes; i++)
1412  {
1413  if (isnull[i])
1414  {
1415  hasnull = true;
1416  break;
1417  }
1418  }
1419 
1420  /*
1421  * Determine total space needed
1422  */
1424 
1425  if (hasnull)
1426  len += BITMAPLEN(numberOfAttributes);
1427 
1428  if (tupleDescriptor->tdhasoid)
1429  len += sizeof(Oid);
1430 
1431  hoff = len = MAXALIGN(len); /* align user data safely */
1432 
1433  data_len = heap_compute_data_size(tupleDescriptor, values, isnull);
1434 
1435  len += data_len;
1436 
1437  /*
1438  * Allocate and zero the space needed.
1439  */
1440  tuple = (MinimalTuple) palloc0(len);
1441 
1442  /*
1443  * And fill in the information.
1444  */
1445  tuple->t_len = len;
1446  HeapTupleHeaderSetNatts(tuple, numberOfAttributes);
1447  tuple->t_hoff = hoff + MINIMAL_TUPLE_OFFSET;
1448 
1449  if (tupleDescriptor->tdhasoid) /* else leave infomask = 0 */
1450  tuple->t_infomask = HEAP_HASOID;
1451 
1452  heap_fill_tuple(tupleDescriptor,
1453  values,
1454  isnull,
1455  (char *) tuple + hoff,
1456  data_len,
1457  &tuple->t_infomask,
1458  (hasnull ? tuple->t_bits : NULL));
1459 
1460  return tuple;
1461 }
void heap_fill_tuple(TupleDesc tupleDesc, Datum *values, bool *isnull, char *data, Size data_size, uint16 *infomask, bits8 *bit)
Definition: heaptuple.c:146
bool tdhasoid
Definition: tupdesc.h:79
#define MaxTupleAttributeNumber
Definition: htup_details.h:33
int errcode(int sqlerrcode)
Definition: elog.c:575
#define BITMAPLEN(NATTS)
Definition: htup_details.h:548
unsigned int Oid
Definition: postgres_ext.h:31
int natts
Definition: tupdesc.h:73
bits8 t_bits[FLEXIBLE_ARRAY_MEMBER]
Definition: htup_details.h:643
#define ERROR
Definition: elog.h:43
MinimalTupleData * MinimalTuple
Definition: htup.h:27
#define ereport(elevel, rest)
Definition: elog.h:122
#define SizeofMinimalTupleHeader
Definition: htup_details.h:650
void * palloc0(Size size)
Definition: mcxt.c:878
#define NULL
Definition: c.h:229
#define HeapTupleHeaderSetNatts(tup, natts)
Definition: htup_details.h:535
size_t Size
Definition: c.h:356
#define MAXALIGN(LEN)
Definition: c.h:588
#define MINIMAL_TUPLE_OFFSET
Definition: htup_details.h:620
Size heap_compute_data_size(TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:85
static Datum values[MAXATTR]
Definition: bootstrap.c:163
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define HEAP_HASOID
Definition: htup_details.h:178
HeapTuple heap_form_tuple ( TupleDesc  tupleDescriptor,
Datum values,
bool isnull 
)

Definition at line 692 of file heaptuple.c.

References BITMAPLEN, ereport, errcode(), errmsg(), ERROR, heap_compute_data_size(), heap_fill_tuple(), HEAP_HASOID, HeapTupleHeaderSetDatumLength, HeapTupleHeaderSetNatts, HeapTupleHeaderSetTypeId, HeapTupleHeaderSetTypMod, HEAPTUPLESIZE, i, InvalidOid, ItemPointerSetInvalid, MAXALIGN, MaxTupleAttributeNumber, tupleDesc::natts, NULL, offsetof, 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, tupleDesc::tdhasoid, tupleDesc::tdtypeid, and tupleDesc::tdtypmod.

Referenced by aclexplode(), AddEnumLabel(), AddRoleMems(), AggregateCreate(), AlterSetting(), ATRewriteTable(), brin_metapage_info(), build_dummy_tuple(), BuildTupleFromCStrings(), CollationCreate(), ConversionCreate(), CopyFrom(), create_proc_lang(), CreateAccessMethod(), CreateCast(), CreateComments(), CreateConstraintEntry(), createdb(), CreateForeignDataWrapper(), CreateForeignServer(), CreateForeignTable(), CreateOpFamily(), CreatePolicy(), CreatePublication(), CreateRole(), CreateSharedComments(), CreateStatistics(), CreateSubscription(), CreateTableSpace(), CreateTransform(), CreateTrigger(), CreateUserMapping(), DefineOpClass(), DefineSequence(), DefineTSConfiguration(), DefineTSDictionary(), DefineTSParser(), DefineTSTemplate(), do_convert_tuple(), each_object_field_end(), each_worker_jsonb(), elements_array_element_end(), elements_worker_jsonb(), EnumValuesCreate(), exec_move_row(), ExecCopySlotTuple(), ExecEvalFieldStoreForm(), ExecEvalRow(), ExtractReplicaIdentity(), file_acquire_sample_rows(), fill_hba_line(), gin_leafpage_items(), gin_metapage_info(), gin_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(), hstore_each(), hstore_populate_record(), insert_event_trigger_tuple(), InsertExtensionTuple(), InsertOneTuple(), InsertPgAttributeTuple(), InsertPgClassTuple(), InsertRule(), inv_truncate(), inv_write(), LargeObjectCreate(), make_tuple_from_result_row(), make_tuple_from_row(), make_tuple_indirect(), MakeConfigurationMapping(), NamespaceCreate(), OperatorCreate(), OperatorShellMake(), page_header(), pg_buffercache_pages(), pg_control_checkpoint(), pg_control_init(), pg_control_recovery(), pg_control_system(), pg_create_logical_replication_slot(), pg_create_physical_replication_slot(), pg_get_object_address(), pg_identify_object(), pg_identify_object_as_address(), pg_last_committed_xact(), pg_lock_status(), pg_ls_dir_files(), pg_prepared_xact(), pg_sequence_parameters(), pg_stat_file(), pg_stat_get_archiver(), pg_stat_get_wal_receiver(), pg_timezone_abbrevs(), pg_timezone_names(), pg_visibility(), pg_visibility_map(), pg_visibility_map_rel(), pg_visibility_map_summary(), pg_visibility_rel(), pg_walfile_name_offset(), pgstatginindex_internal(), pgstathashindex(), pgstattuple_approx_internal(), plperl_build_tuple_result(), PLyGenericObject_ToComposite(), PLyMapping_ToComposite(), PLySequence_ToComposite(), populate_record(), ProcedureCreate(), publication_add_relation(), RangeCreate(), record_in(), record_recv(), recordExtensionInitPrivWorker(), recordMultipleDependencies(), reform_and_rewrite_tuple(), ReorderBufferToastReplace(), replorigin_create(), SetDefaultACL(), SetSecurityLabel(), SetSharedSecurityLabel(), SetSubscriptionRelState(), shdepAddDependency(), shdepChangeDep(), SPI_modifytuple(), ssl_extension_info(), StoreAttrDefault(), StoreCatalogInheritance1(), storeGettuple(), storeOperators(), StorePartitionKey(), storeProcedures(), toast_build_flattened_tuple(), toast_flatten_tuple(), toast_save_datum(), TQRemapTuple(), tsvector_unnest(), TypeCreate(), TypeShellMake(), update_attstats(), and UpdateIndexRelation().

695 {
696  HeapTuple tuple; /* return tuple */
697  HeapTupleHeader td; /* tuple data */
698  Size len,
699  data_len;
700  int hoff;
701  bool hasnull = false;
702  int numberOfAttributes = tupleDescriptor->natts;
703  int i;
704 
705  if (numberOfAttributes > MaxTupleAttributeNumber)
706  ereport(ERROR,
707  (errcode(ERRCODE_TOO_MANY_COLUMNS),
708  errmsg("number of columns (%d) exceeds limit (%d)",
709  numberOfAttributes, MaxTupleAttributeNumber)));
710 
711  /*
712  * Check for nulls
713  */
714  for (i = 0; i < numberOfAttributes; i++)
715  {
716  if (isnull[i])
717  {
718  hasnull = true;
719  break;
720  }
721  }
722 
723  /*
724  * Determine total space needed
725  */
726  len = offsetof(HeapTupleHeaderData, t_bits);
727 
728  if (hasnull)
729  len += BITMAPLEN(numberOfAttributes);
730 
731  if (tupleDescriptor->tdhasoid)
732  len += sizeof(Oid);
733 
734  hoff = len = MAXALIGN(len); /* align user data safely */
735 
736  data_len = heap_compute_data_size(tupleDescriptor, values, isnull);
737 
738  len += data_len;
739 
740  /*
741  * Allocate and zero the space needed. Note that the tuple body and
742  * HeapTupleData management structure are allocated in one chunk.
743  */
744  tuple = (HeapTuple) palloc0(HEAPTUPLESIZE + len);
745  tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
746 
747  /*
748  * And fill in the information. Note we fill the Datum fields even though
749  * this tuple may never become a Datum. This lets HeapTupleHeaderGetDatum
750  * identify the tuple type if needed.
751  */
752  tuple->t_len = len;
753  ItemPointerSetInvalid(&(tuple->t_self));
754  tuple->t_tableOid = InvalidOid;
755 
757  HeapTupleHeaderSetTypeId(td, tupleDescriptor->tdtypeid);
758  HeapTupleHeaderSetTypMod(td, tupleDescriptor->tdtypmod);
759  /* We also make sure that t_ctid is invalid unless explicitly set */
761 
762  HeapTupleHeaderSetNatts(td, numberOfAttributes);
763  td->t_hoff = hoff;
764 
765  if (tupleDescriptor->tdhasoid) /* else leave infomask = 0 */
766  td->t_infomask = HEAP_HASOID;
767 
768  heap_fill_tuple(tupleDescriptor,
769  values,
770  isnull,
771  (char *) td + hoff,
772  data_len,
773  &td->t_infomask,
774  (hasnull ? td->t_bits : NULL));
775 
776  return tuple;
777 }
void heap_fill_tuple(TupleDesc tupleDesc, Datum *values, bool *isnull, char *data, Size data_size, uint16 *infomask, bits8 *bit)
Definition: heaptuple.c:146
HeapTupleData * HeapTuple
Definition: htup.h:70
Oid tdtypeid
Definition: tupdesc.h:77
#define HeapTupleHeaderSetTypeId(tup, typeid)
Definition: htup_details.h:450
bool tdhasoid
Definition: tupdesc.h:79
bits8 t_bits[FLEXIBLE_ARRAY_MEMBER]
Definition: htup_details.h:163
#define MaxTupleAttributeNumber
Definition: htup_details.h:33
HeapTupleHeaderData * HeapTupleHeader
Definition: htup.h:23
int errcode(int sqlerrcode)
Definition: elog.c:575
#define BITMAPLEN(NATTS)
Definition: htup_details.h:548
unsigned int Oid
Definition: postgres_ext.h:31
int natts
Definition: tupdesc.h:73
int32 tdtypmod
Definition: tupdesc.h:78
#define HeapTupleHeaderSetDatumLength(tup, len)
Definition: htup_details.h:442
HeapTupleHeader t_data
Definition: htup.h:67
#define ERROR
Definition: elog.h:43
ItemPointerData t_ctid
Definition: htup_details.h:150
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
Oid t_tableOid
Definition: htup.h:66
#define ereport(elevel, rest)
Definition: elog.h:122
void * palloc0(Size size)
Definition: mcxt.c:878
#define HeapTupleHeaderSetTypMod(tup, typmod)
Definition: htup_details.h:460
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
#define HeapTupleHeaderSetNatts(tup, natts)
Definition: htup_details.h:535
size_t Size
Definition: c.h:356
#define MAXALIGN(LEN)
Definition: c.h:588
Size heap_compute_data_size(TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:85
static Datum values[MAXATTR]
Definition: bootstrap.c:163
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:150
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define HEAPTUPLESIZE
Definition: htup.h:72
int i
#define HEAP_HASOID
Definition: htup_details.h:178
#define offsetof(type, field)
Definition: c.h:555
void heap_free_minimal_tuple ( MinimalTuple  mtup)

Definition at line 1467 of file heaptuple.c.

References pfree().

Referenced by ExecClearTuple(), ExecStoreMinimalTuple(), ExecStoreTuple(), and writetup_heap().

1468 {
1469  pfree(mtup);
1470 }
void pfree(void *pointer)
Definition: mcxt.c:950
void heap_freetuple ( HeapTuple  htup)

Definition at line 1372 of file heaptuple.c.

References pfree().

Referenced by acquire_inherited_sample_rows(), acquire_sample_rows(), AddEnumLabel(), AfterTriggerExecute(), AlterCollation(), AlterDatabaseOwner(), 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(), AlterSubscription(), AlterSubscriptionOwner(), AlterSubscriptionOwner_oid(), AlterTableSpaceOptions(), AlterTSDictionary(), AlterTypeNamespaceInternal(), AlterUserMapping(), analyze_row_processor(), ATExecAddColumn(), ATExecAddIdentity(), ATExecAddOf(), ATExecAlterColumnGenericOptions(), ATExecAlterColumnType(), ATExecAlterConstraint(), ATExecChangeOwner(), ATExecDetachPartition(), ATExecDisableRowSecurity(), ATExecDropColumn(), ATExecDropConstraint(), ATExecDropIdentity(), ATExecDropOf(), ATExecEnableRowSecurity(), ATExecForceNoForceRowSecurity(), ATExecGenericOptions(), ATExecSetIdentity(), ATExecSetOptions(), ATExecSetRelOptions(), ATExecSetStatistics(), ATExecSetStorage(), ATExecSetTableSpace(), ATExecValidateConstraint(), build_tuplestore_recursively(), CatalogCacheCreateEntry(), change_owner_fix_column_acls(), changeDependencyFor(), CollationCreate(), ConversionCreate(), copyTemplateDependencies(), create_toast_table(), CreateAccessMethod(), CreateCast(), CreateComments(), CreateForeignDataWrapper(), CreateForeignServer(), CreateForeignTable(), CreateOpFamily(), CreatePolicy(), CreatePublication(), CreateSharedComments(), CreateStatistics(), CreateSubscription(), CreateTableSpace(), CreateTransform(), CreateTrigger(), CreateUserMapping(), crosstab(), DefineOpClass(), DefineQueryRewrite(), DefineSequence(), DefineTSConfiguration(), DefineTSDictionary(), DefineTSParser(), DefineTSTemplate(), EnableDisableRule(), EnableDisableTrigger(), EnumValuesCreate(), EvalPlanQualSetTuple(), examine_attribute(), exec_assign_value(), exec_move_row(), exec_stmt_block(), exec_stmt_return_query(), ExecARDeleteTriggers(), ExecARUpdateTriggers(), ExecBRDeleteTriggers(), ExecBRInsertTriggers(), ExecBRUpdateTriggers(), ExecClearTuple(), ExecIRDeleteTriggers(), ExecIRInsertTriggers(), ExecIRUpdateTriggers(), ExecLockRows(), ExecReScanAgg(), ExecReScanSetOp(), ExecScanSubPlan(), ExecSetParamPlan(), ExecStoreMinimalTuple(), ExecStoreTuple(), ExtractReplicaIdentity(), file_acquire_sample_rows(), heap_delete(), heap_insert(), heap_update(), index_build(), index_constraint_create(), index_update_stats(), insert_event_trigger_tuple(), InsertExtensionTuple(), InsertOneTuple(), InsertPgAttributeTuple(), InsertPgClassTuple(), InsertRule(), inv_truncate(), inv_write(), LargeObjectCreate(), MakeConfigurationMapping(), mark_index_clustered(), MergeAttributesIntoExisting(), MergeConstraintsIntoExisting(), OperatorShellMake(), PLyGenericObject_ToComposite(), PLyMapping_ToComposite(), PLySequence_ToComposite(), ProcedureCreate(), publication_add_relation(), RangeCreate(), raw_heap_insert(), record_in(), record_recv(), recordMultipleDependencies(), reform_and_rewrite_tuple(), relation_mark_replica_identity(), RelationBuildDesc(), RelationInitPhysicalAddr(), RelationReloadIndexInfo(), RelationSetNewRelfilenode(), RemoveConstraintById(), RemoveInheritance(), RemoveRoleFromObjectPolicy(), renameatt_internal(), RenameConstraintById(), RenameEnumLabel(), RenameRelationInternal(), RenameRewriteRule(), RenameSchema(), RenameTypeInternal(), RenumberEnumType(), replorigin_create(), rewrite_heap_dead_tuple(), rewrite_heap_tuple(), SearchCatCache(), SearchCatCacheList(), SetMatViewPopulatedState(), SetRelationHasSubclass(), SetRelationNumChecks(), SetRelationRuleStatus(), SetSecurityLabel(), SetSharedSecurityLabel(), SetSubscriptionRelState(), shdepAddDependency(), shdepChangeDep(), SPI_freetuple(), statext_store(), StoreAttrDefault(), StoreCatalogInheritance1(), storeOperators(), StorePartitionBound(), storeProcedures(), swap_relation_files(), table_recheck_autovac(), toast_save_datum(), TypeShellMake(), update_attstats(), UpdateIndexRelation(), vac_update_datfrozenxid(), writetup_cluster(), and xpath_table().

1373 {
1374  pfree(htup);
1375 }
void pfree(void *pointer)
Definition: mcxt.c:950
Datum heap_getsysattr ( HeapTuple  tup,
int  attnum,
TupleDesc  tupleDesc,
bool isnull 
)

Definition at line 552 of file heaptuple.c.

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

Referenced by ExecInterpExpr(), and slot_getattr().

553 {
554  Datum result;
555 
556  Assert(tup);
557 
558  /* Currently, no sys attribute ever reads as NULL. */
559  *isnull = false;
560 
561  switch (attnum)
562  {
564  /* pass-by-reference datatype */
565  result = PointerGetDatum(&(tup->t_self));
566  break;
568  result = ObjectIdGetDatum(HeapTupleGetOid(tup));
569  break;
572  break;
575  break;
578 
579  /*
580  * cmin and cmax are now both aliases for the same field, which
581  * can in fact also be a combo command id. XXX perhaps we should
582  * return the "real" cmin or cmax if possible, that is if we are
583  * inside the originating transaction?
584  */
586  break;
588  result = ObjectIdGetDatum(tup->t_tableOid);
589  break;
590  default:
591  elog(ERROR, "invalid attnum: %d", attnum);
592  result = 0; /* keep compiler quiet */
593  break;
594  }
595  return result;
596 }
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
#define PointerGetDatum(X)
Definition: postgres.h:562
return result
Definition: formatting.c:1633
#define MinCommandIdAttributeNumber
Definition: sysattr.h:24
HeapTupleHeader t_data
Definition: htup.h:67
#define HeapTupleHeaderGetRawXmax(tup)
Definition: htup_details.h:369
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define TableOidAttributeNumber
Definition: sysattr.h:27
Oid t_tableOid
Definition: htup.h:66
#define MaxCommandIdAttributeNumber
Definition: sysattr.h:26
#define MaxTransactionIdAttributeNumber
Definition: sysattr.h:25
#define TransactionIdGetDatum(X)
Definition: postgres.h:527
uintptr_t Datum
Definition: postgres.h:372
#define Assert(condition)
Definition: c.h:675
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:302
#define HeapTupleHeaderGetRawCommandId(tup)
Definition: htup_details.h:385
#define CommandIdGetDatum(X)
Definition: postgres.h:548
#define SelfItemPointerAttributeNumber
Definition: sysattr.h:21
#define elog
Definition: elog.h:219
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
#define MinTransactionIdAttributeNumber
Definition: sysattr.h:23
HeapTuple heap_modify_tuple ( HeapTuple  tuple,
TupleDesc  tupleDesc,
Datum replValues,
bool replIsnull,
bool doReplace 
)

Definition at line 791 of file heaptuple.c.

References heap_deform_tuple(), heap_form_tuple(), HeapTupleGetOid, HeapTupleSetOid, tupleDesc::natts, palloc(), pfree(), HeapTupleHeaderData::t_ctid, HeapTupleData::t_data, HeapTupleData::t_self, HeapTupleData::t_tableOid, tupleDesc::tdhasoid, and values.

Referenced by AddRoleMems(), AlterCollation(), AlterDatabase(), AlterDatabaseOwner(), AlterDomainDefault(), AlterForeignDataWrapper(), AlterForeignDataWrapperOwner_internal(), AlterForeignServer(), AlterForeignServerOwner_internal(), AlterFunction(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), AlterOperator(), AlterPolicy(), AlterPublicationOptions(), AlterRole(), AlterSchemaOwner_internal(), AlterSetting(), AlterSubscription(), AlterTableSpaceOptions(), AlterTSDictionary(), AlterTypeOwnerInternal(), AlterUserMapping(), ApplyExtensionUpdates(), ATExecAlterColumnGenericOptions(), ATExecChangeOwner(), ATExecDetachPartition(), ATExecGenericOptions(), ATExecSetOptions(), ATExecSetRelOptions(), change_owner_fix_column_acls(), copyTemplateDependencies(), create_proc_lang(), CreateComments(), CreateSharedComments(), CreateTransform(), DelRoleMems(), ExecGrant_Attribute(), ExecGrant_Database(), ExecGrant_Fdw(), ExecGrant_ForeignServer(), ExecGrant_Function(), ExecGrant_Language(), ExecGrant_Largeobject(), ExecGrant_Namespace(), ExecGrant_Relation(), ExecGrant_Tablespace(), ExecGrant_Type(), extension_config_remove(), InsertRule(), inv_truncate(), inv_write(), MakeConfigurationMapping(), movedb(), OperatorCreate(), pg_extension_config_dump(), plperl_modify_tuple(), PLy_modify_tuple(), ProcedureCreate(), recordExtensionInitPrivWorker(), RemoveRoleFromObjectPolicy(), RenameRole(), SetDefaultACL(), SetSecurityLabel(), SetSharedSecurityLabel(), SetSubscriptionRelState(), statext_store(), StorePartitionBound(), TypeCreate(), and update_attstats().

796 {
797  int numberOfAttributes = tupleDesc->natts;
798  int attoff;
799  Datum *values;
800  bool *isnull;
801  HeapTuple newTuple;
802 
803  /*
804  * allocate and fill values and isnull arrays from either the tuple or the
805  * repl information, as appropriate.
806  *
807  * NOTE: it's debatable whether to use heap_deform_tuple() here or just
808  * heap_getattr() only the non-replaced columns. The latter could win if
809  * there are many replaced columns and few non-replaced ones. However,
810  * heap_deform_tuple costs only O(N) while the heap_getattr way would cost
811  * O(N^2) if there are many non-replaced columns, so it seems better to
812  * err on the side of linear cost.
813  */
814  values = (Datum *) palloc(numberOfAttributes * sizeof(Datum));
815  isnull = (bool *) palloc(numberOfAttributes * sizeof(bool));
816 
817  heap_deform_tuple(tuple, tupleDesc, values, isnull);
818 
819  for (attoff = 0; attoff < numberOfAttributes; attoff++)
820  {
821  if (doReplace[attoff])
822  {
823  values[attoff] = replValues[attoff];
824  isnull[attoff] = replIsnull[attoff];
825  }
826  }
827 
828  /*
829  * create a new tuple from the values and isnull arrays
830  */
831  newTuple = heap_form_tuple(tupleDesc, values, isnull);
832 
833  pfree(values);
834  pfree(isnull);
835 
836  /*
837  * copy the identification info of the old tuple: t_ctid, t_self, and OID
838  * (if any)
839  */
840  newTuple->t_data->t_ctid = tuple->t_data->t_ctid;
841  newTuple->t_self = tuple->t_self;
842  newTuple->t_tableOid = tuple->t_tableOid;
843  if (tupleDesc->tdhasoid)
844  HeapTupleSetOid(newTuple, HeapTupleGetOid(tuple));
845 
846  return newTuple;
847 }
bool tdhasoid
Definition: tupdesc.h:79
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
int natts
Definition: tupdesc.h:73
HeapTupleHeader t_data
Definition: htup.h:67
#define HeapTupleSetOid(tuple, oid)
Definition: htup_details.h:698
void pfree(void *pointer)
Definition: mcxt.c:950
ItemPointerData t_ctid
Definition: htup_details.h:150
ItemPointerData t_self
Definition: htup.h:65
Oid t_tableOid
Definition: htup.h:66
uintptr_t Datum
Definition: postgres.h:372
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:933
static Datum values[MAXATTR]
Definition: bootstrap.c:163
void * palloc(Size size)
Definition: mcxt.c:849
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
HeapTuple heap_modify_tuple_by_cols ( HeapTuple  tuple,
TupleDesc  tupleDesc,
int  nCols,
int *  replCols,
Datum replValues,
bool replIsnull 
)

Definition at line 862 of file heaptuple.c.

References elog, ERROR, heap_deform_tuple(), heap_form_tuple(), HeapTupleGetOid, HeapTupleSetOid, i, tupleDesc::natts, palloc(), pfree(), HeapTupleHeaderData::t_ctid, HeapTupleData::t_data, HeapTupleData::t_self, HeapTupleData::t_tableOid, tupleDesc::tdhasoid, and values.

Referenced by autoinc(), exec_assign_value(), insert_username(), moddatetime(), timetravel(), and tsvector_update_trigger().

868 {
869  int numberOfAttributes = tupleDesc->natts;
870  Datum *values;
871  bool *isnull;
872  HeapTuple newTuple;
873  int i;
874 
875  /*
876  * allocate and fill values and isnull arrays from the tuple, then replace
877  * selected columns from the input arrays.
878  */
879  values = (Datum *) palloc(numberOfAttributes * sizeof(Datum));
880  isnull = (bool *) palloc(numberOfAttributes * sizeof(bool));
881 
882  heap_deform_tuple(tuple, tupleDesc, values, isnull);
883 
884  for (i = 0; i < nCols; i++)
885  {
886  int attnum = replCols[i];
887 
888  if (attnum <= 0 || attnum > numberOfAttributes)
889  elog(ERROR, "invalid column number %d", attnum);
890  values[attnum - 1] = replValues[i];
891  isnull[attnum - 1] = replIsnull[i];
892  }
893 
894  /*
895  * create a new tuple from the values and isnull arrays
896  */
897  newTuple = heap_form_tuple(tupleDesc, values, isnull);
898 
899  pfree(values);
900  pfree(isnull);
901 
902  /*
903  * copy the identification info of the old tuple: t_ctid, t_self, and OID
904  * (if any)
905  */
906  newTuple->t_data->t_ctid = tuple->t_data->t_ctid;
907  newTuple->t_self = tuple->t_self;
908  newTuple->t_tableOid = tuple->t_tableOid;
909  if (tupleDesc->tdhasoid)
910  HeapTupleSetOid(newTuple, HeapTupleGetOid(tuple));
911 
912  return newTuple;
913 }
bool tdhasoid
Definition: tupdesc.h:79
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
int natts
Definition: tupdesc.h:73
HeapTupleHeader t_data
Definition: htup.h:67
#define HeapTupleSetOid(tuple, oid)
Definition: htup_details.h:698
void pfree(void *pointer)
Definition: mcxt.c:950
#define ERROR
Definition: elog.h:43
ItemPointerData t_ctid
Definition: htup_details.h:150
ItemPointerData t_self
Definition: htup.h:65
Oid t_tableOid
Definition: htup.h:66
uintptr_t Datum
Definition: postgres.h:372
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:933
static Datum values[MAXATTR]
Definition: bootstrap.c:163
void * palloc(Size size)
Definition: mcxt.c:849
int i
#define elog
Definition: elog.h:219
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
HeapTuple heap_tuple_from_minimal_tuple ( MinimalTuple  mtup)

Definition at line 1498 of file heaptuple.c.

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

Referenced by ExecCopySlotTuple().

1499 {
1500  HeapTuple result;
1501  uint32 len = mtup->t_len + MINIMAL_TUPLE_OFFSET;
1502 
1503  result = (HeapTuple) palloc(HEAPTUPLESIZE + len);
1504  result->t_len = len;
1505  ItemPointerSetInvalid(&(result->t_self));
1506  result->t_tableOid = InvalidOid;
1507  result->t_data = (HeapTupleHeader) ((char *) result + HEAPTUPLESIZE);
1508  memcpy((char *) result->t_data + MINIMAL_TUPLE_OFFSET, mtup, mtup->t_len);
1509  memset(result->t_data, 0, offsetof(HeapTupleHeaderData, t_infomask2));
1510  return result;
1511 }
HeapTupleData * HeapTuple
Definition: htup.h:70
HeapTupleHeaderData * HeapTupleHeader
Definition: htup.h:23
return result
Definition: formatting.c:1633
HeapTupleHeader t_data
Definition: htup.h:67
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
unsigned int uint32
Definition: c.h:268
Oid t_tableOid
Definition: htup.h:66
#define InvalidOid
Definition: postgres_ext.h:36
#define MINIMAL_TUPLE_OFFSET
Definition: htup_details.h:620
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:150
void * palloc(Size size)
Definition: mcxt.c:849
#define HEAPTUPLESIZE
Definition: htup.h:72
#define offsetof(type, field)
Definition: c.h:555
MinimalTuple minimal_tuple_from_heap_tuple ( HeapTuple  htup)

Definition at line 1520 of file heaptuple.c.

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

Referenced by copytup_heap(), and ExecCopySlotMinimalTuple().

1521 {
1523  uint32 len;
1524 
1526  len = htup->t_len - MINIMAL_TUPLE_OFFSET;
1527  result = (MinimalTuple) palloc(len);
1528  memcpy(result, (char *) htup->t_data + MINIMAL_TUPLE_OFFSET, len);
1529  result->t_len = len;
1530  return result;
1531 }
return result
Definition: formatting.c:1633
HeapTupleHeader t_data
Definition: htup.h:67
uint32 t_len
Definition: htup.h:64
MinimalTupleData * MinimalTuple
Definition: htup.h:27
unsigned int uint32
Definition: c.h:268
#define Assert(condition)
Definition: c.h:675
#define MINIMAL_TUPLE_OFFSET
Definition: htup_details.h:620
void * palloc(Size size)
Definition: mcxt.c:849
Datum nocachegetattr ( HeapTuple  tuple,
int  attnum,
TupleDesc  tupleDesc 
)

Definition at line 352 of file heaptuple.c.

References Assert, att_addlength_pointer, att_align_nominal, att_align_pointer, att_isnull, tupleDesc::attrs, byte, fetchatt, HeapTupleHasNulls, HeapTupleHasVarWidth, HeapTupleNoNulls, i, tupleDesc::natts, HeapTupleHeaderData::t_bits, HeapTupleData::t_data, and HeapTupleHeaderData::t_hoff.

355 {
356  HeapTupleHeader tup = tuple->t_data;
357  Form_pg_attribute *att = tupleDesc->attrs;
358  char *tp; /* ptr to data part of tuple */
359  bits8 *bp = tup->t_bits; /* ptr to null bitmap in tuple */
360  bool slow = false; /* do we have to walk attrs? */
361  int off; /* current offset within data */
362 
363  /* ----------------
364  * Three cases:
365  *
366  * 1: No nulls and no variable-width attributes.
367  * 2: Has a null or a var-width AFTER att.
368  * 3: Has nulls or var-widths BEFORE att.
369  * ----------------
370  */
371 
372  attnum--;
373 
374  if (!HeapTupleNoNulls(tuple))
375  {
376  /*
377  * there's a null somewhere in the tuple
378  *
379  * check to see if any preceding bits are null...
380  */
381  int byte = attnum >> 3;
382  int finalbit = attnum & 0x07;
383 
384  /* check for nulls "before" final bit of last byte */
385  if ((~bp[byte]) & ((1 << finalbit) - 1))
386  slow = true;
387  else
388  {
389  /* check for nulls in any "earlier" bytes */
390  int i;
391 
392  for (i = 0; i < byte; i++)
393  {
394  if (bp[i] != 0xFF)
395  {
396  slow = true;
397  break;
398  }
399  }
400  }
401  }
402 
403  tp = (char *) tup + tup->t_hoff;
404 
405  if (!slow)
406  {
407  /*
408  * If we get here, there are no nulls up to and including the target
409  * attribute. If we have a cached offset, we can use it.
410  */
411  if (att[attnum]->attcacheoff >= 0)
412  {
413  return fetchatt(att[attnum],
414  tp + att[attnum]->attcacheoff);
415  }
416 
417  /*
418  * Otherwise, check for non-fixed-length attrs up to and including
419  * target. If there aren't any, it's safe to cheaply initialize the
420  * cached offsets for these attrs.
421  */
422  if (HeapTupleHasVarWidth(tuple))
423  {
424  int j;
425 
426  for (j = 0; j <= attnum; j++)
427  {
428  if (att[j]->attlen <= 0)
429  {
430  slow = true;
431  break;
432  }
433  }
434  }
435  }
436 
437  if (!slow)
438  {
439  int natts = tupleDesc->natts;
440  int j = 1;
441 
442  /*
443  * If we get here, we have a tuple with no nulls or var-widths up to
444  * and including the target attribute, so we can use the cached offset
445  * ... only we don't have it yet, or we'd not have got here. Since
446  * it's cheap to compute offsets for fixed-width columns, we take the
447  * opportunity to initialize the cached offsets for *all* the leading
448  * fixed-width columns, in hope of avoiding future visits to this
449  * routine.
450  */
451  att[0]->attcacheoff = 0;
452 
453  /* we might have set some offsets in the slow path previously */
454  while (j < natts && att[j]->attcacheoff > 0)
455  j++;
456 
457  off = att[j - 1]->attcacheoff + att[j - 1]->attlen;
458 
459  for (; j < natts; j++)
460  {
461  if (att[j]->attlen <= 0)
462  break;
463 
464  off = att_align_nominal(off, att[j]->attalign);
465 
466  att[j]->attcacheoff = off;
467 
468  off += att[j]->attlen;
469  }
470 
471  Assert(j > attnum);
472 
473  off = att[attnum]->attcacheoff;
474  }
475  else
476  {
477  bool usecache = true;
478  int i;
479 
480  /*
481  * Now we know that we have to walk the tuple CAREFULLY. But we still
482  * might be able to cache some offsets for next time.
483  *
484  * Note - This loop is a little tricky. For each non-null attribute,
485  * we have to first account for alignment padding before the attr,
486  * then advance over the attr based on its length. Nulls have no
487  * storage and no alignment padding either. We can use/set
488  * attcacheoff until we reach either a null or a var-width attribute.
489  */
490  off = 0;
491  for (i = 0;; i++) /* loop exit is at "break" */
492  {
493  if (HeapTupleHasNulls(tuple) && att_isnull(i, bp))
494  {
495  usecache = false;
496  continue; /* this cannot be the target att */
497  }
498 
499  /* If we know the next offset, we can skip the rest */
500  if (usecache && att[i]->attcacheoff >= 0)
501  off = att[i]->attcacheoff;
502  else if (att[i]->attlen == -1)
503  {
504  /*
505  * We can only cache the offset for a varlena attribute if the
506  * offset is already suitably aligned, so that there would be
507  * no pad bytes in any case: then the offset will be valid for
508  * either an aligned or unaligned value.
509  */
510  if (usecache &&
511  off == att_align_nominal(off, att[i]->attalign))
512  att[i]->attcacheoff = off;
513  else
514  {
515  off = att_align_pointer(off, att[i]->attalign, -1,
516  tp + off);
517  usecache = false;
518  }
519  }
520  else
521  {
522  /* not varlena, so safe to use att_align_nominal */
523  off = att_align_nominal(off, att[i]->attalign);
524 
525  if (usecache)
526  att[i]->attcacheoff = off;
527  }
528 
529  if (i == attnum)
530  break;
531 
532  off = att_addlength_pointer(off, att[i]->attlen, tp + off);
533 
534  if (usecache && att[i]->attlen <= 0)
535  usecache = false;
536  }
537  }
538 
539  return fetchatt(att[attnum], tp + off);
540 }
#define HeapTupleHasVarWidth(tuple)
Definition: htup_details.h:668
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:144
bits8 t_bits[FLEXIBLE_ARRAY_MEMBER]
Definition: htup_details.h:163
#define att_isnull(ATT, BITS)
Definition: tupmacs.h:21
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int natts
Definition: tupdesc.h:73
#define fetchatt(A, T)
Definition: tupmacs.h:37
HeapTupleHeader t_data
Definition: htup.h:67
#define HeapTupleHasNulls(tuple)
Definition: htup_details.h:662
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:172
#define HeapTupleNoNulls(tuple)
Definition: htup_details.h:665
#define byte(x, n)
Definition: rijndael.c:68
uint8 bits8
Definition: c.h:275
#define att_align_pointer(cur_offset, attalign, attlen, attptr)
Definition: tupmacs.h:122
#define Assert(condition)
Definition: c.h:675
int i
bool slot_attisnull ( TupleTableSlot slot,
int  attnum 
)

Definition at line 1328 of file heaptuple.c.

References elog, ERROR, heap_attisnull(), tupleDesc::natts, NULL, TupleTableSlot::tts_isnull, TupleTableSlot::tts_minhdr, TupleTableSlot::tts_tuple, and TupleTableSlot::tts_tupleDescriptor.

Referenced by ExecConstraints(), slotAllNulls(), and slotNoNulls().

1329 {
1330  HeapTuple tuple = slot->tts_tuple;
1332 
1333  /*
1334  * system attributes are handled by heap_attisnull
1335  */
1336  if (attnum <= 0)
1337  {
1338  if (tuple == NULL) /* internal error */
1339  elog(ERROR, "cannot extract system attribute from virtual tuple");
1340  if (tuple == &(slot->tts_minhdr)) /* internal error */
1341  elog(ERROR, "cannot extract system attribute from minimal tuple");
1342  return heap_attisnull(tuple, attnum);
1343  }
1344 
1345  /*
1346  * fast path if desired attribute already cached
1347  */
1348  if (attnum <= slot->tts_nvalid)
1349  return slot->tts_isnull[attnum - 1];
1350 
1351  /*
1352  * return NULL if attnum is out of range according to the tupdesc
1353  */
1354  if (attnum > tupleDesc->natts)
1355  return true;
1356 
1357  /*
1358  * otherwise we had better have a physical tuple (tts_nvalid should equal
1359  * natts in all virtual-tuple cases)
1360  */
1361  if (tuple == NULL) /* internal error */
1362  elog(ERROR, "cannot extract attribute from empty tuple slot");
1363 
1364  /* and let the tuple tell it */
1365  return heap_attisnull(tuple, attnum);
1366 }
int natts
Definition: tupdesc.h:73
#define ERROR
Definition: elog.h:43
HeapTupleData tts_minhdr
Definition: tuptable.h:128
bool * tts_isnull
Definition: tuptable.h:126
bool heap_attisnull(HeapTuple tup, int attnum)
Definition: heaptuple.c:297
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
#define NULL
Definition: c.h:229
HeapTuple tts_tuple
Definition: tuptable.h:120
#define elog
Definition: elog.h:219
static void slot_deform_tuple ( TupleTableSlot slot,
int  natts 
)
static

Definition at line 1034 of file heaptuple.c.

References att_addlength_pointer, att_align_nominal, att_align_pointer, att_isnull, tupleDesc::attrs, fetchatt, HeapTupleHasNulls, HeapTupleHeaderData::t_bits, HeapTupleData::t_data, HeapTupleHeaderData::t_hoff, TupleTableSlot::tts_isnull, TupleTableSlot::tts_nvalid, TupleTableSlot::tts_off, TupleTableSlot::tts_slow, TupleTableSlot::tts_tuple, TupleTableSlot::tts_tupleDescriptor, TupleTableSlot::tts_values, and values.

Referenced by slot_getallattrs(), slot_getattr(), and slot_getsomeattrs().

1035 {
1036  HeapTuple tuple = slot->tts_tuple;
1038  Datum *values = slot->tts_values;
1039  bool *isnull = slot->tts_isnull;
1040  HeapTupleHeader tup = tuple->t_data;
1041  bool hasnulls = HeapTupleHasNulls(tuple);
1042  Form_pg_attribute *att = tupleDesc->attrs;
1043  int attnum;
1044  char *tp; /* ptr to tuple data */
1045  long off; /* offset in tuple data */
1046  bits8 *bp = tup->t_bits; /* ptr to null bitmap in tuple */
1047  bool slow; /* can we use/set attcacheoff? */
1048 
1049  /*
1050  * Check whether the first call for this tuple, and initialize or restore
1051  * loop state.
1052  */
1053  attnum = slot->tts_nvalid;
1054  if (attnum == 0)
1055  {
1056  /* Start from the first attribute */
1057  off = 0;
1058  slow = false;
1059  }
1060  else
1061  {
1062  /* Restore state from previous execution */
1063  off = slot->tts_off;
1064  slow = slot->tts_slow;
1065  }
1066 
1067  tp = (char *) tup + tup->t_hoff;
1068 
1069  for (; attnum < natts; attnum++)
1070  {
1071  Form_pg_attribute thisatt = att[attnum];
1072 
1073  if (hasnulls && att_isnull(attnum, bp))
1074  {
1075  values[attnum] = (Datum) 0;
1076  isnull[attnum] = true;
1077  slow = true; /* can't use attcacheoff anymore */
1078  continue;
1079  }
1080 
1081  isnull[attnum] = false;
1082 
1083  if (!slow && thisatt->attcacheoff >= 0)
1084  off = thisatt->attcacheoff;
1085  else if (thisatt->attlen == -1)
1086  {
1087  /*
1088  * We can only cache the offset for a varlena attribute if the
1089  * offset is already suitably aligned, so that there would be no
1090  * pad bytes in any case: then the offset will be valid for either
1091  * an aligned or unaligned value.
1092  */
1093  if (!slow &&
1094  off == att_align_nominal(off, thisatt->attalign))
1095  thisatt->attcacheoff = off;
1096  else
1097  {
1098  off = att_align_pointer(off, thisatt->attalign, -1,
1099  tp + off);
1100  slow = true;
1101  }
1102  }
1103  else
1104  {
1105  /* not varlena, so safe to use att_align_nominal */
1106  off = att_align_nominal(off, thisatt->attalign);
1107 
1108  if (!slow)
1109  thisatt->attcacheoff = off;
1110  }
1111 
1112  values[attnum] = fetchatt(thisatt, tp + off);
1113 
1114  off = att_addlength_pointer(off, thisatt->attlen, tp + off);
1115 
1116  if (thisatt->attlen <= 0)
1117  slow = true; /* can't use attcacheoff anymore */
1118  }
1119 
1120  /*
1121  * Save state for next execution
1122  */
1123  slot->tts_nvalid = attnum;
1124  slot->tts_off = off;
1125  slot->tts_slow = slow;
1126 }
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:144
bits8 t_bits[FLEXIBLE_ARRAY_MEMBER]
Definition: htup_details.h:163
#define att_isnull(ATT, BITS)
Definition: tupmacs.h:21
Form_pg_attribute * attrs
Definition: tupdesc.h:74
Datum * tts_values
Definition: tuptable.h:125
#define fetchatt(A, T)
Definition: tupmacs.h:37
HeapTupleHeader t_data
Definition: htup.h:67
#define HeapTupleHasNulls(tuple)
Definition: htup_details.h:662
bool * tts_isnull
Definition: tuptable.h:126
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:172
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
uint8 bits8
Definition: c.h:275
uintptr_t Datum
Definition: postgres.h:372
#define att_align_pointer(cur_offset, attalign, attlen, attptr)
Definition: tupmacs.h:122
static Datum values[MAXATTR]
Definition: bootstrap.c:163
HeapTuple tts_tuple
Definition: tuptable.h:120
void slot_getallattrs ( TupleTableSlot slot)

Definition at line 1237 of file heaptuple.c.

References elog, ERROR, HeapTupleHeaderGetNatts, Min, tupleDesc::natts, NULL, slot_deform_tuple(), HeapTupleData::t_data, TupleTableSlot::tts_isnull, TupleTableSlot::tts_nvalid, TupleTableSlot::tts_tuple, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.

Referenced by agg_retrieve_hash_table(), copy_dest_receive(), ExecBuildSlotValueDescription(), ExecEvalWholeRowVar(), ExecFilterJunk(), FunctionNext(), printsimple(), printtup(), printtup_20(), printtup_internal_20(), slot_modify_cstrings(), tqueueReceiveSlot(), and tstoreReceiveSlot_detoast().

1238 {
1239  int tdesc_natts = slot->tts_tupleDescriptor->natts;
1240  int attnum;
1241  HeapTuple tuple;
1242 
1243  /* Quick out if we have 'em all already */
1244  if (slot->tts_nvalid == tdesc_natts)
1245  return;
1246 
1247  /*
1248  * otherwise we had better have a physical tuple (tts_nvalid should equal
1249  * natts in all virtual-tuple cases)
1250  */
1251  tuple = slot->tts_tuple;
1252  if (tuple == NULL) /* internal error */
1253  elog(ERROR, "cannot extract attribute from empty tuple slot");
1254 
1255  /*
1256  * load up any slots available from physical tuple
1257  */
1258  attnum = HeapTupleHeaderGetNatts(tuple->t_data);
1259  attnum = Min(attnum, tdesc_natts);
1260 
1261  slot_deform_tuple(slot, attnum);
1262 
1263  /*
1264  * If tuple doesn't have all the atts indicated by tupleDesc, read the
1265  * rest as null
1266  */
1267  for (; attnum < tdesc_natts; attnum++)
1268  {
1269  slot->tts_values[attnum] = (Datum) 0;
1270  slot->tts_isnull[attnum] = true;
1271  }
1272  slot->tts_nvalid = tdesc_natts;
1273 }
#define Min(x, y)
Definition: c.h:806
Datum * tts_values
Definition: tuptable.h:125
int natts
Definition: tupdesc.h:73
HeapTupleHeader t_data
Definition: htup.h:67
#define ERROR
Definition: elog.h:43
#define HeapTupleHeaderGetNatts(tup)
Definition: htup_details.h:532
bool * tts_isnull
Definition: tuptable.h:126
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
uintptr_t Datum
Definition: postgres.h:372
#define NULL
Definition: c.h:229
HeapTuple tts_tuple
Definition: tuptable.h:120
#define elog
Definition: elog.h:219
static void slot_deform_tuple(TupleTableSlot *slot, int natts)
Definition: heaptuple.c:1034
Datum slot_getattr ( TupleTableSlot slot,
int  attnum,
bool isnull 
)

Definition at line 1141 of file heaptuple.c.

References att_isnull, tupleDesc::attrs, elog, ERROR, heap_getsysattr(), HeapTupleHasNulls, HeapTupleHeaderGetNatts, tupleDesc::natts, NULL, slot_deform_tuple(), HeapTupleHeaderData::t_bits, HeapTupleData::t_data, TupleTableSlot::tts_isnull, TupleTableSlot::tts_minhdr, TupleTableSlot::tts_tuple, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.

Referenced by buildSubPlanHash(), convert_prep_stmt_params(), debugtup(), execCurrentOf(), ExecGetJunkAttribute(), ExecJustAssignInnerVar(), ExecJustAssignOuterVar(), ExecJustAssignScanVar(), ExecJustInnerVar(), ExecJustInnerVarFirst(), ExecJustOuterVar(), ExecJustOuterVarFirst(), ExecJustScanVar(), ExecJustScanVarFirst(), ExecMakeFunctionResultSet(), ExecNestLoop(), ExecScanSubPlan(), ExecSetParamPlan(), execTuplesMatch(), execTuplesUnequal(), fetch_remote_table_info(), fetch_table_list(), fetch_tuple_flag(), FormIndexDatum(), FormPartitionKeyDatum(), heap_compare_slots(), hypothetical_dense_rank_final(), hypothetical_rank_common(), postquel_get_single_result(), and TupleHashTableHash().

1142 {
1143  HeapTuple tuple = slot->tts_tuple;
1145  HeapTupleHeader tup;
1146 
1147  /*
1148  * system attributes are handled by heap_getsysattr
1149  */
1150  if (attnum <= 0)
1151  {
1152  if (tuple == NULL) /* internal error */
1153  elog(ERROR, "cannot extract system attribute from virtual tuple");
1154  if (tuple == &(slot->tts_minhdr)) /* internal error */
1155  elog(ERROR, "cannot extract system attribute from minimal tuple");
1156  return heap_getsysattr(tuple, attnum, tupleDesc, isnull);
1157  }
1158 
1159  /*
1160  * fast path if desired attribute already cached
1161  */
1162  if (attnum <= slot->tts_nvalid)
1163  {
1164  *isnull = slot->tts_isnull[attnum - 1];
1165  return slot->tts_values[attnum - 1];
1166  }
1167 
1168  /*
1169  * return NULL if attnum is out of range according to the tupdesc
1170  */
1171  if (attnum > tupleDesc->natts)
1172  {
1173  *isnull = true;
1174  return (Datum) 0;
1175  }
1176 
1177  /*
1178  * otherwise we had better have a physical tuple (tts_nvalid should equal
1179  * natts in all virtual-tuple cases)
1180  */
1181  if (tuple == NULL) /* internal error */
1182  elog(ERROR, "cannot extract attribute from empty tuple slot");
1183 
1184  /*
1185  * return NULL if attnum is out of range according to the tuple
1186  *
1187  * (We have to check this separately because of various inheritance and
1188  * table-alteration scenarios: the tuple could be either longer or shorter
1189  * than the tupdesc.)
1190  */
1191  tup = tuple->t_data;
1192  if (attnum > HeapTupleHeaderGetNatts(tup))
1193  {
1194  *isnull = true;
1195  return (Datum) 0;
1196  }
1197 
1198  /*
1199  * check if target attribute is null: no point in groveling through tuple
1200  */
1201  if (HeapTupleHasNulls(tuple) && att_isnull(attnum - 1, tup->t_bits))
1202  {
1203  *isnull = true;
1204  return (Datum) 0;
1205  }
1206 
1207  /*
1208  * If the attribute's column has been dropped, we force a NULL result.
1209  * This case should not happen in normal use, but it could happen if we
1210  * are executing a plan cached before the column was dropped.
1211  */
1212  if (tupleDesc->attrs[attnum - 1]->attisdropped)
1213  {
1214  *isnull = true;
1215  return (Datum) 0;
1216  }
1217 
1218  /*
1219  * Extract the attribute, along with any preceding attributes.
1220  */
1221  slot_deform_tuple(slot, attnum);
1222 
1223  /*
1224  * The result is acquired from tts_values array.
1225  */
1226  *isnull = slot->tts_isnull[attnum - 1];
1227  return slot->tts_values[attnum - 1];
1228 }
bits8 t_bits[FLEXIBLE_ARRAY_MEMBER]
Definition: htup_details.h:163
#define att_isnull(ATT, BITS)
Definition: tupmacs.h:21
Form_pg_attribute * attrs
Definition: tupdesc.h:74
Datum * tts_values
Definition: tuptable.h:125
int natts
Definition: tupdesc.h:73
HeapTupleHeader t_data
Definition: htup.h:67
#define ERROR
Definition: elog.h:43
Datum heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: heaptuple.c:552
HeapTupleData tts_minhdr
Definition: tuptable.h:128
#define HeapTupleHeaderGetNatts(tup)
Definition: htup_details.h:532
#define HeapTupleHasNulls(tuple)
Definition: htup_details.h:662
bool * tts_isnull
Definition: tuptable.h:126
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
uintptr_t Datum
Definition: postgres.h:372
#define NULL
Definition: c.h:229
HeapTuple tts_tuple
Definition: tuptable.h:120
#define elog
Definition: elog.h:219
static void slot_deform_tuple(TupleTableSlot *slot, int natts)
Definition: heaptuple.c:1034
void slot_getsomeattrs ( TupleTableSlot slot,
int  attnum 
)

Definition at line 1281 of file heaptuple.c.

References elog, ERROR, HeapTupleHeaderGetNatts, Min, tupleDesc::natts, NULL, slot_deform_tuple(), HeapTupleData::t_data, TupleTableSlot::tts_isnull, TupleTableSlot::tts_nvalid, TupleTableSlot::tts_tuple, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.

Referenced by ExecInterpExpr(), lookup_hash_entry(), prepare_projection_slot(), and process_ordered_aggregate_multi().

1282 {
1283  HeapTuple tuple;
1284  int attno;
1285 
1286  /* Quick out if we have 'em all already */
1287  if (slot->tts_nvalid >= attnum)
1288  return;
1289 
1290  /* Check for caller error */
1291  if (attnum <= 0 || attnum > slot->tts_tupleDescriptor->natts)
1292  elog(ERROR, "invalid attribute number %d", attnum);
1293 
1294  /*
1295  * otherwise we had better have a physical tuple (tts_nvalid should equal
1296  * natts in all virtual-tuple cases)
1297  */
1298  tuple = slot->tts_tuple;
1299  if (tuple == NULL) /* internal error */
1300  elog(ERROR, "cannot extract attribute from empty tuple slot");
1301 
1302  /*
1303  * load up any slots available from physical tuple
1304  */
1305  attno = HeapTupleHeaderGetNatts(tuple->t_data);
1306  attno = Min(attno, attnum);
1307 
1308  slot_deform_tuple(slot, attno);
1309 
1310  /*
1311  * If tuple doesn't have all the atts indicated by tupleDesc, read the
1312  * rest as null
1313  */
1314  for (; attno < attnum; attno++)
1315  {
1316  slot->tts_values[attno] = (Datum) 0;
1317  slot->tts_isnull[attno] = true;
1318  }
1319  slot->tts_nvalid = attnum;
1320 }
#define Min(x, y)
Definition: c.h:806
Datum * tts_values
Definition: tuptable.h:125
int natts
Definition: tupdesc.h:73
HeapTupleHeader t_data
Definition: htup.h:67
#define ERROR
Definition: elog.h:43
#define HeapTupleHeaderGetNatts(tup)
Definition: htup_details.h:532
bool * tts_isnull
Definition: tuptable.h:126
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
uintptr_t Datum
Definition: postgres.h:372
#define NULL
Definition: c.h:229
HeapTuple tts_tuple
Definition: tuptable.h:120
#define elog
Definition: elog.h:219
static void slot_deform_tuple(TupleTableSlot *slot, int natts)
Definition: heaptuple.c:1034