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 392 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().

394 {
395  node->pstate_len =
396  add_size(offsetof(ParallelAppendState, pa_finished),
397  sizeof(bool) * node->as_nplans);
398 
400  shm_toc_estimate_keys(&pcxt->estimator, 1);
401 }
Size pstate_len
Definition: execnodes.h:1094
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:622

◆ ExecAppendInitializeDSM()

void ExecAppendInitializeDSM ( AppendState node,
ParallelContext pcxt 
)

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

413 {
414  ParallelAppendState *pstate;
415 
416  pstate = shm_toc_allocate(pcxt->toc, node->pstate_len);
417  memset(pstate, 0, node->pstate_len);
419  shm_toc_insert(pcxt->toc, node->ps.plan->plan_node_id, pstate);
420 
421  node->as_pstate = pstate;
423 }
Size pstate_len
Definition: execnodes.h:1094
int plan_node_id
Definition: plannodes.h:145
PlanState ps
Definition: execnodes.h:1087
ParallelAppendState * as_pstate
Definition: execnodes.h:1093
bool(* choose_next_subplan)(AppendState *)
Definition: execnodes.h:1097
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition: lwlock.c:677
Plan * plan
Definition: execnodes.h:912
static bool choose_next_subplan_for_leader(AppendState *node)
Definition: nodeAppend.c:511
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 448 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().

449 {
450  node->as_pstate = shm_toc_lookup(pwcxt->toc, node->ps.plan->plan_node_id, false);
452 }
int plan_node_id
Definition: plannodes.h:145
PlanState ps
Definition: execnodes.h:1087
ParallelAppendState * as_pstate
Definition: execnodes.h:1093
bool(* choose_next_subplan)(AppendState *)
Definition: execnodes.h:1097
static bool choose_next_subplan_for_worker(AppendState *node)
Definition: nodeAppend.c:592
Plan * plan
Definition: execnodes.h:912
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 432 of file nodeAppend.c.

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

Referenced by ExecParallelReInitializeDSM().

433 {
434  ParallelAppendState *pstate = node->as_pstate;
435 
436  pstate->pa_next_plan = 0;
437  memset(pstate->pa_finished, 0, sizeof(bool) * node->as_nplans);
438 }
ParallelAppendState * as_pstate
Definition: execnodes.h:1093
bool pa_finished[FLEXIBLE_ARRAY_MEMBER]
Definition: nodeAppend.c:77

◆ ExecEndAppend()

void ExecEndAppend ( AppendState node)

Definition at line 319 of file nodeAppend.c.

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

Referenced by ExecEndNode().

320 {
321  PlanState **appendplans;
322  int nplans;
323  int i;
324 
325  /*
326  * get information from the node
327  */
328  appendplans = node->appendplans;
329  nplans = node->as_nplans;
330 
331  /*
332  * shut down each of the subscans
333  */
334  for (i = 0; i < nplans; i++)
335  ExecEndNode(appendplans[i]);
336 }
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:538
PlanState ** appendplans
Definition: execnodes.h:1088
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_is_member(), bms_make_singleton(), bms_num_members(), AppendState::choose_next_subplan, choose_next_subplan_locally(), EXEC_FLAG_MARK, ExecAppend(), ExecAssignExprContext(), ExecFindInitialMatchingSubPlans(), ExecInitNode(), ExecInitResultTupleSlotTL(), ExecLockNonLeafAppendTables(), PartitionPruneState::execparams, PlanState::ExecProcNode, ExecSetupPartitionPruneState(), PartitionPruneState::extparams, Append::first_partial_plan, i, INVALID_SUBPLAN_INDEX, lfirst, list_length(), makeNode, NIL, NO_MATCHING_SUBPLANS, palloc(), Append::part_prune_infos, Append::partitioned_rels, PlanState::plan, AppendState::ps, PlanState::ps_ProjInfo, and PlanState::state.

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  ListCell *lc;
111 
112  /* check for unsupported flags */
113  Assert(!(eflags & EXEC_FLAG_MARK));
114 
115  /*
116  * Lock the non-leaf tables in the partition tree controlled by this node.
117  * It's a no-op for non-partitioned parent tables.
118  */
120 
121  /*
122  * create new AppendState for our append node
123  */
124  appendstate->ps.plan = (Plan *) node;
125  appendstate->ps.state = estate;
126  appendstate->ps.ExecProcNode = ExecAppend;
127 
128  /* Let choose_next_subplan_* function handle setting the first subplan */
129  appendstate->as_whichplan = INVALID_SUBPLAN_INDEX;
130 
131  /* If run-time partition pruning is enabled, then set that up now */
132  if (node->part_prune_infos != NIL)
133  {
134  PartitionPruneState *prunestate;
135 
136  ExecAssignExprContext(estate, &appendstate->ps);
137 
138  prunestate = ExecSetupPartitionPruneState(&appendstate->ps,
139  node->part_prune_infos);
140 
141  /*
142  * When there are external params matching the partition key we may be
143  * able to prune away Append subplans now.
144  */
145  if (!bms_is_empty(prunestate->extparams))
146  {
147  /* Determine which subplans match the external params */
148  validsubplans = ExecFindInitialMatchingSubPlans(prunestate,
149  list_length(node->appendplans));
150 
151  /*
152  * If no subplans match the given parameters then we must handle
153  * this case in a special way. The problem here is that code in
154  * explain.c requires an Append to have at least one subplan in
155  * order for it to properly determine the Vars in that subplan's
156  * targetlist. We sidestep this issue by just initializing the
157  * first subplan and setting as_whichplan to NO_MATCHING_SUBPLANS
158  * to indicate that we don't need to scan any subnodes.
159  */
160  if (bms_is_empty(validsubplans))
161  {
162  appendstate->as_whichplan = NO_MATCHING_SUBPLANS;
163 
164  /* Mark the first as valid so that it's initialized below */
165  validsubplans = bms_make_singleton(0);
166  }
167 
168  nplans = bms_num_members(validsubplans);
169  }
170  else
171  {
172  /* We'll need to initialize all subplans */
173  nplans = list_length(node->appendplans);
174  validsubplans = bms_add_range(NULL, 0, nplans - 1);
175  }
176 
177  /*
178  * If there's no exec params then no further pruning can be done, we
179  * can just set the valid subplans to all remaining subplans.
180  */
181  if (bms_is_empty(prunestate->execparams))
182  appendstate->as_valid_subplans = bms_add_range(NULL, 0, nplans - 1);
183 
184  appendstate->as_prune_state = prunestate;
185 
186  }
187  else
188  {
189  nplans = list_length(node->appendplans);
190 
191  /*
192  * When run-time partition pruning is not enabled we can just mark all
193  * subplans as valid, they must also all be initialized.
194  */
195  appendstate->as_valid_subplans = validsubplans =
196  bms_add_range(NULL, 0, nplans - 1);
197  appendstate->as_prune_state = NULL;
198  }
199 
200  /*
201  * Initialize result tuple type and slot.
202  */
203  ExecInitResultTupleSlotTL(estate, &appendstate->ps);
204 
205  appendplanstates = (PlanState **) palloc(nplans *
206  sizeof(PlanState *));
207 
208  /*
209  * call ExecInitNode on each of the valid plans to be executed and save
210  * the results into the appendplanstates array.
211  *
212  * While at it, find out the first valid partial plan.
213  */
214  j = i = 0;
215  firstvalid = nplans;
216  foreach(lc, node->appendplans)
217  {
218  if (bms_is_member(i, validsubplans))
219  {
220  Plan *initNode = (Plan *) lfirst(lc);
221 
222  /*
223  * Record the lowest appendplans index which is a valid partial
224  * plan.
225  */
226  if (i >= node->first_partial_plan && j < firstvalid)
227  firstvalid = j;
228 
229  appendplanstates[j++] = ExecInitNode(initNode, estate, eflags);
230  }
231  i++;
232  }
233 
234  appendstate->as_first_partial_plan = firstvalid;
235  appendstate->appendplans = appendplanstates;
236  appendstate->as_nplans = nplans;
237 
238  /*
239  * Miscellaneous initialization
240  */
241 
242  appendstate->ps.ps_ProjInfo = NULL;
243 
244  /* For parallel query, this will be overridden later. */
246 
247  return appendstate;
248 }
#define NIL
Definition: pg_list.h:69
void ExecLockNonLeafAppendTables(List *partitioned_rels, EState *estate)
Definition: execUtils.c:866
static TupleTableSlot * ExecAppend(PlanState *pstate)
Definition: nodeAppend.c:257
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:948
#define NO_MATCHING_SUBPLANS
Definition: nodeAppend.c:81
struct PartitionPruneState * as_prune_state
Definition: execnodes.h:1095
static bool choose_next_subplan_locally(AppendState *node)
Definition: nodeAppend.c:462
EState * state
Definition: execnodes.h:914
PlanState ps
Definition: execnodes.h:1087
List * appendplans
Definition: plannodes.h:253
Bitmapset * bms_add_range(Bitmapset *a, int lower, int upper)
Definition: bitmapset.c:862
int first_partial_plan
Definition: plannodes.h:259
bool(* choose_next_subplan)(AppendState *)
Definition: execnodes.h:1097
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:671
Bitmapset * bms_make_singleton(int x)
Definition: bitmapset.c:245
int as_first_partial_plan
Definition: execnodes.h:1091
List * partitioned_rels
Definition: plannodes.h:252
#define INVALID_SUBPLAN_INDEX
Definition: nodeAppend.c:80
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:729
List * part_prune_infos
Definition: plannodes.h:264
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:918
Bitmapset * execparams
Bitmapset * as_valid_subplans
Definition: execnodes.h:1096
void ExecInitResultTupleSlotTL(EState *estate, PlanState *planstate)
Definition: execTuples.c:890
Plan * plan
Definition: execnodes.h:912
#define makeNode(_type_)
Definition: nodes.h:565
#define Assert(condition)
Definition: c.h:699
#define lfirst(lc)
Definition: pg_list.h:106
#define EXEC_FLAG_MARK
Definition: executor.h:61
int as_whichplan
Definition: execnodes.h:1090
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:428
static int list_length(const List *l)
Definition: pg_list.h:89
Bitmapset * ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubnodes)
Bitmapset * extparams
void * palloc(Size size)
Definition: mcxt.c:924
PlanState ** appendplans
Definition: execnodes.h:1088
int i
PartitionPruneState * ExecSetupPartitionPruneState(PlanState *planstate, List *partitionpruneinfo)
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:139
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:486

◆ ExecReScanAppend()

void ExecReScanAppend ( AppendState node)

Definition at line 339 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::execparams, ExecReScan(), i, INVALID_SUBPLAN_INDEX, AppendState::ps, and UpdateChangedParamSet().

Referenced by ExecReScan().

340 {
341  int i;
342 
343  /*
344  * If any of the parameters being used for partition pruning have changed,
345  * then we'd better unset the valid subplans so that they are reselected
346  * for the new parameter values.
347  */
348  if (node->as_prune_state &&
349  bms_overlap(node->ps.chgParam,
350  node->as_prune_state->execparams))
351  {
353  node->as_valid_subplans = NULL;
354  }
355 
356  for (i = 0; i < node->as_nplans; i++)
357  {
358  PlanState *subnode = node->appendplans[i];
359 
360  /*
361  * ExecReScan doesn't know about my subplans, so I have to do
362  * changed-parameter signaling myself.
363  */
364  if (node->ps.chgParam != NULL)
365  UpdateChangedParamSet(subnode, node->ps.chgParam);
366 
367  /*
368  * If chgParam of subnode is not null then plan will be re-scanned by
369  * first ExecProcNode.
370  */
371  if (subnode->chgParam == NULL)
372  ExecReScan(subnode);
373  }
374 
375  /* Let choose_next_subplan_* function handle setting the first subplan */
377 }
struct PartitionPruneState * as_prune_state
Definition: execnodes.h:1095
void ExecReScan(PlanState *node)
Definition: execAmi.c:76
PlanState ps
Definition: execnodes.h:1087
Bitmapset * chgParam
Definition: execnodes.h:941
#define INVALID_SUBPLAN_INDEX
Definition: nodeAppend.c:80
Bitmapset * execparams
Bitmapset * as_valid_subplans
Definition: execnodes.h:1096
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:711
void bms_free(Bitmapset *a)
Definition: bitmapset.c:267
int as_whichplan
Definition: execnodes.h:1090
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:509
PlanState ** appendplans
Definition: execnodes.h:1088
int i