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 "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 270 of file nodeProjectSet.c.

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

Referenced by ExecEndNode().

271 {
272  /*
273  * Free the exprcontext
274  */
275  ExecFreeExprContext(&node->ps);
276 
277  /*
278  * clean out the tuple table
279  */
281 
282  /*
283  * shut down subplans
284  */
286 }
PlanState ps
Definition: execnodes.h:1138
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:624
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
void ExecFreeExprContext(PlanState *planstate)
Definition: execUtils.c:685
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1077
#define outerPlanState(node)
Definition: execnodes.h:1090
ProjectSetState* ExecInitProjectSet ( ProjectSet node,
EState estate,
int  eflags 
)

Definition at line 204 of file nodeProjectSet.c.

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

Referenced by ExecInitNode().

205 {
207 
208  /* check for unsupported flags */
209  Assert(!(eflags & (EXEC_FLAG_MARK | EXEC_FLAG_BACKWARD)));
210 
211  /*
212  * create state structure
213  */
214  state = makeNode(ProjectSetState);
215  state->ps.plan = (Plan *) node;
216  state->ps.state = estate;
217 
218  state->pending_srf_tuples = false;
219 
220  /*
221  * Miscellaneous initialization
222  *
223  * create expression context for node
224  */
225  ExecAssignExprContext(estate, &state->ps);
226 
227  /*
228  * tuple table initialization
229  */
230  ExecInitResultTupleSlot(estate, &state->ps);
231 
232  /*
233  * initialize child expressions
234  */
235  state->ps.targetlist = (List *)
236  ExecInitExpr((Expr *) node->plan.targetlist,
237  (PlanState *) state);
238  Assert(node->plan.qual == NIL);
239 
240  /*
241  * initialize child nodes
242  */
243  outerPlanState(state) = ExecInitNode(outerPlan(node), estate, eflags);
244 
245  /*
246  * we don't use inner plan
247  */
248  Assert(innerPlan(node) == NULL);
249 
250  /*
251  * initialize tuple type and projection info
252  */
254 
255  /* Create workspace for per-SRF is-done state */
256  state->nelems = list_length(node->plan.targetlist);
257  state->elemdone = (ExprDoneCond *)
258  palloc(sizeof(ExprDoneCond) * state->nelems);
259 
260  return state;
261 }
#define NIL
Definition: pg_list.h:69
List * qual
Definition: plannodes.h:130
PlanState ps
Definition: execnodes.h:1138
bool pending_srf_tuples
Definition: execnodes.h:1141
List * targetlist
Definition: execnodes.h:1061
EState * state
Definition: execnodes.h:1049
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:430
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition: execQual.c:4266
void ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
Definition: execTuples.c:832
#define EXEC_FLAG_BACKWARD
Definition: executor.h:60
#define outerPlanState(node)
Definition: execnodes.h:1090
#define innerPlan(node)
Definition: plannodes.h:158
#define outerPlan(node)
Definition: plannodes.h:159
ExprDoneCond
Definition: execnodes.h:166
Plan * plan
Definition: execnodes.h:1047
#define makeNode(_type_)
Definition: nodes.h:556
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
#define EXEC_FLAG_MARK
Definition: executor.h:61
Definition: regguts.h:298
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:408
static int list_length(const List *l)
Definition: pg_list.h:89
List * targetlist
Definition: plannodes.h:129
void * palloc(Size size)
Definition: mcxt.c:891
ExprDoneCond * elemdone
Definition: execnodes.h:1139
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:137
Definition: pg_list.h:45
Plan plan
Definition: plannodes.h:187
TupleTableSlot* ExecProjectSet ( ProjectSetState node)

Definition at line 41 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().

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

Definition at line 118 of file nodeProjectSet.c.

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

Referenced by ExecProjectSet().

119 {
120  TupleTableSlot *resultSlot = node->ps.ps_ResultTupleSlot;
121  ExprContext *econtext = node->ps.ps_ExprContext;
122  bool hassrf PG_USED_FOR_ASSERTS_ONLY = false;
123  bool hasresult;
124  int argno;
125  ListCell *lc;
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  hasresult = false;
136  argno = 0;
137  foreach(lc, node->ps.targetlist)
138  {
139  GenericExprState *gstate = (GenericExprState *) lfirst(lc);
140  ExprDoneCond *isdone = &node->elemdone[argno];
141  Datum *result = &resultSlot->tts_values[argno];
142  bool *isnull = &resultSlot->tts_isnull[argno];
143 
144  if (continuing && *isdone == ExprEndResult)
145  {
146  /*
147  * If we're continuing to project output rows from a source tuple,
148  * return NULLs once the SRF has been exhausted.
149  */
150  *result = (Datum) 0;
151  *isnull = true;
152  hassrf = true;
153  }
154  else if (IsA(gstate->arg, FuncExprState) &&
155  ((FuncExprState *) gstate->arg)->funcReturnsSet)
156  {
157  /*
158  * Evaluate SRF - possibly continuing previously started output.
159  */
160  *result = ExecMakeFunctionResultSet((FuncExprState *) gstate->arg,
161  econtext, isnull, isdone);
162 
163  if (*isdone != ExprEndResult)
164  hasresult = true;
165  if (*isdone == ExprMultipleResult)
166  node->pending_srf_tuples = true;
167  hassrf = true;
168  }
169  else
170  {
171  /* Non-SRF tlist expression, just evaluate normally. */
172  *result = ExecEvalExpr(gstate->arg, econtext, isnull);
173  *isdone = ExprSingleResult;
174  }
175 
176  argno++;
177  }
178 
179  /* ProjectSet should not be used if there's no SRFs */
180  Assert(hassrf);
181 
182  /*
183  * If all the SRFs returned EndResult, we consider that as no row being
184  * produced.
185  */
186  if (hasresult)
187  {
188  ExecStoreVirtualTuple(resultSlot);
189  return resultSlot;
190  }
191 
192  return NULL;
193 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
PlanState ps
Definition: execnodes.h:1138
ExprContext * ps_ExprContext
Definition: execnodes.h:1078
bool pending_srf_tuples
Definition: execnodes.h:1141
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
List * targetlist
Definition: execnodes.h:1061
Datum * tts_values
Definition: tuptable.h:125
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1077
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
bool * tts_isnull
Definition: tuptable.h:126
Datum ExecMakeFunctionResultSet(FuncExprState *fcache, ExprContext *econtext, bool *isNull, ExprDoneCond *isDone)
Definition: execQual.c:1614
ExprState * arg
Definition: execnodes.h:612
ExprDoneCond
Definition: execnodes.h:166
uintptr_t Datum
Definition: postgres.h:374
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
#define lfirst(lc)
Definition: pg_list.h:106
ExprDoneCond * elemdone
Definition: execnodes.h:1139
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:986
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:488
void ExecReScanProjectSet ( ProjectSetState node)

Definition at line 289 of file nodeProjectSet.c.

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

Referenced by ExecReScan().

290 {
291  /* Forget any incompletely-evaluated SRFs */
292  node->pending_srf_tuples = false;
293 
294  /*
295  * If chgParam of subnode is not null then plan will be re-scanned by
296  * first ExecProcNode.
297  */
298  if (node->ps.lefttree->chgParam == NULL)
299  ExecReScan(node->ps.lefttree);
300 }
PlanState ps
Definition: execnodes.h:1138
void ExecReScan(PlanState *node)
Definition: execAmi.c:73
bool pending_srf_tuples
Definition: execnodes.h:1141
struct PlanState * lefttree
Definition: execnodes.h:1063
Bitmapset * chgParam
Definition: execnodes.h:1072
#define NULL
Definition: c.h:226