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

Commit ec38694

Browse files
committed
Move PartitioPruneInfo out of plan nodes into PlannedStmt
The planner will now add a given PartitioPruneInfo to PlannedStmt.partPruneInfos instead of directly to the Append/MergeAppend plan node. What gets set instead in the latter is an index field which points to the list element of PlannedStmt.partPruneInfos containing the PartitioPruneInfo belonging to the plan node. A later commit will make AcquireExecutorLocks() do the initial partition pruning to determine a minimal set of partitions to be locked when validating a plan tree and it will need to consult the PartitioPruneInfos referenced therein to do so. It would be better for the PartitioPruneInfos to be accessible directly than requiring a walk of the plan tree to find them, which is easier when it can be done by simply iterating over PlannedStmt.partPruneInfos. Author: Amit Langote <amitlangote09@gmail.com> Discussion: https://postgr.es/m/CA+HiwqFGkMSge6TgC9KQzde0ohpAycLQuV7ooitEEpbKB0O_mg@mail.gmail.com
1 parent de867c9 commit ec38694

File tree

16 files changed

+114
-63
lines changed

16 files changed

+114
-63
lines changed

src/backend/executor/execMain.c

+1
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,7 @@ InitPlan(QueryDesc *queryDesc, int eflags)
825825
ExecInitRangeTable(estate, rangeTable);
826826

827827
estate->es_plannedstmt = plannedstmt;
828+
estate->es_part_prune_infos = plannedstmt->partPruneInfos;
828829

829830
/*
830831
* Next, build the ExecRowMark array from the PlanRowMark(s), if any.

src/backend/executor/execParallel.c

+1
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ ExecSerializePlan(Plan *plan, EState *estate)
183183
pstmt->dependsOnRole = false;
184184
pstmt->parallelModeNeeded = false;
185185
pstmt->planTree = plan;
186+
pstmt->partPruneInfos = estate->es_part_prune_infos;
186187
pstmt->rtable = estate->es_range_table;
187188
pstmt->resultRelations = NIL;
188189
pstmt->appendRelations = NIL;

src/backend/executor/execPartition.c

+17-1
Original file line numberDiff line numberDiff line change
@@ -1791,6 +1791,9 @@ adjust_partition_colnos_using_map(List *colnos, AttrMap *attrMap)
17911791
* Initialize data structure needed for run-time partition pruning and
17921792
* do initial pruning if needed
17931793
*
1794+
* 'root_parent_relids' identifies the relation to which both the parent plan
1795+
* and the PartitionPruneInfo given by 'part_prune_index' belong.
1796+
*
17941797
* On return, *initially_valid_subplans is assigned the set of indexes of
17951798
* child subplans that must be initialized along with the parent plan node.
17961799
* Initial pruning is performed here if needed and in that case only the
@@ -1803,11 +1806,24 @@ adjust_partition_colnos_using_map(List *colnos, AttrMap *attrMap)
18031806
PartitionPruneState *
18041807
ExecInitPartitionPruning(PlanState *planstate,
18051808
int n_total_subplans,
1806-
PartitionPruneInfo *pruneinfo,
1809+
int part_prune_index,
1810+
Bitmapset *root_parent_relids,
18071811
Bitmapset **initially_valid_subplans)
18081812
{
18091813
PartitionPruneState *prunestate;
18101814
EState *estate = planstate->state;
1815+
PartitionPruneInfo *pruneinfo;
1816+
1817+
/* Obtain the pruneinfo we need, and make sure it's the right one */
1818+
pruneinfo = list_nth(estate->es_part_prune_infos, part_prune_index);
1819+
if (!bms_equal(root_parent_relids, pruneinfo->root_parent_relids))
1820+
ereport(ERROR,
1821+
errcode(ERRCODE_INTERNAL_ERROR),
1822+
errmsg_internal("mismatching PartitionPruneInfo found at part_prune_index %d",
1823+
part_prune_index),
1824+
errdetail_internal("plan node relids %s, pruneinfo relids %s",
1825+
bmsToString(root_parent_relids),
1826+
bmsToString(pruneinfo->root_parent_relids)));
18111827

18121828
/* We may need an expression context to evaluate partition exprs */
18131829
ExecAssignExprContext(estate, planstate);

src/backend/executor/execUtils.c

+1
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ CreateExecutorState(void)
119119
estate->es_relations = NULL;
120120
estate->es_rowmarks = NULL;
121121
estate->es_plannedstmt = NULL;
122+
estate->es_part_prune_infos = NIL;
122123

123124
estate->es_junkFilter = NULL;
124125

src/backend/executor/nodeAppend.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ ExecInitAppend(Append *node, EState *estate, int eflags)
134134
appendstate->as_begun = false;
135135

136136
/* If run-time partition pruning is enabled, then set that up now */
137-
if (node->part_prune_info != NULL)
137+
if (node->part_prune_index >= 0)
138138
{
139139
PartitionPruneState *prunestate;
140140

@@ -145,7 +145,8 @@ ExecInitAppend(Append *node, EState *estate, int eflags)
145145
*/
146146
prunestate = ExecInitPartitionPruning(&appendstate->ps,
147147
list_length(node->appendplans),
148-
node->part_prune_info,
148+
node->part_prune_index,
149+
node->apprelids,
149150
&validsubplans);
150151
appendstate->as_prune_state = prunestate;
151152
nplans = bms_num_members(validsubplans);

src/backend/executor/nodeMergeAppend.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags)
8282
mergestate->ps.ExecProcNode = ExecMergeAppend;
8383

8484
/* If run-time partition pruning is enabled, then set that up now */
85-
if (node->part_prune_info != NULL)
85+
if (node->part_prune_index >= 0)
8686
{
8787
PartitionPruneState *prunestate;
8888

@@ -93,7 +93,8 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags)
9393
*/
9494
prunestate = ExecInitPartitionPruning(&mergestate->ps,
9595
list_length(node->mergeplans),
96-
node->part_prune_info,
96+
node->part_prune_index,
97+
node->apprelids,
9798
&validsubplans);
9899
mergestate->ms_prune_state = prunestate;
99100
nplans = bms_num_members(validsubplans);

src/backend/optimizer/plan/createplan.c

+13-11
Original file line numberDiff line numberDiff line change
@@ -1203,7 +1203,6 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags)
12031203
ListCell *subpaths;
12041204
int nasyncplans = 0;
12051205
RelOptInfo *rel = best_path->path.parent;
1206-
PartitionPruneInfo *partpruneinfo = NULL;
12071206
int nodenumsortkeys = 0;
12081207
AttrNumber *nodeSortColIdx = NULL;
12091208
Oid *nodeSortOperators = NULL;
@@ -1354,6 +1353,9 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags)
13541353
subplans = lappend(subplans, subplan);
13551354
}
13561355

1356+
/* Set below if we find quals that we can use to run-time prune */
1357+
plan->part_prune_index = -1;
1358+
13571359
/*
13581360
* If any quals exist, they may be useful to perform further partition
13591361
* pruning during execution. Gather information needed by the executor to
@@ -1377,16 +1379,14 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags)
13771379
}
13781380

13791381
if (prunequal != NIL)
1380-
partpruneinfo =
1381-
make_partition_pruneinfo(root, rel,
1382-
best_path->subpaths,
1383-
prunequal);
1382+
plan->part_prune_index = make_partition_pruneinfo(root, rel,
1383+
best_path->subpaths,
1384+
prunequal);
13841385
}
13851386

13861387
plan->appendplans = subplans;
13871388
plan->nasyncplans = nasyncplans;
13881389
plan->first_partial_plan = best_path->first_partial_path;
1389-
plan->part_prune_info = partpruneinfo;
13901390

13911391
copy_generic_path_info(&plan->plan, (Path *) best_path);
13921392

@@ -1425,7 +1425,6 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path,
14251425
List *subplans = NIL;
14261426
ListCell *subpaths;
14271427
RelOptInfo *rel = best_path->path.parent;
1428-
PartitionPruneInfo *partpruneinfo = NULL;
14291428

14301429
/*
14311430
* We don't have the actual creation of the MergeAppend node split out
@@ -1518,6 +1517,9 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path,
15181517
subplans = lappend(subplans, subplan);
15191518
}
15201519

1520+
/* Set below if we find quals that we can use to run-time prune */
1521+
node->part_prune_index = -1;
1522+
15211523
/*
15221524
* If any quals exist, they may be useful to perform further partition
15231525
* pruning during execution. Gather information needed by the executor to
@@ -1541,13 +1543,13 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path,
15411543
}
15421544

15431545
if (prunequal != NIL)
1544-
partpruneinfo = make_partition_pruneinfo(root, rel,
1545-
best_path->subpaths,
1546-
prunequal);
1546+
node->part_prune_index = make_partition_pruneinfo(root, rel,
1547+
best_path->subpaths,
1548+
prunequal);
15471549
}
15481550

15491551
node->mergeplans = subplans;
1550-
node->part_prune_info = partpruneinfo;
1552+
15511553

15521554
/*
15531555
* If prepare_sort_from_pathkeys added sort columns, but we were told to

src/backend/optimizer/plan/planner.c

+1
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
519519
result->dependsOnRole = glob->dependsOnRole;
520520
result->parallelModeNeeded = glob->parallelModeNeeded;
521521
result->planTree = top_plan;
522+
result->partPruneInfos = glob->partPruneInfos;
522523
result->rtable = glob->finalrtable;
523524
result->resultRelations = glob->resultRelations;
524525
result->appendRelations = glob->appendRelations;

src/backend/optimizer/plan/setrefs.c

+37-30
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,31 @@ set_plan_references(PlannerInfo *root, Plan *plan)
348348
}
349349
}
350350

351+
/* Also fix up the information in PartitionPruneInfos. */
352+
foreach (lc, root->partPruneInfos)
353+
{
354+
PartitionPruneInfo *pruneinfo = lfirst(lc);
355+
ListCell *l;
356+
357+
pruneinfo->root_parent_relids =
358+
offset_relid_set(pruneinfo->root_parent_relids, rtoffset);
359+
foreach(l, pruneinfo->prune_infos)
360+
{
361+
List *prune_infos = lfirst(l);
362+
ListCell *l2;
363+
364+
foreach(l2, prune_infos)
365+
{
366+
PartitionedRelPruneInfo *pinfo = lfirst(l2);
367+
368+
/* RT index of the table to which the pinfo belongs. */
369+
pinfo->rtindex += rtoffset;
370+
}
371+
}
372+
373+
glob->partPruneInfos = lappend(glob->partPruneInfos, pruneinfo);
374+
}
375+
351376
return result;
352377
}
353378

@@ -1658,21 +1683,12 @@ set_append_references(PlannerInfo *root,
16581683

16591684
aplan->apprelids = offset_relid_set(aplan->apprelids, rtoffset);
16601685

1661-
if (aplan->part_prune_info)
1662-
{
1663-
foreach(l, aplan->part_prune_info->prune_infos)
1664-
{
1665-
List *prune_infos = lfirst(l);
1666-
ListCell *l2;
1667-
1668-
foreach(l2, prune_infos)
1669-
{
1670-
PartitionedRelPruneInfo *pinfo = lfirst(l2);
1671-
1672-
pinfo->rtindex += rtoffset;
1673-
}
1674-
}
1675-
}
1686+
/*
1687+
* PartitionPruneInfos will be added to a list in PlannerGlobal, so update
1688+
* the index.
1689+
*/
1690+
if (aplan->part_prune_index >= 0)
1691+
aplan->part_prune_index += list_length(root->glob->partPruneInfos);
16761692

16771693
/* We don't need to recurse to lefttree or righttree ... */
16781694
Assert(aplan->plan.lefttree == NULL);
@@ -1734,21 +1750,12 @@ set_mergeappend_references(PlannerInfo *root,
17341750

17351751
mplan->apprelids = offset_relid_set(mplan->apprelids, rtoffset);
17361752

1737-
if (mplan->part_prune_info)
1738-
{
1739-
foreach(l, mplan->part_prune_info->prune_infos)
1740-
{
1741-
List *prune_infos = lfirst(l);
1742-
ListCell *l2;
1743-
1744-
foreach(l2, prune_infos)
1745-
{
1746-
PartitionedRelPruneInfo *pinfo = lfirst(l2);
1747-
1748-
pinfo->rtindex += rtoffset;
1749-
}
1750-
}
1751-
}
1753+
/*
1754+
* PartitionPruneInfos will be added to a list in PlannerGlobal, so update
1755+
* the index.
1756+
*/
1757+
if (mplan->part_prune_index >= 0)
1758+
mplan->part_prune_index += list_length(root->glob->partPruneInfos);
17521759

17531760
/* We don't need to recurse to lefttree or righttree ... */
17541761
Assert(mplan->plan.lefttree == NULL);

src/backend/partitioning/partprune.c

+13-6
Original file line numberDiff line numberDiff line change
@@ -209,16 +209,20 @@ static void partkey_datum_from_expr(PartitionPruneContext *context,
209209

210210
/*
211211
* make_partition_pruneinfo
212-
* Builds a PartitionPruneInfo which can be used in the executor to allow
213-
* additional partition pruning to take place. Returns NULL when
214-
* partition pruning would be useless.
212+
* Checks if the given set of quals can be used to build pruning steps
213+
* that the executor can use to prune away unneeded partitions. If
214+
* suitable quals are found then a PartitionPruneInfo is built and tagged
215+
* onto the PlannerInfo's partPruneInfos list.
216+
*
217+
* The return value is the 0-based index of the item added to the
218+
* partPruneInfos list or -1 if nothing was added.
215219
*
216220
* 'parentrel' is the RelOptInfo for an appendrel, and 'subpaths' is the list
217221
* of scan paths for its child rels.
218222
* 'prunequal' is a list of potential pruning quals (i.e., restriction
219223
* clauses that are applicable to the appendrel).
220224
*/
221-
PartitionPruneInfo *
225+
int
222226
make_partition_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
223227
List *subpaths,
224228
List *prunequal)
@@ -332,10 +336,11 @@ make_partition_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
332336
* quals, then we can just not bother with run-time pruning.
333337
*/
334338
if (prunerelinfos == NIL)
335-
return NULL;
339+
return -1;
336340

337341
/* Else build the result data structure */
338342
pruneinfo = makeNode(PartitionPruneInfo);
343+
pruneinfo->root_parent_relids = parentrel->relids;
339344
pruneinfo->prune_infos = prunerelinfos;
340345

341346
/*
@@ -358,7 +363,9 @@ make_partition_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
358363
else
359364
pruneinfo->other_subplans = NULL;
360365

361-
return pruneinfo;
366+
root->partPruneInfos = lappend(root->partPruneInfos, pruneinfo);
367+
368+
return list_length(root->partPruneInfos) - 1;
362369
}
363370

364371
/*

src/include/catalog/catversion.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@
5757
*/
5858

5959
/* yyyymmddN */
60-
#define CATALOG_VERSION_NO 202211301
60+
#define CATALOG_VERSION_NO 202212011
6161

6262
#endif

src/include/executor/execPartition.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,9 @@ typedef struct PartitionPruneState
123123

124124
extern PartitionPruneState *ExecInitPartitionPruning(PlanState *planstate,
125125
int n_total_subplans,
126-
PartitionPruneInfo *pruneinfo,
126+
int part_prune_index,
127+
Bitmapset *root_parent_relids,
127128
Bitmapset **initially_valid_subplans);
128129
extern Bitmapset *ExecFindMatchingSubPlans(PartitionPruneState *prunestate,
129130
bool initial_prune);
130-
131131
#endif /* EXECPARTITION_H */

src/include/nodes/execnodes.h

+1
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,7 @@ typedef struct EState
614614
struct ExecRowMark **es_rowmarks; /* Array of per-range-table-entry
615615
* ExecRowMarks, or NULL if none */
616616
PlannedStmt *es_plannedstmt; /* link to top of plan tree */
617+
List *es_part_prune_infos; /* PlannedStmt.partPruneInfos */
617618
const char *es_sourceText; /* Source text from QueryDesc */
618619

619620
JunkFilter *es_junkFilter; /* top-level junk filter, if any */

src/include/nodes/pathnodes.h

+6
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ typedef struct PlannerGlobal
122122
/* "flat" list of AppendRelInfos */
123123
List *appendRelations;
124124

125+
/* List of PartitionPruneInfo contained in the plan */
126+
List *partPruneInfos;
127+
125128
/* OIDs of relations the plan depends on */
126129
List *relationOids;
127130

@@ -503,6 +506,9 @@ struct PlannerInfo
503506

504507
/* Does this query modify any partition key columns? */
505508
bool partColsUpdated;
509+
510+
/* PartitionPruneInfos added in this query's plan. */
511+
List *partPruneInfos;
506512
};
507513

508514

0 commit comments

Comments
 (0)