PostgreSQL Source Code  git master
nodeAppend.h File Reference
#include "access/parallel.h"
#include "nodes/execnodes.h"
Include dependency graph for nodeAppend.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

AppendStateExecInitAppend (Append *node, EState *estate, int eflags)
 
void ExecEndAppend (AppendState *node)
 
void ExecReScanAppend (AppendState *node)
 
void ExecAppendEstimate (AppendState *node, ParallelContext *pcxt)
 
void ExecAppendInitializeDSM (AppendState *node, ParallelContext *pcxt)
 
void ExecAppendReInitializeDSM (AppendState *node, ParallelContext *pcxt)
 
void ExecAppendInitializeWorker (AppendState *node, ParallelWorkerContext *pwcxt)
 

Function Documentation

◆ ExecAppendEstimate()

void ExecAppendEstimate ( AppendState node,
ParallelContext pcxt 
)

Definition at line 387 of file nodeAppend.c.

References add_size(), AppendState::as_nplans, ParallelContext::estimator, offsetof, ParallelAppendState::pa_finished, AppendState::pstate_len, shm_toc_estimate_chunk, and shm_toc_estimate_keys.

Referenced by ExecParallelEstimate().

389 {
390  node->pstate_len =
391  add_size(offsetof(ParallelAppendState, pa_finished),
392  sizeof(bool) * node->as_nplans);
393 
395  shm_toc_estimate_keys(&pcxt->estimator, 1);
396 }
Size pstate_len
Definition: execnodes.h:1224
shm_toc_estimator estimator
Definition: parallel.h:41
#define shm_toc_estimate_chunk(e, sz)
Definition: shm_toc.h:51
Size add_size(Size s1, Size s2)
Definition: shmem.c:475
#define shm_toc_estimate_keys(e, cnt)
Definition: shm_toc.h:53
#define offsetof(type, field)
Definition: c.h:655

◆ ExecAppendInitializeDSM()

void ExecAppendInitializeDSM ( AppendState node,
ParallelContext pcxt 
)

Definition at line 406 of file nodeAppend.c.

References AppendState::as_pstate, AppendState::choose_next_subplan, choose_next_subplan_for_leader(), LWLockInitialize(), LWTRANCHE_PARALLEL_APPEND, ParallelAppendState::pa_lock, PlanState::plan, Plan::plan_node_id, AppendState::ps, AppendState::pstate_len, shm_toc_allocate(), shm_toc_insert(), and ParallelContext::toc.

Referenced by ExecParallelInitializeDSM().

408 {
409  ParallelAppendState *pstate;
410 
411  pstate = shm_toc_allocate(pcxt->toc, node->pstate_len);
412  memset(pstate, 0, node->pstate_len);
414  shm_toc_insert(pcxt->toc, node->ps.plan->plan_node_id, pstate);
415 
416  node->as_pstate = pstate;
418 }
Size pstate_len
Definition: execnodes.h:1224
int plan_node_id
Definition: plannodes.h:139
PlanState ps
Definition: execnodes.h:1217
ParallelAppendState * as_pstate
Definition: execnodes.h:1223
bool(* choose_next_subplan)(AppendState *)
Definition: execnodes.h:1227
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition: lwlock.c:678
Plan * plan
Definition: execnodes.h:940
static bool choose_next_subplan_for_leader(AppendState *node)
Definition: nodeAppend.c:506
void * shm_toc_allocate(shm_toc *toc, Size nbytes)
Definition: shm_toc.c:88
void shm_toc_insert(shm_toc *toc, uint64 key, void *address)
Definition: shm_toc.c:171
shm_toc * toc
Definition: parallel.h:44

◆ ExecAppendInitializeWorker()

void ExecAppendInitializeWorker ( AppendState node,
ParallelWorkerContext pwcxt 
)

Definition at line 443 of file nodeAppend.c.

References AppendState::as_pstate, AppendState::choose_next_subplan, choose_next_subplan_for_worker(), PlanState::plan, Plan::plan_node_id, AppendState::ps, shm_toc_lookup(), and ParallelWorkerContext::toc.

Referenced by ExecParallelInitializeWorker().

444 {
445  node->as_pstate = shm_toc_lookup(pwcxt->toc, node->ps.plan->plan_node_id, false);
447 }
int plan_node_id
Definition: plannodes.h:139
PlanState ps
Definition: execnodes.h:1217
ParallelAppendState * as_pstate
Definition: execnodes.h:1223
bool(* choose_next_subplan)(AppendState *)
Definition: execnodes.h:1227
static bool choose_next_subplan_for_worker(AppendState *node)
Definition: nodeAppend.c:587
Plan * plan
Definition: execnodes.h:940
void * shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)
Definition: shm_toc.c:232

◆ ExecAppendReInitializeDSM()

void ExecAppendReInitializeDSM ( AppendState node,
ParallelContext pcxt 
)

Definition at line 427 of file nodeAppend.c.

References AppendState::as_nplans, AppendState::as_pstate, ParallelAppendState::pa_finished, and ParallelAppendState::pa_next_plan.

Referenced by ExecParallelReInitializeDSM().

428 {
429  ParallelAppendState *pstate = node->as_pstate;
430 
431  pstate->pa_next_plan = 0;
432  memset(pstate->pa_finished, 0, sizeof(bool) * node->as_nplans);
433 }
ParallelAppendState * as_pstate
Definition: execnodes.h:1223
bool pa_finished[FLEXIBLE_ARRAY_MEMBER]
Definition: nodeAppend.c:77

◆ ExecEndAppend()

void ExecEndAppend ( AppendState node)

Definition at line 314 of file nodeAppend.c.

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

Referenced by ExecEndNode().

315 {
316  PlanState **appendplans;
317  int nplans;
318  int i;
319 
320  /*
321  * get information from the node
322  */
323  appendplans = node->appendplans;
324  nplans = node->as_nplans;
325 
326  /*
327  * shut down each of the subscans
328  */
329  for (i = 0; i < nplans; i++)
330  ExecEndNode(appendplans[i]);
331 }
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:538
PlanState ** appendplans
Definition: execnodes.h:1218
int i

◆ ExecInitAppend()

AppendState* ExecInitAppend ( Append node,
EState estate,
int  eflags 
)

Definition at line 101 of file nodeAppend.c.

References Append::appendplans, AppendState::appendplans, AppendState::as_first_partial_plan, AppendState::as_nplans, AppendState::as_prune_state, AppendState::as_valid_subplans, AppendState::as_whichplan, Assert, bms_add_range(), bms_is_empty(), bms_make_singleton(), bms_next_member(), bms_num_members(), AppendState::choose_next_subplan, choose_next_subplan_locally(), PartitionPruneState::do_exec_prune, PartitionPruneState::do_initial_prune, EXEC_FLAG_MARK, ExecAppend(), ExecAssignExprContext(), ExecCreatePartitionPruneState(), ExecFindInitialMatchingSubPlans(), ExecInitNode(), ExecInitResultTupleSlotTL(), PlanState::ExecProcNode, Append::first_partial_plan, i, INVALID_SUBPLAN_INDEX, list_length(), list_nth(), makeNode, NO_MATCHING_SUBPLANS, palloc(), Append::part_prune_info, PlanState::plan, AppendState::ps, PlanState::ps_ProjInfo, PlanState::resultopsfixed, PlanState::resultopsset, PlanState::state, and TTSOpsVirtual.

Referenced by ExecInitNode().

102 {
103  AppendState *appendstate = makeNode(AppendState);
104  PlanState **appendplanstates;
105  Bitmapset *validsubplans;
106  int nplans;
107  int firstvalid;
108  int i,
109  j;
110 
111  /* check for unsupported flags */
112  Assert(!(eflags & EXEC_FLAG_MARK));
113 
114  /*
115  * create new AppendState for our append node
116  */
117  appendstate->ps.plan = (Plan *) node;
118  appendstate->ps.state = estate;
119  appendstate->ps.ExecProcNode = ExecAppend;
120 
121  /* Let choose_next_subplan_* function handle setting the first subplan */
122  appendstate->as_whichplan = INVALID_SUBPLAN_INDEX;
123 
124  /* If run-time partition pruning is enabled, then set that up now */
125  if (node->part_prune_info != NULL)
126  {
127  PartitionPruneState *prunestate;
128 
129  /* We may need an expression context to evaluate partition exprs */
130  ExecAssignExprContext(estate, &appendstate->ps);
131 
132  /* Create the working data structure for pruning. */
133  prunestate = ExecCreatePartitionPruneState(&appendstate->ps,
134  node->part_prune_info);
135  appendstate->as_prune_state = prunestate;
136 
137  /* Perform an initial partition prune, if required. */
138  if (prunestate->do_initial_prune)
139  {
140  /* Determine which subplans survive initial pruning */
141  validsubplans = ExecFindInitialMatchingSubPlans(prunestate,
142  list_length(node->appendplans));
143 
144  /*
145  * The case where no subplans survive pruning must be handled
146  * specially. The problem here is that code in explain.c requires
147  * an Append to have at least one subplan in order for it to
148  * properly determine the Vars in that subplan's targetlist. We
149  * sidestep this issue by just initializing the first subplan and
150  * setting as_whichplan to NO_MATCHING_SUBPLANS to indicate that
151  * we don't really need to scan any subnodes.
152  */
153  if (bms_is_empty(validsubplans))
154  {
155  appendstate->as_whichplan = NO_MATCHING_SUBPLANS;
156 
157  /* Mark the first as valid so that it's initialized below */
158  validsubplans = bms_make_singleton(0);
159  }
160 
161  nplans = bms_num_members(validsubplans);
162  }
163  else
164  {
165  /* We'll need to initialize all subplans */
166  nplans = list_length(node->appendplans);
167  Assert(nplans > 0);
168  validsubplans = bms_add_range(NULL, 0, nplans - 1);
169  }
170 
171  /*
172  * If no runtime pruning is required, we can fill as_valid_subplans
173  * immediately, preventing later calls to ExecFindMatchingSubPlans.
174  */
175  if (!prunestate->do_exec_prune)
176  {
177  Assert(nplans > 0);
178  appendstate->as_valid_subplans = bms_add_range(NULL, 0, nplans - 1);
179  }
180  }
181  else
182  {
183  nplans = list_length(node->appendplans);
184 
185  /*
186  * When run-time partition pruning is not enabled we can just mark all
187  * subplans as valid; they must also all be initialized.
188  */
189  Assert(nplans > 0);
190  appendstate->as_valid_subplans = validsubplans =
191  bms_add_range(NULL, 0, nplans - 1);
192  appendstate->as_prune_state = NULL;
193  }
194 
195  /*
196  * Initialize result tuple type and slot.
197  */
198  ExecInitResultTupleSlotTL(&appendstate->ps, &TTSOpsVirtual);
199 
200  /* node returns slots from each of its subnodes, therefore not fixed */
201  appendstate->ps.resultopsset = true;
202  appendstate->ps.resultopsfixed = false;
203 
204  appendplanstates = (PlanState **) palloc(nplans *
205  sizeof(PlanState *));
206 
207  /*
208  * call ExecInitNode on each of the valid plans to be executed and save
209  * the results into the appendplanstates array.
210  *
211  * While at it, find out the first valid partial plan.
212  */
213  j = 0;
214  firstvalid = nplans;
215  i = -1;
216  while ((i = bms_next_member(validsubplans, i)) >= 0)
217  {
218  Plan *initNode = (Plan *) list_nth(node->appendplans, i);
219 
220  /*
221  * Record the lowest appendplans index which is a valid partial plan.
222  */
223  if (i >= node->first_partial_plan && j < firstvalid)
224  firstvalid = j;
225 
226  appendplanstates[j++] = ExecInitNode(initNode, estate, eflags);
227  }
228 
229  appendstate->as_first_partial_plan = firstvalid;
230  appendstate->appendplans = appendplanstates;
231  appendstate->as_nplans = nplans;
232 
233  /*
234  * Miscellaneous initialization
235  */
236 
237  appendstate->ps.ps_ProjInfo = NULL;
238 
239  /* For parallel query, this will be overridden later. */
241 
242  return appendstate;
243 }
static TupleTableSlot * ExecAppend(PlanState *pstate)
Definition: nodeAppend.c:252
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:980
#define NO_MATCHING_SUBPLANS
Definition: nodeAppend.c:81
struct PartitionPruneState * as_prune_state
Definition: execnodes.h:1225
static bool choose_next_subplan_locally(AppendState *node)
Definition: nodeAppend.c:457
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:1043
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:84
EState * state
Definition: execnodes.h:942
PlanState ps
Definition: execnodes.h:1217
List * appendplans
Definition: plannodes.h:252
Bitmapset * bms_add_range(Bitmapset *a, int lower, int upper)
Definition: bitmapset.c:834
static void * list_nth(const List *list, int n)
Definition: pg_list.h:277
int first_partial_plan
Definition: plannodes.h:258
bool(* choose_next_subplan)(AppendState *)
Definition: execnodes.h:1227
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:646
Bitmapset * bms_make_singleton(int x)
Definition: bitmapset.c:186
Bitmapset * ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
int as_first_partial_plan
Definition: execnodes.h:1221
bool resultopsset
Definition: execnodes.h:1023
#define INVALID_SUBPLAN_INDEX
Definition: nodeAppend.c:80
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:701
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:946
Bitmapset * as_valid_subplans
Definition: execnodes.h:1226
Plan * plan
Definition: execnodes.h:940
#define makeNode(_type_)
Definition: nodes.h:573
struct PartitionPruneInfo * part_prune_info
Definition: plannodes.h:261
#define Assert(condition)
Definition: c.h:732
#define EXEC_FLAG_MARK
Definition: executor.h:59
int as_whichplan
Definition: execnodes.h:1220
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:444
static int list_length(const List *l)
Definition: pg_list.h:169
void ExecInitResultTupleSlotTL(PlanState *planstate, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1764
bool resultopsfixed
Definition: execnodes.h:1019
void * palloc(Size size)
Definition: mcxt.c:949
PlanState ** appendplans
Definition: execnodes.h:1218
int i
PartitionPruneState * ExecCreatePartitionPruneState(PlanState *planstate, PartitionPruneInfo *partitionpruneinfo)
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:139

◆ ExecReScanAppend()

void ExecReScanAppend ( AppendState node)

Definition at line 334 of file nodeAppend.c.

References AppendState::appendplans, AppendState::as_nplans, AppendState::as_prune_state, AppendState::as_valid_subplans, AppendState::as_whichplan, bms_free(), bms_overlap(), PlanState::chgParam, PartitionPruneState::execparamids, ExecReScan(), i, INVALID_SUBPLAN_INDEX, AppendState::ps, and UpdateChangedParamSet().

Referenced by ExecReScan().

335 {
336  int i;
337 
338  /*
339  * If any PARAM_EXEC Params used in pruning expressions have changed, then
340  * we'd better unset the valid subplans so that they are reselected for
341  * the new parameter values.
342  */
343  if (node->as_prune_state &&
344  bms_overlap(node->ps.chgParam,
346  {
348  node->as_valid_subplans = NULL;
349  }
350 
351  for (i = 0; i < node->as_nplans; i++)
352  {
353  PlanState *subnode = node->appendplans[i];
354 
355  /*
356  * ExecReScan doesn't know about my subplans, so I have to do
357  * changed-parameter signaling myself.
358  */
359  if (node->ps.chgParam != NULL)
360  UpdateChangedParamSet(subnode, node->ps.chgParam);
361 
362  /*
363  * If chgParam of subnode is not null then plan will be re-scanned by
364  * first ExecProcNode.
365  */
366  if (subnode->chgParam == NULL)
367  ExecReScan(subnode);
368  }
369 
370  /* Let choose_next_subplan_* function handle setting the first subplan */
372 }
struct PartitionPruneState * as_prune_state
Definition: execnodes.h:1225
void ExecReScan(PlanState *node)
Definition: execAmi.c:77
PlanState ps
Definition: execnodes.h:1217
Bitmapset * execparamids
Bitmapset * chgParam
Definition: execnodes.h:972
#define INVALID_SUBPLAN_INDEX
Definition: nodeAppend.c:80
Bitmapset * as_valid_subplans
Definition: execnodes.h:1226
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:802
void bms_free(Bitmapset *a)
Definition: bitmapset.c:208
int as_whichplan
Definition: execnodes.h:1220
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:494
PlanState ** appendplans
Definition: execnodes.h:1218
int i