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)
 
void tuplestore_get_stats (Tuplestorestate *state, char **storage_type, int64 *max_space)
 
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 1162 of file tuplestore.c.

1163 {
1164  void *tuple;
1165  bool should_free;
1166 
1167  tuple = tuplestore_gettuple(state, forward, &should_free);
1168 
1169  if (tuple)
1170  {
1171  if (should_free)
1172  pfree(tuple);
1173  return true;
1174  }
1175  else
1176  {
1177  return false;
1178  }
1179 }
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:955

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

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

◆ tuplestore_ateof()

bool tuplestore_ateof ( Tuplestorestate state)

Definition at line 591 of file tuplestore.c.

592 {
593  return state->readptrs[state->activeptr].eof_reached;
594 }

Referenced by CteScanNext(), and ExecMaterial().

◆ tuplestore_begin_heap()

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

Definition at line 330 of file tuplestore.c.

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

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

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

◆ tuplestore_clear()

void tuplestore_clear ( Tuplestorestate state)

Definition at line 430 of file tuplestore.c.

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

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

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

◆ tuplestore_copy_read_pointer()

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

Definition at line 1320 of file tuplestore.c.

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

void tuplestore_get_stats ( Tuplestorestate state,
char **  storage_type,
int64 *  max_space 
)

Definition at line 1533 of file tuplestore.c.

1535 {
1537 
1538  if (state->usedDisk)
1539  *max_storage_type = "Disk";
1540  else
1541  *max_storage_type = "Memory";
1542 
1543  *max_space = state->maxSpace;
1544 }

References tuplestore_updatemax().

Referenced by show_ctescan_info(), show_material_info(), show_recursive_union_info(), show_table_func_scan_info(), and show_windowagg_info().

◆ tuplestore_gettupleslot()

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

Definition at line 1130 of file tuplestore.c.

1132 {
1133  MinimalTuple tuple;
1134  bool should_free;
1135 
1136  tuple = (MinimalTuple) tuplestore_gettuple(state, forward, &should_free);
1137 
1138  if (tuple)
1139  {
1140  if (copy && !should_free)
1141  {
1142  tuple = heap_copy_minimal_tuple(tuple);
1143  should_free = true;
1144  }
1145  ExecStoreMinimalTuple(tuple, slot, should_free);
1146  return true;
1147  }
1148  else
1149  {
1150  ExecClearTuple(slot);
1151  return false;
1152  }
1153 }
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 1554 of file tuplestore.c.

1555 {
1556  return (state->status == TSS_INMEM);
1557 }

References TSS_INMEM.

Referenced by spool_tuples().

◆ tuplestore_puttuple()

void tuplestore_puttuple ( Tuplestorestate state,
HeapTuple  tuple 
)

Definition at line 764 of file tuplestore.c.

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

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

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

786 {
787  MinimalTuple tuple;
788  MemoryContext oldcxt = MemoryContextSwitchTo(state->context);
789 
790  tuple = heap_form_minimal_tuple(tdesc, values, isnull);
792 
793  tuplestore_puttuple_common(state, (void *) tuple);
794 
795  MemoryContextSwitchTo(oldcxt);
796 }
static Datum values[MAXATTR]
Definition: bootstrap.c:150
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_internal(), PutMemoryContextsStatsTupleStore(), show_all_file_settings(), split_text_accum_result(), tfuncLoadRows(), and tstoreReceiveSlot_detoast().

◆ tuplestore_rescan()

void tuplestore_rescan ( Tuplestorestate state)

Definition at line 1285 of file tuplestore.c.

1286 {
1287  TSReadPointer *readptr = &state->readptrs[state->activeptr];
1288 
1289  Assert(readptr->eflags & EXEC_FLAG_REWIND);
1290  Assert(!state->truncated);
1291 
1292  switch (state->status)
1293  {
1294  case TSS_INMEM:
1295  readptr->eof_reached = false;
1296  readptr->current = 0;
1297  break;
1298  case TSS_WRITEFILE:
1299  readptr->eof_reached = false;
1300  readptr->file = 0;
1301  readptr->offset = 0;
1302  break;
1303  case TSS_READFILE:
1304  readptr->eof_reached = false;
1305  if (BufFileSeek(state->myfile, 0, 0, SEEK_SET) != 0)
1306  ereport(ERROR,
1308  errmsg("could not seek in tuplestore temporary file")));
1309  break;
1310  default:
1311  elog(ERROR, "invalid tuplestore state");
1312  break;
1313  }
1314 }

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

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

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

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

References elog, ERROR, i, and TSS_INMEM.

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

◆ tuplestore_skiptuples()

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

Definition at line 1187 of file tuplestore.c.

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

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

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

581 {
582  return state->tuples;
583 }

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