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