Header And Logo

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

Functions

nodeValuesscan.c File Reference

#include "postgres.h"
#include "executor/executor.h"
#include "executor/nodeValuesscan.h"
#include "parser/parsetree.h"
Include dependency graph for nodeValuesscan.c:

Go to the source code of this file.

Functions

static TupleTableSlotValuesNext (ValuesScanState *node)
static bool ValuesRecheck (ValuesScanState *node, TupleTableSlot *slot)
TupleTableSlotExecValuesScan (ValuesScanState *node)
ValuesScanStateExecInitValuesScan (ValuesScan *node, EState *estate, int eflags)
void ExecEndValuesScan (ValuesScanState *node)
void ExecValuesMarkPos (ValuesScanState *node)
void ExecValuesRestrPos (ValuesScanState *node)
void ExecReScanValuesScan (ValuesScanState *node)

Function Documentation

void ExecEndValuesScan ( ValuesScanState node  ) 
ValuesScanState* ExecInitValuesScan ( ValuesScan node,
EState estate,
int  eflags 
)

Definition at line 189 of file nodeValuesscan.c.

References ValuesScanState::array_len, Assert, Alias::colnames, ValuesScanState::curr_idx, RangeTblEntry::eref, EState::es_range_table, ExecAssignExprContext(), ExecAssignResultTypeFromTL(), ExecAssignScanProjectionInfo(), ExecAssignScanType(), ExecInitExpr(), ExecInitResultTupleSlot(), ExecInitScanTupleSlot(), ExecTypeFromExprList(), ValuesScanState::exprlists, i, innerPlan, lfirst, linitial, list_length(), makeNode, ValuesScanState::marked_idx, NULL, outerPlan, palloc(), Scan::plan, PlanState::plan, ScanState::ps, PlanState::ps_ExprContext, PlanState::ps_TupFromTlist, Plan::qual, PlanState::qual, ValuesScanState::rowcontext, rt_fetch, ValuesScan::scan, Scan::scanrelid, ValuesScanState::ss, PlanState::state, Plan::targetlist, PlanState::targetlist, and ValuesScan::values_lists.

Referenced by ExecInitNode().

{
    ValuesScanState *scanstate;
    RangeTblEntry *rte = rt_fetch(node->scan.scanrelid,
                                  estate->es_range_table);
    TupleDesc   tupdesc;
    ListCell   *vtl;
    int         i;
    PlanState  *planstate;

    /*
     * ValuesScan should not have any children.
     */
    Assert(outerPlan(node) == NULL);
    Assert(innerPlan(node) == NULL);

    /*
     * create new ScanState for node
     */
    scanstate = makeNode(ValuesScanState);
    scanstate->ss.ps.plan = (Plan *) node;
    scanstate->ss.ps.state = estate;

    /*
     * Miscellaneous initialization
     */
    planstate = &scanstate->ss.ps;

    /*
     * Create expression contexts.  We need two, one for per-sublist
     * processing and one for execScan.c to use for quals and projections. We
     * cheat a little by using ExecAssignExprContext() to build both.
     */
    ExecAssignExprContext(estate, planstate);
    scanstate->rowcontext = planstate->ps_ExprContext;
    ExecAssignExprContext(estate, planstate);

    /*
     * tuple table initialization
     */
    ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
    ExecInitScanTupleSlot(estate, &scanstate->ss);

    /*
     * 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);

    /*
     * get info about values list
     */
    tupdesc = ExecTypeFromExprList((List *) linitial(node->values_lists),
                                   rte->eref->colnames);

    ExecAssignScanType(&scanstate->ss, tupdesc);

    /*
     * Other node-specific setup
     */
    scanstate->marked_idx = -1;
    scanstate->curr_idx = -1;
    scanstate->array_len = list_length(node->values_lists);

    /* convert list of sublists into array of sublists for easy addressing */
    scanstate->exprlists = (List **)
        palloc(scanstate->array_len * sizeof(List *));
    i = 0;
    foreach(vtl, node->values_lists)
    {
        scanstate->exprlists[i++] = (List *) lfirst(vtl);
    }

    scanstate->ss.ps.ps_TupFromTlist = false;

    /*
     * Initialize result tuple type and projection info.
     */
    ExecAssignResultTypeFromTL(&scanstate->ss.ps);
    ExecAssignScanProjectionInfo(&scanstate->ss);

    return scanstate;
}

void ExecReScanValuesScan ( ValuesScanState node  ) 
void ExecValuesMarkPos ( ValuesScanState node  ) 

Definition at line 307 of file nodeValuesscan.c.

References ValuesScanState::curr_idx, and ValuesScanState::marked_idx.

Referenced by ExecMarkPos().

{
    node->marked_idx = node->curr_idx;
}

void ExecValuesRestrPos ( ValuesScanState node  ) 

Definition at line 319 of file nodeValuesscan.c.

References ValuesScanState::curr_idx, and ValuesScanState::marked_idx.

Referenced by ExecRestrPos().

{
    node->curr_idx = node->marked_idx;
}

TupleTableSlot* ExecValuesScan ( ValuesScanState node  ) 
static TupleTableSlot * ValuesNext ( ValuesScanState node  )  [static]

Definition at line 46 of file nodeValuesscan.c.

References ValuesScanState::array_len, Assert, ValuesScanState::curr_idx, ExprContext::ecxt_per_tuple_memory, EState::es_direction, ExecClearTuple(), ExecEvalExpr, ExecInitExpr(), ExecStoreVirtualTuple(), ValuesScanState::exprlists, lfirst, list_length(), MemoryContextSwitchTo(), tupleDesc::natts, NULL, ScanState::ps, ReScanExprContext(), ValuesScanState::rowcontext, ScanDirectionIsForward, ValuesScanState::ss, ScanState::ss_ScanTupleSlot, PlanState::state, TupleTableSlot::tts_isnull, TupleTableSlot::tts_tupleDescriptor, TupleTableSlot::tts_values, and values.

Referenced by ExecValuesScan().

{
    TupleTableSlot *slot;
    EState     *estate;
    ExprContext *econtext;
    ScanDirection direction;
    List       *exprlist;

    /*
     * get information from the estate and scan state
     */
    estate = node->ss.ps.state;
    direction = estate->es_direction;
    slot = node->ss.ss_ScanTupleSlot;
    econtext = node->rowcontext;

    /*
     * Get the next tuple. Return NULL if no more tuples.
     */
    if (ScanDirectionIsForward(direction))
    {
        if (node->curr_idx < node->array_len)
            node->curr_idx++;
        if (node->curr_idx < node->array_len)
            exprlist = node->exprlists[node->curr_idx];
        else
            exprlist = NIL;
    }
    else
    {
        if (node->curr_idx >= 0)
            node->curr_idx--;
        if (node->curr_idx >= 0)
            exprlist = node->exprlists[node->curr_idx];
        else
            exprlist = NIL;
    }

    /*
     * Always clear the result slot; this is appropriate if we are at the end
     * of the data, and if we're not, we still need it as the first step of
     * the store-virtual-tuple protocol.  It seems wise to clear the slot
     * before we reset the context it might have pointers into.
     */
    ExecClearTuple(slot);

    if (exprlist)
    {
        MemoryContext oldContext;
        List       *exprstatelist;
        Datum      *values;
        bool       *isnull;
        ListCell   *lc;
        int         resind;

        /*
         * Get rid of any prior cycle's leftovers.  We use ReScanExprContext
         * not just ResetExprContext because we want any registered shutdown
         * callbacks to be called.
         */
        ReScanExprContext(econtext);

        /*
         * Build the expression eval state in the econtext's per-tuple memory.
         * This is a tad unusual, but we want to delete the eval state again
         * when we move to the next row, to avoid growth of memory
         * requirements over a long values list.
         */
        oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);

        /*
         * Pass NULL, not my plan node, because we don't want anything in this
         * transient state linking into permanent state.  The only possibility
         * is a SubPlan, and there shouldn't be any (any subselects in the
         * VALUES list should be InitPlans).
         */
        exprstatelist = (List *) ExecInitExpr((Expr *) exprlist, NULL);

        /* parser should have checked all sublists are the same length */
        Assert(list_length(exprstatelist) == slot->tts_tupleDescriptor->natts);

        /*
         * Compute the expressions and build a virtual result tuple. We
         * already did ExecClearTuple(slot).
         */
        values = slot->tts_values;
        isnull = slot->tts_isnull;

        resind = 0;
        foreach(lc, exprstatelist)
        {
            ExprState  *estate = (ExprState *) lfirst(lc);

            values[resind] = ExecEvalExpr(estate,
                                          econtext,
                                          &isnull[resind],
                                          NULL);
            resind++;
        }

        MemoryContextSwitchTo(oldContext);

        /*
         * And return the virtual tuple.
         */
        ExecStoreVirtualTuple(slot);
    }

    return slot;
}

static bool ValuesRecheck ( ValuesScanState node,
TupleTableSlot slot 
) [static]

Definition at line 161 of file nodeValuesscan.c.

Referenced by ExecValuesScan().

{
    /* nothing to check */
    return true;
}