Harmonize parameter names in ecpg code.
[pgsql.git] / src / backend / executor / nodeValuesscan.c
blobdda1c59b23532227ac283e30340881946ce471ce
1 /*-------------------------------------------------------------------------
3 * nodeValuesscan.c
4 * Support routines for scanning Values lists
5 * ("VALUES (...), (...), ..." in rangetable).
7 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
11 * IDENTIFICATION
12 * src/backend/executor/nodeValuesscan.c
14 *-------------------------------------------------------------------------
17 * INTERFACE ROUTINES
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
24 #include "postgres.h"
26 #include "executor/executor.h"
27 #include "executor/nodeValuesscan.h"
28 #include "jit/jit.h"
29 #include "optimizer/clauses.h"
30 #include "utils/expandeddatum.h"
33 static TupleTableSlot *ValuesNext(ValuesScanState *node);
36 /* ----------------------------------------------------------------
37 * Scan Support
38 * ----------------------------------------------------------------
41 /* ----------------------------------------------------------------
42 * ValuesNext
44 * This is a workhorse for ExecValuesScan
45 * ----------------------------------------------------------------
47 static TupleTableSlot *
48 ValuesNext(ValuesScanState *node)
50 TupleTableSlot *slot;
51 EState *estate;
52 ExprContext *econtext;
53 ScanDirection direction;
54 int curr_idx;
57 * get information from the estate and scan state
59 estate = node->ss.ps.state;
60 direction = estate->es_direction;
61 slot = node->ss.ss_ScanTupleSlot;
62 econtext = node->rowcontext;
65 * Get the next tuple. Return NULL if no more tuples.
67 if (ScanDirectionIsForward(direction))
69 if (node->curr_idx < node->array_len)
70 node->curr_idx++;
72 else
74 if (node->curr_idx >= 0)
75 node->curr_idx--;
79 * Always clear the result slot; this is appropriate if we are at the end
80 * of the data, and if we're not, we still need it as the first step of
81 * the store-virtual-tuple protocol. It seems wise to clear the slot
82 * before we reset the context it might have pointers into.
84 ExecClearTuple(slot);
86 curr_idx = node->curr_idx;
87 if (curr_idx >= 0 && curr_idx < node->array_len)
89 List *exprlist = node->exprlists[curr_idx];
90 List *exprstatelist = node->exprstatelists[curr_idx];
91 MemoryContext oldContext;
92 Datum *values;
93 bool *isnull;
94 ListCell *lc;
95 int resind;
98 * Get rid of any prior cycle's leftovers. We use ReScanExprContext
99 * not just ResetExprContext because we want any registered shutdown
100 * callbacks to be called.
102 ReScanExprContext(econtext);
105 * Do per-VALUES-row work in the per-tuple context.
107 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
110 * Unless we already made the expression eval state for this row,
111 * build it in the econtext's per-tuple memory. This is a tad
112 * unusual, but we want to delete the eval state again when we move to
113 * the next row, to avoid growth of memory requirements over a long
114 * values list. For rows in which that won't work, we already built
115 * the eval state at plan startup.
117 if (exprstatelist == NIL)
120 * Pass parent as NULL, not my plan node, because we don't want
121 * anything in this transient state linking into permanent state.
122 * The only expression type that might wish to do so is a SubPlan,
123 * and we already checked that there aren't any.
125 * Note that passing parent = NULL also disables JIT compilation
126 * of the expressions, which is a win, because they're only going
127 * to be used once under normal circumstances.
129 exprstatelist = ExecInitExprList(exprlist, NULL);
132 /* parser should have checked all sublists are the same length */
133 Assert(list_length(exprstatelist) == slot->tts_tupleDescriptor->natts);
136 * Compute the expressions and build a virtual result tuple. We
137 * already did ExecClearTuple(slot).
139 values = slot->tts_values;
140 isnull = slot->tts_isnull;
142 resind = 0;
143 foreach(lc, exprstatelist)
145 ExprState *estate = (ExprState *) lfirst(lc);
146 Form_pg_attribute attr = TupleDescAttr(slot->tts_tupleDescriptor,
147 resind);
149 values[resind] = ExecEvalExpr(estate,
150 econtext,
151 &isnull[resind]);
154 * We must force any R/W expanded datums to read-only state, in
155 * case they are multiply referenced in the plan node's output
156 * expressions, or in case we skip the output projection and the
157 * output column is multiply referenced in higher plan nodes.
159 values[resind] = MakeExpandedObjectReadOnly(values[resind],
160 isnull[resind],
161 attr->attlen);
163 resind++;
166 MemoryContextSwitchTo(oldContext);
169 * And return the virtual tuple.
171 ExecStoreVirtualTuple(slot);
174 return slot;
178 * ValuesRecheck -- access method routine to recheck a tuple in EvalPlanQual
180 static bool
181 ValuesRecheck(ValuesScanState *node, TupleTableSlot *slot)
183 /* nothing to check */
184 return true;
187 /* ----------------------------------------------------------------
188 * ExecValuesScan(node)
190 * Scans the values lists sequentially and returns the next qualifying
191 * tuple.
192 * We call the ExecScan() routine and pass it the appropriate
193 * access method functions.
194 * ----------------------------------------------------------------
196 static TupleTableSlot *
197 ExecValuesScan(PlanState *pstate)
199 ValuesScanState *node = castNode(ValuesScanState, pstate);
201 return ExecScan(&node->ss,
202 (ExecScanAccessMtd) ValuesNext,
203 (ExecScanRecheckMtd) ValuesRecheck);
206 /* ----------------------------------------------------------------
207 * ExecInitValuesScan
208 * ----------------------------------------------------------------
210 ValuesScanState *
211 ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags)
213 ValuesScanState *scanstate;
214 TupleDesc tupdesc;
215 ListCell *vtl;
216 int i;
217 PlanState *planstate;
220 * ValuesScan should not have any children.
222 Assert(outerPlan(node) == NULL);
223 Assert(innerPlan(node) == NULL);
226 * create new ScanState for node
228 scanstate = makeNode(ValuesScanState);
229 scanstate->ss.ps.plan = (Plan *) node;
230 scanstate->ss.ps.state = estate;
231 scanstate->ss.ps.ExecProcNode = ExecValuesScan;
234 * Miscellaneous initialization
236 planstate = &scanstate->ss.ps;
239 * Create expression contexts. We need two, one for per-sublist
240 * processing and one for execScan.c to use for quals and projections. We
241 * cheat a little by using ExecAssignExprContext() to build both.
243 ExecAssignExprContext(estate, planstate);
244 scanstate->rowcontext = planstate->ps_ExprContext;
245 ExecAssignExprContext(estate, planstate);
248 * Get info about values list, initialize scan slot with it.
250 tupdesc = ExecTypeFromExprList((List *) linitial(node->values_lists));
251 ExecInitScanTupleSlot(estate, &scanstate->ss, tupdesc, &TTSOpsVirtual);
254 * Initialize result type and projection.
256 ExecInitResultTypeTL(&scanstate->ss.ps);
257 ExecAssignScanProjectionInfo(&scanstate->ss);
260 * initialize child expressions
262 scanstate->ss.ps.qual =
263 ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
266 * Other node-specific setup
268 scanstate->curr_idx = -1;
269 scanstate->array_len = list_length(node->values_lists);
272 * Convert the list of expression sublists into an array for easier
273 * addressing at runtime. Also, detect whether any sublists contain
274 * SubPlans; for just those sublists, go ahead and do expression
275 * initialization. (This avoids problems with SubPlans wanting to connect
276 * themselves up to the outer plan tree. Notably, EXPLAIN won't see the
277 * subplans otherwise; also we will have troubles with dangling pointers
278 * and/or leaked resources if we try to handle SubPlans the same as
279 * simpler expressions.)
281 scanstate->exprlists = (List **)
282 palloc(scanstate->array_len * sizeof(List *));
283 scanstate->exprstatelists = (List **)
284 palloc0(scanstate->array_len * sizeof(List *));
285 i = 0;
286 foreach(vtl, node->values_lists)
288 List *exprs = lfirst_node(List, vtl);
290 scanstate->exprlists[i] = exprs;
293 * We can avoid the cost of a contain_subplans() scan in the simple
294 * case where there are no SubPlans anywhere.
296 if (estate->es_subplanstates &&
297 contain_subplans((Node *) exprs))
299 int saved_jit_flags;
302 * As these expressions are only used once, disable JIT for them.
303 * This is worthwhile because it's common to insert significant
304 * amounts of data via VALUES(). Note that this doesn't prevent
305 * use of JIT *within* a subplan, since that's initialized
306 * separately; this just affects the upper-level subexpressions.
308 saved_jit_flags = estate->es_jit_flags;
309 estate->es_jit_flags = PGJIT_NONE;
311 scanstate->exprstatelists[i] = ExecInitExprList(exprs,
312 &scanstate->ss.ps);
314 estate->es_jit_flags = saved_jit_flags;
316 i++;
319 return scanstate;
322 /* ----------------------------------------------------------------
323 * ExecEndValuesScan
325 * frees any storage allocated through C routines.
326 * ----------------------------------------------------------------
328 void
329 ExecEndValuesScan(ValuesScanState *node)
332 * Free both exprcontexts
334 ExecFreeExprContext(&node->ss.ps);
335 node->ss.ps.ps_ExprContext = node->rowcontext;
336 ExecFreeExprContext(&node->ss.ps);
339 * clean out the tuple table
341 if (node->ss.ps.ps_ResultTupleSlot)
342 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
343 ExecClearTuple(node->ss.ss_ScanTupleSlot);
346 /* ----------------------------------------------------------------
347 * ExecReScanValuesScan
349 * Rescans the relation.
350 * ----------------------------------------------------------------
352 void
353 ExecReScanValuesScan(ValuesScanState *node)
355 if (node->ss.ps.ps_ResultTupleSlot)
356 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
358 ExecScanReScan(&node->ss);
360 node->curr_idx = -1;