PostgreSQL Source Code git master
Loading...
Searching...
No Matches
nodeMergeAppend.c File Reference
#include "postgres.h"
#include "executor/executor.h"
#include "executor/execPartition.h"
#include "executor/nodeMergeAppend.h"
#include "lib/binaryheap.h"
#include "miscadmin.h"
#include "utils/sortsupport.h"
Include dependency graph for nodeMergeAppend.c:

Go to the source code of this file.

Typedefs

typedef int32 SlotNumber
 

Functions

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

Typedef Documentation

◆ SlotNumber

Definition at line 54 of file nodeMergeAppend.c.

Function Documentation

◆ ExecEndMergeAppend()

void ExecEndMergeAppend ( MergeAppendState node)

Definition at line 337 of file nodeMergeAppend.c.

338{
339 PlanState **mergeplans;
340 int nplans;
341 int i;
342
343 /*
344 * get information from the node
345 */
346 mergeplans = node->mergeplans;
347 nplans = node->ms_nplans;
348
349 /*
350 * shut down each of the subscans
351 */
352 for (i = 0; i < nplans; i++)
353 ExecEndNode(mergeplans[i]);
354}
void ExecEndNode(PlanState *node)
int i
Definition isn.c:77
PlanState ** mergeplans
Definition execnodes.h:1579

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

Referenced by ExecEndNode().

◆ ExecInitMergeAppend()

MergeAppendState * ExecInitMergeAppend ( MergeAppend node,
EState estate,
int  eflags 
)

Definition at line 67 of file nodeMergeAppend.c.

68{
73 int nplans;
74 int i,
75 j;
76
77 /* check for unsupported flags */
79
80 /*
81 * create new MergeAppendState for our node
82 */
83 mergestate->ps.plan = (Plan *) node;
84 mergestate->ps.state = estate;
85 mergestate->ps.ExecProcNode = ExecMergeAppend;
86
87 /* If run-time partition pruning is enabled, then set that up now */
88 if (node->part_prune_index >= 0)
89 {
91
92 /*
93 * Set up pruning data structure. This also initializes the set of
94 * subplans to initialize (validsubplans) by taking into account the
95 * result of performing initial pruning if any.
96 */
99 node->part_prune_index,
100 node->apprelids,
102 mergestate->ms_prune_state = prunestate;
104
105 /*
106 * When no run-time pruning is required and there's at least one
107 * subplan, we can fill ms_valid_subplans immediately, preventing
108 * later calls to ExecFindMatchingSubPlans.
109 */
110 if (!prunestate->do_exec_prune && nplans > 0)
111 mergestate->ms_valid_subplans = bms_add_range(NULL, 0, nplans - 1);
112 }
113 else
114 {
115 nplans = list_length(node->mergeplans);
116
117 /*
118 * When run-time partition pruning is not enabled we can just mark all
119 * subplans as valid; they must also all be initialized.
120 */
121 Assert(nplans > 0);
122 mergestate->ms_valid_subplans = validsubplans =
123 bms_add_range(NULL, 0, nplans - 1);
124 mergestate->ms_prune_state = NULL;
125 }
126
128 mergestate->mergeplans = mergeplanstates;
129 mergestate->ms_nplans = nplans;
130
131 mergestate->ms_slots = palloc0_array(TupleTableSlot *, nplans);
133 mergestate);
134
135 /*
136 * call ExecInitNode on each of the valid plans to be executed and save
137 * the results into the mergeplanstates array.
138 */
139 j = 0;
140 i = -1;
141 while ((i = bms_next_member(validsubplans, i)) >= 0)
142 {
143 Plan *initNode = (Plan *) list_nth(node->mergeplans, i);
144
145 mergeplanstates[j++] = ExecInitNode(initNode, estate, eflags);
146 }
147
148 /*
149 * Initialize MergeAppend's result tuple type and slot. If the child
150 * plans all produce the same fixed slot type, we can use that slot type;
151 * otherwise make a virtual slot. (Note that the result slot itself is
152 * used only to return a null tuple at end of execution; real tuples are
153 * returned to the caller in the children's own result slots. What we are
154 * doing here is allowing the parent plan node to optimize if the
155 * MergeAppend will return only one kind of slot.)
156 */
158 if (mergeops != NULL)
159 {
161 }
162 else
163 {
165 /* show that the output slot type is not fixed */
166 mergestate->ps.resultopsset = true;
167 mergestate->ps.resultopsfixed = false;
168 }
169
170 /*
171 * Miscellaneous initialization
172 */
173 mergestate->ps.ps_ProjInfo = NULL;
174
175 /*
176 * initialize sort-key information
177 */
178 mergestate->ms_nkeys = node->numCols;
179 mergestate->ms_sortkeys = palloc0_array(SortSupportData, node->numCols);
180
181 for (i = 0; i < node->numCols; i++)
182 {
183 SortSupport sortKey = mergestate->ms_sortkeys + i;
184
186 sortKey->ssup_collation = node->collations[i];
187 sortKey->ssup_nulls_first = node->nullsFirst[i];
188 sortKey->ssup_attno = node->sortColIdx[i];
189
190 /*
191 * It isn't feasible to perform abbreviated key conversion, since
192 * tuples are pulled into mergestate's binary heap as needed. It
193 * would likely be counter-productive to convert tuples into an
194 * abbreviated representation as they're pulled up, so opt out of that
195 * additional optimization entirely.
196 */
197 sortKey->abbreviate = false;
198
199 PrepareSortSupportFromOrderingOp(node->sortOperators[i], sortKey);
200 }
201
202 /*
203 * initialize to show we have not run the subplans yet
204 */
205 mergestate->ms_initialized = false;
206
207 return mergestate;
208}
binaryheap * binaryheap_allocate(int capacity, binaryheap_comparator compare, void *arg)
Definition binaryheap.c:37
int bms_next_member(const Bitmapset *a, int prevbit)
Definition bitmapset.c:1290
Bitmapset * bms_add_range(Bitmapset *a, int lower, int upper)
Definition bitmapset.c:1003
int bms_num_members(const Bitmapset *a)
Definition bitmapset.c:744
#define Assert(condition)
Definition c.h:943
PartitionPruneState * ExecInitPartitionExecPruning(PlanState *planstate, int n_total_subplans, int part_prune_index, Bitmapset *relids, Bitmapset **initially_valid_subplans)
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
const TupleTableSlotOps TTSOpsVirtual
Definition execTuples.c:84
void ExecInitResultTupleSlotTL(PlanState *planstate, const TupleTableSlotOps *tts_ops)
const TupleTableSlotOps * ExecGetCommonSlotOps(PlanState **planstates, int nplans)
Definition execUtils.c:541
#define EXEC_FLAG_BACKWARD
Definition executor.h:70
#define EXEC_FLAG_MARK
Definition executor.h:71
#define palloc_array(type, count)
Definition fe_memutils.h:91
#define palloc0_array(type, count)
Definition fe_memutils.h:92
int j
Definition isn.c:78
MemoryContext CurrentMemoryContext
Definition mcxt.c:161
static int heap_compare_slots(Datum a, Datum b, void *arg)
static TupleTableSlot * ExecMergeAppend(PlanState *pstate)
#define makeNode(_type_)
Definition nodes.h:161
static int list_length(const List *l)
Definition pg_list.h:152
static void * list_nth(const List *list, int n)
Definition pg_list.h:331
static int fb(int x)
void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
int part_prune_index
Definition plannodes.h:468
Bitmapset * apprelids
Definition plannodes.h:438
List * mergeplans
Definition plannodes.h:444
MemoryContext ssup_cxt
Definition sortsupport.h:66

References MergeAppend::apprelids, Assert, binaryheap_allocate(), bms_add_range(), bms_next_member(), bms_num_members(), CurrentMemoryContext, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, ExecGetCommonSlotOps(), ExecInitNode(), ExecInitPartitionExecPruning(), ExecInitResultTupleSlotTL(), ExecMergeAppend(), fb(), heap_compare_slots(), i, j, list_length(), list_nth(), makeNode, MergeAppend::mergeplans, MergeAppend::numCols, palloc0_array, palloc_array, MergeAppend::part_prune_index, PrepareSortSupportFromOrderingOp(), SortSupportData::ssup_cxt, and TTSOpsVirtual.

Referenced by ExecInitNode().

◆ ExecMergeAppend()

static TupleTableSlot * ExecMergeAppend ( PlanState pstate)
static

Definition at line 217 of file nodeMergeAppend.c.

218{
222
224
225 if (!node->ms_initialized)
226 {
227 /* Nothing to do if all subplans were pruned */
228 if (node->ms_nplans == 0)
230
231 /*
232 * If we've yet to determine the valid subplans then do so now. If
233 * run-time pruning is disabled then the valid subplans will always be
234 * set to all subplans.
235 */
236 if (node->ms_valid_subplans == NULL)
237 node->ms_valid_subplans =
239
240 /*
241 * First time through: pull the first tuple from each valid subplan,
242 * and set up the heap.
243 */
244 i = -1;
245 while ((i = bms_next_member(node->ms_valid_subplans, i)) >= 0)
246 {
247 node->ms_slots[i] = ExecProcNode(node->mergeplans[i]);
248 if (!TupIsNull(node->ms_slots[i]))
250 }
252 node->ms_initialized = true;
253 }
254 else
255 {
256 /*
257 * Otherwise, pull the next tuple from whichever subplan we returned
258 * from last time, and reinsert the subplan index into the heap,
259 * because it might now compare differently against the existing
260 * elements of the heap. (We could perhaps simplify the logic a bit
261 * by doing this before returning from the prior call, but it's better
262 * to not pull tuples until necessary.)
263 */
265 node->ms_slots[i] = ExecProcNode(node->mergeplans[i]);
266 if (!TupIsNull(node->ms_slots[i]))
268 else
269 (void) binaryheap_remove_first(node->ms_heap);
270 }
271
272 if (binaryheap_empty(node->ms_heap))
273 {
274 /* All the subplans are exhausted, and so is the heap */
276 }
277 else
278 {
280 result = node->ms_slots[i];
281 }
282
283 return result;
284}
void binaryheap_build(binaryheap *heap)
Definition binaryheap.c:136
void binaryheap_replace_first(binaryheap *heap, bh_node_type d)
Definition binaryheap.c:253
bh_node_type binaryheap_first(binaryheap *heap)
Definition binaryheap.c:175
bh_node_type binaryheap_remove_first(binaryheap *heap)
Definition binaryheap.c:190
void binaryheap_add_unordered(binaryheap *heap, bh_node_type d)
Definition binaryheap.c:114
#define binaryheap_empty(h)
Definition binaryheap.h:65
uint32 result
Bitmapset * ExecFindMatchingSubPlans(PartitionPruneState *prunestate, bool initial_prune, Bitmapset **validsubplan_rtis)
static TupleTableSlot * ExecProcNode(PlanState *node)
Definition executor.h:322
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:125
int32 SlotNumber
#define castNode(_type_, nodeptr)
Definition nodes.h:182
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
static int32 DatumGetInt32(Datum X)
Definition postgres.h:202
Bitmapset * ms_valid_subplans
Definition execnodes.h:1587
struct binaryheap * ms_heap
Definition execnodes.h:1584
TupleTableSlot ** ms_slots
Definition execnodes.h:1583
struct PartitionPruneState * ms_prune_state
Definition execnodes.h:1586
TupleTableSlot * ps_ResultTupleSlot
Definition execnodes.h:1241
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition tuptable.h:476
#define TupIsNull(slot)
Definition tuptable.h:325

References binaryheap_add_unordered(), binaryheap_build(), binaryheap_empty, binaryheap_first(), binaryheap_remove_first(), binaryheap_replace_first(), bms_next_member(), castNode, CHECK_FOR_INTERRUPTS, DatumGetInt32(), ExecClearTuple(), ExecFindMatchingSubPlans(), ExecProcNode(), fb(), i, Int32GetDatum(), MergeAppendState::mergeplans, MergeAppendState::ms_heap, MergeAppendState::ms_initialized, MergeAppendState::ms_nplans, MergeAppendState::ms_prune_state, MergeAppendState::ms_slots, MergeAppendState::ms_valid_subplans, MergeAppendState::ps, PlanState::ps_ResultTupleSlot, result, and TupIsNull.

Referenced by ExecInitMergeAppend().

◆ ExecReScanMergeAppend()

void ExecReScanMergeAppend ( MergeAppendState node)

Definition at line 357 of file nodeMergeAppend.c.

358{
359 int i;
360
361 /*
362 * If any PARAM_EXEC Params used in pruning expressions have changed, then
363 * we'd better unset the valid subplans so that they are reselected for
364 * the new parameter values.
365 */
366 if (node->ms_prune_state &&
367 bms_overlap(node->ps.chgParam,
369 {
371 node->ms_valid_subplans = NULL;
372 }
373
374 for (i = 0; i < node->ms_nplans; i++)
375 {
376 PlanState *subnode = node->mergeplans[i];
377
378 /*
379 * ExecReScan doesn't know about my subplans, so I have to do
380 * changed-parameter signaling myself.
381 */
382 if (node->ps.chgParam != NULL)
384
385 /*
386 * If chgParam of subnode is not null then plan will be re-scanned by
387 * first ExecProcNode.
388 */
389 if (subnode->chgParam == NULL)
391 }
393 node->ms_initialized = false;
394}
void binaryheap_reset(binaryheap *heap)
Definition binaryheap.c:61
void bms_free(Bitmapset *a)
Definition bitmapset.c:239
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:575
void ExecReScan(PlanState *node)
Definition execAmi.c:78
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition execUtils.c:936
Bitmapset * execparamids
Bitmapset * chgParam
Definition execnodes.h:1235

References binaryheap_reset(), bms_free(), bms_overlap(), PlanState::chgParam, PartitionPruneState::execparamids, ExecReScan(), fb(), i, MergeAppendState::mergeplans, MergeAppendState::ms_heap, MergeAppendState::ms_initialized, MergeAppendState::ms_nplans, MergeAppendState::ms_prune_state, MergeAppendState::ms_valid_subplans, MergeAppendState::ps, and UpdateChangedParamSet().

Referenced by ExecReScan().

◆ heap_compare_slots()

static int32 heap_compare_slots ( Datum  a,
Datum  b,
void arg 
)
static

Definition at line 290 of file nodeMergeAppend.c.

291{
295
298 int nkey;
299
302
303 for (nkey = 0; nkey < node->ms_nkeys; nkey++)
304 {
307 Datum datum1,
308 datum2;
309 bool isNull1,
310 isNull2;
311 int compare;
312
313 datum1 = slot_getattr(s1, attno, &isNull1);
314 datum2 = slot_getattr(s2, attno, &isNull2);
315
318 sortKey);
319 if (compare != 0)
320 {
322 return compare;
323 }
324 }
325 return 0;
326}
int16 AttrNumber
Definition attnum.h:21
#define INVERT_COMPARE_RESULT(var)
Definition c.h:1193
Datum arg
Definition elog.c:1323
static int compare(const void *arg1, const void *arg2)
Definition geqo_pool.c:145
int b
Definition isn.c:74
int a
Definition isn.c:73
uint64_t Datum
Definition postgres.h:70
char * s1
char * s2
static int ApplySortComparator(Datum datum1, bool isNull1, Datum datum2, bool isNull2, SortSupport ssup)
SortSupport ms_sortkeys
Definition execnodes.h:1582
AttrNumber ssup_attno
Definition sortsupport.h:81
static Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
Definition tuptable.h:417

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

Referenced by ExecInitMergeAppend().