#include "postgres.h"#include "executor/executor.h"#include "executor/nodeValuesscan.h"#include "parser/parsetree.h"
Go to the source code of this file.
Functions | |
| static TupleTableSlot * | ValuesNext (ValuesScanState *node) |
| static bool | ValuesRecheck (ValuesScanState *node, TupleTableSlot *slot) |
| TupleTableSlot * | ExecValuesScan (ValuesScanState *node) |
| ValuesScanState * | ExecInitValuesScan (ValuesScan *node, EState *estate, int eflags) |
| void | ExecEndValuesScan (ValuesScanState *node) |
| void | ExecValuesMarkPos (ValuesScanState *node) |
| void | ExecValuesRestrPos (ValuesScanState *node) |
| void | ExecReScanValuesScan (ValuesScanState *node) |
| void ExecEndValuesScan | ( | ValuesScanState * | node | ) |
Definition at line 284 of file nodeValuesscan.c.
References ExecClearTuple(), ExecFreeExprContext(), ScanState::ps, PlanState::ps_ExprContext, PlanState::ps_ResultTupleSlot, ValuesScanState::rowcontext, ValuesScanState::ss, and ScanState::ss_ScanTupleSlot.
Referenced by ExecEndNode().
{
/*
* Free both exprcontexts
*/
ExecFreeExprContext(&node->ss.ps);
node->ss.ps.ps_ExprContext = node->rowcontext;
ExecFreeExprContext(&node->ss.ps);
/*
* clean out the tuple table
*/
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
ExecClearTuple(node->ss.ss_ScanTupleSlot);
}
| 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 | ) |
Definition at line 331 of file nodeValuesscan.c.
References ValuesScanState::curr_idx, ExecClearTuple(), ExecScanReScan(), ScanState::ps, PlanState::ps_ResultTupleSlot, and ValuesScanState::ss.
Referenced by ExecReScan().
{
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
ExecScanReScan(&node->ss);
node->curr_idx = -1;
}
| 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 | ) |
Definition at line 177 of file nodeValuesscan.c.
References ExecScan(), ValuesScanState::ss, ValuesNext(), and ValuesRecheck().
Referenced by ExecProcNode().
{
return ExecScan(&node->ss,
(ExecScanAccessMtd) ValuesNext,
(ExecScanRecheckMtd) ValuesRecheck);
}
| 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;
}
1.7.1