PostgreSQL Source Code  git master
nodeValuesscan.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * nodeValuesscan.c
4  * Support routines for scanning Values lists
5  * ("VALUES (...), (...), ..." in rangetable).
6  *
7  * Portions Copyright (c) 1996-2017, 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"
28 #include "utils/expandeddatum.h"
29 
30 
32 
33 
34 /* ----------------------------------------------------------------
35  * Scan Support
36  * ----------------------------------------------------------------
37  */
38 
39 /* ----------------------------------------------------------------
40  * ValuesNext
41  *
42  * This is a workhorse for ExecValuesScan
43  * ----------------------------------------------------------------
44  */
45 static TupleTableSlot *
47 {
48  TupleTableSlot *slot;
49  EState *estate;
50  ExprContext *econtext;
51  ScanDirection direction;
52  List *exprlist;
53 
54  /*
55  * get information from the estate and scan state
56  */
57  estate = node->ss.ps.state;
58  direction = estate->es_direction;
59  slot = node->ss.ss_ScanTupleSlot;
60  econtext = node->rowcontext;
61 
62  /*
63  * Get the next tuple. Return NULL if no more tuples.
64  */
65  if (ScanDirectionIsForward(direction))
66  {
67  if (node->curr_idx < node->array_len)
68  node->curr_idx++;
69  if (node->curr_idx < node->array_len)
70  exprlist = node->exprlists[node->curr_idx];
71  else
72  exprlist = NIL;
73  }
74  else
75  {
76  if (node->curr_idx >= 0)
77  node->curr_idx--;
78  if (node->curr_idx >= 0)
79  exprlist = node->exprlists[node->curr_idx];
80  else
81  exprlist = NIL;
82  }
83 
84  /*
85  * Always clear the result slot; this is appropriate if we are at the end
86  * of the data, and if we're not, we still need it as the first step of
87  * the store-virtual-tuple protocol. It seems wise to clear the slot
88  * before we reset the context it might have pointers into.
89  */
90  ExecClearTuple(slot);
91 
92  if (exprlist)
93  {
94  MemoryContext oldContext;
95  List *oldsubplans;
96  List *exprstatelist;
97  Datum *values;
98  bool *isnull;
99  ListCell *lc;
100  int resind;
101 
102  /*
103  * Get rid of any prior cycle's leftovers. We use ReScanExprContext
104  * not just ResetExprContext because we want any registered shutdown
105  * callbacks to be called.
106  */
107  ReScanExprContext(econtext);
108 
109  /*
110  * Build the expression eval state in the econtext's per-tuple memory.
111  * This is a tad unusual, but we want to delete the eval state again
112  * when we move to the next row, to avoid growth of memory
113  * requirements over a long values list.
114  */
115  oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
116 
117  /*
118  * The expressions might contain SubPlans (this is currently only
119  * possible if there's a sub-select containing a LATERAL reference,
120  * otherwise sub-selects in a VALUES list should be InitPlans). Those
121  * subplans will want to hook themselves into our subPlan list, which
122  * would result in a corrupted list after we delete the eval state. We
123  * can work around this by saving and restoring the subPlan list.
124  * (There's no need for the functionality that would be enabled by
125  * having the list entries, since the SubPlans aren't going to be
126  * re-executed anyway.)
127  */
128  oldsubplans = node->ss.ps.subPlan;
129  node->ss.ps.subPlan = NIL;
130 
131  exprstatelist = ExecInitExprList(exprlist, &node->ss.ps);
132 
133  node->ss.ps.subPlan = oldsubplans;
134 
135  /* parser should have checked all sublists are the same length */
136  Assert(list_length(exprstatelist) == slot->tts_tupleDescriptor->natts);
137 
138  /*
139  * Compute the expressions and build a virtual result tuple. We
140  * already did ExecClearTuple(slot).
141  */
142  values = slot->tts_values;
143  isnull = slot->tts_isnull;
144 
145  resind = 0;
146  foreach(lc, exprstatelist)
147  {
148  ExprState *estate = (ExprState *) lfirst(lc);
150  resind);
151 
152  values[resind] = ExecEvalExpr(estate,
153  econtext,
154  &isnull[resind]);
155 
156  /*
157  * We must force any R/W expanded datums to read-only state, in
158  * case they are multiply referenced in the plan node's output
159  * expressions, or in case we skip the output projection and the
160  * output column is multiply referenced in higher plan nodes.
161  */
162  values[resind] = MakeExpandedObjectReadOnly(values[resind],
163  isnull[resind],
164  attr->attlen);
165 
166  resind++;
167  }
168 
169  MemoryContextSwitchTo(oldContext);
170 
171  /*
172  * And return the virtual tuple.
173  */
174  ExecStoreVirtualTuple(slot);
175  }
176 
177  return slot;
178 }
179 
180 /*
181  * ValuesRecheck -- access method routine to recheck a tuple in EvalPlanQual
182  */
183 static bool
185 {
186  /* nothing to check */
187  return true;
188 }
189 
190 /* ----------------------------------------------------------------
191  * ExecValuesScan(node)
192  *
193  * Scans the values lists sequentially and returns the next qualifying
194  * tuple.
195  * We call the ExecScan() routine and pass it the appropriate
196  * access method functions.
197  * ----------------------------------------------------------------
198  */
199 static TupleTableSlot *
201 {
202  ValuesScanState *node = castNode(ValuesScanState, pstate);
203 
204  return ExecScan(&node->ss,
207 }
208 
209 /* ----------------------------------------------------------------
210  * ExecInitValuesScan
211  * ----------------------------------------------------------------
212  */
214 ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags)
215 {
216  ValuesScanState *scanstate;
217  TupleDesc tupdesc;
218  ListCell *vtl;
219  int i;
220  PlanState *planstate;
221 
222  /*
223  * ValuesScan should not have any children.
224  */
225  Assert(outerPlan(node) == NULL);
226  Assert(innerPlan(node) == NULL);
227 
228  /*
229  * create new ScanState for node
230  */
231  scanstate = makeNode(ValuesScanState);
232  scanstate->ss.ps.plan = (Plan *) node;
233  scanstate->ss.ps.state = estate;
234  scanstate->ss.ps.ExecProcNode = ExecValuesScan;
235 
236  /*
237  * Miscellaneous initialization
238  */
239  planstate = &scanstate->ss.ps;
240 
241  /*
242  * Create expression contexts. We need two, one for per-sublist
243  * processing and one for execScan.c to use for quals and projections. We
244  * cheat a little by using ExecAssignExprContext() to build both.
245  */
246  ExecAssignExprContext(estate, planstate);
247  scanstate->rowcontext = planstate->ps_ExprContext;
248  ExecAssignExprContext(estate, planstate);
249 
250  /*
251  * tuple table initialization
252  */
253  ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
254  ExecInitScanTupleSlot(estate, &scanstate->ss);
255 
256  /*
257  * initialize child expressions
258  */
259  scanstate->ss.ps.qual =
260  ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
261 
262  /*
263  * get info about values list
264  */
265  tupdesc = ExecTypeFromExprList((List *) linitial(node->values_lists));
266 
267  ExecAssignScanType(&scanstate->ss, tupdesc);
268 
269  /*
270  * Other node-specific setup
271  */
272  scanstate->curr_idx = -1;
273  scanstate->array_len = list_length(node->values_lists);
274 
275  /* convert list of sublists into array of sublists for easy addressing */
276  scanstate->exprlists = (List **)
277  palloc(scanstate->array_len * sizeof(List *));
278  i = 0;
279  foreach(vtl, node->values_lists)
280  {
281  scanstate->exprlists[i++] = (List *) lfirst(vtl);
282  }
283 
284  /*
285  * Initialize result tuple type and projection info.
286  */
287  ExecAssignResultTypeFromTL(&scanstate->ss.ps);
288  ExecAssignScanProjectionInfo(&scanstate->ss);
289 
290  return scanstate;
291 }
292 
293 /* ----------------------------------------------------------------
294  * ExecEndValuesScan
295  *
296  * frees any storage allocated through C routines.
297  * ----------------------------------------------------------------
298  */
299 void
301 {
302  /*
303  * Free both exprcontexts
304  */
305  ExecFreeExprContext(&node->ss.ps);
306  node->ss.ps.ps_ExprContext = node->rowcontext;
307  ExecFreeExprContext(&node->ss.ps);
308 
309  /*
310  * clean out the tuple table
311  */
314 }
315 
316 /* ----------------------------------------------------------------
317  * ExecReScanValuesScan
318  *
319  * Rescans the relation.
320  * ----------------------------------------------------------------
321  */
322 void
324 {
326 
327  ExecScanReScan(&node->ss);
328 
329  node->curr_idx = -1;
330 }
#define NIL
Definition: pg_list.h:69
List * qual
Definition: plannodes.h:145
Plan plan
Definition: plannodes.h:329
static TupleTableSlot * ExecValuesScan(PlanState *pstate)
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate)
Definition: execTuples.c:842
#define ScanDirectionIsForward(direction)
Definition: sdir.h:55
#define castNode(_type_, nodeptr)
Definition: nodes.h:581
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:90
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
Definition: execScan.c:121
ExprContext * ps_ExprContext
Definition: execnodes.h:884
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:204
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
List * subPlan
Definition: execnodes.h:873
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Datum * tts_values
Definition: tuptable.h:125
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1116
List * values_lists
Definition: plannodes.h:520
EState * state
Definition: execnodes.h:852
Scan scan
Definition: plannodes.h:519
int natts
Definition: tupdesc.h:79
void ExecFreeExprContext(PlanState *planstate)
Definition: execUtils.c:603
ScanDirection es_direction
Definition: execnodes.h:429
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:160
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:448
ScanState ss
Definition: execnodes.h:1469
PlanState ps
Definition: execnodes.h:1113
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:883
#define linitial(l)
Definition: pg_list.h:111
void ExecAssignScanProjectionInfo(ScanState *node)
Definition: execScan.c:235
void ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
Definition: execTuples.c:832
#define innerPlan(node)
Definition: plannodes.h:173
static TupleTableSlot * ValuesNext(ValuesScanState *node)
bool * tts_isnull
Definition: tuptable.h:126
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:277
ScanDirection
Definition: sdir.h:22
void ExecEndValuesScan(ValuesScanState *node)
List * ExecInitExprList(List *nodes, PlanState *parent)
Definition: execExpr.c:266
#define MakeExpandedObjectReadOnly(d, isnull, typlen)
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
static bool ValuesRecheck(ValuesScanState *node, TupleTableSlot *slot)
#define outerPlan(node)
Definition: plannodes.h:174
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition: executor.h:402
ValuesScanState * ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags)
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:856
uintptr_t Datum
Definition: postgres.h:372
ExprContext * rowcontext
Definition: execnodes.h:1470
Plan * plan
Definition: execnodes.h:850
#define makeNode(_type_)
Definition: nodes.h:560
#define Assert(condition)
Definition: c.h:680
#define lfirst(lc)
Definition: pg_list.h:106
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:426
static int list_length(const List *l)
Definition: pg_list.h:89
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:384
ExprState * qual
Definition: execnodes.h:868
void ExecReScanValuesScan(ValuesScanState *node)
static Datum values[MAXATTR]
Definition: bootstrap.c:164
TupleDesc ExecTypeFromExprList(List *exprList)
Definition: execTuples.c:947
void * palloc(Size size)
Definition: mcxt.c:835
int i
void ExecScanReScan(ScanState *node)
Definition: execScan.c:262
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
Definition: execUtils.c:627
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition: executor.h:401
List ** exprlists
Definition: execnodes.h:1471
Definition: pg_list.h:45
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:488