PostgreSQL Source Code  git master
nodeValuesscan.c File Reference
#include "postgres.h"
#include "executor/executor.h"
#include "executor/nodeValuesscan.h"
#include "jit/jit.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 ExecEndValuesScan (ValuesScanState *node)
 
void ExecReScanValuesScan (ValuesScanState *node)
 

Function Documentation

◆ ExecEndValuesScan()

void ExecEndValuesScan ( ValuesScanState node)

Definition at line 303 of file nodeValuesscan.c.

References ExecClearTuple(), ExecFreeExprContext(), ScanState::ps, PlanState::ps_ExprContext, PlanState::ps_ResultTupleSlot, ValuesScanState::rowcontext, ValuesScanState::ss, and ScanState::ss_ScanTupleSlot.

Referenced by ExecEndNode().

304 {
305  /*
306  * Free both exprcontexts
307  */
308  ExecFreeExprContext(&node->ss.ps);
309  node->ss.ps.ps_ExprContext = node->rowcontext;
310  ExecFreeExprContext(&node->ss.ps);
311 
312  /*
313  * clean out the tuple table
314  */
317 }
ExprContext * ps_ExprContext
Definition: execnodes.h:946
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:475
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1194
void ExecFreeExprContext(PlanState *planstate)
Definition: execUtils.c:566
ScanState ss
Definition: execnodes.h:1545
PlanState ps
Definition: execnodes.h:1191
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:945
ExprContext * rowcontext
Definition: execnodes.h:1546

◆ ExecInitValuesScan()

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

Definition at line 224 of file nodeValuesscan.c.

References Assert, ExecAssignExprContext(), ExecAssignScanProjectionInfo(), ExecInitQual(), ExecInitResultTupleSlotTL(), ExecInitScanTupleSlot(), PlanState::ExecProcNode, ExecTypeFromExprList(), ExecValuesScan(), i, innerPlan, lfirst, linitial, list_length(), makeNode, outerPlan, palloc(), Scan::plan, PlanState::plan, ScanState::ps, PlanState::ps_ExprContext, Plan::qual, PlanState::qual, ValuesScanState::rowcontext, ValuesScan::scan, ValuesScanState::ss, PlanState::state, and ValuesScan::values_lists.

Referenced by ExecInitNode().

225 {
226  ValuesScanState *scanstate;
227  TupleDesc tupdesc;
228  ListCell *vtl;
229  int i;
230  PlanState *planstate;
231 
232  /*
233  * ValuesScan should not have any children.
234  */
235  Assert(outerPlan(node) == NULL);
236  Assert(innerPlan(node) == NULL);
237 
238  /*
239  * create new ScanState for node
240  */
241  scanstate = makeNode(ValuesScanState);
242  scanstate->ss.ps.plan = (Plan *) node;
243  scanstate->ss.ps.state = estate;
244  scanstate->ss.ps.ExecProcNode = ExecValuesScan;
245 
246  /*
247  * Miscellaneous initialization
248  */
249  planstate = &scanstate->ss.ps;
250 
251  /*
252  * Create expression contexts. We need two, one for per-sublist
253  * processing and one for execScan.c to use for quals and projections. We
254  * cheat a little by using ExecAssignExprContext() to build both.
255  */
256  ExecAssignExprContext(estate, planstate);
257  scanstate->rowcontext = planstate->ps_ExprContext;
258  ExecAssignExprContext(estate, planstate);
259 
260  /*
261  * Get info about values list, initialize scan slot with it.
262  */
263  tupdesc = ExecTypeFromExprList((List *) linitial(node->values_lists));
264  ExecInitScanTupleSlot(estate, &scanstate->ss, tupdesc);
265 
266  /*
267  * Initialize result slot, type and projection.
268  */
269  ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
270  ExecAssignScanProjectionInfo(&scanstate->ss);
271 
272  /*
273  * initialize child expressions
274  */
275  scanstate->ss.ps.qual =
276  ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
277 
278  /*
279  * Other node-specific setup
280  */
281  scanstate->curr_idx = -1;
282  scanstate->array_len = list_length(node->values_lists);
283 
284  /* convert list of sublists into array of sublists for easy addressing */
285  scanstate->exprlists = (List **)
286  palloc(scanstate->array_len * sizeof(List *));
287  i = 0;
288  foreach(vtl, node->values_lists)
289  {
290  scanstate->exprlists[i++] = (List *) lfirst(vtl);
291  }
292 
293  return scanstate;
294 }
List * qual
Definition: plannodes.h:147
Plan plan
Definition: plannodes.h:342
static TupleTableSlot * ExecValuesScan(PlanState *pstate)
ExprContext * ps_ExprContext
Definition: execnodes.h:946
List * values_lists
Definition: plannodes.h:533
EState * state
Definition: execnodes.h:913
Scan scan
Definition: plannodes.h:532
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:205
ScanState ss
Definition: execnodes.h:1545
PlanState ps
Definition: execnodes.h:1191
#define linitial(l)
Definition: pg_list.h:111
void ExecAssignScanProjectionInfo(ScanState *node)
Definition: execScan.c:235
#define innerPlan(node)
Definition: plannodes.h:175
#define outerPlan(node)
Definition: plannodes.h:176
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:917
ExprContext * rowcontext
Definition: execnodes.h:1546
void ExecInitResultTupleSlotTL(EState *estate, PlanState *planstate)
Definition: execTuples.c:890
Plan * plan
Definition: execnodes.h:911
#define makeNode(_type_)
Definition: nodes.h:565
#define Assert(condition)
Definition: c.h:699
#define lfirst(lc)
Definition: pg_list.h:106
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:428
static int list_length(const List *l)
Definition: pg_list.h:89
ExprState * qual
Definition: execnodes.h:929
TupleDesc ExecTypeFromExprList(List *exprList)
Definition: execTuples.c:1024
void * palloc(Size size)
Definition: mcxt.c:924
int i
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc)
Definition: execTuples.c:915
List ** exprlists
Definition: execnodes.h:1547
Definition: pg_list.h:45

◆ ExecReScanValuesScan()

void ExecReScanValuesScan ( ValuesScanState node)

Definition at line 326 of file nodeValuesscan.c.

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

Referenced by ExecReScan().

327 {
329 
330  ExecScanReScan(&node->ss);
331 
332  node->curr_idx = -1;
333 }
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:475
ScanState ss
Definition: execnodes.h:1545
PlanState ps
Definition: execnodes.h:1191
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:945
void ExecScanReScan(ScanState *node)
Definition: execScan.c:262

◆ ExecValuesScan()

static TupleTableSlot* ExecValuesScan ( PlanState pstate)
static

Definition at line 210 of file nodeValuesscan.c.

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

Referenced by ExecInitValuesScan().

211 {
212  ValuesScanState *node = castNode(ValuesScanState, pstate);
213 
214  return ExecScan(&node->ss,
217 }
#define castNode(_type_, nodeptr)
Definition: nodes.h:586
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
Definition: execScan.c:121
ScanState ss
Definition: execnodes.h:1545
static TupleTableSlot * ValuesNext(ValuesScanState *node)
static bool ValuesRecheck(ValuesScanState *node, TupleTableSlot *slot)
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition: executor.h:422
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition: executor.h:421

◆ ValuesNext()

static TupleTableSlot * ValuesNext ( ValuesScanState node)
static

Definition at line 47 of file nodeValuesscan.c.

References ValuesScanState::array_len, Assert, ValuesScanState::curr_idx, ExprContext::ecxt_estate, ExprContext::ecxt_per_tuple_memory, EState::es_direction, EState::es_jit_flags, ExecClearTuple(), ExecEvalExpr(), ExecInitExprList(), ExecStoreVirtualTuple(), ValuesScanState::exprlists, lfirst, list_length(), MakeExpandedObjectReadOnly, MemoryContextSwitchTo(), tupleDesc::natts, NIL, PGJIT_NONE, ScanState::ps, ReScanExprContext(), ValuesScanState::rowcontext, ScanDirectionIsForward, ValuesScanState::ss, ScanState::ss_ScanTupleSlot, PlanState::state, PlanState::subPlan, TupleTableSlot::tts_isnull, TupleTableSlot::tts_tupleDescriptor, TupleTableSlot::tts_values, TupleDescAttr, and values.

Referenced by ExecValuesScan().

48 {
49  TupleTableSlot *slot;
50  EState *estate;
51  ExprContext *econtext;
52  ScanDirection direction;
53  List *exprlist;
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  if (node->curr_idx < node->array_len)
71  exprlist = node->exprlists[node->curr_idx];
72  else
73  exprlist = NIL;
74  }
75  else
76  {
77  if (node->curr_idx >= 0)
78  node->curr_idx--;
79  if (node->curr_idx >= 0)
80  exprlist = node->exprlists[node->curr_idx];
81  else
82  exprlist = NIL;
83  }
84 
85  /*
86  * Always clear the result slot; this is appropriate if we are at the end
87  * of the data, and if we're not, we still need it as the first step of
88  * the store-virtual-tuple protocol. It seems wise to clear the slot
89  * before we reset the context it might have pointers into.
90  */
91  ExecClearTuple(slot);
92 
93  if (exprlist)
94  {
95  MemoryContext oldContext;
96  List *oldsubplans;
97  List *exprstatelist;
98  Datum *values;
99  bool *isnull;
100  ListCell *lc;
101  int resind;
102  int saved_jit_flags;
103 
104  /*
105  * Get rid of any prior cycle's leftovers. We use ReScanExprContext
106  * not just ResetExprContext because we want any registered shutdown
107  * callbacks to be called.
108  */
109  ReScanExprContext(econtext);
110 
111  /*
112  * Build the expression eval state in the econtext's per-tuple memory.
113  * This is a tad unusual, but we want to delete the eval state again
114  * when we move to the next row, to avoid growth of memory
115  * requirements over a long values list.
116  */
117  oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
118 
119  /*
120  * The expressions might contain SubPlans (this is currently only
121  * possible if there's a sub-select containing a LATERAL reference,
122  * otherwise sub-selects in a VALUES list should be InitPlans). Those
123  * subplans will want to hook themselves into our subPlan list, which
124  * would result in a corrupted list after we delete the eval state. We
125  * can work around this by saving and restoring the subPlan list.
126  * (There's no need for the functionality that would be enabled by
127  * having the list entries, since the SubPlans aren't going to be
128  * re-executed anyway.)
129  */
130  oldsubplans = node->ss.ps.subPlan;
131  node->ss.ps.subPlan = NIL;
132 
133  /*
134  * As the expressions are only ever used once, disable JIT for
135  * them. This is worthwhile because it's common to insert significant
136  * amounts of data via VALUES().
137  */
138  saved_jit_flags = econtext->ecxt_estate->es_jit_flags;
139  econtext->ecxt_estate->es_jit_flags = PGJIT_NONE;
140  exprstatelist = ExecInitExprList(exprlist, &node->ss.ps);
141  econtext->ecxt_estate->es_jit_flags = saved_jit_flags;
142 
143  node->ss.ps.subPlan = oldsubplans;
144 
145  /* parser should have checked all sublists are the same length */
146  Assert(list_length(exprstatelist) == slot->tts_tupleDescriptor->natts);
147 
148  /*
149  * Compute the expressions and build a virtual result tuple. We
150  * already did ExecClearTuple(slot).
151  */
152  values = slot->tts_values;
153  isnull = slot->tts_isnull;
154 
155  resind = 0;
156  foreach(lc, exprstatelist)
157  {
158  ExprState *estate = (ExprState *) lfirst(lc);
160  resind);
161 
162  values[resind] = ExecEvalExpr(estate,
163  econtext,
164  &isnull[resind]);
165 
166  /*
167  * We must force any R/W expanded datums to read-only state, in
168  * case they are multiply referenced in the plan node's output
169  * expressions, or in case we skip the output projection and the
170  * output column is multiply referenced in higher plan nodes.
171  */
172  values[resind] = MakeExpandedObjectReadOnly(values[resind],
173  isnull[resind],
174  attr->attlen);
175 
176  resind++;
177  }
178 
179  MemoryContextSwitchTo(oldContext);
180 
181  /*
182  * And return the virtual tuple.
183  */
184  ExecStoreVirtualTuple(slot);
185  }
186 
187  return slot;
188 }
#define NIL
Definition: pg_list.h:69
#define PGJIT_NONE
Definition: jit.h:19
#define ScanDirectionIsForward(direction)
Definition: sdir.h:55
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:93
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:226
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:475
List * subPlan
Definition: execnodes.h:935
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Datum * tts_values
Definition: tuptable.h:130
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1194
EState * state
Definition: execnodes.h:913
int natts
Definition: tupdesc.h:82
ScanDirection es_direction
Definition: execnodes.h:477
ScanState ss
Definition: execnodes.h:1545
PlanState ps
Definition: execnodes.h:1191
int es_jit_flags
Definition: execnodes.h:572
bool * tts_isnull
Definition: tuptable.h:132
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:281
ScanDirection
Definition: sdir.h:22
List * ExecInitExprList(List *nodes, PlanState *parent)
Definition: execExpr.c:314
#define MakeExpandedObjectReadOnly(d, isnull, typlen)
struct EState * ecxt_estate
Definition: execnodes.h:254
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:197
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:124
uintptr_t Datum
Definition: postgres.h:365
ExprContext * rowcontext
Definition: execnodes.h:1546
#define Assert(condition)
Definition: c.h:699
#define lfirst(lc)
Definition: pg_list.h:106
static int list_length(const List *l)
Definition: pg_list.h:89
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:386
static Datum values[MAXATTR]
Definition: bootstrap.c:164
List ** exprlists
Definition: execnodes.h:1547
Definition: pg_list.h:45
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:524

◆ ValuesRecheck()

static bool ValuesRecheck ( ValuesScanState node,
TupleTableSlot slot 
)
static

Definition at line 194 of file nodeValuesscan.c.

Referenced by ExecValuesScan().

195 {
196  /* nothing to check */
197  return true;
198 }