1 /*-------------------------------------------------------------------------
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
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"
29 #include "optimizer/clauses.h"
30 #include "utils/expandeddatum.h"
33 static TupleTableSlot
*ValuesNext(ValuesScanState
*node
);
36 /* ----------------------------------------------------------------
38 * ----------------------------------------------------------------
41 /* ----------------------------------------------------------------
44 * This is a workhorse for ExecValuesScan
45 * ----------------------------------------------------------------
47 static TupleTableSlot
*
48 ValuesNext(ValuesScanState
*node
)
52 ExprContext
*econtext
;
53 ScanDirection direction
;
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
)
74 if (node
->curr_idx
>= 0)
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.
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
;
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
;
143 foreach(lc
, exprstatelist
)
145 ExprState
*estate
= (ExprState
*) lfirst(lc
);
146 Form_pg_attribute attr
= TupleDescAttr(slot
->tts_tupleDescriptor
,
149 values
[resind
] = ExecEvalExpr(estate
,
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
],
166 MemoryContextSwitchTo(oldContext
);
169 * And return the virtual tuple.
171 ExecStoreVirtualTuple(slot
);
178 * ValuesRecheck -- access method routine to recheck a tuple in EvalPlanQual
181 ValuesRecheck(ValuesScanState
*node
, TupleTableSlot
*slot
)
183 /* nothing to check */
187 /* ----------------------------------------------------------------
188 * ExecValuesScan(node)
190 * Scans the values lists sequentially and returns the next qualifying
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 /* ----------------------------------------------------------------
208 * ----------------------------------------------------------------
211 ExecInitValuesScan(ValuesScan
*node
, EState
*estate
, int eflags
)
213 ValuesScanState
*scanstate
;
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
*));
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
))
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
,
314 estate
->es_jit_flags
= saved_jit_flags
;
322 /* ----------------------------------------------------------------
325 * frees any storage allocated through C routines.
326 * ----------------------------------------------------------------
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 * ----------------------------------------------------------------
353 ExecReScanValuesScan(ValuesScanState
*node
)
355 if (node
->ss
.ps
.ps_ResultTupleSlot
)
356 ExecClearTuple(node
->ss
.ps
.ps_ResultTupleSlot
);
358 ExecScanReScan(&node
->ss
);