PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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 **max_storage_type, int64 *max_space)
 
bool tuplestore_in_memory (Tuplestorestate *state)
 
bool tuplestore_gettupleslot (Tuplestorestate *state, bool forward, bool copy, TupleTableSlot *slot)
 
bool tuplestore_gettupleslot_force (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 40 of file tuplestore.h.

Function Documentation

◆ tuplestore_advance()

bool tuplestore_advance ( Tuplestorestate state,
bool  forward 
)
extern

Definition at line 1195 of file tuplestore.c.

1196{
1197 void *tuple;
1198 bool should_free;
1199
1201
1202 if (tuple)
1203 {
1204 if (should_free)
1205 pfree(tuple);
1206 return true;
1207 }
1208 else
1209 {
1210 return false;
1211 }
1212}
void pfree(void *pointer)
Definition mcxt.c:1616
static int fb(int x)
static void * tuplestore_gettuple(Tuplestorestate *state, bool forward, bool *should_free)
Definition tuplestore.c:956

References fb(), pfree(), and tuplestore_gettuple().

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

◆ tuplestore_alloc_read_pointer()

int tuplestore_alloc_read_pointer ( Tuplestorestate state,
int  eflags 
)
extern

Definition at line 396 of file tuplestore.c.

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

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

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

◆ tuplestore_ateof()

bool tuplestore_ateof ( Tuplestorestate state)
extern

Definition at line 592 of file tuplestore.c.

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

Referenced by CteScanNext(), and ExecMaterial().

◆ tuplestore_begin_heap()

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

Definition at line 331 of file tuplestore.c.

332{
334 int eflags;
335
336 /*
337 * This interpretation of the meaning of randomAccess is compatible with
338 * the pre-8.3 behavior of tuplestores.
339 */
340 eflags = randomAccess ?
343
344 state = tuplestore_begin_common(eflags, interXact, maxKBytes);
345
346 state->copytup = copytup_heap;
347 state->writetup = writetup_heap;
348 state->readtup = readtup_heap;
349
350 return state;
351}
#define EXEC_FLAG_BACKWARD
Definition executor.h:70
#define EXEC_FLAG_REWIND
Definition executor.h:69
static void writetup_heap(Tuplestorestate *state, void *tup)
static void * copytup_heap(Tuplestorestate *state, void *tup)
static Tuplestorestate * tuplestore_begin_common(int eflags, bool interXact, int maxKBytes)
Definition tuplestore.c:257
static void * readtup_heap(Tuplestorestate *state, unsigned int len)

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

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

◆ tuplestore_clear()

void tuplestore_clear ( Tuplestorestate state)
extern

Definition at line 431 of file tuplestore.c.

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

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

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

◆ tuplestore_copy_read_pointer()

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

Definition at line 1353 of file tuplestore.c.

1355{
1356 TSReadPointer *sptr = &state->readptrs[srcptr];
1357 TSReadPointer *dptr = &state->readptrs[destptr];
1358
1359 Assert(srcptr >= 0 && srcptr < state->readptrcount);
1360 Assert(destptr >= 0 && destptr < state->readptrcount);
1361
1362 /* Assigning to self is a no-op */
1363 if (srcptr == destptr)
1364 return;
1365
1366 if (dptr->eflags != sptr->eflags)
1367 {
1368 /* Possible change of overall eflags, so copy and then recompute */
1369 int eflags;
1370 int i;
1371
1372 *dptr = *sptr;
1373 eflags = state->readptrs[0].eflags;
1374 for (i = 1; i < state->readptrcount; i++)
1375 eflags |= state->readptrs[i].eflags;
1376 state->eflags = eflags;
1377 }
1378 else
1379 *dptr = *sptr;
1380
1381 switch (state->status)
1382 {
1383 case TSS_INMEM:
1384 case TSS_WRITEFILE:
1385 /* no work */
1386 break;
1387 case TSS_READFILE:
1388
1389 /*
1390 * This case is a bit tricky since the active read pointer's
1391 * position corresponds to the seek point, not what is in its
1392 * variables. Assigning to the active requires a seek, and
1393 * assigning from the active requires a tell, except when
1394 * eof_reached.
1395 */
1396 if (destptr == state->activeptr)
1397 {
1398 if (dptr->eof_reached)
1399 {
1400 if (BufFileSeek(state->myfile,
1401 state->writepos_file,
1402 state->writepos_offset,
1403 SEEK_SET) != 0)
1404 ereport(ERROR,
1406 errmsg("could not seek in tuplestore temporary file")));
1407 }
1408 else
1409 {
1410 if (BufFileSeek(state->myfile,
1411 dptr->file, dptr->offset,
1412 SEEK_SET) != 0)
1413 ereport(ERROR,
1415 errmsg("could not seek in tuplestore temporary file")));
1416 }
1417 }
1418 else if (srcptr == state->activeptr)
1419 {
1420 if (!dptr->eof_reached)
1421 BufFileTell(state->myfile,
1422 &dptr->file,
1423 &dptr->offset);
1424 }
1425 break;
1426 default:
1427 elog(ERROR, "invalid tuplestore state");
1428 break;
1429 }
1430}
int BufFileSeek(BufFile *file, int fileno, pgoff_t offset, int whence)
Definition buffile.c:741
void BufFileTell(BufFile *file, int *fileno, pgoff_t *offset)
Definition buffile.c:833
int errcode_for_file_access(void)
Definition elog.c:897
#define ereport(elevel,...)
Definition elog.h:150
static char * errmsg
@ TSS_READFILE
Definition tuplestore.c:77
@ TSS_WRITEFILE
Definition tuplestore.c:76

References Assert, BufFileSeek(), BufFileTell(), elog, ereport, errcode_for_file_access(), errmsg, ERROR, fb(), i, TSS_INMEM, TSS_READFILE, and TSS_WRITEFILE.

Referenced by ExecMaterialMarkPos(), and ExecMaterialRestrPos().

◆ tuplestore_end()

◆ tuplestore_get_stats()

void tuplestore_get_stats ( Tuplestorestate state,
char **  max_storage_type,
int64 max_space 
)
extern

Definition at line 1566 of file tuplestore.c.

1568{
1570
1571 if (state->usedDisk)
1572 *max_storage_type = "Disk";
1573 else
1574 *max_storage_type = "Memory";
1575
1576 *max_space = state->maxSpace;
1577}

References fb(), and 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 
)
extern

Definition at line 1131 of file tuplestore.c.

1133{
1134 MinimalTuple tuple;
1135 bool should_free;
1136
1138
1139 if (tuple)
1140 {
1141 if (copy && !should_free)
1142 {
1143 tuple = heap_copy_minimal_tuple(tuple, 0);
1144 should_free = true;
1145 }
1146 ExecStoreMinimalTuple(tuple, slot, should_free);
1147 return true;
1148 }
1149 else
1150 {
1151 ExecClearTuple(slot);
1152 return false;
1153 }
1154}
TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup, Size extra)
Definition heaptuple.c:1490
MinimalTupleData * MinimalTuple
Definition htup.h:27
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition tuptable.h:476

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

Referenced by AfterTriggerExecute(), check_pub_dead_tuple_retention(), check_publications(), check_publications_origin_sequences(), check_publications_origin_tables(), copy_sequences(), CteScanNext(), ExecHashJoinImpl(), ExecMakeFunctionResultSet(), ExecMaterial(), ExecWindowAgg(), fetch_relation_list(), fetch_remote_slots(), fetch_remote_table_info(), FunctionNext(), NamedTuplestoreScanNext(), RunFromStore(), TableFuncNext(), update_frameheadpos(), update_frametailpos(), update_grouptailpos(), validate_remote_info(), window_gettupleslot(), and WorkTableScanNext().

◆ tuplestore_gettupleslot_force()

bool tuplestore_gettupleslot_force ( Tuplestorestate state,
bool  forward,
bool  copy,
TupleTableSlot slot 
)
extern

Definition at line 1163 of file tuplestore.c.

1165{
1166 MinimalTuple tuple;
1167 bool should_free;
1168
1170
1171 if (tuple)
1172 {
1173 if (copy && !should_free)
1174 {
1175 tuple = heap_copy_minimal_tuple(tuple, 0);
1176 should_free = true;
1177 }
1179 return true;
1180 }
1181 else
1182 {
1183 ExecClearTuple(slot);
1184 return false;
1185 }
1186}
void ExecForceStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)

References ExecClearTuple(), ExecForceStoreMinimalTuple(), fb(), heap_copy_minimal_tuple(), and tuplestore_gettuple().

Referenced by ExecHashJoinImpl().

◆ tuplestore_in_memory()

bool tuplestore_in_memory ( Tuplestorestate state)
extern

Definition at line 1587 of file tuplestore.c.

1588{
1589 return (state->status == TSS_INMEM);
1590}

References TSS_INMEM.

Referenced by spool_tuples().

◆ tuplestore_puttuple()

void tuplestore_puttuple ( Tuplestorestate state,
HeapTuple  tuple 
)
extern

Definition at line 765 of file tuplestore.c.

766{
768
769 /*
770 * Copy the tuple. (Must do this even in WRITEFILE case. Note that
771 * COPYTUP includes USEMEM, so we needn't do that here.)
772 */
773 tuple = COPYTUP(state, tuple);
774
776
778}
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
#define COPYTUP(state, tup)
Definition tuplestore.c:186
static void tuplestore_puttuple_common(Tuplestorestate *state, void *tuple)
Definition tuplestore.c:800

References COPYTUP, fb(), 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(), materializeQueryResult(), 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()

◆ tuplestore_putvalues()

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

Definition at line 785 of file tuplestore.c.

787{
788 MinimalTuple tuple;
790
791 tuple = heap_form_minimal_tuple(tdesc, values, isnull, 0);
793
795
797}
static Datum values[MAXATTR]
Definition bootstrap.c:188
MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull, Size extra)
Definition heaptuple.c:1402

References fb(), 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(), injection_points_list(), LogicalOutputWrite(), pg_available_extensions(), pg_buffercache_usage_counts(), pg_config(), pg_cursor(), pg_event_trigger_ddl_commands(), pg_event_trigger_dropped_objects(), pg_extension_update_paths(), pg_get_aios(), pg_get_dsm_registry_allocations(), pg_get_loaded_modules(), pg_get_replication_slots(), pg_get_shmem_allocations(), pg_get_shmem_allocations_numa(), pg_get_wait_events(), pg_get_wal_resource_managers(), pg_ls_dir(), pg_ls_dir_files(), pg_options_to_table(), pg_prepared_statement(), pg_show_replication_origin_status(), pg_stat_get_activity(), 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_io_build_tuples(), pg_stat_statements_internal(), pg_tablespace_databases(), pg_timezone_names(), 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)
extern

Definition at line 1318 of file tuplestore.c.

1319{
1320 TSReadPointer *readptr = &state->readptrs[state->activeptr];
1321
1322 Assert(readptr->eflags & EXEC_FLAG_REWIND);
1323 Assert(!state->truncated);
1324
1325 switch (state->status)
1326 {
1327 case TSS_INMEM:
1328 readptr->eof_reached = false;
1329 readptr->current = 0;
1330 break;
1331 case TSS_WRITEFILE:
1332 readptr->eof_reached = false;
1333 readptr->file = 0;
1334 readptr->offset = 0;
1335 break;
1336 case TSS_READFILE:
1337 readptr->eof_reached = false;
1338 if (BufFileSeek(state->myfile, 0, 0, SEEK_SET) != 0)
1339 ereport(ERROR,
1341 errmsg("could not seek in tuplestore temporary file")));
1342 break;
1343 default:
1344 elog(ERROR, "invalid tuplestore state");
1345 break;
1346 }
1347}
pgoff_t offset
Definition tuplestore.c:98

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

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

◆ tuplestore_select_read_pointer()

void tuplestore_select_read_pointer ( Tuplestorestate state,
int  ptr 
)
extern

Definition at line 508 of file tuplestore.c.

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

References Assert, BufFileSeek(), BufFileTell(), elog, TSReadPointer::eof_reached, ereport, errcode_for_file_access(), errmsg, ERROR, fb(), 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 
)
extern

Definition at line 372 of file tuplestore.c.

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

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 
)
extern

Definition at line 1220 of file tuplestore.c.

1221{
1222 TSReadPointer *readptr = &state->readptrs[state->activeptr];
1223
1224 Assert(forward || (readptr->eflags & EXEC_FLAG_BACKWARD));
1225
1226 if (ntuples <= 0)
1227 return true;
1228
1229 switch (state->status)
1230 {
1231 case TSS_INMEM:
1232 if (forward)
1233 {
1234 if (readptr->eof_reached)
1235 return false;
1236 if (state->memtupcount - readptr->current >= ntuples)
1237 {
1238 readptr->current += ntuples;
1239 return true;
1240 }
1241 readptr->current = state->memtupcount;
1242 readptr->eof_reached = true;
1243 return false;
1244 }
1245 else
1246 {
1247 if (readptr->eof_reached)
1248 {
1249 readptr->current = state->memtupcount;
1250 readptr->eof_reached = false;
1251 ntuples--;
1252 }
1253 if (readptr->current - state->memtupdeleted > ntuples)
1254 {
1255 readptr->current -= ntuples;
1256 return true;
1257 }
1258 Assert(!state->truncated);
1259 readptr->current = state->memtupdeleted;
1260 return false;
1261 }
1262 break;
1263
1264 default:
1265 /* We don't currently try hard to optimize other cases */
1266 while (ntuples-- > 0)
1267 {
1268 void *tuple;
1269 bool should_free;
1270
1272
1273 if (tuple == NULL)
1274 return false;
1275 if (should_free)
1276 pfree(tuple);
1278 }
1279 return true;
1280 }
1281}
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:123

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

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

◆ tuplestore_trim()

void tuplestore_trim ( Tuplestorestate state)
extern

Definition at line 1445 of file tuplestore.c.

1446{
1447 int oldest;
1448 int nremove;
1449 int i;
1450
1451 /*
1452 * Truncation is disallowed if any read pointer requires rewind
1453 * capability.
1454 */
1455 if (state->eflags & EXEC_FLAG_REWIND)
1456 return;
1457
1458 /*
1459 * We don't bother trimming temp files since it usually would mean more
1460 * work than just letting them sit in kernel buffers until they age out.
1461 */
1462 if (state->status != TSS_INMEM)
1463 return;
1464
1465 /* Find the oldest read pointer */
1466 oldest = state->memtupcount;
1467 for (i = 0; i < state->readptrcount; i++)
1468 {
1469 if (!state->readptrs[i].eof_reached)
1470 oldest = Min(oldest, state->readptrs[i].current);
1471 }
1472
1473 /*
1474 * Note: you might think we could remove all the tuples before the oldest
1475 * "current", since that one is the next to be returned. However, since
1476 * tuplestore_gettuple returns a direct pointer to our internal copy of
1477 * the tuple, it's likely that the caller has still got the tuple just
1478 * before "current" referenced in a slot. So we keep one extra tuple
1479 * before the oldest "current". (Strictly speaking, we could require such
1480 * callers to use the "copy" flag to tuplestore_gettupleslot, but for
1481 * efficiency we allow this one case to not use "copy".)
1482 */
1483 nremove = oldest - 1;
1484 if (nremove <= 0)
1485 return; /* nothing to do */
1486
1487 Assert(nremove >= state->memtupdeleted);
1488 Assert(nremove <= state->memtupcount);
1489
1490 /* before freeing any memory, update the statistics */
1492
1493 /* Release no-longer-needed tuples */
1494 for (i = state->memtupdeleted; i < nremove; i++)
1495 {
1496 FREEMEM(state, GetMemoryChunkSpace(state->memtuples[i]));
1497 pfree(state->memtuples[i]);
1498 state->memtuples[i] = NULL;
1499 }
1500 state->memtupdeleted = nremove;
1501
1502 /* mark tuplestore as truncated (used for Assert crosschecks only) */
1503 state->truncated = true;
1504
1505 /*
1506 * If nremove is less than 1/8th memtupcount, just stop here, leaving the
1507 * "deleted" slots as NULL. This prevents us from expending O(N^2) time
1508 * repeatedly memmove-ing a large pointer array. The worst case space
1509 * wastage is pretty small, since it's just pointers and not whole tuples.
1510 */
1511 if (nremove < state->memtupcount / 8)
1512 return;
1513
1514 /*
1515 * Slide the array down and readjust pointers.
1516 *
1517 * In mergejoin's current usage, it's demonstrable that there will always
1518 * be exactly one non-removed tuple; so optimize that case.
1519 */
1520 if (nremove + 1 == state->memtupcount)
1521 state->memtuples[0] = state->memtuples[nremove];
1522 else
1523 memmove(state->memtuples, state->memtuples + nremove,
1524 (state->memtupcount - nremove) * sizeof(void *));
1525
1526 state->memtupdeleted = 0;
1527 state->memtupcount -= nremove;
1528 for (i = 0; i < state->readptrcount; i++)
1529 {
1530 if (!state->readptrs[i].eof_reached)
1531 state->readptrs[i].current -= nremove;
1532 }
1533}
#define Min(x, y)
Definition c.h:1093
#define FREEMEM(state, amt)
Definition tuplestore.c:191

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

Referenced by ExecMaterialMarkPos(), and ExecWindowAgg().

◆ tuplestore_tuple_count()

int64 tuplestore_tuple_count ( Tuplestorestate state)
extern

Definition at line 581 of file tuplestore.c.

582{
583 return state->tuples;
584}

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