PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
nodeValuesscan.c File Reference
#include "postgres.h"
#include "executor/executor.h"
#include "executor/nodeValuesscan.h"
#include "jit/jit.h"
#include "optimizer/clauses.h"
#include "utils/expandeddatum.h"
Include dependency graph for nodeValuesscan.c:

Go to the source code of this file.

Functions

static TupleTableSlotValuesNext (ValuesScanState *node)
 
static bool ValuesRecheck (ValuesScanState *node, TupleTableSlot *slot)
 
static TupleTableSlotExecValuesScan (PlanState *pstate)
 
ValuesScanStateExecInitValuesScan (ValuesScan *node, EState *estate, int eflags)
 
void ExecReScanValuesScan (ValuesScanState *node)
 

Function Documentation

◆ ExecInitValuesScan()

ValuesScanState * ExecInitValuesScan ( ValuesScan node,
EState estate,
int  eflags 
)

Definition at line 210 of file nodeValuesscan.c.

211{
212 ValuesScanState *scanstate;
213 TupleDesc tupdesc;
214 ListCell *vtl;
215 int i;
216 PlanState *planstate;
217
218 /*
219 * ValuesScan should not have any children.
220 */
221 Assert(outerPlan(node) == NULL);
222 Assert(innerPlan(node) == NULL);
223
224 /*
225 * create new ScanState for node
226 */
227 scanstate = makeNode(ValuesScanState);
228 scanstate->ss.ps.plan = (Plan *) node;
229 scanstate->ss.ps.state = estate;
230 scanstate->ss.ps.ExecProcNode = ExecValuesScan;
231
232 /*
233 * Miscellaneous initialization
234 */
235 planstate = &scanstate->ss.ps;
236
237 /*
238 * Create expression contexts. We need two, one for per-sublist
239 * processing and one for execScan.c to use for quals and projections. We
240 * cheat a little by using ExecAssignExprContext() to build both.
241 */
242 ExecAssignExprContext(estate, planstate);
243 scanstate->rowcontext = planstate->ps_ExprContext;
244 ExecAssignExprContext(estate, planstate);
245
246 /*
247 * Get info about values list, initialize scan slot with it.
248 */
249 tupdesc = ExecTypeFromExprList((List *) linitial(node->values_lists));
250 ExecInitScanTupleSlot(estate, &scanstate->ss, tupdesc, &TTSOpsVirtual);
251
252 /*
253 * Initialize result type and projection.
254 */
255 ExecInitResultTypeTL(&scanstate->ss.ps);
256 ExecAssignScanProjectionInfo(&scanstate->ss);
257
258 /*
259 * initialize child expressions
260 */
261 scanstate->ss.ps.qual =
262 ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
263
264 /*
265 * Other node-specific setup
266 */
267 scanstate->curr_idx = -1;
268 scanstate->array_len = list_length(node->values_lists);
269
270 /*
271 * Convert the list of expression sublists into an array for easier
272 * addressing at runtime. Also, detect whether any sublists contain
273 * SubPlans; for just those sublists, go ahead and do expression
274 * initialization. (This avoids problems with SubPlans wanting to connect
275 * themselves up to the outer plan tree. Notably, EXPLAIN won't see the
276 * subplans otherwise; also we will have troubles with dangling pointers
277 * and/or leaked resources if we try to handle SubPlans the same as
278 * simpler expressions.)
279 */
280 scanstate->exprlists = (List **)
281 palloc(scanstate->array_len * sizeof(List *));
282 scanstate->exprstatelists = (List **)
283 palloc0(scanstate->array_len * sizeof(List *));
284 i = 0;
285 foreach(vtl, node->values_lists)
286 {
287 List *exprs = lfirst_node(List, vtl);
288
289 scanstate->exprlists[i] = exprs;
290
291 /*
292 * We can avoid the cost of a contain_subplans() scan in the simple
293 * case where there are no SubPlans anywhere.
294 */
295 if (estate->es_subplanstates &&
296 contain_subplans((Node *) exprs))
297 {
298 int saved_jit_flags;
299
300 /*
301 * As these expressions are only used once, disable JIT for them.
302 * This is worthwhile because it's common to insert significant
303 * amounts of data via VALUES(). Note that this doesn't prevent
304 * use of JIT *within* a subplan, since that's initialized
305 * separately; this just affects the upper-level subexpressions.
306 */
307 saved_jit_flags = estate->es_jit_flags;
308 estate->es_jit_flags = PGJIT_NONE;
309
310 scanstate->exprstatelists[i] = ExecInitExprList(exprs,
311 &scanstate->ss.ps);
312
313 estate->es_jit_flags = saved_jit_flags;
314 }
315 i++;
316 }
317
318 return scanstate;
319}
#define Assert(condition)
Definition: c.h:812
bool contain_subplans(Node *clause)
Definition: clauses.c:329
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:224
List * ExecInitExprList(List *nodes, PlanState *parent)
Definition: execExpr.c:330
void ExecAssignScanProjectionInfo(ScanState *node)
Definition: execScan.c:270
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:84
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1998
void ExecInitResultTypeTL(PlanState *planstate)
Definition: execTuples.c:1942
TupleDesc ExecTypeFromExprList(List *exprList)
Definition: execTuples.c:2184
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:485
int i
Definition: isn.c:72
#define PGJIT_NONE
Definition: jit.h:19
void * palloc0(Size size)
Definition: mcxt.c:1347
void * palloc(Size size)
Definition: mcxt.c:1317
static TupleTableSlot * ExecValuesScan(PlanState *pstate)
#define makeNode(_type_)
Definition: nodes.h:155
#define lfirst_node(type, lc)
Definition: pg_list.h:176
static int list_length(const List *l)
Definition: pg_list.h:152
#define linitial(l)
Definition: pg_list.h:178
#define innerPlan(node)
Definition: plannodes.h:182
#define outerPlan(node)
Definition: plannodes.h:183
int es_jit_flags
Definition: execnodes.h:728
List * es_subplanstates
Definition: execnodes.h:690
Definition: pg_list.h:54
Definition: nodes.h:129
ExprState * qual
Definition: execnodes.h:1147
Plan * plan
Definition: execnodes.h:1126
EState * state
Definition: execnodes.h:1128
ExprContext * ps_ExprContext
Definition: execnodes.h:1165
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:1132
PlanState ps
Definition: execnodes.h:1573
ScanState ss
Definition: execnodes.h:1974
List ** exprlists
Definition: execnodes.h:1976
List ** exprstatelists
Definition: execnodes.h:1977
ExprContext * rowcontext
Definition: execnodes.h:1975
Scan scan
Definition: plannodes.h:623
List * values_lists
Definition: plannodes.h:624

References ValuesScanState::array_len, Assert, contain_subplans(), ValuesScanState::curr_idx, EState::es_jit_flags, EState::es_subplanstates, ExecAssignExprContext(), ExecAssignScanProjectionInfo(), ExecInitExprList(), ExecInitQual(), ExecInitResultTypeTL(), ExecInitScanTupleSlot(), PlanState::ExecProcNode, ExecTypeFromExprList(), ExecValuesScan(), ValuesScanState::exprlists, ValuesScanState::exprstatelists, i, innerPlan, lfirst_node, linitial, list_length(), makeNode, outerPlan, palloc(), palloc0(), PGJIT_NONE, PlanState::plan, ScanState::ps, PlanState::ps_ExprContext, PlanState::qual, ValuesScanState::rowcontext, ValuesScan::scan, ValuesScanState::ss, PlanState::state, TTSOpsVirtual, and ValuesScan::values_lists.

Referenced by ExecInitNode().

◆ ExecReScanValuesScan()

void ExecReScanValuesScan ( ValuesScanState node)

Definition at line 328 of file nodeValuesscan.c.

329{
330 if (node->ss.ps.ps_ResultTupleSlot)
332
333 ExecScanReScan(&node->ss);
334
335 node->curr_idx = -1;
336}
void ExecScanReScan(ScanState *node)
Definition: execScan.c:297
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1164
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:454

References ValuesScanState::curr_idx, ExecClearTuple(), ExecScanReScan(), ScanState::ps, PlanState::ps_ResultTupleSlot, and ValuesScanState::ss.

Referenced by ExecReScan().

◆ ExecValuesScan()

static TupleTableSlot * ExecValuesScan ( PlanState pstate)
static

Definition at line 196 of file nodeValuesscan.c.

197{
199
200 return ExecScan(&node->ss,
203}
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
Definition: execScan.c:156
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition: executor.h:487
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition: executor.h:486
static TupleTableSlot * ValuesNext(ValuesScanState *node)
static bool ValuesRecheck(ValuesScanState *node, TupleTableSlot *slot)
#define castNode(_type_, nodeptr)
Definition: nodes.h:176

References castNode, ExecScan(), ValuesScanState::ss, ValuesNext(), and ValuesRecheck().

Referenced by ExecInitValuesScan().

◆ ValuesNext()

static TupleTableSlot * ValuesNext ( ValuesScanState node)
static

Definition at line 47 of file nodeValuesscan.c.

48{
49 TupleTableSlot *slot;
50 EState *estate;
51 ExprContext *econtext;
52 ScanDirection direction;
53 int curr_idx;
54
55 /*
56 * get information from the estate and scan state
57 */
58 estate = node->ss.ps.state;
59 direction = estate->es_direction;
60 slot = node->ss.ss_ScanTupleSlot;
61 econtext = node->rowcontext;
62
63 /*
64 * Get the next tuple. Return NULL if no more tuples.
65 */
66 if (ScanDirectionIsForward(direction))
67 {
68 if (node->curr_idx < node->array_len)
69 node->curr_idx++;
70 }
71 else
72 {
73 if (node->curr_idx >= 0)
74 node->curr_idx--;
75 }
76
77 /*
78 * Always clear the result slot; this is appropriate if we are at the end
79 * of the data, and if we're not, we still need it as the first step of
80 * the store-virtual-tuple protocol. It seems wise to clear the slot
81 * before we reset the context it might have pointers into.
82 */
83 ExecClearTuple(slot);
84
85 curr_idx = node->curr_idx;
86 if (curr_idx >= 0 && curr_idx < node->array_len)
87 {
88 List *exprlist = node->exprlists[curr_idx];
89 List *exprstatelist = node->exprstatelists[curr_idx];
90 MemoryContext oldContext;
92 bool *isnull;
93 ListCell *lc;
94 int resind;
95
96 /*
97 * Get rid of any prior cycle's leftovers. We use ReScanExprContext
98 * not just ResetExprContext because we want any registered shutdown
99 * callbacks to be called.
100 */
101 ReScanExprContext(econtext);
102
103 /*
104 * Do per-VALUES-row work in the per-tuple context.
105 */
106 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
107
108 /*
109 * Unless we already made the expression eval state for this row,
110 * build it in the econtext's per-tuple memory. This is a tad
111 * unusual, but we want to delete the eval state again when we move to
112 * the next row, to avoid growth of memory requirements over a long
113 * values list. For rows in which that won't work, we already built
114 * the eval state at plan startup.
115 */
116 if (exprstatelist == NIL)
117 {
118 /*
119 * Pass parent as NULL, not my plan node, because we don't want
120 * anything in this transient state linking into permanent state.
121 * The only expression type that might wish to do so is a SubPlan,
122 * and we already checked that there aren't any.
123 *
124 * Note that passing parent = NULL also disables JIT compilation
125 * of the expressions, which is a win, because they're only going
126 * to be used once under normal circumstances.
127 */
128 exprstatelist = ExecInitExprList(exprlist, NULL);
129 }
130
131 /* parser should have checked all sublists are the same length */
132 Assert(list_length(exprstatelist) == slot->tts_tupleDescriptor->natts);
133
134 /*
135 * Compute the expressions and build a virtual result tuple. We
136 * already did ExecClearTuple(slot).
137 */
138 values = slot->tts_values;
139 isnull = slot->tts_isnull;
140
141 resind = 0;
142 foreach(lc, exprstatelist)
143 {
144 ExprState *estate = (ExprState *) lfirst(lc);
146 resind);
147
148 values[resind] = ExecEvalExpr(estate,
149 econtext,
150 &isnull[resind]);
151
152 /*
153 * We must force any R/W expanded datums to read-only state, in
154 * case they are multiply referenced in the plan node's output
155 * expressions, or in case we skip the output projection and the
156 * output column is multiply referenced in higher plan nodes.
157 */
158 values[resind] = MakeExpandedObjectReadOnly(values[resind],
159 isnull[resind],
160 attr->attlen);
161
162 resind++;
163 }
164
165 MemoryContextSwitchTo(oldContext);
166
167 /*
168 * And return the virtual tuple.
169 */
171 }
172
173 return slot;
174}
static Datum values[MAXATTR]
Definition: bootstrap.c:151
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:1739
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:443
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:346
#define MakeExpandedObjectReadOnly(d, isnull, typlen)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
#define lfirst(lc)
Definition: pg_list.h:172
#define NIL
Definition: pg_list.h:68
uintptr_t Datum
Definition: postgres.h:64
#define ScanDirectionIsForward(direction)
Definition: sdir.h:64
ScanDirection
Definition: sdir.h:25
int16 attlen
Definition: tupdesc.h:69
ScanDirection es_direction
Definition: execnodes.h:631
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:266
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1576
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:123
bool * tts_isnull
Definition: tuptable.h:127
Datum * tts_values
Definition: tuptable.h:125
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:169

References ValuesScanState::array_len, Assert, CompactAttribute::attlen, ValuesScanState::curr_idx, ExprContext::ecxt_per_tuple_memory, EState::es_direction, ExecClearTuple(), ExecEvalExpr(), ExecInitExprList(), ExecStoreVirtualTuple(), ValuesScanState::exprlists, ValuesScanState::exprstatelists, lfirst, list_length(), MakeExpandedObjectReadOnly, MemoryContextSwitchTo(), TupleDescData::natts, NIL, ScanState::ps, ReScanExprContext(), ValuesScanState::rowcontext, ScanDirectionIsForward, ValuesScanState::ss, ScanState::ss_ScanTupleSlot, PlanState::state, TupleTableSlot::tts_isnull, TupleTableSlot::tts_tupleDescriptor, TupleTableSlot::tts_values, TupleDescCompactAttr(), and values.

Referenced by ExecValuesScan().

◆ ValuesRecheck()

static bool ValuesRecheck ( ValuesScanState node,
TupleTableSlot slot 
)
static

Definition at line 180 of file nodeValuesscan.c.

181{
182 /* nothing to check */
183 return true;
184}

Referenced by ExecValuesScan().