PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
nodeProjectSet.c File Reference
#include "postgres.h"
#include "executor/executor.h"
#include "executor/nodeProjectSet.h"
#include "nodes/nodeFuncs.h"
#include "utils/memutils.h"
Include dependency graph for nodeProjectSet.c:

Go to the source code of this file.

Functions

static TupleTableSlotExecProjectSRF (ProjectSetState *node, bool continuing)
 
TupleTableSlotExecProjectSet (ProjectSetState *node)
 
ProjectSetStateExecInitProjectSet (ProjectSet *node, EState *estate, int eflags)
 
void ExecEndProjectSet (ProjectSetState *node)
 
void ExecReScanProjectSet (ProjectSetState *node)
 

Function Documentation

void ExecEndProjectSet ( ProjectSetState node)

Definition at line 293 of file nodeProjectSet.c.

References ExecClearTuple(), ExecEndNode(), ExecFreeExprContext(), outerPlanState, ProjectSetState::ps, and PlanState::ps_ResultTupleSlot.

Referenced by ExecEndNode().

294 {
295  /*
296  * Free the exprcontext
297  */
298  ExecFreeExprContext(&node->ps);
299 
300  /*
301  * clean out the tuple table
302  */
304 
305  /*
306  * shut down subplans
307  */
309 }
PlanState ps
Definition: execnodes.h:893
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:644
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
void ExecFreeExprContext(PlanState *planstate)
Definition: execUtils.c:511
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:829
#define outerPlanState(node)
Definition: execnodes.h:842
ProjectSetState* ExecInitProjectSet ( ProjectSet node,
EState estate,
int  eflags 
)

Definition at line 200 of file nodeProjectSet.c.

References Assert, ProjectSetState::elemdone, ProjectSetState::elems, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, ExecAssignExprContext(), ExecAssignResultTypeFromTL(), ExecInitExpr(), ExecInitFunctionResultSet(), ExecInitNode(), ExecInitResultTupleSlot(), TargetEntry::expr, expression_returns_set(), innerPlan, IsA, lfirst, list_length(), makeNode, ProjectSetState::nelems, NIL, NULL, outerPlan, outerPlanState, palloc(), ProjectSetState::pending_srf_tuples, ProjectSet::plan, PlanState::plan, ProjectSetState::ps, PlanState::ps_ExprContext, Plan::qual, PlanState::state, and Plan::targetlist.

Referenced by ExecInitNode().

201 {
203  ListCell *lc;
204  int off;
205 
206  /* check for unsupported flags */
207  Assert(!(eflags & (EXEC_FLAG_MARK | EXEC_FLAG_BACKWARD)));
208 
209  /*
210  * create state structure
211  */
212  state = makeNode(ProjectSetState);
213  state->ps.plan = (Plan *) node;
214  state->ps.state = estate;
215 
216  state->pending_srf_tuples = false;
217 
218  /*
219  * Miscellaneous initialization
220  *
221  * create expression context for node
222  */
223  ExecAssignExprContext(estate, &state->ps);
224 
225  /*
226  * tuple table initialization
227  */
228  ExecInitResultTupleSlot(estate, &state->ps);
229 
230  /* We don't support any qual on ProjectSet nodes */
231  Assert(node->plan.qual == NIL);
232 
233  /*
234  * initialize child nodes
235  */
236  outerPlanState(state) = ExecInitNode(outerPlan(node), estate, eflags);
237 
238  /*
239  * we don't use inner plan
240  */
241  Assert(innerPlan(node) == NULL);
242 
243  /*
244  * initialize tuple type and projection info
245  */
247 
248  /* Create workspace for per-tlist-entry expr state & SRF-is-done state */
249  state->nelems = list_length(node->plan.targetlist);
250  state->elems = (Node **)
251  palloc(sizeof(Node *) * state->nelems);
252  state->elemdone = (ExprDoneCond *)
253  palloc(sizeof(ExprDoneCond) * state->nelems);
254 
255  /*
256  * Build expressions to evaluate targetlist. We can't use
257  * ExecBuildProjectionInfo here, since that doesn't deal with SRFs.
258  * Instead compile each expression separately, using
259  * ExecInitFunctionResultSet where applicable.
260  */
261  off = 0;
262  foreach(lc, node->plan.targetlist)
263  {
264  TargetEntry *te = (TargetEntry *) lfirst(lc);
265  Expr *expr = te->expr;
266 
267  if ((IsA(expr, FuncExpr) &&((FuncExpr *) expr)->funcretset) ||
268  (IsA(expr, OpExpr) &&((OpExpr *) expr)->opretset))
269  {
270  state->elems[off] = (Node *)
272  &state->ps);
273  }
274  else
275  {
276  Assert(!expression_returns_set((Node *) expr));
277  state->elems[off] = (Node *) ExecInitExpr(expr, &state->ps);
278  }
279 
280  off++;
281  }
282 
283  return state;
284 }
#define NIL
Definition: pg_list.h:69
List * qual
Definition: plannodes.h:133
#define IsA(nodeptr, _type_)
Definition: nodes.h:557
PlanState ps
Definition: execnodes.h:893
ExprContext * ps_ExprContext
Definition: execnodes.h:830
bool expression_returns_set(Node *clause)
Definition: nodeFuncs.c:667
bool pending_srf_tuples
Definition: execnodes.h:897
Definition: nodes.h:506
EState * state
Definition: execnodes.h:802
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:435
void ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
Definition: execTuples.c:832
SetExprState * ExecInitFunctionResultSet(Expr *expr, ExprContext *econtext, PlanState *parent)
Definition: execSRF.c:423
#define EXEC_FLAG_BACKWARD
Definition: executor.h:60
#define outerPlanState(node)
Definition: execnodes.h:842
#define innerPlan(node)
Definition: plannodes.h:161
Node ** elems
Definition: execnodes.h:894
#define outerPlan(node)
Definition: plannodes.h:162
ExprDoneCond
Definition: execnodes.h:234
Plan * plan
Definition: execnodes.h:800
#define makeNode(_type_)
Definition: nodes.h:554
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
#define EXEC_FLAG_MARK
Definition: executor.h:61
Definition: regguts.h:298
Expr * expr
Definition: primnodes.h:1352
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:413
static int list_length(const List *l)
Definition: pg_list.h:89
List * targetlist
Definition: plannodes.h:132
void * palloc(Size size)
Definition: mcxt.c:849
ExprDoneCond * elemdone
Definition: execnodes.h:895
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition: execExpr.c:113
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:139
Plan plan
Definition: plannodes.h:190
TupleTableSlot* ExecProjectSet ( ProjectSetState node)

Definition at line 42 of file nodeProjectSet.c.

References ExprContext::ecxt_outertuple, ExecProcNode(), ExecProjectSRF(), NULL, outerPlan, outerPlanState, ProjectSetState::pending_srf_tuples, ProjectSetState::ps, PlanState::ps_ExprContext, ResetExprContext, and TupIsNull.

Referenced by ExecProcNode().

43 {
44  TupleTableSlot *outerTupleSlot;
45  TupleTableSlot *resultSlot;
47  ExprContext *econtext;
48 
49  econtext = node->ps.ps_ExprContext;
50 
51  /*
52  * Check to see if we're still projecting out tuples from a previous scan
53  * tuple (because there is a function-returning-set in the projection
54  * expressions). If so, try to project another one.
55  */
56  if (node->pending_srf_tuples)
57  {
58  resultSlot = ExecProjectSRF(node, true);
59 
60  if (resultSlot != NULL)
61  return resultSlot;
62  }
63 
64  /*
65  * Reset per-tuple memory context to free any expression evaluation
66  * storage allocated in the previous tuple cycle. Note this can't happen
67  * until we're done projecting out tuples from a scan tuple.
68  */
69  ResetExprContext(econtext);
70 
71  /*
72  * Get another input tuple and project SRFs from it.
73  */
74  for (;;)
75  {
76  /*
77  * Retrieve tuples from the outer plan until there are no more.
78  */
79  outerPlan = outerPlanState(node);
80  outerTupleSlot = ExecProcNode(outerPlan);
81 
82  if (TupIsNull(outerTupleSlot))
83  return NULL;
84 
85  /*
86  * Prepare to compute projection expressions, which will expect to
87  * access the input tuples as varno OUTER.
88  */
89  econtext->ecxt_outertuple = outerTupleSlot;
90 
91  /* Evaluate the expressions */
92  resultSlot = ExecProjectSRF(node, false);
93 
94  /*
95  * Return the tuple unless the projection produced no rows (due to an
96  * empty set), in which case we must loop back to see if there are
97  * more outerPlan tuples.
98  */
99  if (resultSlot)
100  return resultSlot;
101  }
102 
103  return NULL;
104 }
TupleTableSlot * ExecProcNode(PlanState *node)
Definition: execProcnode.c:392
PlanState ps
Definition: execnodes.h:893
ExprContext * ps_ExprContext
Definition: execnodes.h:830
bool pending_srf_tuples
Definition: execnodes.h:897
static TupleTableSlot * ExecProjectSRF(ProjectSetState *node, bool continuing)
#define outerPlanState(node)
Definition: execnodes.h:842
#define TupIsNull(slot)
Definition: tuptable.h:138
#define outerPlan(node)
Definition: plannodes.h:162
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:198
#define NULL
Definition: c.h:229
#define ResetExprContext(econtext)
Definition: executor.h:450
static TupleTableSlot * ExecProjectSRF ( ProjectSetState node,
bool  continuing 
)
static

Definition at line 119 of file nodeProjectSet.c.

References Assert, ProjectSetState::elemdone, ProjectSetState::elems, ExecClearTuple(), ExecEvalExpr(), ExecMakeFunctionResultSet(), ExecStoreVirtualTuple(), ExprEndResult, ExprMultipleResult, ExprSingleResult, IsA, ProjectSetState::nelems, NULL, ProjectSetState::pending_srf_tuples, PG_USED_FOR_ASSERTS_ONLY, ProjectSetState::ps, PlanState::ps_ExprContext, PlanState::ps_ResultTupleSlot, result, TupleTableSlot::tts_isnull, and TupleTableSlot::tts_values.

Referenced by ExecProjectSet().

120 {
121  TupleTableSlot *resultSlot = node->ps.ps_ResultTupleSlot;
122  ExprContext *econtext = node->ps.ps_ExprContext;
123  bool hassrf PG_USED_FOR_ASSERTS_ONLY;
124  bool hasresult;
125  int argno;
126 
127  ExecClearTuple(resultSlot);
128 
129  /*
130  * Assume no further tuples are produced unless an ExprMultipleResult is
131  * encountered from a set returning function.
132  */
133  node->pending_srf_tuples = false;
134 
135  hassrf = hasresult = false;
136  for (argno = 0; argno < node->nelems; argno++)
137  {
138  Node *elem = node->elems[argno];
139  ExprDoneCond *isdone = &node->elemdone[argno];
140  Datum *result = &resultSlot->tts_values[argno];
141  bool *isnull = &resultSlot->tts_isnull[argno];
142 
143  if (continuing && *isdone == ExprEndResult)
144  {
145  /*
146  * If we're continuing to project output rows from a source tuple,
147  * return NULLs once the SRF has been exhausted.
148  */
149  *result = (Datum) 0;
150  *isnull = true;
151  hassrf = true;
152  }
153  else if (IsA(elem, SetExprState))
154  {
155  /*
156  * Evaluate SRF - possibly continuing previously started output.
157  */
158  *result = ExecMakeFunctionResultSet((SetExprState *) elem,
159  econtext, isnull, isdone);
160 
161  if (*isdone != ExprEndResult)
162  hasresult = true;
163  if (*isdone == ExprMultipleResult)
164  node->pending_srf_tuples = true;
165  hassrf = true;
166  }
167  else
168  {
169  /* Non-SRF tlist expression, just evaluate normally. */
170  *result = ExecEvalExpr((ExprState *) elem, econtext, isnull);
171  *isdone = ExprSingleResult;
172  }
173  }
174 
175  /* ProjectSet should not be used if there's no SRFs */
176  Assert(hassrf);
177 
178  /*
179  * If all the SRFs returned EndResult, we consider that as no row being
180  * produced.
181  */
182  if (hasresult)
183  {
184  ExecStoreVirtualTuple(resultSlot);
185  return resultSlot;
186  }
187 
188  return NULL;
189 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:557
PlanState ps
Definition: execnodes.h:893
ExprContext * ps_ExprContext
Definition: execnodes.h:830
bool pending_srf_tuples
Definition: execnodes.h:897
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
Definition: nodes.h:506
Datum * tts_values
Definition: tuptable.h:125
return result
Definition: formatting.c:1618
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:829
Node ** elems
Definition: execnodes.h:894
bool * tts_isnull
Definition: tuptable.h:126
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:266
Datum ExecMakeFunctionResultSet(SetExprState *fcache, ExprContext *econtext, bool *isNull, ExprDoneCond *isDone)
Definition: execSRF.c:472
ExprDoneCond
Definition: execnodes.h:234
uintptr_t Datum
Definition: postgres.h:372
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
ExprDoneCond * elemdone
Definition: execnodes.h:895
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:990
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:488
void ExecReScanProjectSet ( ProjectSetState node)

Definition at line 312 of file nodeProjectSet.c.

References PlanState::chgParam, ExecReScan(), PlanState::lefttree, NULL, ProjectSetState::pending_srf_tuples, and ProjectSetState::ps.

Referenced by ExecReScan().

313 {
314  /* Forget any incompletely-evaluated SRFs */
315  node->pending_srf_tuples = false;
316 
317  /*
318  * If chgParam of subnode is not null then plan will be re-scanned by
319  * first ExecProcNode.
320  */
321  if (node->ps.lefttree->chgParam == NULL)
322  ExecReScan(node->ps.lefttree);
323 }
PlanState ps
Definition: execnodes.h:893
void ExecReScan(PlanState *node)
Definition: execAmi.c:74
bool pending_srf_tuples
Definition: execnodes.h:897
struct PlanState * lefttree
Definition: execnodes.h:815
Bitmapset * chgParam
Definition: execnodes.h:824
#define NULL
Definition: c.h:229