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

Go to the source code of this file.

Functions

static bool exec_append_initialize_next (AppendState *appendstate)
 
AppendStateExecInitAppend (Append *node, EState *estate, int eflags)
 
TupleTableSlotExecAppend (AppendState *node)
 
void ExecEndAppend (AppendState *node)
 
void ExecReScanAppend (AppendState *node)
 

Function Documentation

static bool exec_append_initialize_next ( AppendState appendstate)
static

Definition at line 75 of file nodeAppend.c.

References AppendState::as_nplans, AppendState::as_whichplan, FALSE, and TRUE.

Referenced by ExecAppend(), ExecInitAppend(), and ExecReScanAppend().

76 {
77  int whichplan;
78 
79  /*
80  * get information from the append node
81  */
82  whichplan = appendstate->as_whichplan;
83 
84  if (whichplan < 0)
85  {
86  /*
87  * if scanning in reverse, we start at the last scan in the list and
88  * then proceed back to the first.. in any case we inform ExecAppend
89  * that we are at the end of the line by returning FALSE
90  */
91  appendstate->as_whichplan = 0;
92  return FALSE;
93  }
94  else if (whichplan >= appendstate->as_nplans)
95  {
96  /*
97  * as above, end the scan if we go beyond the last scan in our list..
98  */
99  appendstate->as_whichplan = appendstate->as_nplans - 1;
100  return FALSE;
101  }
102  else
103  {
104  return TRUE;
105  }
106 }
#define FALSE
Definition: c.h:218
int as_whichplan
Definition: execnodes.h:1193
#define TRUE
Definition: c.h:214
TupleTableSlot* ExecAppend ( AppendState node)

Definition at line 194 of file nodeAppend.c.

References AppendState::appendplans, AppendState::as_whichplan, EState::es_direction, exec_append_initialize_next(), ExecClearTuple(), ExecProcNode(), AppendState::ps, PlanState::ps_ResultTupleSlot, ScanDirectionIsForward, PlanState::state, and TupIsNull.

Referenced by ExecProcNode().

195 {
196  for (;;)
197  {
198  PlanState *subnode;
199  TupleTableSlot *result;
200 
201  /*
202  * figure out which subplan we are currently processing
203  */
204  subnode = node->appendplans[node->as_whichplan];
205 
206  /*
207  * get a tuple from the subplan
208  */
209  result = ExecProcNode(subnode);
210 
211  if (!TupIsNull(result))
212  {
213  /*
214  * If the subplan gave us something then return it as-is. We do
215  * NOT make use of the result slot that was set up in
216  * ExecInitAppend; there's no need for it.
217  */
218  return result;
219  }
220 
221  /*
222  * Go on to the "next" subplan in the appropriate direction. If no
223  * more subplans, return the empty slot set up for us by
224  * ExecInitAppend.
225  */
227  node->as_whichplan++;
228  else
229  node->as_whichplan--;
230  if (!exec_append_initialize_next(node))
231  return ExecClearTuple(node->ps.ps_ResultTupleSlot);
232 
233  /* Else loop back and try to get a tuple from the new subplan */
234  }
235 }
TupleTableSlot * ExecProcNode(PlanState *node)
Definition: execProcnode.c:380
#define ScanDirectionIsForward(direction)
Definition: sdir.h:55
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
EState * state
Definition: execnodes.h:1049
ScanDirection es_direction
Definition: execnodes.h:369
PlanState ps
Definition: execnodes.h:1190
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1077
#define TupIsNull(slot)
Definition: tuptable.h:138
int as_whichplan
Definition: execnodes.h:1193
static bool exec_append_initialize_next(AppendState *appendstate)
Definition: nodeAppend.c:75
PlanState ** appendplans
Definition: execnodes.h:1191
void ExecEndAppend ( AppendState node)

Definition at line 246 of file nodeAppend.c.

References AppendState::appendplans, AppendState::as_nplans, ExecEndNode(), and i.

Referenced by ExecEndNode().

247 {
248  PlanState **appendplans;
249  int nplans;
250  int i;
251 
252  /*
253  * get information from the node
254  */
255  appendplans = node->appendplans;
256  nplans = node->as_nplans;
257 
258  /*
259  * shut down each of the subscans
260  */
261  for (i = 0; i < nplans; i++)
262  ExecEndNode(appendplans[i]);
263 }
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:624
PlanState ** appendplans
Definition: execnodes.h:1191
int i
AppendState* ExecInitAppend ( Append node,
EState estate,
int  eflags 
)

Definition at line 120 of file nodeAppend.c.

References Append::appendplans, AppendState::appendplans, AppendState::as_nplans, AppendState::as_whichplan, Assert, exec_append_initialize_next(), EXEC_FLAG_MARK, ExecAssignResultTypeFromTL(), ExecInitNode(), ExecInitResultTupleSlot(), i, lfirst, list_length(), makeNode, NULL, palloc0(), PlanState::plan, AppendState::ps, PlanState::ps_ProjInfo, and PlanState::state.

Referenced by ExecInitNode().

121 {
122  AppendState *appendstate = makeNode(AppendState);
123  PlanState **appendplanstates;
124  int nplans;
125  int i;
126  ListCell *lc;
127 
128  /* check for unsupported flags */
129  Assert(!(eflags & EXEC_FLAG_MARK));
130 
131  /*
132  * Set up empty vector of subplan states
133  */
134  nplans = list_length(node->appendplans);
135 
136  appendplanstates = (PlanState **) palloc0(nplans * sizeof(PlanState *));
137 
138  /*
139  * create new AppendState for our append node
140  */
141  appendstate->ps.plan = (Plan *) node;
142  appendstate->ps.state = estate;
143  appendstate->appendplans = appendplanstates;
144  appendstate->as_nplans = nplans;
145 
146  /*
147  * Miscellaneous initialization
148  *
149  * Append plans don't have expression contexts because they never call
150  * ExecQual or ExecProject.
151  */
152 
153  /*
154  * append nodes still have Result slots, which hold pointers to tuples, so
155  * we have to initialize them.
156  */
157  ExecInitResultTupleSlot(estate, &appendstate->ps);
158 
159  /*
160  * call ExecInitNode on each of the plans to be executed and save the
161  * results into the array "appendplans".
162  */
163  i = 0;
164  foreach(lc, node->appendplans)
165  {
166  Plan *initNode = (Plan *) lfirst(lc);
167 
168  appendplanstates[i] = ExecInitNode(initNode, estate, eflags);
169  i++;
170  }
171 
172  /*
173  * initialize output tuple type
174  */
175  ExecAssignResultTypeFromTL(&appendstate->ps);
176  appendstate->ps.ps_ProjInfo = NULL;
177 
178  /*
179  * initialize to scan first subplan
180  */
181  appendstate->as_whichplan = 0;
182  exec_append_initialize_next(appendstate);
183 
184  return appendstate;
185 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:1079
EState * state
Definition: execnodes.h:1049
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:430
PlanState ps
Definition: execnodes.h:1190
List * appendplans
Definition: plannodes.h:230
void ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
Definition: execTuples.c:832
void * palloc0(Size size)
Definition: mcxt.c:920
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 lfirst(lc)
Definition: pg_list.h:106
#define EXEC_FLAG_MARK
Definition: executor.h:61
int as_whichplan
Definition: execnodes.h:1193
static int list_length(const List *l)
Definition: pg_list.h:89
static bool exec_append_initialize_next(AppendState *appendstate)
Definition: nodeAppend.c:75
PlanState ** appendplans
Definition: execnodes.h:1191
int i
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:137
void ExecReScanAppend ( AppendState node)

Definition at line 266 of file nodeAppend.c.

References AppendState::appendplans, AppendState::as_nplans, AppendState::as_whichplan, PlanState::chgParam, exec_append_initialize_next(), ExecReScan(), i, NULL, AppendState::ps, and UpdateChangedParamSet().

Referenced by ExecReScan().

267 {
268  int i;
269 
270  for (i = 0; i < node->as_nplans; i++)
271  {
272  PlanState *subnode = node->appendplans[i];
273 
274  /*
275  * ExecReScan doesn't know about my subplans, so I have to do
276  * changed-parameter signaling myself.
277  */
278  if (node->ps.chgParam != NULL)
279  UpdateChangedParamSet(subnode, node->ps.chgParam);
280 
281  /*
282  * If chgParam of subnode is not null then plan will be re-scanned by
283  * first ExecProcNode.
284  */
285  if (subnode->chgParam == NULL)
286  ExecReScan(subnode);
287  }
288  node->as_whichplan = 0;
290 }
void ExecReScan(PlanState *node)
Definition: execAmi.c:73
PlanState ps
Definition: execnodes.h:1190
Bitmapset * chgParam
Definition: execnodes.h:1072
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:840
#define NULL
Definition: c.h:226
int as_whichplan
Definition: execnodes.h:1193
static bool exec_append_initialize_next(AppendState *appendstate)
Definition: nodeAppend.c:75
PlanState ** appendplans
Definition: execnodes.h:1191
int i