PostgreSQL Source Code  git master
tuplestore.h File Reference
Include dependency graph for tuplestore.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef struct Tuplestorestate Tuplestorestate
 

Functions

Tuplestorestatetuplestore_begin_heap (bool randomAccess, bool interXact, int maxKBytes)
 
void tuplestore_set_eflags (Tuplestorestate *state, int eflags)
 
void tuplestore_puttupleslot (Tuplestorestate *state, TupleTableSlot *slot)
 
void tuplestore_puttuple (Tuplestorestate *state, HeapTuple tuple)
 
void tuplestore_putvalues (Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
 
int tuplestore_alloc_read_pointer (Tuplestorestate *state, int eflags)
 
void tuplestore_select_read_pointer (Tuplestorestate *state, int ptr)
 
void tuplestore_copy_read_pointer (Tuplestorestate *state, int srcptr, int destptr)
 
void tuplestore_trim (Tuplestorestate *state)
 
bool tuplestore_in_memory (Tuplestorestate *state)
 
bool tuplestore_gettupleslot (Tuplestorestate *state, bool forward, bool copy, TupleTableSlot *slot)
 
bool tuplestore_advance (Tuplestorestate *state, bool forward)
 
bool tuplestore_skiptuples (Tuplestorestate *state, int64 ntuples, bool forward)
 
int64 tuplestore_tuple_count (Tuplestorestate *state)
 
bool tuplestore_ateof (Tuplestorestate *state)
 
void tuplestore_rescan (Tuplestorestate *state)
 
void tuplestore_clear (Tuplestorestate *state)
 
void tuplestore_end (Tuplestorestate *state)
 

Typedef Documentation

◆ Tuplestorestate

Definition at line 1 of file tuplestore.h.

Function Documentation

◆ tuplestore_advance()

bool tuplestore_advance ( Tuplestorestate state,
bool  forward 
)

Definition at line 1110 of file tuplestore.c.

1111 {
1112  void *tuple;
1113  bool should_free;
1114 
1115  tuple = tuplestore_gettuple(state, forward, &should_free);
1116 
1117  if (tuple)
1118  {
1119  if (should_free)
1120  pfree(tuple);
1121  return true;
1122  }
1123  else
1124  {
1125  return false;
1126  }
1127 }
void pfree(void *pointer)
Definition: mcxt.c:1520
Definition: regguts.h:323
static void * tuplestore_gettuple(Tuplestorestate *state, bool forward, bool *should_free)
Definition: tuplestore.c:903

References pfree(), and tuplestore_gettuple().

Referenced by CteScanNext(), ExecMaterial(), and window_gettupleslot().

◆ tuplestore_alloc_read_pointer()

int tuplestore_alloc_read_pointer ( Tuplestorestate state,
int  eflags 
)

Definition at line 383 of file tuplestore.c.

384 {
385  /* Check for possible increase of requirements */
386  if (state->status != TSS_INMEM || state->memtupcount != 0)
387  {
388  if ((state->eflags | eflags) != state->eflags)
389  elog(ERROR, "too late to require new tuplestore eflags");
390  }
391 
392  /* Make room for another read pointer if needed */
393  if (state->readptrcount >= state->readptrsize)
394  {
395  int newcnt = state->readptrsize * 2;
396 
397  state->readptrs = (TSReadPointer *)
398  repalloc(state->readptrs, newcnt * sizeof(TSReadPointer));
399  state->readptrsize = newcnt;
400  }
401 
402  /* And set it up */
403  state->readptrs[state->readptrcount] = state->readptrs[0];
404  state->readptrs[state->readptrcount].eflags = eflags;
405 
406  state->eflags |= eflags;
407 
408  return state->readptrcount++;
409 }
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1540
@ TSS_INMEM
Definition: tuplestore.c:74

References elog, ERROR, repalloc(), and TSS_INMEM.

Referenced by begin_partition(), ExecInitCteScan(), ExecInitNamedTuplestoreScan(), and ExecMaterial().

◆ tuplestore_ateof()

bool tuplestore_ateof ( Tuplestorestate state)

Definition at line 557 of file tuplestore.c.

558 {
559  return state->readptrs[state->activeptr].eof_reached;
560 }

Referenced by CteScanNext(), and ExecMaterial().

◆ tuplestore_begin_heap()

Tuplestorestate* tuplestore_begin_heap ( bool  randomAccess,
bool  interXact,
int  maxKBytes 
)

Definition at line 318 of file tuplestore.c.

319 {
321  int eflags;
322 
323  /*
324  * This interpretation of the meaning of randomAccess is compatible with
325  * the pre-8.3 behavior of tuplestores.
326  */
327  eflags = randomAccess ?
330 
331  state = tuplestore_begin_common(eflags, interXact, maxKBytes);
332 
333  state->copytup = copytup_heap;
334  state->writetup = writetup_heap;
335  state->readtup = readtup_heap;
336 
337  return state;
338 }
#define EXEC_FLAG_BACKWARD
Definition: executor.h:68
#define EXEC_FLAG_REWIND
Definition: executor.h:67
static void writetup_heap(Tuplestorestate *state, void *tup)
Definition: tuplestore.c:1500
static void * copytup_heap(Tuplestorestate *state, void *tup)
Definition: tuplestore.c:1490
static Tuplestorestate * tuplestore_begin_common(int eflags, bool interXact, int maxKBytes)
Definition: tuplestore.c:253
static void * readtup_heap(Tuplestorestate *state, unsigned int len)
Definition: tuplestore.c:1521

References copytup_heap(), EXEC_FLAG_BACKWARD, EXEC_FLAG_REWIND, readtup_heap(), tuplestore_begin_common(), and writetup_heap().

Referenced by begin_partition(), connectby(), crosstab(), exec_init_tuple_store(), ExecInitCteScan(), ExecInitRecursiveUnion(), ExecMakeTableFunctionResult(), ExecMaterial(), ExecRecursiveUnion(), fmgr_sql(), get_crosstab_tuplestore(), GetCurrentFDWTuplestore(), InitMaterializedSRF(), libpqrcv_processTuples(), MakeTransitionCaptureState(), materializeResult(), plperl_return_next_internal(), pltcl_init_tuple_store(), populate_recordset_worker(), PortalCreateHoldStore(), storeRow(), and tfuncFetchRows().

◆ tuplestore_clear()

void tuplestore_clear ( Tuplestorestate state)

Definition at line 418 of file tuplestore.c.

419 {
420  int i;
421  TSReadPointer *readptr;
422 
423  if (state->myfile)
424  BufFileClose(state->myfile);
425  state->myfile = NULL;
426  if (state->memtuples)
427  {
428  for (i = state->memtupdeleted; i < state->memtupcount; i++)
429  {
430  FREEMEM(state, GetMemoryChunkSpace(state->memtuples[i]));
431  pfree(state->memtuples[i]);
432  }
433  }
434  state->status = TSS_INMEM;
435  state->truncated = false;
436  state->memtupdeleted = 0;
437  state->memtupcount = 0;
438  state->tuples = 0;
439  readptr = state->readptrs;
440  for (i = 0; i < state->readptrcount; readptr++, i++)
441  {
442  readptr->eof_reached = false;
443  readptr->current = 0;
444  }
445 }
void BufFileClose(BufFile *file)
Definition: buffile.c:412
int i
Definition: isn.c:73
Size GetMemoryChunkSpace(void *pointer)
Definition: mcxt.c:721
bool eof_reached
Definition: tuplestore.c:94
#define FREEMEM(state, amt)
Definition: tuplestore.c:188

References BufFileClose(), TSReadPointer::current, TSReadPointer::eof_reached, FREEMEM, GetMemoryChunkSpace(), i, pfree(), and TSS_INMEM.

Referenced by ExecReScanCteScan(), ExecReScanRecursiveUnion(), and fmgr_sql().

◆ tuplestore_copy_read_pointer()

void tuplestore_copy_read_pointer ( Tuplestorestate state,
int  srcptr,
int  destptr 
)

Definition at line 1268 of file tuplestore.c.

1270 {
1271  TSReadPointer *sptr = &state->readptrs[srcptr];
1272  TSReadPointer *dptr = &state->readptrs[destptr];
1273 
1274  Assert(srcptr >= 0 && srcptr < state->readptrcount);
1275  Assert(destptr >= 0 && destptr < state->readptrcount);
1276 
1277  /* Assigning to self is a no-op */
1278  if (srcptr == destptr)
1279  return;
1280 
1281  if (dptr->eflags != sptr->eflags)
1282  {
1283  /* Possible change of overall eflags, so copy and then recompute */
1284  int eflags;
1285  int i;
1286 
1287  *dptr = *sptr;
1288  eflags = state->readptrs[0].eflags;
1289  for (i = 1; i < state->readptrcount; i++)
1290  eflags |= state->readptrs[i].eflags;
1291  state->eflags = eflags;
1292  }
1293  else
1294  *dptr = *sptr;
1295 
1296  switch (state->status)
1297  {
1298  case TSS_INMEM:
1299  case TSS_WRITEFILE:
1300  /* no work */
1301  break;
1302  case TSS_READFILE:
1303 
1304  /*
1305  * This case is a bit tricky since the active read pointer's
1306  * position corresponds to the seek point, not what is in its
1307  * variables. Assigning to the active requires a seek, and
1308  * assigning from the active requires a tell, except when
1309  * eof_reached.
1310  */
1311  if (destptr == state->activeptr)
1312  {
1313  if (dptr->eof_reached)
1314  {
1315  if (BufFileSeek(state->myfile,
1316  state->writepos_file,
1317  state->writepos_offset,
1318  SEEK_SET) != 0)
1319  ereport(ERROR,
1321  errmsg("could not seek in tuplestore temporary file")));
1322  }
1323  else
1324  {
1325  if (BufFileSeek(state->myfile,
1326  dptr->file, dptr->offset,
1327  SEEK_SET) != 0)
1328  ereport(ERROR,
1330  errmsg("could not seek in tuplestore temporary file")));
1331  }
1332  }
1333  else if (srcptr == state->activeptr)
1334  {
1335  if (!dptr->eof_reached)
1336  BufFileTell(state->myfile,
1337  &dptr->file,
1338  &dptr->offset);
1339  }
1340  break;
1341  default:
1342  elog(ERROR, "invalid tuplestore state");
1343  break;
1344  }
1345 }
void BufFileTell(BufFile *file, int *fileno, off_t *offset)
Definition: buffile.c:833
int BufFileSeek(BufFile *file, int fileno, off_t offset, int whence)
Definition: buffile.c:740
#define Assert(condition)
Definition: c.h:858
int errcode_for_file_access(void)
Definition: elog.c:882
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ereport(elevel,...)
Definition: elog.h:149
off_t offset
Definition: tuplestore.c:97
@ TSS_READFILE
Definition: tuplestore.c:76
@ TSS_WRITEFILE
Definition: tuplestore.c:75

References Assert, BufFileSeek(), BufFileTell(), TSReadPointer::eflags, elog, TSReadPointer::eof_reached, ereport, errcode_for_file_access(), errmsg(), ERROR, TSReadPointer::file, i, TSReadPointer::offset, TSS_INMEM, TSS_READFILE, and TSS_WRITEFILE.

Referenced by ExecMaterialMarkPos(), and ExecMaterialRestrPos().

◆ tuplestore_end()

void tuplestore_end ( Tuplestorestate state)

Definition at line 453 of file tuplestore.c.

454 {
455  int i;
456 
457  if (state->myfile)
458  BufFileClose(state->myfile);
459  if (state->memtuples)
460  {
461  for (i = state->memtupdeleted; i < state->memtupcount; i++)
462  pfree(state->memtuples[i]);
463  pfree(state->memtuples);
464  }
465  pfree(state->readptrs);
466  pfree(state);
467 }

References BufFileClose(), i, and pfree().

Referenced by AfterTriggerFreeQuery(), ExecEndCteScan(), ExecEndFunctionScan(), ExecEndMaterial(), ExecEndRecursiveUnion(), ExecEndTableFuncScan(), ExecMakeFunctionResultSet(), ExecRecursiveUnion(), ExecReScanFunctionScan(), ExecReScanMaterial(), ExecReScanTableFuncScan(), PortalDrop(), release_partition(), ShutdownSetExpr(), ShutdownSQLFunction(), storeRow(), and walrcv_clear_result().

◆ tuplestore_gettupleslot()

bool tuplestore_gettupleslot ( Tuplestorestate state,
bool  forward,
bool  copy,
TupleTableSlot slot 
)

Definition at line 1078 of file tuplestore.c.

1080 {
1081  MinimalTuple tuple;
1082  bool should_free;
1083 
1084  tuple = (MinimalTuple) tuplestore_gettuple(state, forward, &should_free);
1085 
1086  if (tuple)
1087  {
1088  if (copy && !should_free)
1089  {
1090  tuple = heap_copy_minimal_tuple(tuple);
1091  should_free = true;
1092  }
1093  ExecStoreMinimalTuple(tuple, slot, should_free);
1094  return true;
1095  }
1096  else
1097  {
1098  ExecClearTuple(slot);
1099  return false;
1100  }
1101 }
TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
Definition: execTuples.c:1533
MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1535
MinimalTupleData * MinimalTuple
Definition: htup.h:27
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:454

References ExecClearTuple(), ExecStoreMinimalTuple(), heap_copy_minimal_tuple(), and tuplestore_gettuple().

Referenced by AfterTriggerExecute(), check_publications(), check_publications_origin(), CteScanNext(), ExecMakeFunctionResultSet(), ExecMaterial(), ExecWindowAgg(), fetch_remote_table_info(), fetch_table_list(), fmgr_sql(), FunctionNext(), NamedTuplestoreScanNext(), RunFromStore(), synchronize_slots(), TableFuncNext(), update_frameheadpos(), update_frametailpos(), update_grouptailpos(), validate_remote_info(), window_gettupleslot(), and WorkTableScanNext().

◆ tuplestore_in_memory()

bool tuplestore_in_memory ( Tuplestorestate state)

Definition at line 1455 of file tuplestore.c.

1456 {
1457  return (state->status == TSS_INMEM);
1458 }

References TSS_INMEM.

Referenced by spool_tuples().

◆ tuplestore_puttuple()

void tuplestore_puttuple ( Tuplestorestate state,
HeapTuple  tuple 
)

Definition at line 730 of file tuplestore.c.

731 {
732  MemoryContext oldcxt = MemoryContextSwitchTo(state->context);
733 
734  /*
735  * Copy the tuple. (Must do this even in WRITEFILE case. Note that
736  * COPYTUP includes USEMEM, so we needn't do that here.)
737  */
738  tuple = COPYTUP(state, tuple);
739 
740  tuplestore_puttuple_common(state, (void *) tuple);
741 
742  MemoryContextSwitchTo(oldcxt);
743 }
MemoryContextSwitchTo(old_ctx)
#define COPYTUP(state, tup)
Definition: tuplestore.c:183
static void tuplestore_puttuple_common(Tuplestorestate *state, void *tuple)
Definition: tuplestore.c:765

References COPYTUP, MemoryContextSwitchTo(), and tuplestore_puttuple_common().

Referenced by build_tuplestore_recursively(), crosstab(), each_object_field_end(), elements_array_element_end(), exec_stmt_return_next(), ExecMakeTableFunctionResult(), fill_hba_line(), fill_ident_line(), get_crosstab_tuplestore(), libpqrcv_processTuples(), materializeResult(), pg_available_wal_summaries(), pg_wal_summary_contents(), pgrowlocks(), plperl_return_next_internal(), pltcl_returnnext(), populate_recordset_record(), report_corruption_internal(), storeRow(), and xpath_table().

◆ tuplestore_puttupleslot()

void tuplestore_puttupleslot ( Tuplestorestate state,
TupleTableSlot slot 
)

Definition at line 708 of file tuplestore.c.

710 {
711  MinimalTuple tuple;
712  MemoryContext oldcxt = MemoryContextSwitchTo(state->context);
713 
714  /*
715  * Form a MinimalTuple in working memory
716  */
717  tuple = ExecCopySlotMinimalTuple(slot);
719 
720  tuplestore_puttuple_common(state, (void *) tuple);
721 
722  MemoryContextSwitchTo(oldcxt);
723 }
#define USEMEM(state, amt)
Definition: tuplestore.c:187
static MinimalTuple ExecCopySlotMinimalTuple(TupleTableSlot *slot)
Definition: tuptable.h:492

References ExecCopySlotMinimalTuple(), GetMemoryChunkSpace(), MemoryContextSwitchTo(), tuplestore_puttuple_common(), and USEMEM.

Referenced by AfterTriggerSaveEvent(), begin_partition(), CteScanNext(), ExecMaterial(), ExecRecursiveUnion(), spool_tuples(), sqlfunction_receive(), TransitionTableAddTuple(), tstoreReceiveSlot_notoast(), and tstoreReceiveSlot_tupmap().

◆ tuplestore_putvalues()

void tuplestore_putvalues ( Tuplestorestate state,
TupleDesc  tdesc,
const Datum values,
const bool isnull 
)

Definition at line 750 of file tuplestore.c.

752 {
753  MinimalTuple tuple;
754  MemoryContext oldcxt = MemoryContextSwitchTo(state->context);
755 
756  tuple = heap_form_minimal_tuple(tdesc, values, isnull);
758 
759  tuplestore_puttuple_common(state, (void *) tuple);
760 
761  MemoryContextSwitchTo(oldcxt);
762 }
static Datum values[MAXATTR]
Definition: bootstrap.c:152
MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1452

References GetMemoryChunkSpace(), heap_form_minimal_tuple(), MemoryContextSwitchTo(), tuplestore_puttuple_common(), USEMEM, and values.

Referenced by brin_page_items(), dblink_get_notify(), each_worker_jsonb(), elements_worker_jsonb(), exec_stmt_return_next(), ExecMakeTableFunctionResult(), get_altertable_subcmdinfo(), get_available_versions_for_extension(), GetWALBlockInfo(), GetWALRecordsInfo(), GetXLogSummaryStats(), gist_page_items(), gist_page_items_bytea(), LogicalOutputWrite(), pg_available_extensions(), pg_config(), pg_cursor(), pg_event_trigger_ddl_commands(), pg_event_trigger_dropped_objects(), pg_extension_update_paths(), pg_get_replication_slots(), pg_get_shmem_allocations(), pg_get_wait_events(), pg_ls_dir(), pg_ls_dir_files(), pg_prepared_statement(), pg_show_replication_origin_status(), pg_stat_get_activity(), pg_stat_get_io(), pg_stat_get_progress_info(), pg_stat_get_recovery_prefetch(), pg_stat_get_slru(), pg_stat_get_subscription(), pg_stat_get_wal_senders(), pg_stat_statements_internal(), pg_tablespace_databases(), plperl_return_next_internal(), pltcl_returnnext(), postgres_fdw_get_connections(), PutMemoryContextsStatsTupleStore(), show_all_file_settings(), split_text_accum_result(), tfuncLoadRows(), and tstoreReceiveSlot_detoast().

◆ tuplestore_rescan()

void tuplestore_rescan ( Tuplestorestate state)

Definition at line 1233 of file tuplestore.c.

1234 {
1235  TSReadPointer *readptr = &state->readptrs[state->activeptr];
1236 
1237  Assert(readptr->eflags & EXEC_FLAG_REWIND);
1238  Assert(!state->truncated);
1239 
1240  switch (state->status)
1241  {
1242  case TSS_INMEM:
1243  readptr->eof_reached = false;
1244  readptr->current = 0;
1245  break;
1246  case TSS_WRITEFILE:
1247  readptr->eof_reached = false;
1248  readptr->file = 0;
1249  readptr->offset = 0;
1250  break;
1251  case TSS_READFILE:
1252  readptr->eof_reached = false;
1253  if (BufFileSeek(state->myfile, 0, 0, SEEK_SET) != 0)
1254  ereport(ERROR,
1256  errmsg("could not seek in tuplestore temporary file")));
1257  break;
1258  default:
1259  elog(ERROR, "invalid tuplestore state");
1260  break;
1261  }
1262 }

References Assert, BufFileSeek(), TSReadPointer::current, TSReadPointer::eflags, elog, TSReadPointer::eof_reached, ereport, errcode_for_file_access(), errmsg(), ERROR, EXEC_FLAG_REWIND, TSReadPointer::file, TSReadPointer::offset, TSS_INMEM, TSS_READFILE, and TSS_WRITEFILE.

Referenced by DoPortalRewind(), ExecInitCteScan(), ExecInitNamedTuplestoreScan(), ExecReScanCteScan(), ExecReScanFunctionScan(), ExecReScanMaterial(), ExecReScanNamedTuplestoreScan(), ExecReScanTableFuncScan(), ExecReScanWorkTableScan(), FunctionNext(), and PersistHoldablePortal().

◆ tuplestore_select_read_pointer()

void tuplestore_select_read_pointer ( Tuplestorestate state,
int  ptr 
)

Definition at line 473 of file tuplestore.c.

474 {
475  TSReadPointer *readptr;
476  TSReadPointer *oldptr;
477 
478  Assert(ptr >= 0 && ptr < state->readptrcount);
479 
480  /* No work if already active */
481  if (ptr == state->activeptr)
482  return;
483 
484  readptr = &state->readptrs[ptr];
485  oldptr = &state->readptrs[state->activeptr];
486 
487  switch (state->status)
488  {
489  case TSS_INMEM:
490  case TSS_WRITEFILE:
491  /* no work */
492  break;
493  case TSS_READFILE:
494 
495  /*
496  * First, save the current read position in the pointer about to
497  * become inactive.
498  */
499  if (!oldptr->eof_reached)
500  BufFileTell(state->myfile,
501  &oldptr->file,
502  &oldptr->offset);
503 
504  /*
505  * We have to make the temp file's seek position equal to the
506  * logical position of the new read pointer. In eof_reached
507  * state, that's the EOF, which we have available from the saved
508  * write position.
509  */
510  if (readptr->eof_reached)
511  {
512  if (BufFileSeek(state->myfile,
513  state->writepos_file,
514  state->writepos_offset,
515  SEEK_SET) != 0)
516  ereport(ERROR,
518  errmsg("could not seek in tuplestore temporary file")));
519  }
520  else
521  {
522  if (BufFileSeek(state->myfile,
523  readptr->file,
524  readptr->offset,
525  SEEK_SET) != 0)
526  ereport(ERROR,
528  errmsg("could not seek in tuplestore temporary file")));
529  }
530  break;
531  default:
532  elog(ERROR, "invalid tuplestore state");
533  break;
534  }
535 
536  state->activeptr = ptr;
537 }

References Assert, BufFileSeek(), BufFileTell(), elog, TSReadPointer::eof_reached, ereport, errcode_for_file_access(), errmsg(), ERROR, TSReadPointer::file, TSReadPointer::offset, TSS_INMEM, TSS_READFILE, and TSS_WRITEFILE.

Referenced by CteScanNext(), ExecInitCteScan(), ExecInitNamedTuplestoreScan(), ExecReScanCteScan(), ExecReScanNamedTuplestoreScan(), ExecWindowAgg(), NamedTuplestoreScanNext(), update_frameheadpos(), update_frametailpos(), update_grouptailpos(), window_gettupleslot(), and WinSetMarkPosition().

◆ tuplestore_set_eflags()

void tuplestore_set_eflags ( Tuplestorestate state,
int  eflags 
)

Definition at line 359 of file tuplestore.c.

360 {
361  int i;
362 
363  if (state->status != TSS_INMEM || state->memtupcount != 0)
364  elog(ERROR, "too late to call tuplestore_set_eflags");
365 
366  state->readptrs[0].eflags = eflags;
367  for (i = 1; i < state->readptrcount; i++)
368  eflags |= state->readptrs[i].eflags;
369  state->eflags = eflags;
370 }

References elog, ERROR, i, and TSS_INMEM.

Referenced by begin_partition(), ExecInitCteScan(), and ExecMaterial().

◆ tuplestore_skiptuples()

bool tuplestore_skiptuples ( Tuplestorestate state,
int64  ntuples,
bool  forward 
)

Definition at line 1135 of file tuplestore.c.

1136 {
1137  TSReadPointer *readptr = &state->readptrs[state->activeptr];
1138 
1139  Assert(forward || (readptr->eflags & EXEC_FLAG_BACKWARD));
1140 
1141  if (ntuples <= 0)
1142  return true;
1143 
1144  switch (state->status)
1145  {
1146  case TSS_INMEM:
1147  if (forward)
1148  {
1149  if (readptr->eof_reached)
1150  return false;
1151  if (state->memtupcount - readptr->current >= ntuples)
1152  {
1153  readptr->current += ntuples;
1154  return true;
1155  }
1156  readptr->current = state->memtupcount;
1157  readptr->eof_reached = true;
1158  return false;
1159  }
1160  else
1161  {
1162  if (readptr->eof_reached)
1163  {
1164  readptr->current = state->memtupcount;
1165  readptr->eof_reached = false;
1166  ntuples--;
1167  }
1168  if (readptr->current - state->memtupdeleted > ntuples)
1169  {
1170  readptr->current -= ntuples;
1171  return true;
1172  }
1173  Assert(!state->truncated);
1174  readptr->current = state->memtupdeleted;
1175  return false;
1176  }
1177  break;
1178 
1179  default:
1180  /* We don't currently try hard to optimize other cases */
1181  while (ntuples-- > 0)
1182  {
1183  void *tuple;
1184  bool should_free;
1185 
1186  tuple = tuplestore_gettuple(state, forward, &should_free);
1187 
1188  if (tuple == NULL)
1189  return false;
1190  if (should_free)
1191  pfree(tuple);
1193  }
1194  return true;
1195  }
1196 }
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122

References Assert, CHECK_FOR_INTERRUPTS, TSReadPointer::current, TSReadPointer::eflags, TSReadPointer::eof_reached, EXEC_FLAG_BACKWARD, pfree(), TSS_INMEM, and tuplestore_gettuple().

Referenced by PersistHoldablePortal(), window_gettupleslot(), and WinSetMarkPosition().

◆ tuplestore_trim()

void tuplestore_trim ( Tuplestorestate state)

Definition at line 1360 of file tuplestore.c.

1361 {
1362  int oldest;
1363  int nremove;
1364  int i;
1365 
1366  /*
1367  * Truncation is disallowed if any read pointer requires rewind
1368  * capability.
1369  */
1370  if (state->eflags & EXEC_FLAG_REWIND)
1371  return;
1372 
1373  /*
1374  * We don't bother trimming temp files since it usually would mean more
1375  * work than just letting them sit in kernel buffers until they age out.
1376  */
1377  if (state->status != TSS_INMEM)
1378  return;
1379 
1380  /* Find the oldest read pointer */
1381  oldest = state->memtupcount;
1382  for (i = 0; i < state->readptrcount; i++)
1383  {
1384  if (!state->readptrs[i].eof_reached)
1385  oldest = Min(oldest, state->readptrs[i].current);
1386  }
1387 
1388  /*
1389  * Note: you might think we could remove all the tuples before the oldest
1390  * "current", since that one is the next to be returned. However, since
1391  * tuplestore_gettuple returns a direct pointer to our internal copy of
1392  * the tuple, it's likely that the caller has still got the tuple just
1393  * before "current" referenced in a slot. So we keep one extra tuple
1394  * before the oldest "current". (Strictly speaking, we could require such
1395  * callers to use the "copy" flag to tuplestore_gettupleslot, but for
1396  * efficiency we allow this one case to not use "copy".)
1397  */
1398  nremove = oldest - 1;
1399  if (nremove <= 0)
1400  return; /* nothing to do */
1401 
1402  Assert(nremove >= state->memtupdeleted);
1403  Assert(nremove <= state->memtupcount);
1404 
1405  /* Release no-longer-needed tuples */
1406  for (i = state->memtupdeleted; i < nremove; i++)
1407  {
1408  FREEMEM(state, GetMemoryChunkSpace(state->memtuples[i]));
1409  pfree(state->memtuples[i]);
1410  state->memtuples[i] = NULL;
1411  }
1412  state->memtupdeleted = nremove;
1413 
1414  /* mark tuplestore as truncated (used for Assert crosschecks only) */
1415  state->truncated = true;
1416 
1417  /*
1418  * If nremove is less than 1/8th memtupcount, just stop here, leaving the
1419  * "deleted" slots as NULL. This prevents us from expending O(N^2) time
1420  * repeatedly memmove-ing a large pointer array. The worst case space
1421  * wastage is pretty small, since it's just pointers and not whole tuples.
1422  */
1423  if (nremove < state->memtupcount / 8)
1424  return;
1425 
1426  /*
1427  * Slide the array down and readjust pointers.
1428  *
1429  * In mergejoin's current usage, it's demonstrable that there will always
1430  * be exactly one non-removed tuple; so optimize that case.
1431  */
1432  if (nremove + 1 == state->memtupcount)
1433  state->memtuples[0] = state->memtuples[nremove];
1434  else
1435  memmove(state->memtuples, state->memtuples + nremove,
1436  (state->memtupcount - nremove) * sizeof(void *));
1437 
1438  state->memtupdeleted = 0;
1439  state->memtupcount -= nremove;
1440  for (i = 0; i < state->readptrcount; i++)
1441  {
1442  if (!state->readptrs[i].eof_reached)
1443  state->readptrs[i].current -= nremove;
1444  }
1445 }
#define Min(x, y)
Definition: c.h:1004

References Assert, EXEC_FLAG_REWIND, FREEMEM, GetMemoryChunkSpace(), i, Min, pfree(), and TSS_INMEM.

Referenced by ExecMaterialMarkPos(), and ExecWindowAgg().

◆ tuplestore_tuple_count()

int64 tuplestore_tuple_count ( Tuplestorestate state)

Definition at line 546 of file tuplestore.c.

547 {
548  return state->tuples;
549 }

Referenced by exec_stmt_return_query(), fetch_remote_table_info(), and SPI_register_trigger_data().