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

Go to the source code of this file.

Typedefs

typedef int32 SlotNumber
 

Functions

static int heap_compare_slots (Datum a, Datum b, void *arg)
 
MergeAppendStateExecInitMergeAppend (MergeAppend *node, EState *estate, int eflags)
 
TupleTableSlotExecMergeAppend (MergeAppendState *node)
 
void ExecEndMergeAppend (MergeAppendState *node)
 
void ExecReScanMergeAppend (MergeAppendState *node)
 

Typedef Documentation

Definition at line 51 of file nodeMergeAppend.c.

Function Documentation

void ExecEndMergeAppend ( MergeAppendState node)

Definition at line 267 of file nodeMergeAppend.c.

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

Referenced by ExecEndNode().

268 {
269  PlanState **mergeplans;
270  int nplans;
271  int i;
272 
273  /*
274  * get information from the node
275  */
276  mergeplans = node->mergeplans;
277  nplans = node->ms_nplans;
278 
279  /*
280  * shut down each of the subscans
281  */
282  for (i = 0; i < nplans; i++)
283  ExecEndNode(mergeplans[i]);
284 }
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:624
PlanState ** mergeplans
Definition: execnodes.h:1209
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(), 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(), 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  * Set up empty vector of subplan states
76  */
77  nplans = list_length(node->mergeplans);
78 
79  mergeplanstates = (PlanState **) palloc0(nplans * sizeof(PlanState *));
80 
81  /*
82  * create new MergeAppendState for our node
83  */
84  mergestate->ps.plan = (Plan *) node;
85  mergestate->ps.state = estate;
86  mergestate->mergeplans = mergeplanstates;
87  mergestate->ms_nplans = nplans;
88 
89  mergestate->ms_slots = (TupleTableSlot **) palloc0(sizeof(TupleTableSlot *) * nplans);
90  mergestate->ms_heap = binaryheap_allocate(nplans, heap_compare_slots,
91  mergestate);
92 
93  /*
94  * Miscellaneous initialization
95  *
96  * MergeAppend plans don't have expression contexts because they never
97  * call ExecQual or ExecProject.
98  */
99 
100  /*
101  * MergeAppend nodes do have Result slots, which hold pointers to tuples,
102  * so we have to initialize them.
103  */
104  ExecInitResultTupleSlot(estate, &mergestate->ps);
105 
106  /*
107  * call ExecInitNode on each of the plans to be executed and save the
108  * results into the array "mergeplans".
109  */
110  i = 0;
111  foreach(lc, node->mergeplans)
112  {
113  Plan *initNode = (Plan *) lfirst(lc);
114 
115  mergeplanstates[i] = ExecInitNode(initNode, estate, eflags);
116  i++;
117  }
118 
119  /*
120  * initialize output tuple type
121  */
122  ExecAssignResultTypeFromTL(&mergestate->ps);
123  mergestate->ps.ps_ProjInfo = NULL;
124 
125  /*
126  * initialize sort-key information
127  */
128  mergestate->ms_nkeys = node->numCols;
129  mergestate->ms_sortkeys = palloc0(sizeof(SortSupportData) * node->numCols);
130 
131  for (i = 0; i < node->numCols; i++)
132  {
133  SortSupport sortKey = mergestate->ms_sortkeys + i;
134 
135  sortKey->ssup_cxt = CurrentMemoryContext;
136  sortKey->ssup_collation = node->collations[i];
137  sortKey->ssup_nulls_first = node->nullsFirst[i];
138  sortKey->ssup_attno = node->sortColIdx[i];
139 
140  /*
141  * It isn't feasible to perform abbreviated key conversion, since
142  * tuples are pulled into mergestate's binary heap as needed. It
143  * would likely be counter-productive to convert tuples into an
144  * abbreviated representation as they're pulled up, so opt out of that
145  * additional optimization entirely.
146  */
147  sortKey->abbreviate = false;
148 
150  }
151 
152  /*
153  * initialize to show we have not run the subplans yet
154  */
155  mergestate->ms_initialized = false;
156 
157  return mergestate;
158 }
bool ssup_nulls_first
Definition: sortsupport.h:75
TupleTableSlot ** ms_slots
Definition: execnodes.h:1213
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:1078
SortSupport ms_sortkeys
Definition: execnodes.h:1212
Oid * collations
Definition: plannodes.h:246
void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
Definition: sortsupport.c:133
EState * state
Definition: execnodes.h:1048
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:429
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
PlanState ** mergeplans
Definition: execnodes.h:1209
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
void * palloc0(Size size)
Definition: mcxt.c:920
AttrNumber ssup_attno
Definition: sortsupport.h:81
Plan * plan
Definition: execnodes.h:1046
PlanState ps
Definition: execnodes.h:1208
struct binaryheap * ms_heap
Definition: execnodes.h:1214
#define makeNode(_type_)
Definition: nodes.h:556
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
#define lfirst(lc)
Definition: pg_list.h:106
#define EXEC_FLAG_MARK
Definition: executor.h:61
AttrNumber * sortColIdx
Definition: plannodes.h:244
static int list_length(const List *l)
Definition: pg_list.h:89
bool * nullsFirst
Definition: plannodes.h:247
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:241
int i
Oid * sortOperators
Definition: plannodes.h:245
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:137
TupleTableSlot* ExecMergeAppend ( MergeAppendState node)

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

168 {
169  TupleTableSlot *result;
170  SlotNumber i;
171 
172  if (!node->ms_initialized)
173  {
174  /*
175  * First time through: pull the first tuple from each subplan, and set
176  * up the heap.
177  */
178  for (i = 0; i < node->ms_nplans; i++)
179  {
180  node->ms_slots[i] = ExecProcNode(node->mergeplans[i]);
181  if (!TupIsNull(node->ms_slots[i]))
183  }
184  binaryheap_build(node->ms_heap);
185  node->ms_initialized = true;
186  }
187  else
188  {
189  /*
190  * Otherwise, pull the next tuple from whichever subplan we returned
191  * from last time, and reinsert the subplan index into the heap,
192  * because it might now compare differently against the existing
193  * elements of the heap. (We could perhaps simplify the logic a bit
194  * by doing this before returning from the prior call, but it's better
195  * to not pull tuples until necessary.)
196  */
198  node->ms_slots[i] = ExecProcNode(node->mergeplans[i]);
199  if (!TupIsNull(node->ms_slots[i]))
201  else
202  (void) binaryheap_remove_first(node->ms_heap);
203  }
204 
205  if (binaryheap_empty(node->ms_heap))
206  {
207  /* All the subplans are exhausted, and so is the heap */
208  result = ExecClearTuple(node->ps.ps_ResultTupleSlot);
209  }
210  else
211  {
213  result = node->ms_slots[i];
214  }
215 
216  return result;
217 }
TupleTableSlot * ExecProcNode(PlanState *node)
Definition: execProcnode.c:380
TupleTableSlot ** ms_slots
Definition: execnodes.h:1213
#define binaryheap_empty(h)
Definition: binaryheap.h:52
#define DatumGetInt32(X)
Definition: postgres.h:480
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:1076
Datum binaryheap_first(binaryheap *heap)
Definition: binaryheap.c:159
PlanState ** mergeplans
Definition: execnodes.h:1209
#define TupIsNull(slot)
Definition: tuptable.h:138
PlanState ps
Definition: execnodes.h:1208
void binaryheap_build(binaryheap *heap)
Definition: binaryheap.c:126
struct binaryheap * ms_heap
Definition: execnodes.h:1214
#define Int32GetDatum(X)
Definition: postgres.h:487
int i
Datum binaryheap_remove_first(binaryheap *heap)
Definition: binaryheap.c:174
int32 SlotNumber
void ExecReScanMergeAppend ( MergeAppendState node)

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

288 {
289  int i;
290 
291  for (i = 0; i < node->ms_nplans; i++)
292  {
293  PlanState *subnode = node->mergeplans[i];
294 
295  /*
296  * ExecReScan doesn't know about my subplans, so I have to do
297  * changed-parameter signaling myself.
298  */
299  if (node->ps.chgParam != NULL)
300  UpdateChangedParamSet(subnode, node->ps.chgParam);
301 
302  /*
303  * If chgParam of subnode is not null then plan will be re-scanned by
304  * first ExecProcNode.
305  */
306  if (subnode->chgParam == NULL)
307  ExecReScan(subnode);
308  }
309  binaryheap_reset(node->ms_heap);
310  node->ms_initialized = false;
311 }
void ExecReScan(PlanState *node)
Definition: execAmi.c:73
PlanState ** mergeplans
Definition: execnodes.h:1209
void binaryheap_reset(binaryheap *heap)
Definition: binaryheap.c:57
Bitmapset * chgParam
Definition: execnodes.h:1071
PlanState ps
Definition: execnodes.h:1208
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:839
struct binaryheap * ms_heap
Definition: execnodes.h:1214
#define NULL
Definition: c.h:226
int i
static int32 heap_compare_slots ( Datum  a,
Datum  b,
void *  arg 
)
static

Definition at line 223 of file nodeMergeAppend.c.

References ApplySortComparator(), Assert, compare(), DatumGetInt32, MergeAppendState::ms_nkeys, MergeAppendState::ms_slots, MergeAppendState::ms_sortkeys, s1, s2, slot_getattr(), SortSupportData::ssup_attno, and TupIsNull.

Referenced by ExecInitMergeAppend().

224 {
226  SlotNumber slot1 = DatumGetInt32(a);
227  SlotNumber slot2 = DatumGetInt32(b);
228 
229  TupleTableSlot *s1 = node->ms_slots[slot1];
230  TupleTableSlot *s2 = node->ms_slots[slot2];
231  int nkey;
232 
233  Assert(!TupIsNull(s1));
234  Assert(!TupIsNull(s2));
235 
236  for (nkey = 0; nkey < node->ms_nkeys; nkey++)
237  {
238  SortSupport sortKey = node->ms_sortkeys + nkey;
239  AttrNumber attno = sortKey->ssup_attno;
240  Datum datum1,
241  datum2;
242  bool isNull1,
243  isNull2;
244  int compare;
245 
246  datum1 = slot_getattr(s1, attno, &isNull1);
247  datum2 = slot_getattr(s2, attno, &isNull2);
248 
249  compare = ApplySortComparator(datum1, isNull1,
250  datum2, isNull2,
251  sortKey);
252  if (compare != 0)
253  return -compare;
254  }
255  return 0;
256 }
TupleTableSlot ** ms_slots
Definition: execnodes.h:1213
SortSupport ms_sortkeys
Definition: execnodes.h:1212
#define DatumGetInt32(X)
Definition: postgres.h:480
static int compare(const void *arg1, const void *arg2)
Definition: geqo_pool.c:145
char * s1
#define TupIsNull(slot)
Definition: tuptable.h:138
char * s2
uintptr_t Datum
Definition: postgres.h:374
AttrNumber ssup_attno
Definition: sortsupport.h:81
#define Assert(condition)
Definition: c.h:670
Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
Definition: heaptuple.c:1143
void * arg
static int ApplySortComparator(Datum datum1, bool isNull1, Datum datum2, bool isNull2, SortSupport ssup)
Definition: sortsupport.h:201
int16 AttrNumber
Definition: attnum.h:21
int32 SlotNumber