#include "nodes/execnodes.h"
Go to the source code of this file.
Functions | |
CteScanState * | ExecInitCteScan (CteScan *node, EState *estate, int eflags) |
TupleTableSlot * | ExecCteScan (CteScanState *node) |
void | ExecEndCteScan (CteScanState *node) |
void | ExecReScanCteScan (CteScanState *node) |
TupleTableSlot* ExecCteScan | ( | CteScanState * | node | ) |
Definition at line 153 of file nodeCtescan.c.
References CteScanNext(), CteScanRecheck(), ExecScan(), and CteScanState::ss.
Referenced by ExecProcNode().
{ return ExecScan(&node->ss, (ExecScanAccessMtd) CteScanNext, (ExecScanRecheckMtd) CteScanRecheck); }
void ExecEndCteScan | ( | CteScanState * | node | ) |
Definition at line 280 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().
{ /* * Free exprcontext */ ExecFreeExprContext(&node->ss.ps); /* * clean out the tuple table */ ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); /* * If I am the leader, free the tuplestore. */ if (node->leader == node) { tuplestore_end(node->cte_table); node->cte_table = NULL; } }
CteScanState* ExecInitCteScan | ( | CteScan * | node, | |
EState * | estate, | |||
int | eflags | |||
) |
Definition at line 166 of file nodeCtescan.c.
References Assert, 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, ExecAssignExprContext(), ExecAssignResultTypeFromTL(), ExecAssignScanProjectionInfo(), ExecAssignScanType(), ExecGetResultType(), ExecInitExpr(), ExecInitResultTupleSlot(), ExecInitScanTupleSlot(), ParamExecData::execPlan, innerPlan, IsA, ParamExecData::isnull, CteScanState::leader, list_nth(), makeNode, NULL, outerPlan, Scan::plan, PlanState::plan, PointerGetDatum, ScanState::ps, PlanState::ps_TupFromTlist, Plan::qual, PlanState::qual, CteScanState::readptr, CteScan::scan, CteScanState::ss, PlanState::state, Plan::targetlist, PlanState::targetlist, tuplestore_alloc_read_pointer(), tuplestore_begin_heap(), tuplestore_set_eflags(), ParamExecData::value, and work_mem.
Referenced by ExecInitNode().
{ CteScanState *scanstate; ParamExecData *prmdata; /* check for unsupported flags */ Assert(!(eflags & EXEC_FLAG_MARK)); /* * For the moment we have to force the tuplestore to allow REWIND, because * we might be asked to rescan the CTE even though upper levels didn't * tell us to be prepared to do it efficiently. Annoying, since this * prevents truncation of the tuplestore. XXX FIXME */ eflags |= EXEC_FLAG_REWIND; /* * CteScan should not have any children. */ Assert(outerPlan(node) == NULL); Assert(innerPlan(node) == NULL); /* * create new CteScanState for node */ scanstate = makeNode(CteScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; scanstate->eflags = eflags; scanstate->cte_table = NULL; scanstate->eof_cte = false; /* * Find the already-initialized plan for the CTE query. */ scanstate->cteplanstate = (PlanState *) list_nth(estate->es_subplanstates, node->ctePlanId - 1); /* * The Param slot associated with the CTE query is used to hold a pointer * to the CteState of the first CteScan node that initializes for this * CTE. This node will be the one that holds the shared state for all the * CTEs, particularly the shared tuplestore. */ prmdata = &(estate->es_param_exec_vals[node->cteParam]); Assert(prmdata->execPlan == NULL); Assert(!prmdata->isnull); scanstate->leader = (CteScanState *) DatumGetPointer(prmdata->value); if (scanstate->leader == NULL) { /* I am the leader */ prmdata->value = PointerGetDatum(scanstate); scanstate->leader = scanstate; scanstate->cte_table = tuplestore_begin_heap(true, false, work_mem); tuplestore_set_eflags(scanstate->cte_table, scanstate->eflags); scanstate->readptr = 0; } else { /* Not the leader */ Assert(IsA(scanstate->leader, CteScanState)); scanstate->readptr = tuplestore_alloc_read_pointer(scanstate->leader->cte_table, scanstate->eflags); } /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &scanstate->ss.ps); /* * initialize child expressions */ scanstate->ss.ps.targetlist = (List *) ExecInitExpr((Expr *) node->scan.plan.targetlist, (PlanState *) scanstate); scanstate->ss.ps.qual = (List *) ExecInitExpr((Expr *) node->scan.plan.qual, (PlanState *) scanstate); /* * tuple table initialization */ ExecInitResultTupleSlot(estate, &scanstate->ss.ps); ExecInitScanTupleSlot(estate, &scanstate->ss); /* * The scan tuple type (ie, the rowtype we expect to find in the work * table) is the same as the result rowtype of the CTE query. */ ExecAssignScanType(&scanstate->ss, ExecGetResultType(scanstate->cteplanstate)); /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&scanstate->ss.ps); ExecAssignScanProjectionInfo(&scanstate->ss); scanstate->ss.ps.ps_TupFromTlist = false; return scanstate; }
void ExecReScanCteScan | ( | CteScanState * | node | ) |
Definition at line 310 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().
{ Tuplestorestate *tuplestorestate = node->leader->cte_table; ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecScanReScan(&node->ss); /* * Clear the tuplestore if a new scan of the underlying CTE is required. * This implicitly resets all the tuplestore's read pointers. Note that * multiple CTE nodes might redundantly clear the tuplestore; that's OK, * and not unduly expensive. We'll stop taking this path as soon as * somebody has attempted to read something from the underlying CTE * (thereby causing its chgParam to be cleared). */ if (node->leader->cteplanstate->chgParam != NULL) { tuplestore_clear(tuplestorestate); node->leader->eof_cte = false; } else { /* * Else, just rewind my own pointer. Either the underlying CTE * doesn't need a rescan (and we can re-read what's in the tuplestore * now), or somebody else already took care of it. */ tuplestore_select_read_pointer(tuplestorestate, node->readptr); tuplestore_rescan(tuplestorestate); } }