PostgreSQL Source Code  git master
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 287 of file nodeCtescan.c.

References CteScanState::cte_table, ExecClearTuple(), ExecFreeExprContext(), CteScanState::leader, ScanState::ps, PlanState::ps_ResultTupleSlot, CteScanState::ss, ScanState::ss_ScanTupleSlot, and tuplestore_end().

Referenced by ExecEndNode().

288 {
289  /*
290  * Free exprcontext
291  */
292  ExecFreeExprContext(&node->ss.ps);
293 
294  /*
295  * clean out the tuple table
296  */
299 
300  /*
301  * If I am the leader, free the tuplestore.
302  */
303  if (node->leader == node)
304  {
305  tuplestore_end(node->cte_table);
306  node->cte_table = NULL;
307  }
308 }
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:475
struct CteScanState * leader
Definition: execnodes.h:1529
ScanState ss
Definition: execnodes.h:1524
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1127
void ExecFreeExprContext(PlanState *planstate)
Definition: execUtils.c:561
PlanState ps
Definition: execnodes.h:1124
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:901
void tuplestore_end(Tuplestorestate *state)
Definition: tuplestore.c:453
Tuplestorestate * cte_table
Definition: execnodes.h:1531

◆ ExecInitCteScan()

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

Definition at line 175 of file nodeCtescan.c.

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(), ExecInitResultTupleSlotTL(), ExecInitScanTupleSlot(), ParamExecData::execPlan, PlanState::ExecProcNode, innerPlan, ParamExecData::isnull, CteScanState::leader, list_nth(), makeNode, outerPlan, Scan::plan, PlanState::plan, PointerGetDatum, ScanState::ps, Plan::qual, PlanState::qual, CteScanState::readptr, CteScan::scan, CteScanState::ss, PlanState::state, tuplestore_alloc_read_pointer(), tuplestore_begin_heap(), tuplestore_rescan(), tuplestore_select_read_pointer(), tuplestore_set_eflags(), ParamExecData::value, and work_mem.

Referenced by ExecInitNode().

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);
248  tuplestore_rescan(scanstate->leader->cte_table);
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,
263  ExecGetResultType(scanstate->cteplanstate));
264 
265  /*
266  * Initialize result slot, type and projection.
267  */
268  ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
269  ExecAssignScanProjectionInfo(&scanstate->ss);
270 
271  /*
272  * initialize child expressions
273  */
274  scanstate->ss.ps.qual =
275  ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
276 
277  return scanstate;
278 }
void tuplestore_rescan(Tuplestorestate *state)
Definition: tuplestore.c:1233
static TupleTableSlot * ExecCteScan(PlanState *pstate)
Definition: nodeCtescan.c:160
List * qual
Definition: plannodes.h:145
void * execPlan
Definition: params.h:147
Plan plan
Definition: plannodes.h:330
#define castNode(_type_, nodeptr)
Definition: nodes.h:582
void tuplestore_set_eflags(Tuplestorestate *state, int eflags)
Definition: tuplestore.c:359
#define PointerGetDatum(X)
Definition: postgres.h:539
struct CteScanState * leader
Definition: execnodes.h:1529
ScanState ss
Definition: execnodes.h:1524
EState * state
Definition: execnodes.h:870
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:204
PlanState ps
Definition: execnodes.h:1124
ParamExecData * es_param_exec_vals
Definition: execnodes.h:483
int cteParam
Definition: plannodes.h:542
void ExecAssignScanProjectionInfo(ScanState *node)
Definition: execScan.c:235
bool isnull
Definition: params.h:149
Scan scan
Definition: plannodes.h:540
#define innerPlan(node)
Definition: plannodes.h:173
void * list_nth(const List *list, int n)
Definition: list.c:410
int ctePlanId
Definition: plannodes.h:541
#define EXEC_FLAG_REWIND
Definition: executor.h:60
#define outerPlan(node)
Definition: plannodes.h:174
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
Definition: tuplestore.c:318
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:874
int work_mem
Definition: globals.c:113
void ExecInitResultTupleSlotTL(EState *estate, PlanState *planstate)
Definition: execTuples.c:870
Plan * plan
Definition: execnodes.h:868
#define makeNode(_type_)
Definition: nodes.h:561
#define Assert(condition)
Definition: c.h:688
#define EXEC_FLAG_MARK
Definition: executor.h:62
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:425
List * es_subplanstates
Definition: execnodes.h:503
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:435
ExprState * qual
Definition: execnodes.h:886
#define DatumGetPointer(X)
Definition: postgres.h:532
int tuplestore_alloc_read_pointer(Tuplestorestate *state, int eflags)
Definition: tuplestore.c:383
PlanState * cteplanstate
Definition: execnodes.h:1527
void tuplestore_select_read_pointer(Tuplestorestate *state, int ptr)
Definition: tuplestore.c:473
Datum value
Definition: params.h:148
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc)
Definition: execTuples.c:895
Tuplestorestate * cte_table
Definition: execnodes.h:1531

◆ ExecReScanCteScan()

void ExecReScanCteScan ( CteScanState node)

Definition at line 317 of file nodeCtescan.c.

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().

318 {
319  Tuplestorestate *tuplestorestate = node->leader->cte_table;
320 
322 
323  ExecScanReScan(&node->ss);
324 
325  /*
326  * Clear the tuplestore if a new scan of the underlying CTE is required.
327  * This implicitly resets all the tuplestore's read pointers. Note that
328  * multiple CTE nodes might redundantly clear the tuplestore; that's OK,
329  * and not unduly expensive. We'll stop taking this path as soon as
330  * somebody has attempted to read something from the underlying CTE
331  * (thereby causing its chgParam to be cleared).
332  */
333  if (node->leader->cteplanstate->chgParam != NULL)
334  {
335  tuplestore_clear(tuplestorestate);
336  node->leader->eof_cte = false;
337  }
338  else
339  {
340  /*
341  * Else, just rewind my own pointer. Either the underlying CTE
342  * doesn't need a rescan (and we can re-read what's in the tuplestore
343  * now), or somebody else already took care of it.
344  */
345  tuplestore_select_read_pointer(tuplestorestate, node->readptr);
346  tuplestore_rescan(tuplestorestate);
347  }
348 }
void tuplestore_rescan(Tuplestorestate *state)
Definition: tuplestore.c:1233
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:475
struct CteScanState * leader
Definition: execnodes.h:1529
ScanState ss
Definition: execnodes.h:1524
PlanState ps
Definition: execnodes.h:1124
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:901
void tuplestore_clear(Tuplestorestate *state)
Definition: tuplestore.c:418
Bitmapset * chgParam
Definition: execnodes.h:896
PlanState * cteplanstate
Definition: execnodes.h:1527
void ExecScanReScan(ScanState *node)
Definition: execScan.c:262
void tuplestore_select_read_pointer(Tuplestorestate *state, int ptr)
Definition: tuplestore.c:473
Tuplestorestate * cte_table
Definition: execnodes.h:1531