1 /*-------------------------------------------------------------------------
2 *
3 * nodeValuesscan.c
4 * Support routines for scanning Values lists
5 * ("VALUES (...), (...), ..." in rangetable).
6 *
7 * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
9 *
10 *
11 * IDENTIFICATION
12 * src/backend/executor/nodeValuesscan.c
13 *
14 *-------------------------------------------------------------------------
15 */
16 /*
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
23 */
24 #include "postgres.h"
25
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"
31
32
33 static TupleTableSlot *ValuesNext(ValuesScanState *node);
34
35
36 /* ----------------------------------------------------------------
37 * Scan Support
38 * ----------------------------------------------------------------
39 */
40
41 /* ----------------------------------------------------------------
42 * ValuesNext
43 *
44 * This is a workhorse for ExecValuesScan
45 * ----------------------------------------------------------------
46 */
47 static TupleTableSlot *
ValuesNext(ValuesScanState * node)48 ValuesNext(ValuesScanState *node)
49 {
50 TupleTableSlot *slot;
51 EState *estate;
52 ExprContext *econtext;
53 ScanDirection direction;
54 int curr_idx;
55
56 /*
57 * get information from the estate and scan state
58 */
59 estate = node->ss.ps.state;
60 direction = estate->es_direction;
61 slot = node->ss.ss_ScanTupleSlot;
62 econtext = node->rowcontext;
63
64 /*
65 * Get the next tuple. Return NULL if no more tuples.
66 */
67 if (ScanDirectionIsForward(direction))
68 {
69 if (node->curr_idx < node->array_len)
70 node->curr_idx++;
71 }
72 else
73 {
74 if (node->curr_idx >= 0)
75 node->curr_idx--;
76 }
77
78 /*
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.
83 */
84 ExecClearTuple(slot);
85
86 curr_idx = node->curr_idx;
87 if (curr_idx >= 0 && curr_idx < node->array_len)
88 {
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;
96
97 /*
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.
101 */
102 ReScanExprContext(econtext);
103
104 /*
105 * Do per-VALUES-row work in the per-tuple context.
106 */
107 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
108
109 /*
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.
116 */
117 if (exprstatelist == NIL)
118 {
119 /*
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.
124 *
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.
128 */
129 exprstatelist = ExecInitExprList(exprlist, NULL);
130 }
131
132 /* parser should have checked all sublists are the same length */
133 Assert(list_length(exprstatelist) == slot->tts_tupleDescriptor->natts);
134
135 /*
136 * Compute the expressions and build a virtual result tuple. We
137 * already did ExecClearTuple(slot).
138 */
139 values = slot->tts_values;
140 isnull = slot->tts_isnull;
141
142 resind = 0;
143 foreach(lc, exprstatelist)
144 {
145 ExprState *estate = (ExprState *) lfirst(lc);
146 Form_pg_attribute attr = TupleDescAttr(slot->tts_tupleDescriptor,
147 resind);
148
149 values[resind] = ExecEvalExpr(estate,
150 econtext,
151 &isnull[resind]);
152
153 /*
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.
158 */
159 values[resind] = MakeExpandedObjectReadOnly(values[resind],
160 isnull[resind],
161 attr->attlen);
162
163 resind++;
164 }
165
166 MemoryContextSwitchTo(oldContext);
167
168 /*
169 * And return the virtual tuple.
170 */
171 ExecStoreVirtualTuple(slot);
172 }
173
174 return slot;
175 }
176
177 /*
178 * ValuesRecheck -- access method routine to recheck a tuple in EvalPlanQual
179 */
180 static bool
ValuesRecheck(ValuesScanState * node,TupleTableSlot * slot)181 ValuesRecheck(ValuesScanState *node, TupleTableSlot *slot)
182 {
183 /* nothing to check */
184 return true;
185 }
186
187 /* ----------------------------------------------------------------
188 * ExecValuesScan(node)
189 *
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 * ----------------------------------------------------------------
195 */
196 static TupleTableSlot *
ExecValuesScan(PlanState * pstate)197 ExecValuesScan(PlanState *pstate)
198 {
199 ValuesScanState *node = castNode(ValuesScanState, pstate);
200
201 return ExecScan(&node->ss,
202 (ExecScanAccessMtd) ValuesNext,
203 (ExecScanRecheckMtd) ValuesRecheck);
204 }
205
206 /* ----------------------------------------------------------------
207 * ExecInitValuesScan
208 * ----------------------------------------------------------------
209 */
210 ValuesScanState *
ExecInitValuesScan(ValuesScan * node,EState * estate,int eflags)211 ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags)
212 {
213 ValuesScanState *scanstate;
214 TupleDesc tupdesc;
215 ListCell *vtl;
216 int i;
217 PlanState *planstate;
218
219 /*
220 * ValuesScan should not have any children.
221 */
222 Assert(outerPlan(node) == NULL);
223 Assert(innerPlan(node) == NULL);
224
225 /*
226 * create new ScanState for node
227 */
228 scanstate = makeNode(ValuesScanState);
229 scanstate->ss.ps.plan = (Plan *) node;
230 scanstate->ss.ps.state = estate;
231 scanstate->ss.ps.ExecProcNode = ExecValuesScan;
232
233 /*
234 * Miscellaneous initialization
235 */
236 planstate = &scanstate->ss.ps;
237
238 /*
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.
242 */
243 ExecAssignExprContext(estate, planstate);
244 scanstate->rowcontext = planstate->ps_ExprContext;
245 ExecAssignExprContext(estate, planstate);
246
247 /*
248 * Get info about values list, initialize scan slot with it.
249 */
250 tupdesc = ExecTypeFromExprList((List *) linitial(node->values_lists));
251 ExecInitScanTupleSlot(estate, &scanstate->ss, tupdesc, &TTSOpsVirtual);
252
253 /*
254 * Initialize result type and projection.
255 */
256 ExecInitResultTypeTL(&scanstate->ss.ps);
257 ExecAssignScanProjectionInfo(&scanstate->ss);
258
259 /*
260 * initialize child expressions
261 */
262 scanstate->ss.ps.qual =
263 ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
264
265 /*
266 * Other node-specific setup
267 */
268 scanstate->curr_idx = -1;
269 scanstate->array_len = list_length(node->values_lists);
270
271 /*
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.)
280 */
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)
287 {
288 List *exprs = castNode(List, lfirst(vtl));
289
290 scanstate->exprlists[i] = exprs;
291
292 /*
293 * We can avoid the cost of a contain_subplans() scan in the simple
294 * case where there are no SubPlans anywhere.
295 */
296 if (estate->es_subplanstates &&
297 contain_subplans((Node *) exprs))
298 {
299 int saved_jit_flags;
300
301 /*
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.
307 */
308 saved_jit_flags = estate->es_jit_flags;
309 estate->es_jit_flags = PGJIT_NONE;
310
311 scanstate->exprstatelists[i] = ExecInitExprList(exprs,
312 &scanstate->ss.ps);
313
314 estate->es_jit_flags = saved_jit_flags;
315 }
316 i++;
317 }
318
319 return scanstate;
320 }
321
322 /* ----------------------------------------------------------------
323 * ExecEndValuesScan
324 *
325 * frees any storage allocated through C routines.
326 * ----------------------------------------------------------------
327 */
328 void
ExecEndValuesScan(ValuesScanState * node)329 ExecEndValuesScan(ValuesScanState *node)
330 {
331 /*
332 * Free both exprcontexts
333 */
334 ExecFreeExprContext(&node->ss.ps);
335 node->ss.ps.ps_ExprContext = node->rowcontext;
336 ExecFreeExprContext(&node->ss.ps);
337
338 /*
339 * clean out the tuple table
340 */
341 if (node->ss.ps.ps_ResultTupleSlot)
342 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
343 ExecClearTuple(node->ss.ss_ScanTupleSlot);
344 }
345
346 /* ----------------------------------------------------------------
347 * ExecReScanValuesScan
348 *
349 * Rescans the relation.
350 * ----------------------------------------------------------------
351 */
352 void
ExecReScanValuesScan(ValuesScanState * node)353 ExecReScanValuesScan(ValuesScanState *node)
354 {
355 if (node->ss.ps.ps_ResultTupleSlot)
356 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
357
358 ExecScanReScan(&node->ss);
359
360 node->curr_idx = -1;
361 }
362