PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
nodeMergeAppend.h File Reference
#include "nodes/execnodes.h"
Include dependency graph for nodeMergeAppend.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

MergeAppendStateExecInitMergeAppend (MergeAppend *node, EState *estate, int eflags)
 
TupleTableSlotExecMergeAppend (MergeAppendState *node)
 
void ExecEndMergeAppend (MergeAppendState *node)
 
void ExecReScanMergeAppend (MergeAppendState *node)
 

Function Documentation

void ExecEndMergeAppend ( MergeAppendState node)

Definition at line 273 of file nodeMergeAppend.c.

References ExecEndNode(), i, MergeAppendState::mergeplans, and MergeAppendState::ms_nplans.

Referenced by ExecEndNode().

274 {
275  PlanState **mergeplans;
276  int nplans;
277  int i;
278 
279  /*
280  * get information from the node
281  */
282  mergeplans = node->mergeplans;
283  nplans = node->ms_nplans;
284 
285  /*
286  * shut down each of the subscans
287  */
288  for (i = 0; i < nplans; i++)
289  ExecEndNode(mergeplans[i]);
290 }
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:644
PlanState ** mergeplans
Definition: execnodes.h:1212
int i
MergeAppendState* ExecInitMergeAppend ( MergeAppend node,
EState estate,
int  eflags 
)

Definition at line 63 of file nodeMergeAppend.c.

References SortSupportData::abbreviate, Assert, binaryheap_allocate(), MergeAppend::collations, CurrentMemoryContext, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, ExecAssignResultTypeFromTL(), ExecInitNode(), ExecInitResultTupleSlot(), ExecLockNonLeafAppendTables(), heap_compare_slots(), i, lfirst, list_length(), makeNode, MergeAppend::mergeplans, MergeAppendState::mergeplans, MergeAppendState::ms_heap, MergeAppendState::ms_initialized, MergeAppendState::ms_nkeys, MergeAppendState::ms_nplans, MergeAppendState::ms_slots, MergeAppendState::ms_sortkeys, NULL, MergeAppend::nullsFirst, MergeAppend::numCols, palloc0(), MergeAppend::partitioned_rels, PlanState::plan, PrepareSortSupportFromOrderingOp(), MergeAppendState::ps, PlanState::ps_ProjInfo, MergeAppend::sortColIdx, MergeAppend::sortOperators, SortSupportData::ssup_attno, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, SortSupportData::ssup_nulls_first, and PlanState::state.

Referenced by ExecInitNode().

64 {
66  PlanState **mergeplanstates;
67  int nplans;
68  int i;
69  ListCell *lc;
70 
71  /* check for unsupported flags */
72  Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
73 
74  /*
75  * Lock the non-leaf tables in the partition tree controlled by this
76  * node. It's a no-op for non-partitioned parent tables.
77  */
79 
80  /*
81  * Set up empty vector of subplan states
82  */
83  nplans = list_length(node->mergeplans);
84 
85  mergeplanstates = (PlanState **) palloc0(nplans * sizeof(PlanState *));
86 
87  /*
88  * create new MergeAppendState for our node
89  */
90  mergestate->ps.plan = (Plan *) node;
91  mergestate->ps.state = estate;
92  mergestate->mergeplans = mergeplanstates;
93  mergestate->ms_nplans = nplans;
94 
95  mergestate->ms_slots = (TupleTableSlot **) palloc0(sizeof(TupleTableSlot *) * nplans);
96  mergestate->ms_heap = binaryheap_allocate(nplans, heap_compare_slots,
97  mergestate);
98 
99  /*
100  * Miscellaneous initialization
101  *
102  * MergeAppend plans don't have expression contexts because they never
103  * call ExecQual or ExecProject.
104  */
105 
106  /*
107  * MergeAppend nodes do have Result slots, which hold pointers to tuples,
108  * so we have to initialize them.
109  */
110  ExecInitResultTupleSlot(estate, &mergestate->ps);
111 
112  /*
113  * call ExecInitNode on each of the plans to be executed and save the
114  * results into the array "mergeplans".
115  */
116  i = 0;
117  foreach(lc, node->mergeplans)
118  {
119  Plan *initNode = (Plan *) lfirst(lc);
120 
121  mergeplanstates[i] = ExecInitNode(initNode, estate, eflags);
122  i++;
123  }
124 
125  /*
126  * initialize output tuple type
127  */
128  ExecAssignResultTypeFromTL(&mergestate->ps);
129  mergestate->ps.ps_ProjInfo = NULL;
130 
131  /*
132  * initialize sort-key information
133  */
134  mergestate->ms_nkeys = node->numCols;
135  mergestate->ms_sortkeys = palloc0(sizeof(SortSupportData) * node->numCols);
136 
137  for (i = 0; i < node->numCols; i++)
138  {
139  SortSupport sortKey = mergestate->ms_sortkeys + i;
140 
141  sortKey->ssup_cxt = CurrentMemoryContext;
142  sortKey->ssup_collation = node->collations[i];
143  sortKey->ssup_nulls_first = node->nullsFirst[i];
144  sortKey->ssup_attno = node->sortColIdx[i];
145 
146  /*
147  * It isn't feasible to perform abbreviated key conversion, since
148  * tuples are pulled into mergestate's binary heap as needed. It
149  * would likely be counter-productive to convert tuples into an
150  * abbreviated representation as they're pulled up, so opt out of that
151  * additional optimization entirely.
152  */
153  sortKey->abbreviate = false;
154 
156  }
157 
158  /*
159  * initialize to show we have not run the subplans yet
160  */
161  mergestate->ms_initialized = false;
162 
163  return mergestate;
164 }
bool ssup_nulls_first
Definition: sortsupport.h:75
void ExecLockNonLeafAppendTables(List *partitioned_rels, EState *estate)
Definition: execUtils.c:966
TupleTableSlot ** ms_slots
Definition: execnodes.h:1216
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:1081
SortSupport ms_sortkeys
Definition: execnodes.h:1215
Oid * collations
Definition: plannodes.h:255
void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
Definition: sortsupport.c:133
EState * state
Definition: execnodes.h:1051
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:431
void ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
Definition: execTuples.c:832
MemoryContext ssup_cxt
Definition: sortsupport.h:66
#define EXEC_FLAG_BACKWARD
Definition: executor.h:60
List * partitioned_rels
Definition: plannodes.h:249
PlanState ** mergeplans
Definition: execnodes.h:1212
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
void * palloc0(Size size)
Definition: mcxt.c:878
AttrNumber ssup_attno
Definition: sortsupport.h:81
Plan * plan
Definition: execnodes.h:1049
PlanState ps
Definition: execnodes.h:1211
struct binaryheap * ms_heap
Definition: execnodes.h:1217
#define makeNode(_type_)
Definition: nodes.h:567
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
#define EXEC_FLAG_MARK
Definition: executor.h:61
AttrNumber * sortColIdx
Definition: plannodes.h:253
static int list_length(const List *l)
Definition: pg_list.h:89
bool * nullsFirst
Definition: plannodes.h:256
static int heap_compare_slots(Datum a, Datum b, void *arg)
binaryheap * binaryheap_allocate(int capacity, binaryheap_comparator compare, void *arg)
Definition: binaryheap.c:33
List * mergeplans
Definition: plannodes.h:250
int i
Oid * sortOperators
Definition: plannodes.h:254
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:139
TupleTableSlot* ExecMergeAppend ( MergeAppendState node)

Definition at line 173 of file nodeMergeAppend.c.

References binaryheap_add_unordered(), binaryheap_build(), binaryheap_empty, binaryheap_first(), binaryheap_remove_first(), binaryheap_replace_first(), DatumGetInt32, ExecClearTuple(), ExecProcNode(), i, Int32GetDatum, MergeAppendState::mergeplans, MergeAppendState::ms_heap, MergeAppendState::ms_initialized, MergeAppendState::ms_nplans, MergeAppendState::ms_slots, MergeAppendState::ps, PlanState::ps_ResultTupleSlot, and TupIsNull.

Referenced by ExecProcNode().

174 {
175  TupleTableSlot *result;
176  SlotNumber i;
177 
178  if (!node->ms_initialized)
179  {
180  /*
181  * First time through: pull the first tuple from each subplan, and set
182  * up the heap.
183  */
184  for (i = 0; i < node->ms_nplans; i++)
185  {
186  node->ms_slots[i] = ExecProcNode(node->mergeplans[i]);
187  if (!TupIsNull(node->ms_slots[i]))
189  }
190  binaryheap_build(node->ms_heap);
191  node->ms_initialized = true;
192  }
193  else
194  {
195  /*
196  * Otherwise, pull the next tuple from whichever subplan we returned
197  * from last time, and reinsert the subplan index into the heap,
198  * because it might now compare differently against the existing
199  * elements of the heap. (We could perhaps simplify the logic a bit
200  * by doing this before returning from the prior call, but it's better
201  * to not pull tuples until necessary.)
202  */
204  node->ms_slots[i] = ExecProcNode(node->mergeplans[i]);
205  if (!TupIsNull(node->ms_slots[i]))
207  else
208  (void) binaryheap_remove_first(node->ms_heap);
209  }
210 
211  if (binaryheap_empty(node->ms_heap))
212  {
213  /* All the subplans are exhausted, and so is the heap */
214  result = ExecClearTuple(node->ps.ps_ResultTupleSlot);
215  }
216  else
217  {
219  result = node->ms_slots[i];
220  }
221 
222  return result;
223 }
TupleTableSlot * ExecProcNode(PlanState *node)
Definition: execProcnode.c:392
TupleTableSlot ** ms_slots
Definition: execnodes.h:1216
#define binaryheap_empty(h)
Definition: binaryheap.h:52
#define DatumGetInt32(X)
Definition: postgres.h:478
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
void binaryheap_replace_first(binaryheap *heap, Datum d)
Definition: binaryheap.c:204
void binaryheap_add_unordered(binaryheap *heap, Datum d)
Definition: binaryheap.c:110
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1079
Datum binaryheap_first(binaryheap *heap)
Definition: binaryheap.c:159
PlanState ** mergeplans
Definition: execnodes.h:1212
int32 SlotNumber
#define TupIsNull(slot)
Definition: tuptable.h:138
PlanState ps
Definition: execnodes.h:1211
void binaryheap_build(binaryheap *heap)
Definition: binaryheap.c:126
struct binaryheap * ms_heap
Definition: execnodes.h:1217
#define Int32GetDatum(X)
Definition: postgres.h:485
int i
Datum binaryheap_remove_first(binaryheap *heap)
Definition: binaryheap.c:174
void ExecReScanMergeAppend ( MergeAppendState node)

Definition at line 293 of file nodeMergeAppend.c.

References binaryheap_reset(), PlanState::chgParam, ExecReScan(), i, MergeAppendState::mergeplans, MergeAppendState::ms_heap, MergeAppendState::ms_initialized, MergeAppendState::ms_nplans, NULL, MergeAppendState::ps, and UpdateChangedParamSet().

Referenced by ExecReScan().

294 {
295  int i;
296 
297  for (i = 0; i < node->ms_nplans; i++)
298  {
299  PlanState *subnode = node->mergeplans[i];
300 
301  /*
302  * ExecReScan doesn't know about my subplans, so I have to do
303  * changed-parameter signaling myself.
304  */
305  if (node->ps.chgParam != NULL)
306  UpdateChangedParamSet(subnode, node->ps.chgParam);
307 
308  /*
309  * If chgParam of subnode is not null then plan will be re-scanned by
310  * first ExecProcNode.
311  */
312  if (subnode->chgParam == NULL)
313  ExecReScan(subnode);
314  }
315  binaryheap_reset(node->ms_heap);
316  node->ms_initialized = false;
317 }
void ExecReScan(PlanState *node)
Definition: execAmi.c:74
PlanState ** mergeplans
Definition: execnodes.h:1212
void binaryheap_reset(binaryheap *heap)
Definition: binaryheap.c:57
Bitmapset * chgParam
Definition: execnodes.h:1074
PlanState ps
Definition: execnodes.h:1211
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:841
struct binaryheap * ms_heap
Definition: execnodes.h:1217
#define NULL
Definition: c.h:229
int i