PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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)
 
TupleTableSlotExecCteScan (CteScanState *node)
 
void ExecEndCteScan (CteScanState *node)
 
void ExecReScanCteScan (CteScanState *node)
 

Function Documentation

TupleTableSlot* ExecCteScan ( CteScanState node)

Definition at line 153 of file nodeCtescan.c.

References CteScanNext(), CteScanRecheck(), ExecScan(), and CteScanState::ss.

Referenced by ExecProcNode().

154 {
155  return ExecScan(&node->ss,
158 }
static bool CteScanRecheck(CteScanState *node, TupleTableSlot *slot)
Definition: nodeCtescan.c:138
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
Definition: execScan.c:121
ScanState ss
Definition: execnodes.h:1598
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition: executor.h:271
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition: executor.h:272
static TupleTableSlot * CteScanNext(CteScanState *node)
Definition: nodeCtescan.c:31
void ExecEndCteScan ( CteScanState node)

Definition at line 281 of file nodeCtescan.c.

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

Referenced by ExecEndNode().

282 {
283  /*
284  * Free exprcontext
285  */
286  ExecFreeExprContext(&node->ss.ps);
287 
288  /*
289  * clean out the tuple table
290  */
293 
294  /*
295  * If I am the leader, free the tuplestore.
296  */
297  if (node->leader == node)
298  {
299  tuplestore_end(node->cte_table);
300  node->cte_table = NULL;
301  }
302 }
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
struct CteScanState * leader
Definition: execnodes.h:1603
ScanState ss
Definition: execnodes.h:1598
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1290
void ExecFreeExprContext(PlanState *planstate)
Definition: execUtils.c:684
PlanState ps
Definition: execnodes.h:1287
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1076
#define NULL
Definition: c.h:226
void tuplestore_end(Tuplestorestate *state)
Definition: tuplestore.c:450
Tuplestorestate * cte_table
Definition: execnodes.h:1605
CteScanState* ExecInitCteScan ( CteScan node,
EState estate,
int  eflags 
)

Definition at line 166 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(), ExecAssignResultTypeFromTL(), ExecAssignScanProjectionInfo(), ExecAssignScanType(), ExecGetResultType(), ExecInitExpr(), ExecInitResultTupleSlot(), ExecInitScanTupleSlot(), ParamExecData::execPlan, innerPlan, ParamExecData::isnull, CteScanState::leader, list_nth(), makeNode, NULL, outerPlan, Scan::plan, PlanState::plan, PointerGetDatum, ScanState::ps, Plan::qual, PlanState::qual, CteScanState::readptr, CteScan::scan, CteScanState::ss, PlanState::state, Plan::targetlist, PlanState::targetlist, tuplestore_alloc_read_pointer(), tuplestore_begin_heap(), tuplestore_rescan(), tuplestore_select_read_pointer(), tuplestore_set_eflags(), ParamExecData::value, and work_mem.

Referenced by ExecInitNode().

167 {
168  CteScanState *scanstate;
169  ParamExecData *prmdata;
170 
171  /* check for unsupported flags */
172  Assert(!(eflags & EXEC_FLAG_MARK));
173 
174  /*
175  * For the moment we have to force the tuplestore to allow REWIND, because
176  * we might be asked to rescan the CTE even though upper levels didn't
177  * tell us to be prepared to do it efficiently. Annoying, since this
178  * prevents truncation of the tuplestore. XXX FIXME
179  */
180  eflags |= EXEC_FLAG_REWIND;
181 
182  /*
183  * CteScan should not have any children.
184  */
185  Assert(outerPlan(node) == NULL);
186  Assert(innerPlan(node) == NULL);
187 
188  /*
189  * create new CteScanState for node
190  */
191  scanstate = makeNode(CteScanState);
192  scanstate->ss.ps.plan = (Plan *) node;
193  scanstate->ss.ps.state = estate;
194  scanstate->eflags = eflags;
195  scanstate->cte_table = NULL;
196  scanstate->eof_cte = false;
197 
198  /*
199  * Find the already-initialized plan for the CTE query.
200  */
201  scanstate->cteplanstate = (PlanState *) list_nth(estate->es_subplanstates,
202  node->ctePlanId - 1);
203 
204  /*
205  * The Param slot associated with the CTE query is used to hold a pointer
206  * to the CteState of the first CteScan node that initializes for this
207  * CTE. This node will be the one that holds the shared state for all the
208  * CTEs, particularly the shared tuplestore.
209  */
210  prmdata = &(estate->es_param_exec_vals[node->cteParam]);
211  Assert(prmdata->execPlan == NULL);
212  Assert(!prmdata->isnull);
213  scanstate->leader = castNode(CteScanState, DatumGetPointer(prmdata->value));
214  if (scanstate->leader == NULL)
215  {
216  /* I am the leader */
217  prmdata->value = PointerGetDatum(scanstate);
218  scanstate->leader = scanstate;
219  scanstate->cte_table = tuplestore_begin_heap(true, false, work_mem);
220  tuplestore_set_eflags(scanstate->cte_table, scanstate->eflags);
221  scanstate->readptr = 0;
222  }
223  else
224  {
225  /* Not the leader */
226  /* Create my own read pointer, and ensure it is at start */
227  scanstate->readptr =
229  scanstate->eflags);
231  scanstate->readptr);
232  tuplestore_rescan(scanstate->leader->cte_table);
233  }
234 
235  /*
236  * Miscellaneous initialization
237  *
238  * create expression context for node
239  */
240  ExecAssignExprContext(estate, &scanstate->ss.ps);
241 
242  /*
243  * initialize child expressions
244  */
245  scanstate->ss.ps.targetlist = (List *)
247  (PlanState *) scanstate);
248  scanstate->ss.ps.qual = (List *)
249  ExecInitExpr((Expr *) node->scan.plan.qual,
250  (PlanState *) scanstate);
251 
252  /*
253  * tuple table initialization
254  */
255  ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
256  ExecInitScanTupleSlot(estate, &scanstate->ss);
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  ExecAssignScanType(&scanstate->ss,
263  ExecGetResultType(scanstate->cteplanstate));
264 
265  /*
266  * Initialize result tuple type and projection info.
267  */
268  ExecAssignResultTypeFromTL(&scanstate->ss.ps);
269  ExecAssignScanProjectionInfo(&scanstate->ss);
270 
271  return scanstate;
272 }
void tuplestore_rescan(Tuplestorestate *state)
Definition: tuplestore.c:1216
List * qual
Definition: plannodes.h:130
void * execPlan
Definition: params.h:99
Plan plan
Definition: plannodes.h:305
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate)
Definition: execTuples.c:842
#define castNode(_type_, nodeptr)
Definition: nodes.h:577
void tuplestore_set_eflags(Tuplestorestate *state, int eflags)
Definition: tuplestore.c:357
#define PointerGetDatum(X)
Definition: postgres.h:564
List * qual
Definition: execnodes.h:1061
struct CteScanState * leader
Definition: execnodes.h:1603
ScanState ss
Definition: execnodes.h:1598
List * targetlist
Definition: execnodes.h:1060
EState * state
Definition: execnodes.h:1048
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:429
PlanState ps
Definition: execnodes.h:1287
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition: execQual.c:4266
ParamExecData * es_param_exec_vals
Definition: execnodes.h:393
int cteParam
Definition: plannodes.h:506
void ExecAssignScanProjectionInfo(ScanState *node)
Definition: execScan.c:235
bool isnull
Definition: params.h:101
void ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
Definition: execTuples.c:832
Scan scan
Definition: plannodes.h:504
#define innerPlan(node)
Definition: plannodes.h:158
void * list_nth(const List *list, int n)
Definition: list.c:410
int ctePlanId
Definition: plannodes.h:505
#define EXEC_FLAG_REWIND
Definition: executor.h:59
#define outerPlan(node)
Definition: plannodes.h:159
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
Definition: tuplestore.c:316
int work_mem
Definition: globals.c:112
Plan * plan
Definition: execnodes.h:1046
#define makeNode(_type_)
Definition: nodes.h:556
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
#define EXEC_FLAG_MARK
Definition: executor.h:61
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:407
List * es_subplanstates
Definition: execnodes.h:411
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:458
List * targetlist
Definition: plannodes.h:129
#define DatumGetPointer(X)
Definition: postgres.h:557
int tuplestore_alloc_read_pointer(Tuplestorestate *state, int eflags)
Definition: tuplestore.c:381
PlanState * cteplanstate
Definition: execnodes.h:1601
void tuplestore_select_read_pointer(Tuplestorestate *state, int ptr)
Definition: tuplestore.c:470
Datum value
Definition: params.h:100
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
Definition: execUtils.c:708
Tuplestorestate * cte_table
Definition: execnodes.h:1605
Definition: pg_list.h:45
void ExecReScanCteScan ( CteScanState node)

Definition at line 311 of file nodeCtescan.c.

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

Referenced by ExecReScan().

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