PostgreSQL Source Code git master
Loading...
Searching...
No Matches
nodeWorktablescan.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * nodeWorktablescan.c
4 * routines to handle WorkTableScan nodes.
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/executor/nodeWorktablescan.c
12 *
13 *-------------------------------------------------------------------------
14 */
15
16#include "postgres.h"
17
18#include "executor/executor.h"
20#include "utils/tuplestore.h"
21
23
24/* ----------------------------------------------------------------
25 * WorkTableScanNext
26 *
27 * This is a workhorse for ExecWorkTableScan
28 * ----------------------------------------------------------------
29 */
30static TupleTableSlot *
32{
33 TupleTableSlot *slot;
34 Tuplestorestate *tuplestorestate;
35
36 /*
37 * get information from the estate and scan state
38 *
39 * Note: we intentionally do not support backward scan. Although it would
40 * take only a couple more lines here, it would force nodeRecursiveunion.c
41 * to create the tuplestore with backward scan enabled, which has a
42 * performance cost. In practice backward scan is never useful for a
43 * worktable plan node, since it cannot appear high enough in the plan
44 * tree of a scrollable cursor to be exposed to a backward-scan
45 * requirement. So it's not worth expending effort to support it.
46 *
47 * Note: we are also assuming that this node is the only reader of the
48 * worktable. Therefore, we don't need a private read pointer for the
49 * tuplestore, nor do we need to tell tuplestore_gettupleslot to copy.
50 */
52
53 tuplestorestate = node->rustate->working_table;
54
55 /*
56 * Get the next tuple from tuplestore. Return NULL if no more tuples.
57 */
58 slot = node->ss.ss_ScanTupleSlot;
59 (void) tuplestore_gettupleslot(tuplestorestate, true, false, slot);
60 return slot;
61}
62
63/*
64 * WorkTableScanRecheck -- access method routine to recheck a tuple in EvalPlanQual
65 */
66static bool
68{
69 /* nothing to check */
70 return true;
71}
72
73/* ----------------------------------------------------------------
74 * ExecWorkTableScan(node)
75 *
76 * Scans the worktable sequentially and returns the next qualifying tuple.
77 * We call the ExecScan() routine and pass it the appropriate
78 * access method functions.
79 * ----------------------------------------------------------------
80 */
81static TupleTableSlot *
83{
85
86 /*
87 * On the first call, find the ancestor RecursiveUnion's state via the
88 * Param slot reserved for it. (We can't do this during node init because
89 * there are corner cases where we'll get the init call before the
90 * RecursiveUnion does.)
91 */
92 if (node->rustate == NULL)
93 {
95 EState *estate = node->ss.ps.state;
96 ParamExecData *param;
97
98 param = &(estate->es_param_exec_vals[plan->wtParam]);
99 Assert(param->execPlan == NULL);
100 Assert(!param->isnull);
102 Assert(node->rustate);
103
104 /*
105 * The scan tuple type (ie, the rowtype we expect to find in the work
106 * table) is the same as the result rowtype of the ancestor
107 * RecursiveUnion node. Note this depends on the assumption that
108 * RecursiveUnion doesn't allow projection.
109 */
110 ExecAssignScanType(&node->ss,
111 ExecGetResultType(&node->rustate->ps));
112
113 /*
114 * Now we can initialize the projection info. This must be completed
115 * before we can call ExecScan().
116 */
118 }
119
120 return ExecScan(&node->ss,
123}
124
125
126/* ----------------------------------------------------------------
127 * ExecInitWorkTableScan
128 * ----------------------------------------------------------------
129 */
131ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags)
132{
134
135 /* check for unsupported flags */
137
138 /*
139 * WorkTableScan should not have any children.
140 */
141 Assert(outerPlan(node) == NULL);
142 Assert(innerPlan(node) == NULL);
143
144 /*
145 * create new WorkTableScanState for node
146 */
148 scanstate->ss.ps.plan = (Plan *) node;
149 scanstate->ss.ps.state = estate;
150 scanstate->ss.ps.ExecProcNode = ExecWorkTableScan;
151 scanstate->rustate = NULL; /* we'll set this later */
152
153 /*
154 * Miscellaneous initialization
155 *
156 * create expression context for node
157 */
158 ExecAssignExprContext(estate, &scanstate->ss.ps);
159
160 /*
161 * tuple table initialization
162 */
164
165 /* signal that return type is not yet known */
166 scanstate->ss.ps.resultopsset = true;
167 scanstate->ss.ps.resultopsfixed = false;
168
170
171 /*
172 * initialize child expressions
173 */
174 scanstate->ss.ps.qual =
175 ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
176
177 /*
178 * Do not yet initialize projection info, see ExecWorkTableScan() for
179 * details.
180 */
181
182 return scanstate;
183}
184
185/* ----------------------------------------------------------------
186 * ExecReScanWorkTableScan
187 *
188 * Rescans the relation.
189 * ----------------------------------------------------------------
190 */
191void
193{
194 if (node->ss.ps.ps_ResultTupleSlot)
196
197 ExecScanReScan(&node->ss);
198
199 /* No need (or way) to rescan if ExecWorkTableScan not called yet */
200 if (node->rustate)
202}
#define Assert(condition)
Definition c.h:945
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition execExpr.c:250
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
Definition execScan.c:47
void ExecAssignScanProjectionInfo(ScanState *node)
Definition execScan.c:81
void ExecScanReScan(ScanState *node)
Definition execScan.c:108
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops, uint16 flags)
void ExecInitResultTypeTL(PlanState *planstate)
const TupleTableSlotOps TTSOpsMinimalTuple
Definition execTuples.c:86
TupleDesc ExecGetResultType(PlanState *planstate)
Definition execUtils.c:500
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition execUtils.c:490
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
Definition execUtils.c:697
#define EXEC_FLAG_BACKWARD
Definition executor.h:70
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition executor.h:583
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition executor.h:582
#define EXEC_FLAG_MARK
Definition executor.h:71
static TupleTableSlot * ExecWorkTableScan(PlanState *pstate)
WorkTableScanState * ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags)
static TupleTableSlot * WorkTableScanNext(WorkTableScanState *node)
void ExecReScanWorkTableScan(WorkTableScanState *node)
static bool WorkTableScanRecheck(WorkTableScanState *node, TupleTableSlot *slot)
#define makeNode(_type_)
Definition nodes.h:161
#define castNode(_type_, nodeptr)
Definition nodes.h:182
#define plan(x)
Definition pg_regress.c:161
#define innerPlan(node)
Definition plannodes.h:264
#define outerPlan(node)
Definition plannodes.h:265
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:332
static int fb(int x)
#define ScanDirectionIsForward(direction)
Definition sdir.h:64
ParamExecData * es_param_exec_vals
Definition execnodes.h:717
ScanDirection es_direction
Definition execnodes.h:671
bool isnull
Definition params.h:149
Datum value
Definition params.h:148
void * execPlan
Definition params.h:147
Plan * plan
Definition execnodes.h:1177
EState * state
Definition execnodes.h:1179
TupleTableSlot * ps_ResultTupleSlot
Definition execnodes.h:1215
Tuplestorestate * working_table
Definition execnodes.h:1580
TupleTableSlot * ss_ScanTupleSlot
Definition execnodes.h:1636
PlanState ps
Definition execnodes.h:1633
RecursiveUnionState * rustate
Definition execnodes.h:2056
bool tuplestore_gettupleslot(Tuplestorestate *state, bool forward, bool copy, TupleTableSlot *slot)
void tuplestore_rescan(Tuplestorestate *state)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition tuptable.h:476