Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions

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  ) 
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);
    }
}