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

Go to the source code of this file.

Functions

GatherMergeStateExecInitGatherMerge (GatherMerge *node, EState *estate, int eflags)
 
void ExecEndGatherMerge (GatherMergeState *node)
 
void ExecReScanGatherMerge (GatherMergeState *node)
 
void ExecShutdownGatherMerge (GatherMergeState *node)
 

Function Documentation

◆ ExecEndGatherMerge()

void ExecEndGatherMerge ( GatherMergeState node)

Definition at line 291 of file nodeGatherMerge.c.

292 {
293  ExecEndNode(outerPlanState(node)); /* let children clean up first */
295 }
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:562
#define outerPlanState(node)
Definition: execnodes.h:1223
void ExecShutdownGatherMerge(GatherMergeState *node)

References ExecEndNode(), ExecShutdownGatherMerge(), and outerPlanState.

Referenced by ExecEndNode().

◆ ExecInitGatherMerge()

GatherMergeState* ExecInitGatherMerge ( GatherMerge node,
EState estate,
int  eflags 
)

Definition at line 67 of file nodeGatherMerge.c.

68 {
69  GatherMergeState *gm_state;
70  Plan *outerNode;
71  TupleDesc tupDesc;
72 
73  /* Gather merge node doesn't have innerPlan node. */
74  Assert(innerPlan(node) == NULL);
75 
76  /*
77  * create state structure
78  */
79  gm_state = makeNode(GatherMergeState);
80  gm_state->ps.plan = (Plan *) node;
81  gm_state->ps.state = estate;
82  gm_state->ps.ExecProcNode = ExecGatherMerge;
83 
84  gm_state->initialized = false;
85  gm_state->gm_initialized = false;
86  gm_state->tuples_needed = -1;
87 
88  /*
89  * Miscellaneous initialization
90  *
91  * create expression context for node
92  */
93  ExecAssignExprContext(estate, &gm_state->ps);
94 
95  /*
96  * GatherMerge doesn't support checking a qual (it's always more efficient
97  * to do it in the child node).
98  */
99  Assert(!node->plan.qual);
100 
101  /*
102  * now initialize outer plan
103  */
104  outerNode = outerPlan(node);
105  outerPlanState(gm_state) = ExecInitNode(outerNode, estate, eflags);
106 
107  /*
108  * Leader may access ExecProcNode result directly (if
109  * need_to_scan_locally), or from workers via tuple queue. So we can't
110  * trivially rely on the slot type being fixed for expressions evaluated
111  * within this node.
112  */
113  gm_state->ps.outeropsset = true;
114  gm_state->ps.outeropsfixed = false;
115 
116  /*
117  * Store the tuple descriptor into gather merge state, so we can use it
118  * while initializing the gather merge slots.
119  */
120  tupDesc = ExecGetResultType(outerPlanState(gm_state));
121  gm_state->tupDesc = tupDesc;
122 
123  /*
124  * Initialize result type and projection.
125  */
126  ExecInitResultTypeTL(&gm_state->ps);
127  ExecConditionalAssignProjectionInfo(&gm_state->ps, tupDesc, OUTER_VAR);
128 
129  /*
130  * Without projections result slot type is not trivially known, see
131  * comment above.
132  */
133  if (gm_state->ps.ps_ProjInfo == NULL)
134  {
135  gm_state->ps.resultopsset = true;
136  gm_state->ps.resultopsfixed = false;
137  }
138 
139  /*
140  * initialize sort-key information
141  */
142  if (node->numCols)
143  {
144  int i;
145 
146  gm_state->gm_nkeys = node->numCols;
147  gm_state->gm_sortkeys =
148  palloc0(sizeof(SortSupportData) * node->numCols);
149 
150  for (i = 0; i < node->numCols; i++)
151  {
152  SortSupport sortKey = gm_state->gm_sortkeys + i;
153 
154  sortKey->ssup_cxt = CurrentMemoryContext;
155  sortKey->ssup_collation = node->collations[i];
156  sortKey->ssup_nulls_first = node->nullsFirst[i];
157  sortKey->ssup_attno = node->sortColIdx[i];
158 
159  /*
160  * We don't perform abbreviated key conversion here, for the same
161  * reasons that it isn't used in MergeAppend
162  */
163  sortKey->abbreviate = false;
164 
165  PrepareSortSupportFromOrderingOp(node->sortOperators[i], sortKey);
166  }
167  }
168 
169  /* Now allocate the workspace for gather merge */
170  gather_merge_setup(gm_state);
171 
172  return gm_state;
173 }
#define Assert(condition)
Definition: c.h:837
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:142
void ExecInitResultTypeTL(PlanState *planstate)
Definition: execTuples.c:1842
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:495
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:485
void ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc, int varno)
Definition: execUtils.c:560
int i
Definition: isn.c:72
void * palloc0(Size size)
Definition: mcxt.c:1347
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
static void gather_merge_setup(GatherMergeState *gm_state)
static TupleTableSlot * ExecGatherMerge(PlanState *pstate)
#define makeNode(_type_)
Definition: nodes.h:155
#define innerPlan(node)
Definition: plannodes.h:182
#define outerPlan(node)
Definition: plannodes.h:183
#define OUTER_VAR
Definition: primnodes.h:237
void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
Definition: sortsupport.c:134
TupleDesc tupDesc
Definition: execnodes.h:2737
SortSupport gm_sortkeys
Definition: execnodes.h:2739
PlanState ps
Definition: execnodes.h:2731
bool outeropsset
Definition: execnodes.h:1210
bool resultopsset
Definition: execnodes.h:1212
Plan * plan
Definition: execnodes.h:1127
bool outeropsfixed
Definition: execnodes.h:1206
EState * state
Definition: execnodes.h:1129
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:1167
bool resultopsfixed
Definition: execnodes.h:1208
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:1133
List * qual
Definition: plannodes.h:154
AttrNumber ssup_attno
Definition: sortsupport.h:81
bool ssup_nulls_first
Definition: sortsupport.h:75
MemoryContext ssup_cxt
Definition: sortsupport.h:66

References SortSupportData::abbreviate, Assert, CurrentMemoryContext, ExecAssignExprContext(), ExecConditionalAssignProjectionInfo(), ExecGatherMerge(), ExecGetResultType(), ExecInitNode(), ExecInitResultTypeTL(), PlanState::ExecProcNode, gather_merge_setup(), GatherMergeState::gm_initialized, GatherMergeState::gm_nkeys, GatherMergeState::gm_sortkeys, i, GatherMergeState::initialized, innerPlan, makeNode, GatherMerge::numCols, OUTER_VAR, PlanState::outeropsfixed, PlanState::outeropsset, outerPlan, outerPlanState, palloc0(), PlanState::plan, GatherMerge::plan, PrepareSortSupportFromOrderingOp(), GatherMergeState::ps, PlanState::ps_ProjInfo, Plan::qual, PlanState::resultopsfixed, PlanState::resultopsset, SortSupportData::ssup_attno, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, SortSupportData::ssup_nulls_first, PlanState::state, GatherMergeState::tupDesc, and GatherMergeState::tuples_needed.

Referenced by ExecInitNode().

◆ ExecReScanGatherMerge()

void ExecReScanGatherMerge ( GatherMergeState node)

Definition at line 341 of file nodeGatherMerge.c.

342 {
343  GatherMerge *gm = (GatherMerge *) node->ps.plan;
345 
346  /* Make sure any existing workers are gracefully shut down */
348 
349  /* Free any unused tuples, so we don't leak memory across rescans */
351 
352  /* Mark node so that shared state will be rebuilt at next call */
353  node->initialized = false;
354  node->gm_initialized = false;
355 
356  /*
357  * Set child node's chgParam to tell it that the next scan might deliver a
358  * different set of rows within the leader process. (The overall rowset
359  * shouldn't change, but the leader process's subset might; hence nodes
360  * between here and the parallel table scan node mustn't optimize on the
361  * assumption of an unchanging rowset.)
362  */
363  if (gm->rescan_param >= 0)
364  outerPlan->chgParam = bms_add_member(outerPlan->chgParam,
365  gm->rescan_param);
366 
367  /*
368  * If chgParam of subnode is not null then plan will be re-scanned by
369  * first ExecProcNode. Note: because this does nothing if we have a
370  * rescan_param, it's currently guaranteed that parallel-aware child nodes
371  * will not see a ReScan call until after they get a ReInitializeDSM call.
372  * That ordering might not be something to rely on, though. A good rule
373  * of thumb is that ReInitializeDSM should reset only shared state, ReScan
374  * should reset only local state, and anything that depends on both of
375  * those steps being finished must wait until the first ExecProcNode call.
376  */
377  if (outerPlan->chgParam == NULL)
379 }
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:815
void ExecReScan(PlanState *node)
Definition: execAmi.c:76
static void gather_merge_clear_tuples(GatherMergeState *gm_state)
static void ExecShutdownGatherMergeWorkers(GatherMergeState *node)
int rescan_param
Definition: plannodes.h:1164

References bms_add_member(), ExecReScan(), ExecShutdownGatherMergeWorkers(), gather_merge_clear_tuples(), GatherMergeState::gm_initialized, GatherMergeState::initialized, outerPlan, outerPlanState, PlanState::plan, GatherMergeState::ps, and GatherMerge::rescan_param.

Referenced by ExecReScan().

◆ ExecShutdownGatherMerge()

void ExecShutdownGatherMerge ( GatherMergeState node)

Definition at line 304 of file nodeGatherMerge.c.

305 {
307 
308  /* Now destroy the parallel context. */
309  if (node->pei != NULL)
310  {
311  ExecParallelCleanup(node->pei);
312  node->pei = NULL;
313  }
314 }
void ExecParallelCleanup(ParallelExecutorInfo *pei)
struct ParallelExecutorInfo * pei
Definition: execnodes.h:2740

References ExecParallelCleanup(), ExecShutdownGatherMergeWorkers(), and GatherMergeState::pei.

Referenced by ExecEndGatherMerge(), and ExecShutdownNode_walker().