PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
nodeCtescan.h File Reference
#include "nodes/execnodes.h"
Include dependency graph for nodeCtescan.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

CteScanStateExecInitCteScan (CteScan *node, EState *estate, int eflags)
 
void ExecEndCteScan (CteScanState *node)
 
void ExecReScanCteScan (CteScanState *node)
 

Function Documentation

◆ ExecEndCteScan()

void ExecEndCteScan ( CteScanState node)

Definition at line 288 of file nodeCtescan.c.

289{
290 /*
291 * If I am the leader, free the tuplestore.
292 */
293 if (node->leader == node)
294 {
296 node->cte_table = NULL;
297 }
298}
Tuplestorestate * cte_table
Definition: execnodes.h:2028
struct CteScanState * leader
Definition: execnodes.h:2026
void tuplestore_end(Tuplestorestate *state)
Definition: tuplestore.c:492

References CteScanState::cte_table, CteScanState::leader, and tuplestore_end().

Referenced by ExecEndNode().

◆ ExecInitCteScan()

CteScanState * ExecInitCteScan ( CteScan node,
EState estate,
int  eflags 
)

Definition at line 175 of file nodeCtescan.c.

176{
177 CteScanState *scanstate;
178 ParamExecData *prmdata;
179
180 /* check for unsupported flags */
181 Assert(!(eflags & EXEC_FLAG_MARK));
182
183 /*
184 * For the moment we have to force the tuplestore to allow REWIND, because
185 * we might be asked to rescan the CTE even though upper levels didn't
186 * tell us to be prepared to do it efficiently. Annoying, since this
187 * prevents truncation of the tuplestore. XXX FIXME
188 *
189 * Note: if we are in an EPQ recheck plan tree, it's likely that no access
190 * to the tuplestore is needed at all, making this even more annoying.
191 * It's not worth improving that as long as all the read pointers would
192 * have REWIND anyway, but if we ever improve this logic then that aspect
193 * should be considered too.
194 */
195 eflags |= EXEC_FLAG_REWIND;
196
197 /*
198 * CteScan should not have any children.
199 */
200 Assert(outerPlan(node) == NULL);
201 Assert(innerPlan(node) == NULL);
202
203 /*
204 * create new CteScanState for node
205 */
206 scanstate = makeNode(CteScanState);
207 scanstate->ss.ps.plan = (Plan *) node;
208 scanstate->ss.ps.state = estate;
209 scanstate->ss.ps.ExecProcNode = ExecCteScan;
210 scanstate->eflags = eflags;
211 scanstate->cte_table = NULL;
212 scanstate->eof_cte = false;
213
214 /*
215 * Find the already-initialized plan for the CTE query.
216 */
217 scanstate->cteplanstate = (PlanState *) list_nth(estate->es_subplanstates,
218 node->ctePlanId - 1);
219
220 /*
221 * The Param slot associated with the CTE query is used to hold a pointer
222 * to the CteState of the first CteScan node that initializes for this
223 * CTE. This node will be the one that holds the shared state for all the
224 * CTEs, particularly the shared tuplestore.
225 */
226 prmdata = &(estate->es_param_exec_vals[node->cteParam]);
227 Assert(prmdata->execPlan == NULL);
228 Assert(!prmdata->isnull);
229 scanstate->leader = castNode(CteScanState, DatumGetPointer(prmdata->value));
230 if (scanstate->leader == NULL)
231 {
232 /* I am the leader */
233 prmdata->value = PointerGetDatum(scanstate);
234 scanstate->leader = scanstate;
235 scanstate->cte_table = tuplestore_begin_heap(true, false, work_mem);
236 tuplestore_set_eflags(scanstate->cte_table, scanstate->eflags);
237 scanstate->readptr = 0;
238 }
239 else
240 {
241 /* Not the leader */
242 /* Create my own read pointer, and ensure it is at start */
243 scanstate->readptr =
245 scanstate->eflags);
247 scanstate->readptr);
249 }
250
251 /*
252 * Miscellaneous initialization
253 *
254 * create expression context for node
255 */
256 ExecAssignExprContext(estate, &scanstate->ss.ps);
257
258 /*
259 * The scan tuple type (ie, the rowtype we expect to find in the work
260 * table) is the same as the result rowtype of the CTE query.
261 */
262 ExecInitScanTupleSlot(estate, &scanstate->ss,
265
266 /*
267 * Initialize result type and projection.
268 */
269 ExecInitResultTypeTL(&scanstate->ss.ps);
270 ExecAssignScanProjectionInfo(&scanstate->ss);
271
272 /*
273 * initialize child expressions
274 */
275 scanstate->ss.ps.qual =
276 ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
277
278 return scanstate;
279}
#define Assert(condition)
Definition: c.h:812
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:224
void ExecAssignScanProjectionInfo(ScanState *node)
Definition: execScan.c:270
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1998
void ExecInitResultTypeTL(PlanState *planstate)
Definition: execTuples.c:1942
const TupleTableSlotOps TTSOpsMinimalTuple
Definition: execTuples.c:86
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:495
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:485
#define EXEC_FLAG_REWIND
Definition: executor.h:67
#define EXEC_FLAG_MARK
Definition: executor.h:69
int work_mem
Definition: globals.c:130
static TupleTableSlot * ExecCteScan(PlanState *pstate)
Definition: nodeCtescan.c:160
#define makeNode(_type_)
Definition: nodes.h:155
#define castNode(_type_, nodeptr)
Definition: nodes.h:176
static void * list_nth(const List *list, int n)
Definition: pg_list.h:299
#define innerPlan(node)
Definition: plannodes.h:182
#define outerPlan(node)
Definition: plannodes.h:183
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
ScanState ss
Definition: execnodes.h:2021
PlanState * cteplanstate
Definition: execnodes.h:2024
int ctePlanId
Definition: plannodes.h:644
int cteParam
Definition: plannodes.h:645
Scan scan
Definition: plannodes.h:643
ParamExecData * es_param_exec_vals
Definition: execnodes.h:670
List * es_subplanstates
Definition: execnodes.h:690
bool isnull
Definition: params.h:150
Datum value
Definition: params.h:149
void * execPlan
Definition: params.h:148
ExprState * qual
Definition: execnodes.h:1147
Plan * plan
Definition: execnodes.h:1126
EState * state
Definition: execnodes.h:1128
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:1132
PlanState ps
Definition: execnodes.h:1573
void tuplestore_select_read_pointer(Tuplestorestate *state, int ptr)
Definition: tuplestore.c:507
void tuplestore_rescan(Tuplestorestate *state)
Definition: tuplestore.c:1285
int tuplestore_alloc_read_pointer(Tuplestorestate *state, int eflags)
Definition: tuplestore.c:395
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
Definition: tuplestore.c:330
void tuplestore_set_eflags(Tuplestorestate *state, int eflags)
Definition: tuplestore.c:371

References Assert, castNode, CteScanState::cte_table, CteScan::cteParam, CteScan::ctePlanId, CteScanState::cteplanstate, DatumGetPointer(), CteScanState::eflags, CteScanState::eof_cte, EState::es_param_exec_vals, EState::es_subplanstates, EXEC_FLAG_MARK, EXEC_FLAG_REWIND, ExecAssignExprContext(), ExecAssignScanProjectionInfo(), ExecCteScan(), ExecGetResultType(), ExecInitQual(), ExecInitResultTypeTL(), ExecInitScanTupleSlot(), ParamExecData::execPlan, PlanState::ExecProcNode, innerPlan, ParamExecData::isnull, CteScanState::leader, list_nth(), makeNode, outerPlan, PlanState::plan, PointerGetDatum(), ScanState::ps, PlanState::qual, CteScanState::readptr, CteScan::scan, CteScanState::ss, PlanState::state, TTSOpsMinimalTuple, tuplestore_alloc_read_pointer(), tuplestore_begin_heap(), tuplestore_rescan(), tuplestore_select_read_pointer(), tuplestore_set_eflags(), ParamExecData::value, and work_mem.

Referenced by ExecInitNode().

◆ ExecReScanCteScan()

void ExecReScanCteScan ( CteScanState node)

Definition at line 307 of file nodeCtescan.c.

308{
309 Tuplestorestate *tuplestorestate = node->leader->cte_table;
310
311 if (node->ss.ps.ps_ResultTupleSlot)
313
314 ExecScanReScan(&node->ss);
315
316 /*
317 * Clear the tuplestore if a new scan of the underlying CTE is required.
318 * This implicitly resets all the tuplestore's read pointers. Note that
319 * multiple CTE nodes might redundantly clear the tuplestore; that's OK,
320 * and not unduly expensive. We'll stop taking this path as soon as
321 * somebody has attempted to read something from the underlying CTE
322 * (thereby causing its chgParam to be cleared).
323 */
324 if (node->leader->cteplanstate->chgParam != NULL)
325 {
326 tuplestore_clear(tuplestorestate);
327 node->leader->eof_cte = false;
328 }
329 else
330 {
331 /*
332 * Else, just rewind my own pointer. Either the underlying CTE
333 * doesn't need a rescan (and we can re-read what's in the tuplestore
334 * now), or somebody else already took care of it.
335 */
336 tuplestore_select_read_pointer(tuplestorestate, node->readptr);
337 tuplestore_rescan(tuplestorestate);
338 }
339}
void ExecScanReScan(ScanState *node)
Definition: execScan.c:297
Bitmapset * chgParam
Definition: execnodes.h:1158
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1164
void tuplestore_clear(Tuplestorestate *state)
Definition: tuplestore.c:430
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:454

References PlanState::chgParam, CteScanState::cte_table, CteScanState::cteplanstate, CteScanState::eof_cte, ExecClearTuple(), ExecScanReScan(), CteScanState::leader, ScanState::ps, PlanState::ps_ResultTupleSlot, CteScanState::readptr, CteScanState::ss, tuplestore_clear(), tuplestore_rescan(), and tuplestore_select_read_pointer().

Referenced by ExecReScan().