1 /*-------------------------------------------------------------------------
4 * Support routines for scanning Values lists
5 * ("VALUES (...), (...), ..." in rangetable).
7 * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
12 * src/backend/executor/nodeValuesscan.c
14 *-------------------------------------------------------------------------
18 * ExecValuesScan scans a values list.
19 * ExecValuesNext retrieve next tuple in sequential order.
20 * ExecInitValuesScan creates and initializes a valuesscan node.
21 * ExecEndValuesScan releases any storage allocated.
22 * ExecReScanValuesScan rescans the values list
26 #include "executor/executor.h"
27 #include "executor/nodeValuesscan.h"
30 static TupleTableSlot *ValuesNext(ValuesScanState *node);
33 /* ----------------------------------------------------------------
35 * ----------------------------------------------------------------
38 /* ----------------------------------------------------------------
41 * This is a workhorse for ExecValuesScan
42 * ----------------------------------------------------------------
44 static TupleTableSlot *
45 ValuesNext(ValuesScanState *node)
49 ExprContext *econtext;
50 ScanDirection direction;
54 * get information from the estate and scan state
56 estate = node->ss.ps.state;
57 direction = estate->es_direction;
58 slot = node->ss.ss_ScanTupleSlot;
59 econtext = node->rowcontext;
62 * Get the next tuple. Return NULL if no more tuples.
64 if (ScanDirectionIsForward(direction))
66 if (node->curr_idx < node->array_len)
68 if (node->curr_idx < node->array_len)
69 exprlist = node->exprlists[node->curr_idx];
75 if (node->curr_idx >= 0)
77 if (node->curr_idx >= 0)
78 exprlist = node->exprlists[node->curr_idx];
84 * Always clear the result slot; this is appropriate if we are at the end
85 * of the data, and if we're not, we still need it as the first step of
86 * the store-virtual-tuple protocol. It seems wise to clear the slot
87 * before we reset the context it might have pointers into.
93 MemoryContext oldContext;
101 * Get rid of any prior cycle's leftovers. We use ReScanExprContext
102 * not just ResetExprContext because we want any registered shutdown
103 * callbacks to be called.
105 ReScanExprContext(econtext);
108 * Build the expression eval state in the econtext's per-tuple memory.
109 * This is a tad unusual, but we want to delete the eval state again
110 * when we move to the next row, to avoid growth of memory
111 * requirements over a long values list.
113 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
116 * Pass NULL, not my plan node, because we don't want anything in this
117 * transient state linking into permanent state. The only possibility
118 * is a SubPlan, and there shouldn't be any (any subselects in the
119 * VALUES list should be InitPlans).
121 exprstatelist = (List *) ExecInitExpr((Expr *) exprlist, NULL);
123 /* parser should have checked all sublists are the same length */
124 Assert(list_length(exprstatelist) == slot->tts_tupleDescriptor->natts);
127 * Compute the expressions and build a virtual result tuple. We
128 * already did ExecClearTuple(slot).
130 values = slot->tts_values;
131 isnull = slot->tts_isnull;
134 foreach(lc, exprstatelist)
136 ExprState *estate = (ExprState *) lfirst(lc);
138 values[resind] = ExecEvalExpr(estate,
145 MemoryContextSwitchTo(oldContext);
148 * And return the virtual tuple.
150 ExecStoreVirtualTuple(slot);
157 * ValuesRecheck -- access method routine to recheck a tuple in EvalPlanQual
160 ValuesRecheck(ValuesScanState *node, TupleTableSlot *slot)
162 /* nothing to check */
166 /* ----------------------------------------------------------------
167 * ExecValuesScan(node)
169 * Scans the values lists sequentially and returns the next qualifying
171 * We call the ExecScan() routine and pass it the appropriate
172 * access method functions.
173 * ----------------------------------------------------------------
176 ExecValuesScan(ValuesScanState *node)
178 return ExecScan(&node->ss,
179 (ExecScanAccessMtd) ValuesNext,
180 (ExecScanRecheckMtd) ValuesRecheck);
183 /* ----------------------------------------------------------------
185 * ----------------------------------------------------------------
188 ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags)
190 ValuesScanState *scanstate;
194 PlanState *planstate;
197 * ValuesScan should not have any children.
199 Assert(outerPlan(node) == NULL);
200 Assert(innerPlan(node) == NULL);
203 * create new ScanState for node
205 scanstate = makeNode(ValuesScanState);
206 scanstate->ss.ps.plan = (Plan *) node;
207 scanstate->ss.ps.state = estate;
210 * Miscellaneous initialization
212 planstate = &scanstate->ss.ps;
215 * Create expression contexts. We need two, one for per-sublist
216 * processing and one for execScan.c to use for quals and projections. We
217 * cheat a little by using ExecAssignExprContext() to build both.
219 ExecAssignExprContext(estate, planstate);
220 scanstate->rowcontext = planstate->ps_ExprContext;
221 ExecAssignExprContext(estate, planstate);
224 * tuple table initialization
226 ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
227 ExecInitScanTupleSlot(estate, &scanstate->ss);
230 * initialize child expressions
232 scanstate->ss.ps.targetlist = (List *)
233 ExecInitExpr((Expr *) node->scan.plan.targetlist,
234 (PlanState *) scanstate);
235 scanstate->ss.ps.qual = (List *)
236 ExecInitExpr((Expr *) node->scan.plan.qual,
237 (PlanState *) scanstate);
240 * get info about values list
242 tupdesc = ExecTypeFromExprList((List *) linitial(node->values_lists));
244 ExecAssignScanType(&scanstate->ss, tupdesc);
247 * Other node-specific setup
249 scanstate->curr_idx = -1;
250 scanstate->array_len = list_length(node->values_lists);
252 /* convert list of sublists into array of sublists for easy addressing */
253 scanstate->exprlists = (List **)
254 palloc(scanstate->array_len * sizeof(List *));
256 foreach(vtl, node->values_lists)
258 scanstate->exprlists[i++] = (List *) lfirst(vtl);
261 scanstate->ss.ps.ps_TupFromTlist = false;
264 * Initialize result tuple type and projection info.
266 ExecAssignResultTypeFromTL(&scanstate->ss.ps);
267 ExecAssignScanProjectionInfo(&scanstate->ss);
272 /* ----------------------------------------------------------------
275 * frees any storage allocated through C routines.
276 * ----------------------------------------------------------------
279 ExecEndValuesScan(ValuesScanState *node)
282 * Free both exprcontexts
284 ExecFreeExprContext(&node->ss.ps);
285 node->ss.ps.ps_ExprContext = node->rowcontext;
286 ExecFreeExprContext(&node->ss.ps);
289 * clean out the tuple table
291 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
292 ExecClearTuple(node->ss.ss_ScanTupleSlot);
295 /* ----------------------------------------------------------------
296 * ExecReScanValuesScan
298 * Rescans the relation.
299 * ----------------------------------------------------------------
302 ExecReScanValuesScan(ValuesScanState *node)
304 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
306 ExecScanReScan(&node->ss);