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)
 
const char * tuplestore_storage_type_name (Tuplestorestate *state)
 
int64 tuplestore_space_used (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 1152 of file tuplestore.c.

1153 {
1154  void *tuple;
1155  bool should_free;
1156 
1157  tuple = tuplestore_gettuple(state, forward, &should_free);
1158 
1159  if (tuple)
1160  {
1161  if (should_free)
1162  pfree(tuple);
1163  return true;
1164  }
1165  else
1166  {
1167  return false;
1168  }
1169 }
void pfree(void *pointer)
Definition: mcxt.c:1521
Definition: regguts.h:323
static void * tuplestore_gettuple(Tuplestorestate *state, bool forward, bool *should_free)
Definition: tuplestore.c:945

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 393 of file tuplestore.c.

394 {
395  /* Check for possible increase of requirements */
396  if (state->status != TSS_INMEM || state->memtupcount != 0)
397  {
398  if ((state->eflags | eflags) != state->eflags)
399  elog(ERROR, "too late to require new tuplestore eflags");
400  }
401 
402  /* Make room for another read pointer if needed */
403  if (state->readptrcount >= state->readptrsize)
404  {
405  int newcnt = state->readptrsize * 2;
406 
407  state->readptrs = (TSReadPointer *)
408  repalloc(state->readptrs, newcnt * sizeof(TSReadPointer));
409  state->readptrsize = newcnt;
410  }
411 
412  /* And set it up */
413  state->readptrs[state->readptrcount] = state->readptrs[0];
414  state->readptrs[state->readptrcount].eflags = eflags;
415 
416  state->eflags |= eflags;
417 
418  return state->readptrcount++;
419 }
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1541
@ 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 589 of file tuplestore.c.

590 {
591  return state->readptrs[state->activeptr].eof_reached;
592 }

Referenced by CteScanNext(), and ExecMaterial().

◆ tuplestore_begin_heap()

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

Definition at line 328 of file tuplestore.c.

329 {
331  int eflags;
332 
333  /*
334  * This interpretation of the meaning of randomAccess is compatible with
335  * the pre-8.3 behavior of tuplestores.
336  */
337  eflags = randomAccess ?
340 
341  state = tuplestore_begin_common(eflags, interXact, maxKBytes);
342 
343  state->copytup = copytup_heap;
344  state->writetup = writetup_heap;
345  state->readtup = readtup_heap;
346 
347  return state;
348 }
#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:1588
static void * copytup_heap(Tuplestorestate *state, void *tup)
Definition: tuplestore.c:1578
static Tuplestorestate * tuplestore_begin_common(int eflags, bool interXact, int maxKBytes)
Definition: tuplestore.c:255
static void * readtup_heap(Tuplestorestate *state, unsigned int len)
Definition: tuplestore.c:1610

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 428 of file tuplestore.c.

429 {
430  int i;
431  TSReadPointer *readptr;
432 
433  /* update the maxSpace before doing any USEMEM/FREEMEM adjustments */
435 
436  if (state->myfile)
437  BufFileClose(state->myfile);
438  state->myfile = NULL;
439 
440 #ifdef USE_ASSERT_CHECKING
441  {
442  int64 availMem = state->availMem;
443 
444  /*
445  * Below, we reset the memory context for storing tuples. To save
446  * from having to always call GetMemoryChunkSpace() on all stored
447  * tuples, we adjust the availMem to forget all the tuples and just
448  * recall USEMEM for the space used by the memtuples array. Here we
449  * just Assert that's correct and the memory tracking hasn't gone
450  * wrong anywhere.
451  */
452  for (i = state->memtupdeleted; i < state->memtupcount; i++)
453  availMem += GetMemoryChunkSpace(state->memtuples[i]);
454 
455  availMem += GetMemoryChunkSpace(state->memtuples);
456 
457  Assert(availMem == state->allowedMem);
458  }
459 #endif
460 
461  /* clear the memory consumed by the memory tuples */
462  MemoryContextReset(state->context);
463 
464  /*
465  * Zero the used memory and re-consume the space for the memtuples array.
466  * This saves having to FREEMEM for each stored tuple.
467  */
468  state->availMem = state->allowedMem;
469  USEMEM(state, GetMemoryChunkSpace(state->memtuples));
470 
471  state->status = TSS_INMEM;
472  state->truncated = false;
473  state->memtupdeleted = 0;
474  state->memtupcount = 0;
475  state->tuples = 0;
476  readptr = state->readptrs;
477  for (i = 0; i < state->readptrcount; readptr++, i++)
478  {
479  readptr->eof_reached = false;
480  readptr->current = 0;
481  }
482 }
void BufFileClose(BufFile *file)
Definition: buffile.c:412
#define Assert(condition)
Definition: c.h:858
int i
Definition: isn.c:73
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:383
Size GetMemoryChunkSpace(void *pointer)
Definition: mcxt.c:721
bool eof_reached
Definition: tuplestore.c:94
#define USEMEM(state, amt)
Definition: tuplestore.c:188
static void tuplestore_updatemax(Tuplestorestate *state)
Definition: tuplestore.c:1497

References Assert, BufFileClose(), TSReadPointer::current, TSReadPointer::eof_reached, GetMemoryChunkSpace(), i, MemoryContextReset(), TSS_INMEM, tuplestore_updatemax(), and USEMEM.

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 1310 of file tuplestore.c.

1312 {
1313  TSReadPointer *sptr = &state->readptrs[srcptr];
1314  TSReadPointer *dptr = &state->readptrs[destptr];
1315 
1316  Assert(srcptr >= 0 && srcptr < state->readptrcount);
1317  Assert(destptr >= 0 && destptr < state->readptrcount);
1318 
1319  /* Assigning to self is a no-op */
1320  if (srcptr == destptr)
1321  return;
1322 
1323  if (dptr->eflags != sptr->eflags)
1324  {
1325  /* Possible change of overall eflags, so copy and then recompute */
1326  int eflags;
1327  int i;
1328 
1329  *dptr = *sptr;
1330  eflags = state->readptrs[0].eflags;
1331  for (i = 1; i < state->readptrcount; i++)
1332  eflags |= state->readptrs[i].eflags;
1333  state->eflags = eflags;
1334  }
1335  else
1336  *dptr = *sptr;
1337 
1338  switch (state->status)
1339  {
1340  case TSS_INMEM:
1341  case TSS_WRITEFILE:
1342  /* no work */
1343  break;
1344  case TSS_READFILE:
1345 
1346  /*
1347  * This case is a bit tricky since the active read pointer's
1348  * position corresponds to the seek point, not what is in its
1349  * variables. Assigning to the active requires a seek, and
1350  * assigning from the active requires a tell, except when
1351  * eof_reached.
1352  */
1353  if (destptr == state->activeptr)
1354  {
1355  if (dptr->eof_reached)
1356  {
1357  if (BufFileSeek(state->myfile,
1358  state->writepos_file,
1359  state->writepos_offset,
1360  SEEK_SET) != 0)
1361  ereport(ERROR,
1363  errmsg("could not seek in tuplestore temporary file")));
1364  }
1365  else
1366  {
1367  if (BufFileSeek(state->myfile,
1368  dptr->file, dptr->offset,
1369  SEEK_SET) != 0)
1370  ereport(ERROR,
1372  errmsg("could not seek in tuplestore temporary file")));
1373  }
1374  }
1375  else if (srcptr == state->activeptr)
1376  {
1377  if (!dptr->eof_reached)
1378  BufFileTell(state->myfile,
1379  &dptr->file,
1380  &dptr->offset);
1381  }
1382  break;
1383  default:
1384  elog(ERROR, "invalid tuplestore state");
1385  break;
1386  }
1387 }
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
int errcode_for_file_access(void)
Definition: elog.c:878
int errmsg(const char *fmt,...)
Definition: elog.c:1068
#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()

◆ tuplestore_gettupleslot()

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

Definition at line 1120 of file tuplestore.c.

1122 {
1123  MinimalTuple tuple;
1124  bool should_free;
1125 
1126  tuple = (MinimalTuple) tuplestore_gettuple(state, forward, &should_free);
1127 
1128  if (tuple)
1129  {
1130  if (copy && !should_free)
1131  {
1132  tuple = heap_copy_minimal_tuple(tuple);
1133  should_free = true;
1134  }
1135  ExecStoreMinimalTuple(tuple, slot, should_free);
1136  return true;
1137  }
1138  else
1139  {
1140  ExecClearTuple(slot);
1141  return false;
1142  }
1143 }
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 1543 of file tuplestore.c.

1544 {
1545  return (state->status == TSS_INMEM);
1546 }

References TSS_INMEM.

Referenced by spool_tuples().

◆ tuplestore_puttuple()

void tuplestore_puttuple ( Tuplestorestate state,
HeapTuple  tuple 
)

Definition at line 762 of file tuplestore.c.

763 {
764  MemoryContext oldcxt = MemoryContextSwitchTo(state->context);
765 
766  /*
767  * Copy the tuple. (Must do this even in WRITEFILE case. Note that
768  * COPYTUP includes USEMEM, so we needn't do that here.)
769  */
770  tuple = COPYTUP(state, tuple);
771 
772  tuplestore_puttuple_common(state, (void *) tuple);
773 
774  MemoryContextSwitchTo(oldcxt);
775 }
MemoryContextSwitchTo(old_ctx)
#define COPYTUP(state, tup)
Definition: tuplestore.c:184
static void tuplestore_puttuple_common(Tuplestorestate *state, void *tuple)
Definition: tuplestore.c:797

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 740 of file tuplestore.c.

742 {
743  MinimalTuple tuple;
744  MemoryContext oldcxt = MemoryContextSwitchTo(state->context);
745 
746  /*
747  * Form a MinimalTuple in working memory
748  */
749  tuple = ExecCopySlotMinimalTuple(slot);
751 
752  tuplestore_puttuple_common(state, (void *) tuple);
753 
754  MemoryContextSwitchTo(oldcxt);
755 }
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 782 of file tuplestore.c.

784 {
785  MinimalTuple tuple;
786  MemoryContext oldcxt = MemoryContextSwitchTo(state->context);
787 
788  tuple = heap_form_minimal_tuple(tdesc, values, isnull);
790 
791  tuplestore_puttuple_common(state, (void *) tuple);
792 
793  MemoryContextSwitchTo(oldcxt);
794 }
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 1275 of file tuplestore.c.

1276 {
1277  TSReadPointer *readptr = &state->readptrs[state->activeptr];
1278 
1279  Assert(readptr->eflags & EXEC_FLAG_REWIND);
1280  Assert(!state->truncated);
1281 
1282  switch (state->status)
1283  {
1284  case TSS_INMEM:
1285  readptr->eof_reached = false;
1286  readptr->current = 0;
1287  break;
1288  case TSS_WRITEFILE:
1289  readptr->eof_reached = false;
1290  readptr->file = 0;
1291  readptr->offset = 0;
1292  break;
1293  case TSS_READFILE:
1294  readptr->eof_reached = false;
1295  if (BufFileSeek(state->myfile, 0, 0, SEEK_SET) != 0)
1296  ereport(ERROR,
1298  errmsg("could not seek in tuplestore temporary file")));
1299  break;
1300  default:
1301  elog(ERROR, "invalid tuplestore state");
1302  break;
1303  }
1304 }

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 505 of file tuplestore.c.

506 {
507  TSReadPointer *readptr;
508  TSReadPointer *oldptr;
509 
510  Assert(ptr >= 0 && ptr < state->readptrcount);
511 
512  /* No work if already active */
513  if (ptr == state->activeptr)
514  return;
515 
516  readptr = &state->readptrs[ptr];
517  oldptr = &state->readptrs[state->activeptr];
518 
519  switch (state->status)
520  {
521  case TSS_INMEM:
522  case TSS_WRITEFILE:
523  /* no work */
524  break;
525  case TSS_READFILE:
526 
527  /*
528  * First, save the current read position in the pointer about to
529  * become inactive.
530  */
531  if (!oldptr->eof_reached)
532  BufFileTell(state->myfile,
533  &oldptr->file,
534  &oldptr->offset);
535 
536  /*
537  * We have to make the temp file's seek position equal to the
538  * logical position of the new read pointer. In eof_reached
539  * state, that's the EOF, which we have available from the saved
540  * write position.
541  */
542  if (readptr->eof_reached)
543  {
544  if (BufFileSeek(state->myfile,
545  state->writepos_file,
546  state->writepos_offset,
547  SEEK_SET) != 0)
548  ereport(ERROR,
550  errmsg("could not seek in tuplestore temporary file")));
551  }
552  else
553  {
554  if (BufFileSeek(state->myfile,
555  readptr->file,
556  readptr->offset,
557  SEEK_SET) != 0)
558  ereport(ERROR,
560  errmsg("could not seek in tuplestore temporary file")));
561  }
562  break;
563  default:
564  elog(ERROR, "invalid tuplestore state");
565  break;
566  }
567 
568  state->activeptr = ptr;
569 }

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 369 of file tuplestore.c.

370 {
371  int i;
372 
373  if (state->status != TSS_INMEM || state->memtupcount != 0)
374  elog(ERROR, "too late to call tuplestore_set_eflags");
375 
376  state->readptrs[0].eflags = eflags;
377  for (i = 1; i < state->readptrcount; i++)
378  eflags |= state->readptrs[i].eflags;
379  state->eflags = eflags;
380 }

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 1177 of file tuplestore.c.

1178 {
1179  TSReadPointer *readptr = &state->readptrs[state->activeptr];
1180 
1181  Assert(forward || (readptr->eflags & EXEC_FLAG_BACKWARD));
1182 
1183  if (ntuples <= 0)
1184  return true;
1185 
1186  switch (state->status)
1187  {
1188  case TSS_INMEM:
1189  if (forward)
1190  {
1191  if (readptr->eof_reached)
1192  return false;
1193  if (state->memtupcount - readptr->current >= ntuples)
1194  {
1195  readptr->current += ntuples;
1196  return true;
1197  }
1198  readptr->current = state->memtupcount;
1199  readptr->eof_reached = true;
1200  return false;
1201  }
1202  else
1203  {
1204  if (readptr->eof_reached)
1205  {
1206  readptr->current = state->memtupcount;
1207  readptr->eof_reached = false;
1208  ntuples--;
1209  }
1210  if (readptr->current - state->memtupdeleted > ntuples)
1211  {
1212  readptr->current -= ntuples;
1213  return true;
1214  }
1215  Assert(!state->truncated);
1216  readptr->current = state->memtupdeleted;
1217  return false;
1218  }
1219  break;
1220 
1221  default:
1222  /* We don't currently try hard to optimize other cases */
1223  while (ntuples-- > 0)
1224  {
1225  void *tuple;
1226  bool should_free;
1227 
1228  tuple = tuplestore_gettuple(state, forward, &should_free);
1229 
1230  if (tuple == NULL)
1231  return false;
1232  if (should_free)
1233  pfree(tuple);
1235  }
1236  return true;
1237  }
1238 }
#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_space_used()

int64 tuplestore_space_used ( Tuplestorestate state)

Definition at line 1524 of file tuplestore.c.

1525 {
1526  /* First, update the maxSpace field */
1528 
1529  if (state->status == TSS_INMEM)
1530  return state->maxSpace;
1531  else
1532  return BufFileSize(state->myfile);
1533 }
int64 BufFileSize(BufFile *file)
Definition: buffile.c:866

References BufFileSize(), TSS_INMEM, and tuplestore_updatemax().

Referenced by show_material_info().

◆ tuplestore_storage_type_name()

const char* tuplestore_storage_type_name ( Tuplestorestate state)

Definition at line 1510 of file tuplestore.c.

1511 {
1512  if (state->status == TSS_INMEM)
1513  return "Memory";
1514  else
1515  return "Disk";
1516 }

References TSS_INMEM.

Referenced by show_material_info().

◆ tuplestore_trim()

void tuplestore_trim ( Tuplestorestate state)

Definition at line 1402 of file tuplestore.c.

1403 {
1404  int oldest;
1405  int nremove;
1406  int i;
1407 
1408  /*
1409  * Truncation is disallowed if any read pointer requires rewind
1410  * capability.
1411  */
1412  if (state->eflags & EXEC_FLAG_REWIND)
1413  return;
1414 
1415  /*
1416  * We don't bother trimming temp files since it usually would mean more
1417  * work than just letting them sit in kernel buffers until they age out.
1418  */
1419  if (state->status != TSS_INMEM)
1420  return;
1421 
1422  /* Find the oldest read pointer */
1423  oldest = state->memtupcount;
1424  for (i = 0; i < state->readptrcount; i++)
1425  {
1426  if (!state->readptrs[i].eof_reached)
1427  oldest = Min(oldest, state->readptrs[i].current);
1428  }
1429 
1430  /*
1431  * Note: you might think we could remove all the tuples before the oldest
1432  * "current", since that one is the next to be returned. However, since
1433  * tuplestore_gettuple returns a direct pointer to our internal copy of
1434  * the tuple, it's likely that the caller has still got the tuple just
1435  * before "current" referenced in a slot. So we keep one extra tuple
1436  * before the oldest "current". (Strictly speaking, we could require such
1437  * callers to use the "copy" flag to tuplestore_gettupleslot, but for
1438  * efficiency we allow this one case to not use "copy".)
1439  */
1440  nremove = oldest - 1;
1441  if (nremove <= 0)
1442  return; /* nothing to do */
1443 
1444  Assert(nremove >= state->memtupdeleted);
1445  Assert(nremove <= state->memtupcount);
1446 
1447  /* before freeing any memory, update maxSpace */
1449 
1450  /* Release no-longer-needed tuples */
1451  for (i = state->memtupdeleted; i < nremove; i++)
1452  {
1453  FREEMEM(state, GetMemoryChunkSpace(state->memtuples[i]));
1454  pfree(state->memtuples[i]);
1455  state->memtuples[i] = NULL;
1456  }
1457  state->memtupdeleted = nremove;
1458 
1459  /* mark tuplestore as truncated (used for Assert crosschecks only) */
1460  state->truncated = true;
1461 
1462  /*
1463  * If nremove is less than 1/8th memtupcount, just stop here, leaving the
1464  * "deleted" slots as NULL. This prevents us from expending O(N^2) time
1465  * repeatedly memmove-ing a large pointer array. The worst case space
1466  * wastage is pretty small, since it's just pointers and not whole tuples.
1467  */
1468  if (nremove < state->memtupcount / 8)
1469  return;
1470 
1471  /*
1472  * Slide the array down and readjust pointers.
1473  *
1474  * In mergejoin's current usage, it's demonstrable that there will always
1475  * be exactly one non-removed tuple; so optimize that case.
1476  */
1477  if (nremove + 1 == state->memtupcount)
1478  state->memtuples[0] = state->memtuples[nremove];
1479  else
1480  memmove(state->memtuples, state->memtuples + nremove,
1481  (state->memtupcount - nremove) * sizeof(void *));
1482 
1483  state->memtupdeleted = 0;
1484  state->memtupcount -= nremove;
1485  for (i = 0; i < state->readptrcount; i++)
1486  {
1487  if (!state->readptrs[i].eof_reached)
1488  state->readptrs[i].current -= nremove;
1489  }
1490 }
#define Min(x, y)
Definition: c.h:1004
#define FREEMEM(state, amt)
Definition: tuplestore.c:189

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

Referenced by ExecMaterialMarkPos(), and ExecWindowAgg().

◆ tuplestore_tuple_count()

int64 tuplestore_tuple_count ( Tuplestorestate state)

Definition at line 578 of file tuplestore.c.

579 {
580  return state->tuples;
581 }

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