/*-------------------------------------------------------------------------
*
* nodeWorktablescan . c
* routines to handle WorkTableScan nodes .
*
* Portions Copyright ( c ) 1996 - 2025 , PostgreSQL Global Development Group
* Portions Copyright ( c ) 1994 , Regents of the University of California
*
*
* IDENTIFICATION
* src / backend / executor / nodeWorktablescan . c
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
#include "postgres.h"
#include "executor/executor.h"
#include "executor/nodeWorktablescan.h"
static TupleTableSlot *WorkTableScanNext(WorkTableScanState *node);
/* ----------------------------------------------------------------
* WorkTableScanNext
*
* This is a workhorse for ExecWorkTableScan
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
static TupleTableSlot *
WorkTableScanNext(WorkTableScanState *node)
{
TupleTableSlot *slot;
Tuplestorestate *tuplestorestate;
/*
* get information from the estate and scan state
*
* Note : we intentionally do not support backward scan . Although it would
* take only a couple more lines here , it would force nodeRecursiveunion . c
* to create the tuplestore with backward scan enabled , which has a
* performance cost . In practice backward scan is never useful for a
* worktable plan node , since it cannot appear high enough in the plan
* tree of a scrollable cursor to be exposed to a backward - scan
* requirement . So it ' s not worth expending effort to support it .
*
* Note : we are also assuming that this node is the only reader of the
* worktable . Therefore , we don ' t need a private read pointer for the
* tuplestore , nor do we need to tell tuplestore_gettupleslot to copy .
*/
Assert(ScanDirectionIsForward(node->ss.ps.state->es_direction));
tuplestorestate = node->rustate->working_table;
/*
* Get the next tuple from tuplestore . Return NULL if no more tuples .
*/
slot = node->ss.ss_ScanTupleSlot;
(void ) tuplestore_gettupleslot(tuplestorestate, true , false , slot);
return slot;
}
/*
* WorkTableScanRecheck - - access method routine to recheck a tuple in EvalPlanQual
*/
static bool
WorkTableScanRecheck(WorkTableScanState *node, TupleTableSlot *slot)
{
/* nothing to check */
return true ;
}
/* ----------------------------------------------------------------
* ExecWorkTableScan ( node )
*
* Scans the worktable sequentially and returns the next qualifying tuple .
* We call the ExecScan ( ) routine and pass it the appropriate
* access method functions .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
static TupleTableSlot *
ExecWorkTableScan(PlanState *pstate)
{
WorkTableScanState *node = castNode(WorkTableScanState, pstate);
/*
* On the first call , find the ancestor RecursiveUnion ' s state via the
* Param slot reserved for it . ( We can ' t do this during node init because
* there are corner cases where we ' ll get the init call before the
* RecursiveUnion does . )
*/
if (node->rustate == NULL)
{
WorkTableScan *plan = (WorkTableScan *) node->ss.ps.plan;
EState *estate = node->ss.ps.state;
ParamExecData *param;
param = &(estate->es_param_exec_vals[plan->wtParam]);
Assert(param->execPlan == NULL);
Assert(!param->isnull);
node->rustate = castNode(RecursiveUnionState, DatumGetPointer(param->value));
Assert(node->rustate);
/*
* The scan tuple type ( ie , the rowtype we expect to find in the work
* table ) is the same as the result rowtype of the ancestor
* RecursiveUnion node . Note this depends on the assumption that
* RecursiveUnion doesn ' t allow projection .
*/
ExecAssignScanType(&node->ss,
ExecGetResultType(&node->rustate->ps));
/*
* Now we can initialize the projection info . This must be completed
* before we can call ExecScan ( ) .
*/
ExecAssignScanProjectionInfo(&node->ss);
}
return ExecScan(&node->ss,
(ExecScanAccessMtd) WorkTableScanNext,
(ExecScanRecheckMtd) WorkTableScanRecheck);
}
/* ----------------------------------------------------------------
* ExecInitWorkTableScan
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
WorkTableScanState *
ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags)
{
WorkTableScanState *scanstate;
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
/*
* WorkTableScan should not have any children .
*/
Assert(outerPlan(node) == NULL);
Assert(innerPlan(node) == NULL);
/*
* create new WorkTableScanState for node
*/
scanstate = makeNode(WorkTableScanState);
scanstate->ss.ps.plan = (Plan *) node;
scanstate->ss.ps.state = estate;
scanstate->ss.ps.ExecProcNode = ExecWorkTableScan;
scanstate->rustate = NULL; /* we'll set this later */
/*
* Miscellaneous initialization
*
* create expression context for node
*/
ExecAssignExprContext(estate, &scanstate->ss.ps);
/*
* tuple table initialization
*/
ExecInitResultTypeTL(&scanstate->ss.ps);
/* signal that return type is not yet known */
scanstate->ss.ps.resultopsset = true ;
scanstate->ss.ps.resultopsfixed = false ;
ExecInitScanTupleSlot(estate, &scanstate->ss, NULL, &TTSOpsMinimalTuple);
/*
* initialize child expressions
*/
scanstate->ss.ps.qual =
ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
/*
* Do not yet initialize projection info , see ExecWorkTableScan ( ) for
* details .
*/
return scanstate;
}
/* ----------------------------------------------------------------
* ExecReScanWorkTableScan
*
* Rescans the relation .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
void
ExecReScanWorkTableScan(WorkTableScanState *node)
{
if (node->ss.ps.ps_ResultTupleSlot)
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
ExecScanReScan(&node->ss);
/* No need (or way) to rescan if ExecWorkTableScan not called yet */
if (node->rustate)
tuplestore_rescan(node->rustate->working_table);
}
Messung V0.5 in Prozent C=92 H=95 G=93
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-08-08)
¤
*© Formatika GbR, Deutschland