PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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.

Macros

#define tuplestore_donestoring(state)   ((void) 0)
 

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, Datum *values, 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)
 
bool tuplestore_ateof (Tuplestorestate *state)
 
void tuplestore_rescan (Tuplestorestate *state)
 
void tuplestore_clear (Tuplestorestate *state)
 
void tuplestore_end (Tuplestorestate *state)
 

Macro Definition Documentation

Typedef Documentation

Definition at line 40 of file tuplestore.h.

Function Documentation

bool tuplestore_advance ( Tuplestorestate state,
bool  forward 
)

Definition at line 1093 of file tuplestore.c.

References pfree(), and tuplestore_gettuple().

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

1094 {
1095  void *tuple;
1096  bool should_free;
1097 
1098  tuple = tuplestore_gettuple(state, forward, &should_free);
1099 
1100  if (tuple)
1101  {
1102  if (should_free)
1103  pfree(tuple);
1104  return true;
1105  }
1106  else
1107  {
1108  return false;
1109  }
1110 }
void pfree(void *pointer)
Definition: mcxt.c:992
static void * tuplestore_gettuple(Tuplestorestate *state, bool forward, bool *should_free)
Definition: tuplestore.c:886
int tuplestore_alloc_read_pointer ( Tuplestorestate state,
int  eflags 
)

Definition at line 381 of file tuplestore.c.

References TSReadPointer::eflags, Tuplestorestate::eflags, elog, ERROR, Tuplestorestate::memtupcount, Tuplestorestate::readptrcount, Tuplestorestate::readptrs, Tuplestorestate::readptrsize, repalloc(), Tuplestorestate::status, and TSS_INMEM.

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

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

Definition at line 542 of file tuplestore.c.

References Tuplestorestate::activeptr, TSReadPointer::eof_reached, and Tuplestorestate::readptrs.

Referenced by CteScanNext(), and ExecMaterial().

543 {
544  return state->readptrs[state->activeptr].eof_reached;
545 }
bool eof_reached
Definition: tuplestore.c:94
TSReadPointer * readptrs
Definition: tuplestore.c:173
Tuplestorestate* tuplestore_begin_heap ( bool  randomAccess,
bool  interXact,
int  maxKBytes 
)

Definition at line 316 of file tuplestore.c.

References Tuplestorestate::copytup, copytup_heap(), EXEC_FLAG_BACKWARD, EXEC_FLAG_REWIND, Tuplestorestate::readtup, readtup_heap(), tuplestore_begin_common(), Tuplestorestate::writetup, and writetup_heap().

Referenced by begin_partition(), brin_page_items(), connectby(), crosstab(), dblink_get_notify(), deflist_to_tuplestore(), each_worker(), each_worker_jsonb(), elements_worker(), elements_worker_jsonb(), exec_init_tuple_store(), ExecInitCteScan(), ExecInitRecursiveUnion(), ExecMakeTableFunctionResult(), ExecMaterial(), ExecRecursiveUnion(), fmgr_sql(), get_crosstab_tuplestore(), GetTriggerTransitionTuplestore(), materializeQueryResult(), materializeResult(), pg_available_extension_versions(), 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_hba_file_rules(), pg_logical_slot_get_changes_guts(), pg_prepared_statement(), pg_show_replication_origin_status(), pg_stat_get_activity(), pg_stat_get_progress_info(), pg_stat_get_subscription(), pg_stat_get_wal_senders(), pg_stat_statements_internal(), pg_stop_backup_v2(), plperl_return_next(), pltcl_init_tuple_store(), populate_recordset_worker(), PortalCreateHoldStore(), show_all_file_settings(), storeRow(), and xpath_table().

317 {
319  int eflags;
320 
321  /*
322  * This interpretation of the meaning of randomAccess is compatible with
323  * the pre-8.3 behavior of tuplestores.
324  */
325  eflags = randomAccess ?
328 
329  state = tuplestore_begin_common(eflags, interXact, maxKBytes);
330 
331  state->copytup = copytup_heap;
332  state->writetup = writetup_heap;
333  state->readtup = readtup_heap;
334 
335  return state;
336 }
void(* writetup)(Tuplestorestate *state, void *tup)
Definition: tuplestore.c:139
void *(* readtup)(Tuplestorestate *state, unsigned int len)
Definition: tuplestore.c:147
static void * copytup_heap(Tuplestorestate *state, void *tup)
Definition: tuplestore.c:1476
#define EXEC_FLAG_BACKWARD
Definition: executor.h:60
#define EXEC_FLAG_REWIND
Definition: executor.h:59
static void * readtup_heap(Tuplestorestate *state, unsigned int len)
Definition: tuplestore.c:1519
static void writetup_heap(Tuplestorestate *state, void *tup)
Definition: tuplestore.c:1486
void *(* copytup)(Tuplestorestate *state, void *tup)
Definition: tuplestore.c:130
Definition: regguts.h:298
static Tuplestorestate * tuplestore_begin_common(int eflags, bool interXact, int maxKBytes)
Definition: tuplestore.c:252
void tuplestore_clear ( Tuplestorestate state)

Definition at line 416 of file tuplestore.c.

References BufFileClose(), TSReadPointer::current, TSReadPointer::eof_reached, FREEMEM, GetMemoryChunkSpace(), i, Tuplestorestate::memtupcount, Tuplestorestate::memtupdeleted, Tuplestorestate::memtuples, Tuplestorestate::myfile, NULL, pfree(), Tuplestorestate::readptrcount, Tuplestorestate::readptrs, Tuplestorestate::status, Tuplestorestate::truncated, and TSS_INMEM.

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

417 {
418  int i;
419  TSReadPointer *readptr;
420 
421  if (state->myfile)
422  BufFileClose(state->myfile);
423  state->myfile = NULL;
424  if (state->memtuples)
425  {
426  for (i = state->memtupdeleted; i < state->memtupcount; i++)
427  {
428  FREEMEM(state, GetMemoryChunkSpace(state->memtuples[i]));
429  pfree(state->memtuples[i]);
430  }
431  }
432  state->status = TSS_INMEM;
433  state->truncated = false;
434  state->memtupdeleted = 0;
435  state->memtupcount = 0;
436  readptr = state->readptrs;
437  for (i = 0; i < state->readptrcount; readptr++, i++)
438  {
439  readptr->eof_reached = false;
440  readptr->current = 0;
441  }
442 }
#define FREEMEM(state, amt)
Definition: tuplestore.c:187
bool eof_reached
Definition: tuplestore.c:94
TSReadPointer * readptrs
Definition: tuplestore.c:173
BufFile * myfile
Definition: tuplestore.c:112
Size GetMemoryChunkSpace(void *pointer)
Definition: mcxt.c:390
TupStoreStatus status
Definition: tuplestore.c:105
void BufFileClose(BufFile *file)
Definition: buffile.c:202
void pfree(void *pointer)
Definition: mcxt.c:992
#define NULL
Definition: c.h:226
void ** memtuples
Definition: tuplestore.c:159
int i
void tuplestore_copy_read_pointer ( Tuplestorestate state,
int  srcptr,
int  destptr 
)

Definition at line 1251 of file tuplestore.c.

References Tuplestorestate::activeptr, Assert, BufFileSeek(), BufFileTell(), TSReadPointer::eflags, Tuplestorestate::eflags, elog, TSReadPointer::eof_reached, ereport, errcode_for_file_access(), errmsg(), ERROR, TSReadPointer::file, i, Tuplestorestate::myfile, TSReadPointer::offset, Tuplestorestate::readptrcount, Tuplestorestate::readptrs, Tuplestorestate::status, TSS_INMEM, TSS_READFILE, TSS_WRITEFILE, Tuplestorestate::writepos_file, and Tuplestorestate::writepos_offset.

Referenced by ExecMaterialMarkPos(), and ExecMaterialRestrPos().

1253 {
1254  TSReadPointer *sptr = &state->readptrs[srcptr];
1255  TSReadPointer *dptr = &state->readptrs[destptr];
1256 
1257  Assert(srcptr >= 0 && srcptr < state->readptrcount);
1258  Assert(destptr >= 0 && destptr < state->readptrcount);
1259 
1260  /* Assigning to self is a no-op */
1261  if (srcptr == destptr)
1262  return;
1263 
1264  if (dptr->eflags != sptr->eflags)
1265  {
1266  /* Possible change of overall eflags, so copy and then recompute */
1267  int eflags;
1268  int i;
1269 
1270  *dptr = *sptr;
1271  eflags = state->readptrs[0].eflags;
1272  for (i = 1; i < state->readptrcount; i++)
1273  eflags |= state->readptrs[i].eflags;
1274  state->eflags = eflags;
1275  }
1276  else
1277  *dptr = *sptr;
1278 
1279  switch (state->status)
1280  {
1281  case TSS_INMEM:
1282  case TSS_WRITEFILE:
1283  /* no work */
1284  break;
1285  case TSS_READFILE:
1286 
1287  /*
1288  * This case is a bit tricky since the active read pointer's
1289  * position corresponds to the seek point, not what is in its
1290  * variables. Assigning to the active requires a seek, and
1291  * assigning from the active requires a tell, except when
1292  * eof_reached.
1293  */
1294  if (destptr == state->activeptr)
1295  {
1296  if (dptr->eof_reached)
1297  {
1298  if (BufFileSeek(state->myfile,
1299  state->writepos_file,
1300  state->writepos_offset,
1301  SEEK_SET) != 0)
1302  ereport(ERROR,
1304  errmsg("could not seek in tuplestore temporary file: %m")));
1305  }
1306  else
1307  {
1308  if (BufFileSeek(state->myfile,
1309  dptr->file, dptr->offset,
1310  SEEK_SET) != 0)
1311  ereport(ERROR,
1313  errmsg("could not seek in tuplestore temporary file: %m")));
1314  }
1315  }
1316  else if (srcptr == state->activeptr)
1317  {
1318  if (!dptr->eof_reached)
1319  BufFileTell(state->myfile,
1320  &dptr->file,
1321  &dptr->offset);
1322  }
1323  break;
1324  default:
1325  elog(ERROR, "invalid tuplestore state");
1326  break;
1327  }
1328 }
int BufFileSeek(BufFile *file, int fileno, off_t offset, int whence)
Definition: buffile.c:478
bool eof_reached
Definition: tuplestore.c:94
TSReadPointer * readptrs
Definition: tuplestore.c:173
BufFile * myfile
Definition: tuplestore.c:112
TupStoreStatus status
Definition: tuplestore.c:105
#define ERROR
Definition: elog.h:43
off_t writepos_offset
Definition: tuplestore.c:179
int errcode_for_file_access(void)
Definition: elog.c:598
off_t offset
Definition: tuplestore.c:97
#define ereport(elevel, rest)
Definition: elog.h:122
void BufFileTell(BufFile *file, int *fileno, off_t *offset)
Definition: buffile.c:564
#define Assert(condition)
Definition: c.h:670
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define elog
Definition: elog.h:219
void tuplestore_end ( Tuplestorestate state)

Definition at line 450 of file tuplestore.c.

References BufFileClose(), i, Tuplestorestate::memtupdeleted, Tuplestorestate::memtuples, Tuplestorestate::myfile, pfree(), and Tuplestorestate::readptrs.

Referenced by AfterTriggerEndQuery(), AfterTriggerEndSubXact(), ExecEndCteScan(), ExecEndFunctionScan(), ExecEndMaterial(), ExecEndRecursiveUnion(), ExecMakeFunctionResultSet(), ExecRecursiveUnion(), ExecReScanFunctionScan(), ExecReScanMaterial(), PortalDrop(), release_partition(), ShutdownFuncExpr(), ShutdownSQLFunction(), and storeRow().

451 {
452  int i;
453 
454  if (state->myfile)
455  BufFileClose(state->myfile);
456  if (state->memtuples)
457  {
458  for (i = state->memtupdeleted; i < state->memtupcount; i++)
459  pfree(state->memtuples[i]);
460  pfree(state->memtuples);
461  }
462  pfree(state->readptrs);
463  pfree(state);
464 }
TSReadPointer * readptrs
Definition: tuplestore.c:173
BufFile * myfile
Definition: tuplestore.c:112
void BufFileClose(BufFile *file)
Definition: buffile.c:202
void pfree(void *pointer)
Definition: mcxt.c:992
void ** memtuples
Definition: tuplestore.c:159
int i
bool tuplestore_gettupleslot ( Tuplestorestate state,
bool  forward,
bool  copy,
TupleTableSlot slot 
)

Definition at line 1061 of file tuplestore.c.

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

Referenced by AfterTriggerExecute(), CteScanNext(), ExecMakeFunctionResultSet(), ExecMaterial(), ExecWindowAgg(), fmgr_sql(), FunctionNext(), RunFromStore(), window_gettupleslot(), and WorkTableScanNext().

1063 {
1064  MinimalTuple tuple;
1065  bool should_free;
1066 
1067  tuple = (MinimalTuple) tuplestore_gettuple(state, forward, &should_free);
1068 
1069  if (tuple)
1070  {
1071  if (copy && !should_free)
1072  {
1073  tuple = heap_copy_minimal_tuple(tuple);
1074  should_free = true;
1075  }
1076  ExecStoreMinimalTuple(tuple, slot, should_free);
1077  return true;
1078  }
1079  else
1080  {
1081  ExecClearTuple(slot);
1082  return false;
1083  }
1084 }
TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
Definition: execTuples.c:384
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1481
MinimalTupleData * MinimalTuple
Definition: htup.h:27
static void * tuplestore_gettuple(Tuplestorestate *state, bool forward, bool *should_free)
Definition: tuplestore.c:886
bool tuplestore_in_memory ( Tuplestorestate state)

Definition at line 1438 of file tuplestore.c.

References Tuplestorestate::status, and TSS_INMEM.

Referenced by spool_tuples().

1439 {
1440  return (state->status == TSS_INMEM);
1441 }
TupStoreStatus status
Definition: tuplestore.c:105
void tuplestore_puttuple ( Tuplestorestate state,
HeapTuple  tuple 
)

Definition at line 715 of file tuplestore.c.

References Tuplestorestate::context, COPYTUP, MemoryContextSwitchTo(), and tuplestore_puttuple_common().

Referenced by AfterTriggerSaveEvent(), build_tuplestore_recursively(), crosstab(), each_object_field_end(), each_worker_jsonb(), elements_array_element_end(), elements_worker_jsonb(), exec_stmt_return_next(), exec_stmt_return_query(), ExecMakeTableFunctionResult(), fill_hba_line(), get_crosstab_tuplestore(), make_row_from_rec_and_jsonb(), materializeQueryResult(), materializeResult(), pg_config(), plperl_return_next(), pltcl_returnnext(), populate_recordset_object_end(), storeRow(), and xpath_table().

716 {
718 
719  /*
720  * Copy the tuple. (Must do this even in WRITEFILE case. Note that
721  * COPYTUP includes USEMEM, so we needn't do that here.)
722  */
723  tuple = COPYTUP(state, tuple);
724 
725  tuplestore_puttuple_common(state, (void *) tuple);
726 
727  MemoryContextSwitchTo(oldcxt);
728 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define COPYTUP(state, tup)
Definition: tuplestore.c:182
static void tuplestore_puttuple_common(Tuplestorestate *state, void *tuple)
Definition: tuplestore.c:750
MemoryContext context
Definition: tuplestore.c:113
void tuplestore_puttupleslot ( Tuplestorestate state,
TupleTableSlot slot 
)

Definition at line 693 of file tuplestore.c.

References Tuplestorestate::context, ExecCopySlotMinimalTuple(), GetMemoryChunkSpace(), MemoryContextSwitchTo(), tuplestore_puttuple_common(), and USEMEM.

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

695 {
696  MinimalTuple tuple;
698 
699  /*
700  * Form a MinimalTuple in working memory
701  */
702  tuple = ExecCopySlotMinimalTuple(slot);
703  USEMEM(state, GetMemoryChunkSpace(tuple));
704 
705  tuplestore_puttuple_common(state, (void *) tuple);
706 
707  MemoryContextSwitchTo(oldcxt);
708 }
#define USEMEM(state, amt)
Definition: tuplestore.c:186
MinimalTuple ExecCopySlotMinimalTuple(TupleTableSlot *slot)
Definition: execTuples.c:577
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Size GetMemoryChunkSpace(void *pointer)
Definition: mcxt.c:390
static void tuplestore_puttuple_common(Tuplestorestate *state, void *tuple)
Definition: tuplestore.c:750
MemoryContext context
Definition: tuplestore.c:113
void tuplestore_putvalues ( Tuplestorestate state,
TupleDesc  tdesc,
Datum values,
bool isnull 
)

Definition at line 735 of file tuplestore.c.

References Tuplestorestate::context, GetMemoryChunkSpace(), heap_form_minimal_tuple(), MemoryContextSwitchTo(), tuplestore_puttuple_common(), and USEMEM.

Referenced by brin_page_items(), dblink_get_notify(), deflist_to_tuplestore(), exec_stmt_return_next(), ExecMakeTableFunctionResult(), get_available_versions_for_extension(), LogicalOutputWrite(), pg_available_extensions(), pg_cursor(), pg_event_trigger_ddl_commands(), pg_event_trigger_dropped_objects(), pg_extension_update_paths(), pg_get_replication_slots(), pg_prepared_statement(), pg_show_replication_origin_status(), pg_stat_get_activity(), pg_stat_get_progress_info(), pg_stat_get_subscription(), pg_stat_get_wal_senders(), pg_stat_statements_internal(), pg_stop_backup_v2(), plperl_return_next(), pltcl_returnnext(), show_all_file_settings(), and tstoreReceiveSlot_detoast().

737 {
738  MinimalTuple tuple;
740 
741  tuple = heap_form_minimal_tuple(tdesc, values, isnull);
742  USEMEM(state, GetMemoryChunkSpace(tuple));
743 
744  tuplestore_puttuple_common(state, (void *) tuple);
745 
746  MemoryContextSwitchTo(oldcxt);
747 }
#define USEMEM(state, amt)
Definition: tuplestore.c:186
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Size GetMemoryChunkSpace(void *pointer)
Definition: mcxt.c:390
static void tuplestore_puttuple_common(Tuplestorestate *state, void *tuple)
Definition: tuplestore.c:750
MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1392
MemoryContext context
Definition: tuplestore.c:113
static Datum values[MAXATTR]
Definition: bootstrap.c:162
void tuplestore_rescan ( Tuplestorestate state)

Definition at line 1216 of file tuplestore.c.

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

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

1217 {
1218  TSReadPointer *readptr = &state->readptrs[state->activeptr];
1219 
1220  Assert(readptr->eflags & EXEC_FLAG_REWIND);
1221  Assert(!state->truncated);
1222 
1223  switch (state->status)
1224  {
1225  case TSS_INMEM:
1226  readptr->eof_reached = false;
1227  readptr->current = 0;
1228  break;
1229  case TSS_WRITEFILE:
1230  readptr->eof_reached = false;
1231  readptr->file = 0;
1232  readptr->offset = 0L;
1233  break;
1234  case TSS_READFILE:
1235  readptr->eof_reached = false;
1236  if (BufFileSeek(state->myfile, 0, 0L, SEEK_SET) != 0)
1237  ereport(ERROR,
1239  errmsg("could not seek in tuplestore temporary file: %m")));
1240  break;
1241  default:
1242  elog(ERROR, "invalid tuplestore state");
1243  break;
1244  }
1245 }
int BufFileSeek(BufFile *file, int fileno, off_t offset, int whence)
Definition: buffile.c:478
bool eof_reached
Definition: tuplestore.c:94
TSReadPointer * readptrs
Definition: tuplestore.c:173
BufFile * myfile
Definition: tuplestore.c:112
TupStoreStatus status
Definition: tuplestore.c:105
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:598
off_t offset
Definition: tuplestore.c:97
#define EXEC_FLAG_REWIND
Definition: executor.h:59
#define ereport(elevel, rest)
Definition: elog.h:122
#define Assert(condition)
Definition: c.h:670
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
void tuplestore_select_read_pointer ( Tuplestorestate state,
int  ptr 
)

Definition at line 470 of file tuplestore.c.

References Tuplestorestate::activeptr, Assert, BufFileSeek(), BufFileTell(), elog, TSReadPointer::eof_reached, ereport, errcode_for_file_access(), errmsg(), ERROR, TSReadPointer::file, Tuplestorestate::myfile, TSReadPointer::offset, Tuplestorestate::readptrs, Tuplestorestate::status, TSS_INMEM, TSS_READFILE, TSS_WRITEFILE, Tuplestorestate::writepos_file, and Tuplestorestate::writepos_offset.

Referenced by CteScanNext(), ExecInitCteScan(), ExecReScanCteScan(), ExecWindowAgg(), window_gettupleslot(), and WinSetMarkPosition().

471 {
472  TSReadPointer *readptr;
473  TSReadPointer *oldptr;
474 
475  Assert(ptr >= 0 && ptr < state->readptrcount);
476 
477  /* No work if already active */
478  if (ptr == state->activeptr)
479  return;
480 
481  readptr = &state->readptrs[ptr];
482  oldptr = &state->readptrs[state->activeptr];
483 
484  switch (state->status)
485  {
486  case TSS_INMEM:
487  case TSS_WRITEFILE:
488  /* no work */
489  break;
490  case TSS_READFILE:
491 
492  /*
493  * First, save the current read position in the pointer about to
494  * become inactive.
495  */
496  if (!oldptr->eof_reached)
497  BufFileTell(state->myfile,
498  &oldptr->file,
499  &oldptr->offset);
500 
501  /*
502  * We have to make the temp file's seek position equal to the
503  * logical position of the new read pointer. In eof_reached
504  * state, that's the EOF, which we have available from the saved
505  * write position.
506  */
507  if (readptr->eof_reached)
508  {
509  if (BufFileSeek(state->myfile,
510  state->writepos_file,
511  state->writepos_offset,
512  SEEK_SET) != 0)
513  ereport(ERROR,
515  errmsg("could not seek in tuplestore temporary file: %m")));
516  }
517  else
518  {
519  if (BufFileSeek(state->myfile,
520  readptr->file,
521  readptr->offset,
522  SEEK_SET) != 0)
523  ereport(ERROR,
525  errmsg("could not seek in tuplestore temporary file: %m")));
526  }
527  break;
528  default:
529  elog(ERROR, "invalid tuplestore state");
530  break;
531  }
532 
533  state->activeptr = ptr;
534 }
int BufFileSeek(BufFile *file, int fileno, off_t offset, int whence)
Definition: buffile.c:478
bool eof_reached
Definition: tuplestore.c:94
TSReadPointer * readptrs
Definition: tuplestore.c:173
BufFile * myfile
Definition: tuplestore.c:112
TupStoreStatus status
Definition: tuplestore.c:105
#define ERROR
Definition: elog.h:43
off_t writepos_offset
Definition: tuplestore.c:179
int errcode_for_file_access(void)
Definition: elog.c:598
off_t offset
Definition: tuplestore.c:97
#define ereport(elevel, rest)
Definition: elog.h:122
void BufFileTell(BufFile *file, int *fileno, off_t *offset)
Definition: buffile.c:564
#define Assert(condition)
Definition: c.h:670
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
void tuplestore_set_eflags ( Tuplestorestate state,
int  eflags 
)

Definition at line 357 of file tuplestore.c.

References TSReadPointer::eflags, Tuplestorestate::eflags, elog, ERROR, i, Tuplestorestate::memtupcount, Tuplestorestate::readptrcount, Tuplestorestate::readptrs, Tuplestorestate::status, and TSS_INMEM.

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

358 {
359  int i;
360 
361  if (state->status != TSS_INMEM || state->memtupcount != 0)
362  elog(ERROR, "too late to call tuplestore_set_eflags");
363 
364  state->readptrs[0].eflags = eflags;
365  for (i = 1; i < state->readptrcount; i++)
366  eflags |= state->readptrs[i].eflags;
367  state->eflags = eflags;
368 }
TSReadPointer * readptrs
Definition: tuplestore.c:173
TupStoreStatus status
Definition: tuplestore.c:105
#define ERROR
Definition: elog.h:43
int i
#define elog
Definition: elog.h:219
bool tuplestore_skiptuples ( Tuplestorestate state,
int64  ntuples,
bool  forward 
)

Definition at line 1118 of file tuplestore.c.

References Tuplestorestate::activeptr, Assert, CHECK_FOR_INTERRUPTS, TSReadPointer::current, TSReadPointer::eflags, TSReadPointer::eof_reached, EXEC_FLAG_BACKWARD, Tuplestorestate::memtupcount, Tuplestorestate::memtupdeleted, NULL, pfree(), Tuplestorestate::readptrs, Tuplestorestate::status, Tuplestorestate::truncated, TSS_INMEM, and tuplestore_gettuple().

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

1119 {
1120  TSReadPointer *readptr = &state->readptrs[state->activeptr];
1121 
1122  Assert(forward || (readptr->eflags & EXEC_FLAG_BACKWARD));
1123 
1124  if (ntuples <= 0)
1125  return true;
1126 
1127  switch (state->status)
1128  {
1129  case TSS_INMEM:
1130  if (forward)
1131  {
1132  if (readptr->eof_reached)
1133  return false;
1134  if (state->memtupcount - readptr->current >= ntuples)
1135  {
1136  readptr->current += ntuples;
1137  return true;
1138  }
1139  readptr->current = state->memtupcount;
1140  readptr->eof_reached = true;
1141  return false;
1142  }
1143  else
1144  {
1145  if (readptr->eof_reached)
1146  {
1147  readptr->current = state->memtupcount;
1148  readptr->eof_reached = false;
1149  ntuples--;
1150  }
1151  if (readptr->current - state->memtupdeleted > ntuples)
1152  {
1153  readptr->current -= ntuples;
1154  return true;
1155  }
1156  Assert(!state->truncated);
1157  readptr->current = state->memtupdeleted;
1158  return false;
1159  }
1160  break;
1161 
1162  default:
1163  /* We don't currently try hard to optimize other cases */
1164  while (ntuples-- > 0)
1165  {
1166  void *tuple;
1167  bool should_free;
1168 
1169  tuple = tuplestore_gettuple(state, forward, &should_free);
1170 
1171  if (tuple == NULL)
1172  return false;
1173  if (should_free)
1174  pfree(tuple);
1176  }
1177  return true;
1178  }
1179 }
bool eof_reached
Definition: tuplestore.c:94
TSReadPointer * readptrs
Definition: tuplestore.c:173
TupStoreStatus status
Definition: tuplestore.c:105
void pfree(void *pointer)
Definition: mcxt.c:992
#define EXEC_FLAG_BACKWARD
Definition: executor.h:60
static void * tuplestore_gettuple(Tuplestorestate *state, bool forward, bool *should_free)
Definition: tuplestore.c:886
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:97
void tuplestore_trim ( Tuplestorestate state)

Definition at line 1343 of file tuplestore.c.

References Assert, TSReadPointer::current, Tuplestorestate::eflags, TSReadPointer::eof_reached, EXEC_FLAG_REWIND, FREEMEM, GetMemoryChunkSpace(), i, memmove, Tuplestorestate::memtupcount, Tuplestorestate::memtupdeleted, Tuplestorestate::memtuples, Min, NULL, pfree(), Tuplestorestate::readptrcount, Tuplestorestate::readptrs, Tuplestorestate::status, Tuplestorestate::truncated, and TSS_INMEM.

Referenced by ExecMaterialMarkPos(), and ExecWindowAgg().

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