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