Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 11cad29

Browse files
committed
Support MergeAppend plans, to allow sorted output from append relations.
This patch eliminates the former need to sort the output of an Append scan when an ordered scan of an inheritance tree is wanted. This should be particularly useful for fast-start cases such as queries with LIMIT. Original patch by Greg Stark, with further hacking by Hans-Jurgen Schonig, Robert Haas, and Tom Lane.
1 parent 30e749d commit 11cad29

26 files changed

+1316
-68
lines changed

src/backend/commands/explain.c

+50-7
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ static void show_upper_qual(List *qual, const char *qlabel,
7373
ExplainState *es);
7474
static void show_sort_keys(SortState *sortstate, List *ancestors,
7575
ExplainState *es);
76+
static void show_merge_append_keys(MergeAppendState *mstate, List *ancestors,
77+
ExplainState *es);
78+
static void show_sort_keys_common(PlanState *planstate,
79+
int nkeys, AttrNumber *keycols,
80+
List *ancestors, ExplainState *es);
7681
static void show_sort_info(SortState *sortstate, ExplainState *es);
7782
static void show_hash_info(HashState *hashstate, ExplainState *es);
7883
static const char *explain_get_index_name(Oid indexId);
@@ -647,6 +652,9 @@ ExplainNode(PlanState *planstate, List *ancestors,
647652
case T_Append:
648653
pname = sname = "Append";
649654
break;
655+
case T_MergeAppend:
656+
pname = sname = "Merge Append";
657+
break;
650658
case T_RecursiveUnion:
651659
pname = sname = "Recursive Union";
652660
break;
@@ -1074,6 +1082,10 @@ ExplainNode(PlanState *planstate, List *ancestors,
10741082
show_sort_keys((SortState *) planstate, ancestors, es);
10751083
show_sort_info((SortState *) planstate, es);
10761084
break;
1085+
case T_MergeAppend:
1086+
show_merge_append_keys((MergeAppendState *) planstate,
1087+
ancestors, es);
1088+
break;
10771089
case T_Result:
10781090
show_upper_qual((List *) ((Result *) plan)->resconstantqual,
10791091
"One-Time Filter", planstate, ancestors, es);
@@ -1170,6 +1182,7 @@ ExplainNode(PlanState *planstate, List *ancestors,
11701182
innerPlanState(planstate) ||
11711183
IsA(plan, ModifyTable) ||
11721184
IsA(plan, Append) ||
1185+
IsA(plan, MergeAppend) ||
11731186
IsA(plan, BitmapAnd) ||
11741187
IsA(plan, BitmapOr) ||
11751188
IsA(plan, SubqueryScan) ||
@@ -1208,6 +1221,11 @@ ExplainNode(PlanState *planstate, List *ancestors,
12081221
((AppendState *) planstate)->appendplans,
12091222
ancestors, es);
12101223
break;
1224+
case T_MergeAppend:
1225+
ExplainMemberNodes(((MergeAppend *) plan)->mergeplans,
1226+
((MergeAppendState *) planstate)->mergeplans,
1227+
ancestors, es);
1228+
break;
12111229
case T_BitmapAnd:
12121230
ExplainMemberNodes(((BitmapAnd *) plan)->bitmapplans,
12131231
((BitmapAndState *) planstate)->bitmapplans,
@@ -1265,7 +1283,9 @@ show_plan_tlist(PlanState *planstate, List *ancestors, ExplainState *es)
12651283
/* The tlist of an Append isn't real helpful, so suppress it */
12661284
if (IsA(plan, Append))
12671285
return;
1268-
/* Likewise for RecursiveUnion */
1286+
/* Likewise for MergeAppend and RecursiveUnion */
1287+
if (IsA(plan, MergeAppend))
1288+
return;
12691289
if (IsA(plan, RecursiveUnion))
12701290
return;
12711291

@@ -1369,8 +1389,31 @@ static void
13691389
show_sort_keys(SortState *sortstate, List *ancestors, ExplainState *es)
13701390
{
13711391
Sort *plan = (Sort *) sortstate->ss.ps.plan;
1372-
int nkeys = plan->numCols;
1373-
AttrNumber *keycols = plan->sortColIdx;
1392+
1393+
show_sort_keys_common((PlanState *) sortstate,
1394+
plan->numCols, plan->sortColIdx,
1395+
ancestors, es);
1396+
}
1397+
1398+
/*
1399+
* Likewise, for a MergeAppend node.
1400+
*/
1401+
static void
1402+
show_merge_append_keys(MergeAppendState *mstate, List *ancestors,
1403+
ExplainState *es)
1404+
{
1405+
MergeAppend *plan = (MergeAppend *) mstate->ps.plan;
1406+
1407+
show_sort_keys_common((PlanState *) mstate,
1408+
plan->numCols, plan->sortColIdx,
1409+
ancestors, es);
1410+
}
1411+
1412+
static void
1413+
show_sort_keys_common(PlanState *planstate, int nkeys, AttrNumber *keycols,
1414+
List *ancestors, ExplainState *es)
1415+
{
1416+
Plan *plan = planstate->plan;
13741417
List *context;
13751418
List *result = NIL;
13761419
bool useprefix;
@@ -1381,7 +1424,7 @@ show_sort_keys(SortState *sortstate, List *ancestors, ExplainState *es)
13811424
return;
13821425

13831426
/* Set up deparsing context */
1384-
context = deparse_context_for_planstate((Node *) sortstate,
1427+
context = deparse_context_for_planstate((Node *) planstate,
13851428
ancestors,
13861429
es->rtable);
13871430
useprefix = (list_length(es->rtable) > 1 || es->verbose);
@@ -1390,7 +1433,7 @@ show_sort_keys(SortState *sortstate, List *ancestors, ExplainState *es)
13901433
{
13911434
/* find key expression in tlist */
13921435
AttrNumber keyresno = keycols[keyno];
1393-
TargetEntry *target = get_tle_by_resno(plan->plan.targetlist,
1436+
TargetEntry *target = get_tle_by_resno(plan->targetlist,
13941437
keyresno);
13951438

13961439
if (!target)
@@ -1603,8 +1646,8 @@ ExplainScanTarget(Scan *plan, ExplainState *es)
16031646
}
16041647

16051648
/*
1606-
* Explain the constituent plans of a ModifyTable, Append, BitmapAnd,
1607-
* or BitmapOr node.
1649+
* Explain the constituent plans of a ModifyTable, Append, MergeAppend,
1650+
* BitmapAnd, or BitmapOr node.
16081651
*
16091652
* The ancestors list should already contain the immediate parent of these
16101653
* plans.

src/backend/executor/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ OBJS = execAmi.o execCurrent.o execGrouping.o execJunk.o execMain.o \
1818
nodeBitmapAnd.o nodeBitmapOr.o \
1919
nodeBitmapHeapscan.o nodeBitmapIndexscan.o nodeHash.o \
2020
nodeHashjoin.o nodeIndexscan.o nodeLimit.o nodeLockRows.o \
21-
nodeMaterial.o nodeMergejoin.o nodeModifyTable.o \
21+
nodeMaterial.o nodeMergeAppend.o nodeMergejoin.o nodeModifyTable.o \
2222
nodeNestloop.o nodeFunctionscan.o nodeRecursiveunion.o nodeResult.o \
2323
nodeSeqscan.o nodeSetOp.o nodeSort.o nodeUnique.o \
2424
nodeValuesscan.o nodeCtescan.o nodeWorktablescan.o \

src/backend/executor/execAmi.c

+5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "executor/nodeLimit.h"
3131
#include "executor/nodeLockRows.h"
3232
#include "executor/nodeMaterial.h"
33+
#include "executor/nodeMergeAppend.h"
3334
#include "executor/nodeMergejoin.h"
3435
#include "executor/nodeModifyTable.h"
3536
#include "executor/nodeNestloop.h"
@@ -129,6 +130,10 @@ ExecReScan(PlanState *node)
129130
ExecReScanAppend((AppendState *) node);
130131
break;
131132

133+
case T_MergeAppendState:
134+
ExecReScanMergeAppend((MergeAppendState *) node);
135+
break;
136+
132137
case T_RecursiveUnionState:
133138
ExecReScanRecursiveUnion((RecursiveUnionState *) node);
134139
break;

src/backend/executor/execCurrent.c

+23
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,29 @@ search_plan_tree(PlanState *node, Oid table_oid)
295295
return result;
296296
}
297297

298+
/*
299+
* Similarly for MergeAppend
300+
*/
301+
case T_MergeAppendState:
302+
{
303+
MergeAppendState *mstate = (MergeAppendState *) node;
304+
ScanState *result = NULL;
305+
int i;
306+
307+
for (i = 0; i < mstate->ms_nplans; i++)
308+
{
309+
ScanState *elem = search_plan_tree(mstate->mergeplans[i],
310+
table_oid);
311+
312+
if (!elem)
313+
continue;
314+
if (result)
315+
return NULL; /* multiple matches */
316+
result = elem;
317+
}
318+
return result;
319+
}
320+
298321
/*
299322
* Result and Limit can be descended through (these are safe
300323
* because they always return their input's current row)

src/backend/executor/execProcnode.c

+14
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
#include "executor/nodeLimit.h"
9494
#include "executor/nodeLockRows.h"
9595
#include "executor/nodeMaterial.h"
96+
#include "executor/nodeMergeAppend.h"
9697
#include "executor/nodeMergejoin.h"
9798
#include "executor/nodeModifyTable.h"
9899
#include "executor/nodeNestloop.h"
@@ -158,6 +159,11 @@ ExecInitNode(Plan *node, EState *estate, int eflags)
158159
estate, eflags);
159160
break;
160161

162+
case T_MergeAppend:
163+
result = (PlanState *) ExecInitMergeAppend((MergeAppend *) node,
164+
estate, eflags);
165+
break;
166+
161167
case T_RecursiveUnion:
162168
result = (PlanState *) ExecInitRecursiveUnion((RecursiveUnion *) node,
163169
estate, eflags);
@@ -363,6 +369,10 @@ ExecProcNode(PlanState *node)
363369
result = ExecAppend((AppendState *) node);
364370
break;
365371

372+
case T_MergeAppendState:
373+
result = ExecMergeAppend((MergeAppendState *) node);
374+
break;
375+
366376
case T_RecursiveUnionState:
367377
result = ExecRecursiveUnion((RecursiveUnionState *) node);
368378
break;
@@ -581,6 +591,10 @@ ExecEndNode(PlanState *node)
581591
ExecEndAppend((AppendState *) node);
582592
break;
583593

594+
case T_MergeAppendState:
595+
ExecEndMergeAppend((MergeAppendState *) node);
596+
break;
597+
584598
case T_RecursiveUnionState:
585599
ExecEndRecursiveUnion((RecursiveUnionState *) node);
586600
break;

0 commit comments

Comments
 (0)