PostgreSQL Source Code  git master
execTuples.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/tuptoaster.h"
#include "funcapi.h"
#include "catalog/pg_type.h"
#include "nodes/nodeFuncs.h"
#include "storage/bufmgr.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/typcache.h"
Include dependency graph for execTuples.c:

Go to the source code of this file.

Functions

static TupleDesc ExecTypeFromTLInternal (List *targetList, bool hasoid, bool skipjunk)
 
TupleTableSlotMakeTupleTableSlot (void)
 
TupleTableSlotExecAllocTableSlot (List **tupleTable)
 
void ExecResetTupleTable (List *tupleTable, bool shouldFree)
 
TupleTableSlotMakeSingleTupleTableSlot (TupleDesc tupdesc)
 
void ExecDropSingleTupleTableSlot (TupleTableSlot *slot)
 
void ExecSetSlotDescriptor (TupleTableSlot *slot, TupleDesc tupdesc)
 
TupleTableSlotExecStoreTuple (HeapTuple tuple, TupleTableSlot *slot, Buffer buffer, bool shouldFree)
 
TupleTableSlotExecStoreMinimalTuple (MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
 
TupleTableSlotExecClearTuple (TupleTableSlot *slot)
 
TupleTableSlotExecStoreVirtualTuple (TupleTableSlot *slot)
 
TupleTableSlotExecStoreAllNullTuple (TupleTableSlot *slot)
 
HeapTuple ExecCopySlotTuple (TupleTableSlot *slot)
 
MinimalTuple ExecCopySlotMinimalTuple (TupleTableSlot *slot)
 
HeapTuple ExecFetchSlotTuple (TupleTableSlot *slot)
 
MinimalTuple ExecFetchSlotMinimalTuple (TupleTableSlot *slot)
 
Datum ExecFetchSlotTupleDatum (TupleTableSlot *slot)
 
HeapTuple ExecMaterializeSlot (TupleTableSlot *slot)
 
TupleTableSlotExecCopySlot (TupleTableSlot *dstslot, TupleTableSlot *srcslot)
 
void ExecInitResultTupleSlot (EState *estate, PlanState *planstate)
 
void ExecInitScanTupleSlot (EState *estate, ScanState *scanstate)
 
TupleTableSlotExecInitExtraTupleSlot (EState *estate)
 
TupleTableSlotExecInitNullTupleSlot (EState *estate, TupleDesc tupType)
 
TupleDesc ExecTypeFromTL (List *targetList, bool hasoid)
 
TupleDesc ExecCleanTypeFromTL (List *targetList, bool hasoid)
 
TupleDesc ExecTypeFromExprList (List *exprList)
 
void ExecTypeSetColNames (TupleDesc typeInfo, List *namesList)
 
TupleDesc BlessTupleDesc (TupleDesc tupdesc)
 
TupleTableSlotTupleDescGetSlot (TupleDesc tupdesc)
 
AttInMetadataTupleDescGetAttInMetadata (TupleDesc tupdesc)
 
HeapTuple BuildTupleFromCStrings (AttInMetadata *attinmeta, char **values)
 
Datum HeapTupleHeaderGetDatum (HeapTupleHeader tuple)
 
TupOutputStatebegin_tup_output_tupdesc (DestReceiver *dest, TupleDesc tupdesc)
 
void do_tup_output (TupOutputState *tstate, Datum *values, bool *isnull)
 
void do_text_output_multiline (TupOutputState *tstate, const char *txt)
 
void end_tup_output (TupOutputState *tstate)
 

Function Documentation

◆ begin_tup_output_tupdesc()

TupOutputState* begin_tup_output_tupdesc ( DestReceiver dest,
TupleDesc  tupdesc 
)

Definition at line 1235 of file execTuples.c.

References CMD_SELECT, generate_unaccent_rules::dest, TupOutputState::dest, MakeSingleTupleTableSlot(), palloc(), _DestReceiver::rStartup, and TupOutputState::slot.

Referenced by CreateReplicationSlot(), ExplainQuery(), IdentifySystem(), ShowAllGUCConfig(), ShowGUCConfigOption(), and StartReplication().

1236 {
1237  TupOutputState *tstate;
1238 
1239  tstate = (TupOutputState *) palloc(sizeof(TupOutputState));
1240 
1241  tstate->slot = MakeSingleTupleTableSlot(tupdesc);
1242  tstate->dest = dest;
1243 
1244  tstate->dest->rStartup(tstate->dest, (int) CMD_SELECT, tupdesc);
1245 
1246  return tstate;
1247 }
TupleTableSlot * slot
Definition: executor.h:425
void(* rStartup)(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: dest.h:121
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc)
Definition: execTuples.c:199
void * palloc(Size size)
Definition: mcxt.c:848
DestReceiver * dest
Definition: executor.h:426

◆ BlessTupleDesc()

TupleDesc BlessTupleDesc ( TupleDesc  tupdesc)

Definition at line 1032 of file execTuples.c.

References assign_record_type_typmod(), RECORDOID, tupleDesc::tdtypeid, and tupleDesc::tdtypmod.

Referenced by aclexplode(), brin_metapage_info(), each_worker(), each_worker_jsonb(), elements_worker(), elements_worker_jsonb(), exec_eval_datum(), ExecEvalWholeRowVar(), ExecInitExprRec(), ExecInitFunctionScan(), hash_bitmap_info(), hash_metapage_info(), hash_page_items(), hash_page_stats(), init_sql_fcache(), pg_buffercache_pages(), pg_control_checkpoint(), pg_control_init(), pg_control_recovery(), pg_control_system(), 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_timezone_abbrevs(), pg_timezone_names(), pg_visibility_map_summary(), pg_visibility_tupdesc(), pg_walfile_name_offset(), pgstathashindex(), plpgsql_exec_get_datum_type(), plpgsql_exec_get_datum_type_info(), PLy_output_setup_record(), setup_firstcall(), ssl_extension_info(), ts_setup_firstcall(), tsvector_unnest(), TupleDescGetAttInMetadata(), and TupleDescGetSlot().

1033 {
1034  if (tupdesc->tdtypeid == RECORDOID &&
1035  tupdesc->tdtypmod < 0)
1036  assign_record_type_typmod(tupdesc);
1037 
1038  return tupdesc; /* just for notational convenience */
1039 }
Oid tdtypeid
Definition: tupdesc.h:80
int32 tdtypmod
Definition: tupdesc.h:81
void assign_record_type_typmod(TupleDesc tupDesc)
Definition: typcache.c:1738
#define RECORDOID
Definition: pg_type.h:680

◆ BuildTupleFromCStrings()

HeapTuple BuildTupleFromCStrings ( AttInMetadata attinmeta,
char **  values 
)

Definition at line 1118 of file execTuples.c.

References AttInMetadata::attinfuncs, AttInMetadata::attioparams, AttInMetadata::atttypmods, heap_form_tuple(), i, InputFunctionCall(), tupleDesc::natts, palloc(), pfree(), AttInMetadata::tupdesc, and TupleDescAttr.

Referenced by bt_metap(), bt_page_print_tuples(), bt_page_stats(), build_pgstattuple_type(), build_tuplestore_recursively(), crosstab(), dblink_get_pkey(), get_crosstab_tuplestore(), libpqrcv_processTuples(), materializeQueryResult(), materializeResult(), pg_config(), pg_get_keywords(), pg_get_multixact_members(), pg_logdir_ls(), pgp_armor_headers(), pgrowlocks(), pgstatindex_impl(), pltcl_build_tuple_result(), prs_process_call(), show_all_settings(), storeRow(), ts_process_call(), tt_process_call(), and xpath_table().

1119 {
1120  TupleDesc tupdesc = attinmeta->tupdesc;
1121  int natts = tupdesc->natts;
1122  Datum *dvalues;
1123  bool *nulls;
1124  int i;
1125  HeapTuple tuple;
1126 
1127  dvalues = (Datum *) palloc(natts * sizeof(Datum));
1128  nulls = (bool *) palloc(natts * sizeof(bool));
1129 
1130  /* Call the "in" function for each non-dropped attribute */
1131  for (i = 0; i < natts; i++)
1132  {
1133  if (!TupleDescAttr(tupdesc, i)->attisdropped)
1134  {
1135  /* Non-dropped attributes */
1136  dvalues[i] = InputFunctionCall(&attinmeta->attinfuncs[i],
1137  values[i],
1138  attinmeta->attioparams[i],
1139  attinmeta->atttypmods[i]);
1140  if (values[i] != NULL)
1141  nulls[i] = false;
1142  else
1143  nulls[i] = true;
1144  }
1145  else
1146  {
1147  /* Handle dropped attributes by setting to NULL */
1148  dvalues[i] = (Datum) 0;
1149  nulls[i] = true;
1150  }
1151  }
1152 
1153  /*
1154  * Form a tuple
1155  */
1156  tuple = heap_form_tuple(tupdesc, dvalues, nulls);
1157 
1158  /*
1159  * Release locally palloc'd space. XXX would probably be good to pfree
1160  * values of pass-by-reference datums, as well.
1161  */
1162  pfree(dvalues);
1163  pfree(nulls);
1164 
1165  return tuple;
1166 }
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:90
int32 * atttypmods
Definition: funcapi.h:48
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:695
Oid * attioparams
Definition: funcapi.h:45
int natts
Definition: tupdesc.h:79
void pfree(void *pointer)
Definition: mcxt.c:949
TupleDesc tupdesc
Definition: funcapi.h:39
uintptr_t Datum
Definition: postgres.h:372
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1618
static Datum values[MAXATTR]
Definition: bootstrap.c:164
void * palloc(Size size)
Definition: mcxt.c:848
int i
FmgrInfo * attinfuncs
Definition: funcapi.h:42

◆ do_text_output_multiline()

void do_text_output_multiline ( TupOutputState tstate,
const char *  txt 
)

Definition at line 1281 of file execTuples.c.

References cstring_to_text_with_len(), DatumGetPointer, do_tup_output(), pfree(), PointerGetDatum, and values.

Referenced by ExplainQuery().

1282 {
1283  Datum values[1];
1284  bool isnull[1] = {false};
1285 
1286  while (*txt)
1287  {
1288  const char *eol;
1289  int len;
1290 
1291  eol = strchr(txt, '\n');
1292  if (eol)
1293  {
1294  len = eol - txt;
1295  eol++;
1296  }
1297  else
1298  {
1299  len = strlen(txt);
1300  eol = txt + len;
1301  }
1302 
1303  values[0] = PointerGetDatum(cstring_to_text_with_len(txt, len));
1304  do_tup_output(tstate, values, isnull);
1305  pfree(DatumGetPointer(values[0]));
1306  txt = eol;
1307  }
1308 }
#define PointerGetDatum(X)
Definition: postgres.h:562
void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull)
Definition: execTuples.c:1253
void pfree(void *pointer)
Definition: mcxt.c:949
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:161
uintptr_t Datum
Definition: postgres.h:372
#define DatumGetPointer(X)
Definition: postgres.h:555
static Datum values[MAXATTR]
Definition: bootstrap.c:164

◆ do_tup_output()

void do_tup_output ( TupOutputState tstate,
Datum values,
bool isnull 
)

Definition at line 1253 of file execTuples.c.

References TupOutputState::dest, ExecClearTuple(), ExecStoreVirtualTuple(), tupleDesc::natts, _DestReceiver::receiveSlot, TupOutputState::slot, TupleTableSlot::tts_isnull, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.

Referenced by CreateReplicationSlot(), do_text_output_multiline(), IdentifySystem(), ShowAllGUCConfig(), and StartReplication().

1254 {
1255  TupleTableSlot *slot = tstate->slot;
1256  int natts = slot->tts_tupleDescriptor->natts;
1257 
1258  /* make sure the slot is clear */
1259  ExecClearTuple(slot);
1260 
1261  /* insert data */
1262  memcpy(slot->tts_values, values, natts * sizeof(Datum));
1263  memcpy(slot->tts_isnull, isnull, natts * sizeof(bool));
1264 
1265  /* mark slot as containing a virtual tuple */
1266  ExecStoreVirtualTuple(slot);
1267 
1268  /* send the tuple to the receiver */
1269  (void) tstate->dest->receiveSlot(slot, tstate->dest);
1270 
1271  /* clean up */
1272  ExecClearTuple(slot);
1273 }
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
Definition: dest.h:118
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
Datum * tts_values
Definition: tuptable.h:125
TupleTableSlot * slot
Definition: executor.h:425
int natts
Definition: tupdesc.h:79
bool * tts_isnull
Definition: tuptable.h:126
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
uintptr_t Datum
Definition: postgres.h:372
static Datum values[MAXATTR]
Definition: bootstrap.c:164
DestReceiver * dest
Definition: executor.h:426
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:488

◆ end_tup_output()

void end_tup_output ( TupOutputState tstate)

Definition at line 1311 of file execTuples.c.

References TupOutputState::dest, ExecDropSingleTupleTableSlot(), pfree(), _DestReceiver::rShutdown, and TupOutputState::slot.

Referenced by CreateReplicationSlot(), ExplainQuery(), IdentifySystem(), ShowAllGUCConfig(), ShowGUCConfigOption(), and StartReplication().

1312 {
1313  tstate->dest->rShutdown(tstate->dest);
1314  /* note that destroying the dest is not ours to do */
1316  pfree(tstate);
1317 }
TupleTableSlot * slot
Definition: executor.h:425
void pfree(void *pointer)
Definition: mcxt.c:949
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:216
void(* rShutdown)(DestReceiver *self)
Definition: dest.h:124
DestReceiver * dest
Definition: executor.h:426

◆ ExecAllocTableSlot()

TupleTableSlot* ExecAllocTableSlot ( List **  tupleTable)

Definition at line 137 of file execTuples.c.

References lappend(), and MakeTupleTableSlot().

Referenced by ExecInitExtraTupleSlot(), ExecInitResultTupleSlot(), and ExecInitScanTupleSlot().

138 {
140 
141  *tupleTable = lappend(*tupleTable, slot);
142 
143  return slot;
144 }
TupleTableSlot * MakeTupleTableSlot(void)
Definition: execTuples.c:111
List * lappend(List *list, void *datum)
Definition: list.c:128

◆ ExecCleanTypeFromTL()

TupleDesc ExecCleanTypeFromTL ( List targetList,
bool  hasoid 
)

Definition at line 900 of file execTuples.c.

References ExecTypeFromTLInternal().

Referenced by ExecInitJunkFilter(), PlanCacheComputeResultDesc(), and PortalStart().

901 {
902  return ExecTypeFromTLInternal(targetList, hasoid, true);
903 }
static TupleDesc ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk)
Definition: execTuples.c:906

◆ ExecClearTuple()

TupleTableSlot* ExecClearTuple ( TupleTableSlot slot)

Definition at line 439 of file execTuples.c.

References Assert, BufferIsValid, heap_free_minimal_tuple(), heap_freetuple(), InvalidBuffer, ReleaseBuffer(), TupleTableSlot::tts_buffer, TupleTableSlot::tts_isempty, TupleTableSlot::tts_mintuple, TupleTableSlot::tts_nvalid, TupleTableSlot::tts_shouldFree, TupleTableSlot::tts_shouldFreeMin, and TupleTableSlot::tts_tuple.

Referenced by advance_aggregates(), agg_retrieve_hash_table(), apply_handle_update(), begin_partition(), BitmapHeapNext(), buildSubPlanHash(), CteScanNext(), do_tup_output(), eval_windowaggregates(), ExecAppend(), ExecDelete(), ExecDropSingleTupleTableSlot(), ExecEndAgg(), ExecEndBitmapHeapScan(), ExecEndCteScan(), ExecEndCustomScan(), ExecEndForeignScan(), ExecEndFunctionScan(), ExecEndGather(), ExecEndGatherMerge(), ExecEndGroup(), ExecEndHashJoin(), ExecEndIndexOnlyScan(), ExecEndIndexScan(), ExecEndMaterial(), ExecEndMergeJoin(), ExecEndModifyTable(), ExecEndNamedTuplestoreScan(), ExecEndNestLoop(), ExecEndProjectSet(), ExecEndRecursiveUnion(), ExecEndResult(), ExecEndSampleScan(), ExecEndSeqScan(), ExecEndSetOp(), ExecEndSort(), ExecEndSubqueryScan(), ExecEndTableFuncScan(), ExecEndTidScan(), ExecEndUnique(), ExecEndValuesScan(), ExecEndWindowAgg(), ExecEndWorkTableScan(), ExecFilterJunk(), ExecFindPartition(), ExecGather(), ExecHashJoinGetSavedTuple(), ExecHashSubPlan(), ExecMaterial(), ExecMergeAppend(), ExecProject(), ExecProjectSRF(), ExecReScanAgg(), ExecReScanCteScan(), ExecReScanFunctionScan(), ExecReScanGroup(), ExecReScanMaterial(), ExecReScanMergeJoin(), ExecReScanNamedTuplestoreScan(), ExecReScanSetOp(), ExecReScanSort(), ExecReScanTableFuncScan(), ExecReScanUnique(), ExecReScanValuesScan(), ExecReScanWindowAgg(), ExecReScanWorkTableScan(), ExecResetTupleTable(), ExecScan(), ExecScanFetch(), ExecSetSlotDescriptor(), ExecStoreAllNullTuple(), ExecUnique(), fetch_remote_table_info(), fetch_table_list(), fileIterateForeignScan(), FunctionNext(), gather_getnext(), gather_merge_clear_tuples(), gather_merge_init(), get_returning_data(), hypothetical_dense_rank_final(), hypothetical_rank_common(), IndexNext(), IndexNextWithReorder(), IndexOnlyNext(), lookup_hash_entry(), ordered_set_shutdown(), ordered_set_transition_multi(), per_MultiFuncCall(), postgresIterateDirectModify(), postgresIterateForeignScan(), process_ordered_aggregate_multi(), RunFromStore(), SampleNext(), SeqNext(), setop_retrieve_direct(), setop_retrieve_hash_table(), ShutdownSetExpr(), slot_modify_cstrings(), slot_store_cstrings(), StoreIndexTuple(), tfuncLoadRows(), TidNext(), tuplesort_gettupleslot(), tuplestore_gettupleslot(), ValuesNext(), and WinRowsArePeers().

440 {
441  /*
442  * sanity checks
443  */
444  Assert(slot != NULL);
445 
446  /*
447  * Free the old physical tuple if necessary.
448  */
449  if (slot->tts_shouldFree)
450  heap_freetuple(slot->tts_tuple);
451  if (slot->tts_shouldFreeMin)
453 
454  slot->tts_tuple = NULL;
455  slot->tts_mintuple = NULL;
456  slot->tts_shouldFree = false;
457  slot->tts_shouldFreeMin = false;
458 
459  /*
460  * Drop the pin on the referenced buffer, if there is one.
461  */
462  if (BufferIsValid(slot->tts_buffer))
463  ReleaseBuffer(slot->tts_buffer);
464 
465  slot->tts_buffer = InvalidBuffer;
466 
467  /*
468  * Mark it empty.
469  */
470  slot->tts_isempty = true;
471  slot->tts_nvalid = 0;
472 
473  return slot;
474 }
bool tts_isempty
Definition: tuptable.h:116
#define InvalidBuffer
Definition: buf.h:25
bool tts_shouldFreeMin
Definition: tuptable.h:118
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3309
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1373
void heap_free_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1468
bool tts_shouldFree
Definition: tuptable.h:117
#define Assert(condition)
Definition: c.h:670
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
MinimalTuple tts_mintuple
Definition: tuptable.h:127
HeapTuple tts_tuple
Definition: tuptable.h:120
Buffer tts_buffer
Definition: tuptable.h:123

◆ ExecCopySlot()

TupleTableSlot* ExecCopySlot ( TupleTableSlot dstslot,
TupleTableSlot srcslot 
)

Definition at line 795 of file execTuples.c.

References ExecCopySlotTuple(), ExecStoreTuple(), InvalidBuffer, MemoryContextSwitchTo(), and TupleTableSlot::tts_mcxt.

Referenced by begin_partition(), CteScanNext(), ExecGroup(), ExecUnique(), postgresRecheckForeignScan(), and spool_tuples().

796 {
797  HeapTuple newTuple;
798  MemoryContext oldContext;
799 
800  /*
801  * There might be ways to optimize this when the source is virtual, but
802  * for now just always build a physical copy. Make sure it is in the
803  * right context.
804  */
805  oldContext = MemoryContextSwitchTo(dstslot->tts_mcxt);
806  newTuple = ExecCopySlotTuple(srcslot);
807  MemoryContextSwitchTo(oldContext);
808 
809  return ExecStoreTuple(newTuple, dstslot, InvalidBuffer, true);
810 }
TupleTableSlot * ExecStoreTuple(HeapTuple tuple, TupleTableSlot *slot, Buffer buffer, bool shouldFree)
Definition: execTuples.c:320
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define InvalidBuffer
Definition: buf.h:25
MemoryContext tts_mcxt
Definition: tuptable.h:122
HeapTuple ExecCopySlotTuple(TupleTableSlot *slot)
Definition: execTuples.c:545

◆ ExecCopySlotMinimalTuple()

MinimalTuple ExecCopySlotMinimalTuple ( TupleTableSlot slot)

Definition at line 577 of file execTuples.c.

References Assert, heap_copy_minimal_tuple(), heap_form_minimal_tuple(), minimal_tuple_from_heap_tuple(), TupleTableSlot::tts_isempty, TupleTableSlot::tts_isnull, TupleTableSlot::tts_mintuple, TupleTableSlot::tts_tuple, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.

Referenced by copytup_heap(), ExecFetchSlotMinimalTuple(), LookupTupleHashEntry(), and tuplestore_puttupleslot().

578 {
579  /*
580  * sanity checks
581  */
582  Assert(slot != NULL);
583  Assert(!slot->tts_isempty);
584 
585  /*
586  * If we have a physical tuple then just copy it. Prefer to copy
587  * tts_mintuple since that's a tad cheaper.
588  */
589  if (slot->tts_mintuple)
591  if (slot->tts_tuple)
593 
594  /*
595  * Otherwise we need to build a tuple from the Datum array.
596  */
598  slot->tts_values,
599  slot->tts_isnull);
600 }
bool tts_isempty
Definition: tuptable.h:116
Datum * tts_values
Definition: tuptable.h:125
MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1480
bool * tts_isnull
Definition: tuptable.h:126
MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1391
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
#define Assert(condition)
Definition: c.h:670
MinimalTuple tts_mintuple
Definition: tuptable.h:127
MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup)
Definition: heaptuple.c:1521
HeapTuple tts_tuple
Definition: tuptable.h:120

◆ ExecCopySlotTuple()

HeapTuple ExecCopySlotTuple ( TupleTableSlot slot)

Definition at line 545 of file execTuples.c.

References Assert, heap_copytuple(), heap_form_tuple(), heap_tuple_from_minimal_tuple(), TTS_HAS_PHYSICAL_TUPLE, TupleTableSlot::tts_isempty, TupleTableSlot::tts_isnull, TupleTableSlot::tts_mintuple, TupleTableSlot::tts_tuple, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.

Referenced by agg_retrieve_direct(), ExecCopySlot(), ExecMaterializeSlot(), ExecScanSubPlan(), ExecSetParamPlan(), setop_retrieve_direct(), and spi_printtup().

546 {
547  /*
548  * sanity checks
549  */
550  Assert(slot != NULL);
551  Assert(!slot->tts_isempty);
552 
553  /*
554  * If we have a physical tuple (either format) then just copy it.
555  */
556  if (TTS_HAS_PHYSICAL_TUPLE(slot))
557  return heap_copytuple(slot->tts_tuple);
558  if (slot->tts_mintuple)
560 
561  /*
562  * Otherwise we need to build a tuple from the Datum array.
563  */
565  slot->tts_values,
566  slot->tts_isnull);
567 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:611
bool tts_isempty
Definition: tuptable.h:116
Datum * tts_values
Definition: tuptable.h:125
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:695
bool * tts_isnull
Definition: tuptable.h:126
HeapTuple heap_tuple_from_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1499
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
#define Assert(condition)
Definition: c.h:670
MinimalTuple tts_mintuple
Definition: tuptable.h:127
HeapTuple tts_tuple
Definition: tuptable.h:120
#define TTS_HAS_PHYSICAL_TUPLE(slot)
Definition: tuptable.h:132

◆ ExecDropSingleTupleTableSlot()

void ExecDropSingleTupleTableSlot ( TupleTableSlot slot)

Definition at line 216 of file execTuples.c.

References Assert, ExecClearTuple(), IsA, pfree(), ReleaseTupleDesc, TupleTableSlot::tts_isnull, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.

Referenced by afterTriggerInvokeEvents(), ATRewriteTable(), CatalogIndexInsert(), check_default_allows_bound(), check_exclusion_or_unique_constraint(), compute_index_stats(), CopyFrom(), end_tup_output(), ExecEndModifyTable(), fetch_remote_table_info(), fetch_table_list(), get_actual_variable_range(), hypothetical_dense_rank_final(), IndexBuildHeapRangeScan(), IndexCheckExclusion(), RunFromStore(), tuplesort_end(), unique_key_recheck(), validate_index_heapscan(), and validateCheckConstraint().

217 {
218  /* This should match ExecResetTupleTable's processing of one slot */
219  Assert(IsA(slot, TupleTableSlot));
220  ExecClearTuple(slot);
221  if (slot->tts_tupleDescriptor)
223  if (slot->tts_values)
224  pfree(slot->tts_values);
225  if (slot->tts_isnull)
226  pfree(slot->tts_isnull);
227  pfree(slot);
228 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:562
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
Datum * tts_values
Definition: tuptable.h:125
void pfree(void *pointer)
Definition: mcxt.c:949
bool * tts_isnull
Definition: tuptable.h:126
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
#define Assert(condition)
Definition: c.h:670
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:121

◆ ExecFetchSlotMinimalTuple()

MinimalTuple ExecFetchSlotMinimalTuple ( TupleTableSlot slot)

Definition at line 652 of file execTuples.c.

References Assert, ExecCopySlotMinimalTuple(), MemoryContextSwitchTo(), TupleTableSlot::tts_isempty, TupleTableSlot::tts_mcxt, TupleTableSlot::tts_mintuple, and TupleTableSlot::tts_shouldFreeMin.

Referenced by ExecHashJoin(), ExecHashSkewTableInsert(), and ExecHashTableInsert().

653 {
654  MemoryContext oldContext;
655 
656  /*
657  * sanity checks
658  */
659  Assert(slot != NULL);
660  Assert(!slot->tts_isempty);
661 
662  /*
663  * If we have a minimal physical tuple (local or not) then just return it.
664  */
665  if (slot->tts_mintuple)
666  return slot->tts_mintuple;
667 
668  /*
669  * Otherwise, copy or build a minimal tuple, and store it into the slot.
670  *
671  * We may be called in a context that is shorter-lived than the tuple
672  * slot, but we have to ensure that the materialized tuple will survive
673  * anyway.
674  */
675  oldContext = MemoryContextSwitchTo(slot->tts_mcxt);
677  slot->tts_shouldFreeMin = true;
678  MemoryContextSwitchTo(oldContext);
679 
680  /*
681  * Note: we may now have a situation where we have a local minimal tuple
682  * attached to a virtual or non-local physical tuple. There seems no harm
683  * in that at the moment, but if any materializes, we should change this
684  * function to force the slot into minimal-tuple-only state.
685  */
686 
687  return slot->tts_mintuple;
688 }
bool tts_isempty
Definition: tuptable.h:116
MinimalTuple ExecCopySlotMinimalTuple(TupleTableSlot *slot)
Definition: execTuples.c:577
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
bool tts_shouldFreeMin
Definition: tuptable.h:118
MemoryContext tts_mcxt
Definition: tuptable.h:122
#define Assert(condition)
Definition: c.h:670
MinimalTuple tts_mintuple
Definition: tuptable.h:127

◆ ExecFetchSlotTuple()

HeapTuple ExecFetchSlotTuple ( TupleTableSlot slot)

Definition at line 618 of file execTuples.c.

References Assert, ExecMaterializeSlot(), TTS_HAS_PHYSICAL_TUPLE, TupleTableSlot::tts_isempty, and TupleTableSlot::tts_tuple.

Referenced by ExecConstraints(), ExecFetchSlotTupleDatum(), ExecFindPartition(), ExecPartitionCheck(), and ExecWithCheckOptions().

619 {
620  /*
621  * sanity checks
622  */
623  Assert(slot != NULL);
624  Assert(!slot->tts_isempty);
625 
626  /*
627  * If we have a regular physical tuple then just return it.
628  */
629  if (TTS_HAS_PHYSICAL_TUPLE(slot))
630  return slot->tts_tuple;
631 
632  /*
633  * Otherwise materialize the slot...
634  */
635  return ExecMaterializeSlot(slot);
636 }
bool tts_isempty
Definition: tuptable.h:116
#define Assert(condition)
Definition: c.h:670
HeapTuple ExecMaterializeSlot(TupleTableSlot *slot)
Definition: execTuples.c:725
HeapTuple tts_tuple
Definition: tuptable.h:120
#define TTS_HAS_PHYSICAL_TUPLE(slot)
Definition: tuptable.h:132

◆ ExecFetchSlotTupleDatum()

Datum ExecFetchSlotTupleDatum ( TupleTableSlot slot)

Definition at line 698 of file execTuples.c.

References ExecFetchSlotTuple(), heap_copy_tuple_as_datum(), and TupleTableSlot::tts_tupleDescriptor.

Referenced by ExecMakeFunctionResultSet(), and postquel_get_single_result().

699 {
700  HeapTuple tup;
701  TupleDesc tupdesc;
702 
703  /* Fetch slot's contents in regular-physical-tuple form */
704  tup = ExecFetchSlotTuple(slot);
705  tupdesc = slot->tts_tupleDescriptor;
706 
707  /* Convert to Datum form */
708  return heap_copy_tuple_as_datum(tup, tupdesc);
709 }
Datum heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc)
Definition: heaptuple.c:659
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
HeapTuple ExecFetchSlotTuple(TupleTableSlot *slot)
Definition: execTuples.c:618

◆ ExecInitExtraTupleSlot()

◆ ExecInitNullTupleSlot()

TupleTableSlot* ExecInitNullTupleSlot ( EState estate,
TupleDesc  tupType 
)

Definition at line 866 of file execTuples.c.

References ExecInitExtraTupleSlot(), ExecSetSlotDescriptor(), and ExecStoreAllNullTuple().

Referenced by ExecInitHashJoin(), ExecInitMergeJoin(), and ExecInitNestLoop().

867 {
868  TupleTableSlot *slot = ExecInitExtraTupleSlot(estate);
869 
870  ExecSetSlotDescriptor(slot, tupType);
871 
872  return ExecStoreAllNullTuple(slot);
873 }
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate)
Definition: execTuples.c:852
TupleTableSlot * ExecStoreAllNullTuple(TupleTableSlot *slot)
Definition: execTuples.c:512
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:247

◆ ExecInitResultTupleSlot()

◆ ExecInitScanTupleSlot()

◆ ExecMaterializeSlot()

HeapTuple ExecMaterializeSlot ( TupleTableSlot slot)

Definition at line 725 of file execTuples.c.

References Assert, BufferIsValid, ExecCopySlotTuple(), InvalidBuffer, MemoryContextSwitchTo(), ReleaseBuffer(), TupleTableSlot::tts_buffer, TupleTableSlot::tts_isempty, TupleTableSlot::tts_mcxt, TupleTableSlot::tts_mintuple, TupleTableSlot::tts_nvalid, TupleTableSlot::tts_shouldFree, TupleTableSlot::tts_shouldFreeMin, and TupleTableSlot::tts_tuple.

Referenced by AfterTriggerExecute(), CopyFrom(), EvalPlanQual(), ExecBRInsertTriggers(), ExecBRUpdateTriggers(), ExecDelete(), ExecFetchSlotTuple(), ExecInsert(), ExecIRInsertTriggers(), ExecIRUpdateTriggers(), ExecProcessReturning(), ExecSimpleRelationInsert(), ExecSimpleRelationUpdate(), ExecUpdate(), ForeignNext(), intorel_receive(), RelationFindReplTupleByIndex(), RelationFindReplTupleSeq(), tqueueReceiveSlot(), and transientrel_receive().

726 {
727  MemoryContext oldContext;
728 
729  /*
730  * sanity checks
731  */
732  Assert(slot != NULL);
733  Assert(!slot->tts_isempty);
734 
735  /*
736  * If we have a regular physical tuple, and it's locally palloc'd, we have
737  * nothing to do.
738  */
739  if (slot->tts_tuple && slot->tts_shouldFree)
740  return slot->tts_tuple;
741 
742  /*
743  * Otherwise, copy or build a physical tuple, and store it into the slot.
744  *
745  * We may be called in a context that is shorter-lived than the tuple
746  * slot, but we have to ensure that the materialized tuple will survive
747  * anyway.
748  */
749  oldContext = MemoryContextSwitchTo(slot->tts_mcxt);
750  slot->tts_tuple = ExecCopySlotTuple(slot);
751  slot->tts_shouldFree = true;
752  MemoryContextSwitchTo(oldContext);
753 
754  /*
755  * Drop the pin on the referenced buffer, if there is one.
756  */
757  if (BufferIsValid(slot->tts_buffer))
758  ReleaseBuffer(slot->tts_buffer);
759 
760  slot->tts_buffer = InvalidBuffer;
761 
762  /*
763  * Mark extracted state invalid. This is important because the slot is
764  * not supposed to depend any more on the previous external data; we
765  * mustn't leave any dangling pass-by-reference datums in tts_values.
766  * However, we have not actually invalidated any such datums, if there
767  * happen to be any previously fetched from the slot. (Note in particular
768  * that we have not pfree'd tts_mintuple, if there is one.)
769  */
770  slot->tts_nvalid = 0;
771 
772  /*
773  * On the same principle of not depending on previous remote storage,
774  * forget the mintuple if it's not local storage. (If it is local
775  * storage, we must not pfree it now, since callers might have already
776  * fetched datum pointers referencing it.)
777  */
778  if (!slot->tts_shouldFreeMin)
779  slot->tts_mintuple = NULL;
780 
781  return slot->tts_tuple;
782 }
bool tts_isempty
Definition: tuptable.h:116
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define InvalidBuffer
Definition: buf.h:25
bool tts_shouldFreeMin
Definition: tuptable.h:118
MemoryContext tts_mcxt
Definition: tuptable.h:122
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3309
bool tts_shouldFree
Definition: tuptable.h:117
HeapTuple ExecCopySlotTuple(TupleTableSlot *slot)
Definition: execTuples.c:545
#define Assert(condition)
Definition: c.h:670
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
MinimalTuple tts_mintuple
Definition: tuptable.h:127
HeapTuple tts_tuple
Definition: tuptable.h:120
Buffer tts_buffer
Definition: tuptable.h:123

◆ ExecResetTupleTable()

void ExecResetTupleTable ( List tupleTable,
bool  shouldFree 
)

Definition at line 156 of file execTuples.c.

References ExecClearTuple(), lfirst_node, list_free(), pfree(), ReleaseTupleDesc, TupleTableSlot::tts_isnull, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.

Referenced by apply_handle_delete(), apply_handle_insert(), apply_handle_update(), CopyFrom(), EvalPlanQualEnd(), and ExecEndPlan().

158 {
159  ListCell *lc;
160 
161  foreach(lc, tupleTable)
162  {
164 
165  /* Always release resources and reset the slot to empty */
166  ExecClearTuple(slot);
167  if (slot->tts_tupleDescriptor)
168  {
170  slot->tts_tupleDescriptor = NULL;
171  }
172 
173  /* If shouldFree, release memory occupied by the slot itself */
174  if (shouldFree)
175  {
176  if (slot->tts_values)
177  pfree(slot->tts_values);
178  if (slot->tts_isnull)
179  pfree(slot->tts_isnull);
180  pfree(slot);
181  }
182  }
183 
184  /* If shouldFree, release the list structure */
185  if (shouldFree)
186  list_free(tupleTable);
187 }
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
Datum * tts_values
Definition: tuptable.h:125
void pfree(void *pointer)
Definition: mcxt.c:949
#define lfirst_node(type, lc)
Definition: pg_list.h:109
bool * tts_isnull
Definition: tuptable.h:126
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
void list_free(List *list)
Definition: list.c:1133
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:121

◆ ExecSetSlotDescriptor()

void ExecSetSlotDescriptor ( TupleTableSlot slot,
TupleDesc  tupdesc 
)

Definition at line 247 of file execTuples.c.

References ExecClearTuple(), MemoryContextAlloc(), tupleDesc::natts, pfree(), PinTupleDesc, ReleaseTupleDesc, TupleTableSlot::tts_isnull, TupleTableSlot::tts_mcxt, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.

Referenced by apply_handle_delete(), apply_handle_insert(), apply_handle_update(), build_pertrans_for_aggref(), CopyFrom(), ExecAssignResultType(), ExecAssignScanType(), ExecBRInsertTriggers(), ExecBRUpdateTriggers(), ExecConstraints(), ExecDelete(), ExecInitAgg(), ExecInitFunctionScan(), ExecInitGather(), ExecInitHashJoin(), ExecInitJunkFilter(), ExecInitJunkFilterConversion(), ExecInitMergeJoin(), ExecInitModifyTable(), ExecInitNullTupleSlot(), ExecInitSubPlan(), ExecInitWindowAgg(), ExecInsert(), ExecIRInsertTriggers(), ExecIRUpdateTriggers(), ExecPartitionCheck(), ExecWithCheckOptions(), find_hash_columns(), gather_merge_setup(), MakeSingleTupleTableSlot(), and TriggerEnabled().

249 {
250  /* For safety, make sure slot is empty before changing it */
251  ExecClearTuple(slot);
252 
253  /*
254  * Release any old descriptor. Also release old Datum/isnull arrays if
255  * present (we don't bother to check if they could be re-used).
256  */
257  if (slot->tts_tupleDescriptor)
259 
260  if (slot->tts_values)
261  pfree(slot->tts_values);
262  if (slot->tts_isnull)
263  pfree(slot->tts_isnull);
264 
265  /*
266  * Install the new descriptor; if it's refcounted, bump its refcount.
267  */
268  slot->tts_tupleDescriptor = tupdesc;
269  PinTupleDesc(tupdesc);
270 
271  /*
272  * Allocate Datum/isnull arrays of the appropriate size. These must have
273  * the same lifetime as the slot, so allocate in the slot's own context.
274  */
275  slot->tts_values = (Datum *)
276  MemoryContextAlloc(slot->tts_mcxt, tupdesc->natts * sizeof(Datum));
277  slot->tts_isnull = (bool *)
278  MemoryContextAlloc(slot->tts_mcxt, tupdesc->natts * sizeof(bool));
279 }
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
MemoryContext tts_mcxt
Definition: tuptable.h:122
Datum * tts_values
Definition: tuptable.h:125
int natts
Definition: tupdesc.h:79
void pfree(void *pointer)
Definition: mcxt.c:949
bool * tts_isnull
Definition: tuptable.h:126
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
uintptr_t Datum
Definition: postgres.h:372
#define PinTupleDesc(tupdesc)
Definition: tupdesc.h:115
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:706
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:121

◆ ExecStoreAllNullTuple()

TupleTableSlot* ExecStoreAllNullTuple ( TupleTableSlot slot)

Definition at line 512 of file execTuples.c.

References Assert, ExecClearTuple(), ExecStoreVirtualTuple(), MemSet, tupleDesc::natts, TupleTableSlot::tts_isnull, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.

Referenced by BitmapHeapNext(), ExecDelete(), ExecInitNullTupleSlot(), get_returning_data(), and prepare_projection_slot().

513 {
514  /*
515  * sanity checks
516  */
517  Assert(slot != NULL);
518  Assert(slot->tts_tupleDescriptor != NULL);
519 
520  /* Clear any old contents */
521  ExecClearTuple(slot);
522 
523  /*
524  * Fill all the columns of the virtual tuple with nulls
525  */
526  MemSet(slot->tts_values, 0,
527  slot->tts_tupleDescriptor->natts * sizeof(Datum));
528  memset(slot->tts_isnull, true,
529  slot->tts_tupleDescriptor->natts * sizeof(bool));
530 
531  return ExecStoreVirtualTuple(slot);
532 }
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
#define MemSet(start, val, len)
Definition: c.h:853
Datum * tts_values
Definition: tuptable.h:125
int natts
Definition: tupdesc.h:79
bool * tts_isnull
Definition: tuptable.h:126
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
uintptr_t Datum
Definition: postgres.h:372
#define Assert(condition)
Definition: c.h:670
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:488

◆ ExecStoreMinimalTuple()

TupleTableSlot* ExecStoreMinimalTuple ( MinimalTuple  mtup,
TupleTableSlot slot,
bool  shouldFree 
)

Definition at line 384 of file execTuples.c.

References Assert, BufferIsValid, heap_free_minimal_tuple(), heap_freetuple(), InvalidBuffer, MINIMAL_TUPLE_OFFSET, ReleaseBuffer(), HeapTupleData::t_data, HeapTupleData::t_len, MinimalTupleData::t_len, TupleTableSlot::tts_buffer, TupleTableSlot::tts_isempty, TupleTableSlot::tts_minhdr, TupleTableSlot::tts_mintuple, TupleTableSlot::tts_nvalid, TupleTableSlot::tts_shouldFree, TupleTableSlot::tts_shouldFreeMin, TupleTableSlot::tts_tuple, and TupleTableSlot::tts_tupleDescriptor.

Referenced by agg_retrieve_hash_table(), ExecHashJoinGetSavedTuple(), ExecScanHashBucket(), ExecScanHashTableForUnmatched(), findPartialMatch(), setop_retrieve_hash_table(), TupleHashTableHash(), TupleHashTableMatch(), tuplesort_gettupleslot(), and tuplestore_gettupleslot().

387 {
388  /*
389  * sanity checks
390  */
391  Assert(mtup != NULL);
392  Assert(slot != NULL);
393  Assert(slot->tts_tupleDescriptor != NULL);
394 
395  /*
396  * Free any old physical tuple belonging to the slot.
397  */
398  if (slot->tts_shouldFree)
399  heap_freetuple(slot->tts_tuple);
400  if (slot->tts_shouldFreeMin)
402 
403  /*
404  * Drop the pin on the referenced buffer, if there is one.
405  */
406  if (BufferIsValid(slot->tts_buffer))
407  ReleaseBuffer(slot->tts_buffer);
408 
409  slot->tts_buffer = InvalidBuffer;
410 
411  /*
412  * Store the new tuple into the specified slot.
413  */
414  slot->tts_isempty = false;
415  slot->tts_shouldFree = false;
416  slot->tts_shouldFreeMin = shouldFree;
417  slot->tts_tuple = &slot->tts_minhdr;
418  slot->tts_mintuple = mtup;
419 
420  slot->tts_minhdr.t_len = mtup->t_len + MINIMAL_TUPLE_OFFSET;
421  slot->tts_minhdr.t_data = (HeapTupleHeader) ((char *) mtup - MINIMAL_TUPLE_OFFSET);
422  /* no need to set t_self or t_tableOid since we won't allow access */
423 
424  /* Mark extracted state invalid */
425  slot->tts_nvalid = 0;
426 
427  return slot;
428 }
bool tts_isempty
Definition: tuptable.h:116
HeapTupleHeaderData * HeapTupleHeader
Definition: htup.h:23
#define InvalidBuffer
Definition: buf.h:25
bool tts_shouldFreeMin
Definition: tuptable.h:118
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3309
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1373
HeapTupleHeader t_data
Definition: htup.h:67
HeapTupleData tts_minhdr
Definition: tuptable.h:128
void heap_free_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1468
uint32 t_len
Definition: htup.h:64
bool tts_shouldFree
Definition: tuptable.h:117
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
#define Assert(condition)
Definition: c.h:670
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
MinimalTuple tts_mintuple
Definition: tuptable.h:127
#define MINIMAL_TUPLE_OFFSET
Definition: htup_details.h:625
HeapTuple tts_tuple
Definition: tuptable.h:120
Buffer tts_buffer
Definition: tuptable.h:123

◆ ExecStoreTuple()

TupleTableSlot* ExecStoreTuple ( HeapTuple  tuple,
TupleTableSlot slot,
Buffer  buffer,
bool  shouldFree 
)

Definition at line 320 of file execTuples.c.

References Assert, buffer, BufferIsValid, heap_free_minimal_tuple(), heap_freetuple(), IncrBufferRefCount(), ReleaseBuffer(), TupleTableSlot::tts_buffer, TupleTableSlot::tts_isempty, TupleTableSlot::tts_mintuple, TupleTableSlot::tts_nvalid, TupleTableSlot::tts_shouldFree, TupleTableSlot::tts_shouldFreeMin, TupleTableSlot::tts_tuple, and TupleTableSlot::tts_tupleDescriptor.

Referenced by agg_retrieve_direct(), apply_handle_update(), ATRewriteTable(), BitmapHeapNext(), CatalogIndexInsert(), check_default_allows_bound(), check_exclusion_or_unique_constraint(), comparetup_cluster(), compute_index_stats(), CopyFrom(), CopyFromInsertBatch(), ExecBRInsertTriggers(), ExecBRUpdateTriggers(), ExecConstraints(), ExecCopySlot(), ExecDelete(), ExecFindPartition(), ExecInsert(), ExecIRInsertTriggers(), ExecIRUpdateTriggers(), ExecOnConflictUpdate(), ExecPartitionCheck(), ExecScanFetch(), ExecWithCheckOptions(), gather_getnext(), gather_merge_readnext(), get_actual_variable_range(), get_returning_data(), IndexBuildHeapRangeScan(), IndexCheckExclusion(), IndexNext(), IndexNextWithReorder(), IndexOnlyNext(), postgresIterateForeignScan(), RelationFindReplTupleByIndex(), RelationFindReplTupleSeq(), SampleNext(), SeqNext(), setop_retrieve_direct(), store_returning_result(), TidNext(), TriggerEnabled(), unique_key_recheck(), validate_index_heapscan(), and validateCheckConstraint().

324 {
325  /*
326  * sanity checks
327  */
328  Assert(tuple != NULL);
329  Assert(slot != NULL);
330  Assert(slot->tts_tupleDescriptor != NULL);
331  /* passing shouldFree=true for a tuple on a disk page is not sane */
332  Assert(BufferIsValid(buffer) ? (!shouldFree) : true);
333 
334  /*
335  * Free any old physical tuple belonging to the slot.
336  */
337  if (slot->tts_shouldFree)
338  heap_freetuple(slot->tts_tuple);
339  if (slot->tts_shouldFreeMin)
341 
342  /*
343  * Store the new tuple into the specified slot.
344  */
345  slot->tts_isempty = false;
346  slot->tts_shouldFree = shouldFree;
347  slot->tts_shouldFreeMin = false;
348  slot->tts_tuple = tuple;
349  slot->tts_mintuple = NULL;
350 
351  /* Mark extracted state invalid */
352  slot->tts_nvalid = 0;
353 
354  /*
355  * If tuple is on a disk page, keep the page pinned as long as we hold a
356  * pointer into it. We assume the caller already has such a pin.
357  *
358  * This is coded to optimize the case where the slot previously held a
359  * tuple on the same disk page: in that case releasing and re-acquiring
360  * the pin is a waste of cycles. This is a common situation during
361  * seqscans, so it's worth troubling over.
362  */
363  if (slot->tts_buffer != buffer)
364  {
365  if (BufferIsValid(slot->tts_buffer))
366  ReleaseBuffer(slot->tts_buffer);
367  slot->tts_buffer = buffer;
368  if (BufferIsValid(buffer))
370  }
371 
372  return slot;
373 }
bool tts_isempty
Definition: tuptable.h:116
bool tts_shouldFreeMin
Definition: tuptable.h:118
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3309
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1373
void heap_free_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1468
bool tts_shouldFree
Definition: tuptable.h:117
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
#define Assert(condition)
Definition: c.h:670
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
MinimalTuple tts_mintuple
Definition: tuptable.h:127
HeapTuple tts_tuple
Definition: tuptable.h:120
Buffer tts_buffer
Definition: tuptable.h:123
void IncrBufferRefCount(Buffer buffer)
Definition: bufmgr.c:3347

◆ ExecStoreVirtualTuple()

◆ ExecTypeFromExprList()

TupleDesc ExecTypeFromExprList ( List exprList)

Definition at line 947 of file execTuples.c.

References CreateTemplateTupleDesc(), exprCollation(), exprType(), exprTypmod(), lfirst, list_length(), TupleDescInitEntry(), and TupleDescInitEntryCollation().

Referenced by ExecInitExprRec(), and ExecInitValuesScan().

948 {
949  TupleDesc typeInfo;
950  ListCell *lc;
951  int cur_resno = 1;
952 
953  typeInfo = CreateTemplateTupleDesc(list_length(exprList), false);
954 
955  foreach(lc, exprList)
956  {
957  Node *e = lfirst(lc);
958 
959  TupleDescInitEntry(typeInfo,
960  cur_resno,
961  NULL,
962  exprType(e),
963  exprTypmod(e),
964  0);
966  cur_resno,
967  exprCollation(e));
968  cur_resno++;
969  }
970 
971  return typeInfo;
972 }
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:276
Definition: nodes.h:511
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:664
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:505
#define lfirst(lc)
Definition: pg_list.h:106
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
static int list_length(const List *l)
Definition: pg_list.h:89
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:720
TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid)
Definition: tupdesc.c:43
e
Definition: preproc-init.c:82

◆ ExecTypeFromTL()

TupleDesc ExecTypeFromTL ( List targetList,
bool  hasoid 
)

Definition at line 888 of file execTuples.c.

References ExecTypeFromTLInternal().

Referenced by build_pertrans_for_aggref(), ExecAssignResultTypeFromTL(), ExecInitAgg(), ExecInitCustomScan(), ExecInitForeignScan(), ExecInitGather(), ExecInitGatherMerge(), ExecInitIndexOnlyScan(), ExecInitModifyTable(), ExecInitSubPlan(), find_hash_columns(), and ordered_set_startup().

889 {
890  return ExecTypeFromTLInternal(targetList, hasoid, false);
891 }
static TupleDesc ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk)
Definition: execTuples.c:906

◆ ExecTypeFromTLInternal()

static TupleDesc ExecTypeFromTLInternal ( List targetList,
bool  hasoid,
bool  skipjunk 
)
static

Definition at line 906 of file execTuples.c.

References CreateTemplateTupleDesc(), ExecCleanTargetListLength(), ExecTargetListLength(), TargetEntry::expr, exprCollation(), exprType(), exprTypmod(), lfirst, TargetEntry::resjunk, TargetEntry::resname, TupleDescInitEntry(), and TupleDescInitEntryCollation().

Referenced by ExecCleanTypeFromTL(), and ExecTypeFromTL().

907 {
908  TupleDesc typeInfo;
909  ListCell *l;
910  int len;
911  int cur_resno = 1;
912 
913  if (skipjunk)
914  len = ExecCleanTargetListLength(targetList);
915  else
916  len = ExecTargetListLength(targetList);
917  typeInfo = CreateTemplateTupleDesc(len, hasoid);
918 
919  foreach(l, targetList)
920  {
921  TargetEntry *tle = lfirst(l);
922 
923  if (skipjunk && tle->resjunk)
924  continue;
925  TupleDescInitEntry(typeInfo,
926  cur_resno,
927  tle->resname,
928  exprType((Node *) tle->expr),
929  exprTypmod((Node *) tle->expr),
930  0);
932  cur_resno,
933  exprCollation((Node *) tle->expr));
934  cur_resno++;
935  }
936 
937  return typeInfo;
938 }
int ExecTargetListLength(List *targetlist)
Definition: execUtils.c:1006
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:276
Definition: nodes.h:511
char * resname
Definition: primnodes.h:1377
bool resjunk
Definition: primnodes.h:1382
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:664
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:505
int ExecCleanTargetListLength(List *targetlist)
Definition: execUtils.c:1016
#define lfirst(lc)
Definition: pg_list.h:106
Expr * expr
Definition: primnodes.h:1375
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:720
TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid)
Definition: tupdesc.c:43

◆ ExecTypeSetColNames()

void ExecTypeSetColNames ( TupleDesc  typeInfo,
List namesList 
)

Definition at line 986 of file execTuples.c.

References lfirst, NameStr, namestrcpy(), tupleDesc::natts, RECORDOID, strVal, tupleDesc::tdtypeid, tupleDesc::tdtypmod, and TupleDescAttr.

Referenced by ExecEvalWholeRowVar(), and ExecInitExprRec().

987 {
988  bool modified = false;
989  int colno = 0;
990  ListCell *lc;
991 
992  foreach(lc, namesList)
993  {
994  char *cname = strVal(lfirst(lc));
995  Form_pg_attribute attr;
996 
997  /* Guard against too-long names list */
998  if (colno >= typeInfo->natts)
999  break;
1000  attr = TupleDescAttr(typeInfo, colno);
1001  colno++;
1002 
1003  /* Ignore empty aliases (these must be for dropped columns) */
1004  if (cname[0] == '\0')
1005  continue;
1006 
1007  /* Change tupdesc only if alias is actually different */
1008  if (strcmp(cname, NameStr(attr->attname)) != 0)
1009  {
1010  namestrcpy(&(attr->attname), cname);
1011  modified = true;
1012  }
1013  }
1014 
1015  /* If we modified the tupdesc, it's now a new record type */
1016  if (modified)
1017  {
1018  typeInfo->tdtypeid = RECORDOID;
1019  typeInfo->tdtypmod = -1;
1020  }
1021 }
Oid tdtypeid
Definition: tupdesc.h:80
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:90
#define strVal(v)
Definition: value.h:54
int namestrcpy(Name name, const char *str)
Definition: name.c:216
int natts
Definition: tupdesc.h:79
int32 tdtypmod
Definition: tupdesc.h:81
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
#define RECORDOID
Definition: pg_type.h:680
#define lfirst(lc)
Definition: pg_list.h:106
#define NameStr(name)
Definition: c.h:547

◆ HeapTupleHeaderGetDatum()

Datum HeapTupleHeaderGetDatum ( HeapTupleHeader  tuple)

Definition at line 1204 of file execTuples.c.

References HeapTupleHeaderGetDatumLength, HeapTupleHeaderGetTypeId, HeapTupleHeaderGetTypMod, HeapTupleHeaderHasExternal, lookup_rowtype_tupdesc(), PointerGetDatum, ReleaseTupleDesc, and toast_flatten_tuple_to_datum().

Referenced by populate_composite(), and populate_recordset_record().

1205 {
1206  Datum result;
1207  TupleDesc tupDesc;
1208 
1209  /* No work if there are no external TOAST pointers in the tuple */
1210  if (!HeapTupleHeaderHasExternal(tuple))
1211  return PointerGetDatum(tuple);
1212 
1213  /* Use the type data saved by heap_form_tuple to look up the rowtype */
1215  HeapTupleHeaderGetTypMod(tuple));
1216 
1217  /* And do the flattening */
1218  result = toast_flatten_tuple_to_datum(tuple,
1220  tupDesc);
1221 
1222  ReleaseTupleDesc(tupDesc);
1223 
1224  return result;
1225 }
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1618
#define PointerGetDatum(X)
Definition: postgres.h:562
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:460
Datum toast_flatten_tuple_to_datum(HeapTupleHeader tup, uint32 tup_len, TupleDesc tupleDesc)
Definition: tuptoaster.c:1187
uintptr_t Datum
Definition: postgres.h:372
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:450
#define HeapTupleHeaderHasExternal(tup)
Definition: htup_details.h:545
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:121
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:444

◆ MakeSingleTupleTableSlot()

◆ MakeTupleTableSlot()

TupleTableSlot* MakeTupleTableSlot ( void  )

Definition at line 111 of file execTuples.c.

References CurrentMemoryContext, InvalidBuffer, makeNode, TupleTableSlot::tts_buffer, TupleTableSlot::tts_isempty, TupleTableSlot::tts_isnull, TupleTableSlot::tts_mcxt, TupleTableSlot::tts_mintuple, TupleTableSlot::tts_nvalid, TupleTableSlot::tts_shouldFree, TupleTableSlot::tts_shouldFreeMin, TupleTableSlot::tts_tuple, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.

Referenced by ExecAllocTableSlot(), ExecSetupPartitionTupleRouting(), and MakeSingleTupleTableSlot().

112 {
114 
115  slot->tts_isempty = true;
116  slot->tts_shouldFree = false;
117  slot->tts_shouldFreeMin = false;
118  slot->tts_tuple = NULL;
119  slot->tts_tupleDescriptor = NULL;
121  slot->tts_buffer = InvalidBuffer;
122  slot->tts_nvalid = 0;
123  slot->tts_values = NULL;
124  slot->tts_isnull = NULL;
125  slot->tts_mintuple = NULL;
126 
127  return slot;
128 }
bool tts_isempty
Definition: tuptable.h:116
#define InvalidBuffer
Definition: buf.h:25
bool tts_shouldFreeMin
Definition: tuptable.h:118
MemoryContext tts_mcxt
Definition: tuptable.h:122
Datum * tts_values
Definition: tuptable.h:125
bool * tts_isnull
Definition: tuptable.h:126
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
bool tts_shouldFree
Definition: tuptable.h:117
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
#define makeNode(_type_)
Definition: nodes.h:559
MinimalTuple tts_mintuple
Definition: tuptable.h:127
HeapTuple tts_tuple
Definition: tuptable.h:120
Buffer tts_buffer
Definition: tuptable.h:123

◆ TupleDescGetAttInMetadata()

AttInMetadata* TupleDescGetAttInMetadata ( TupleDesc  tupdesc)

Definition at line 1069 of file execTuples.c.

References AttInMetadata::attinfuncs, AttInMetadata::attioparams, AttInMetadata::atttypmods, BlessTupleDesc(), fmgr_info(), getTypeInputInfo(), i, tupleDesc::natts, palloc(), palloc0(), AttInMetadata::tupdesc, and TupleDescAttr.

Referenced by bt_metap(), bt_page_items(), bt_page_items_bytea(), bt_page_stats(), build_pgstattuple_type(), connectby_text(), connectby_text_serial(), crosstab(), dblink_get_pkey(), get_crosstab_tuplestore(), hash_page_items(), libpqrcv_processTuples(), materializeQueryResult(), materializeResult(), pg_config(), pg_get_keywords(), pg_get_multixact_members(), pg_logdir_ls(), pgp_armor_headers(), pgrowlocks(), pgstatindex_impl(), pltcl_build_tuple_result(), pltcl_func_handler(), pltcl_init_tuple_store(), postgresAcquireSampleRowsFunc(), postgresBeginDirectModify(), postgresBeginForeignModify(), postgresBeginForeignScan(), prs_setup_firstcall(), show_all_settings(), storeRow(), ts_setup_firstcall(), tt_setup_firstcall(), and xpath_table().

1070 {
1071  int natts = tupdesc->natts;
1072  int i;
1073  Oid atttypeid;
1074  Oid attinfuncid;
1075  FmgrInfo *attinfuncinfo;
1076  Oid *attioparams;
1077  int32 *atttypmods;
1078  AttInMetadata *attinmeta;
1079 
1080  attinmeta = (AttInMetadata *) palloc(sizeof(AttInMetadata));
1081 
1082  /* "Bless" the tupledesc so that we can make rowtype datums with it */
1083  attinmeta->tupdesc = BlessTupleDesc(tupdesc);
1084 
1085  /*
1086  * Gather info needed later to call the "in" function for each attribute
1087  */
1088  attinfuncinfo = (FmgrInfo *) palloc0(natts * sizeof(FmgrInfo));
1089  attioparams = (Oid *) palloc0(natts * sizeof(Oid));
1090  atttypmods = (int32 *) palloc0(natts * sizeof(int32));
1091 
1092  for (i = 0; i < natts; i++)
1093  {
1094  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
1095 
1096  /* Ignore dropped attributes */
1097  if (!att->attisdropped)
1098  {
1099  atttypeid = att->atttypid;
1100  getTypeInputInfo(atttypeid, &attinfuncid, &attioparams[i]);
1101  fmgr_info(attinfuncid, &attinfuncinfo[i]);
1102  atttypmods[i] = att->atttypmod;
1103  }
1104  }
1105  attinmeta->attinfuncs = attinfuncinfo;
1106  attinmeta->attioparams = attioparams;
1107  attinmeta->atttypmods = atttypmods;
1108 
1109  return attinmeta;
1110 }
Definition: fmgr.h:56
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:90
int32 * atttypmods
Definition: funcapi.h:48
unsigned int Oid
Definition: postgres_ext.h:31
Oid * attioparams
Definition: funcapi.h:45
int natts
Definition: tupdesc.h:79
signed int int32
Definition: c.h:284
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:122
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:1032
TupleDesc tupdesc
Definition: funcapi.h:39
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2613
void * palloc0(Size size)
Definition: mcxt.c:877
void * palloc(Size size)
Definition: mcxt.c:848
int i
FmgrInfo * attinfuncs
Definition: funcapi.h:42

◆ TupleDescGetSlot()

TupleTableSlot* TupleDescGetSlot ( TupleDesc  tupdesc)

Definition at line 1049 of file execTuples.c.

References BlessTupleDesc(), and MakeSingleTupleTableSlot().

1050 {
1051  TupleTableSlot *slot;
1052 
1053  /* The useful work is here */
1054  BlessTupleDesc(tupdesc);
1055 
1056  /* Make a standalone slot */
1057  slot = MakeSingleTupleTableSlot(tupdesc);
1058 
1059  /* Return the slot */
1060  return slot;
1061 }
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:1032
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc)
Definition: execTuples.c:199