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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 17 additions & 1 deletion
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 3 additions & 2 deletions
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

Lines changed: 3 additions & 2 deletions
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

Lines changed: 13 additions & 11 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 37 additions & 30 deletions
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

Lines changed: 13 additions & 6 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 6 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy