diff options
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r-- | src/backend/optimizer/path/allpaths.c | 12 | ||||
-rw-r--r-- | src/backend/optimizer/path/joinrels.c | 2 | ||||
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 45 | ||||
-rw-r--r-- | src/backend/optimizer/plan/planner.c | 8 | ||||
-rw-r--r-- | src/backend/optimizer/prep/prepunion.c | 6 | ||||
-rw-r--r-- | src/backend/optimizer/util/pathnode.c | 26 |
6 files changed, 78 insertions, 21 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 65a34a255d2..3ba3f87eb7c 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1604,7 +1604,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, * if we have zero or one live subpath due to constraint exclusion.) */ if (subpaths_valid) - add_path(rel, (Path *) create_append_path(rel, subpaths, NIL, + add_path(rel, (Path *) create_append_path(root, rel, subpaths, NIL, NULL, 0, false, partitioned_rels, -1)); @@ -1646,8 +1646,8 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, Assert(parallel_workers > 0); /* Generate a partial append path. */ - appendpath = create_append_path(rel, NIL, partial_subpaths, NULL, - parallel_workers, + appendpath = create_append_path(root, rel, NIL, partial_subpaths, + NULL, parallel_workers, enable_parallel_append, partitioned_rels, -1); @@ -1695,7 +1695,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, max_parallel_workers_per_gather); Assert(parallel_workers > 0); - appendpath = create_append_path(rel, pa_nonpartial_subpaths, + appendpath = create_append_path(root, rel, pa_nonpartial_subpaths, pa_partial_subpaths, NULL, parallel_workers, true, partitioned_rels, partial_rows); @@ -1758,7 +1758,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, if (subpaths_valid) add_path(rel, (Path *) - create_append_path(rel, subpaths, NIL, + create_append_path(root, rel, subpaths, NIL, required_outer, 0, false, partitioned_rels, -1)); } @@ -2024,7 +2024,7 @@ set_dummy_rel_pathlist(RelOptInfo *rel) rel->pathlist = NIL; rel->partial_pathlist = NIL; - add_path(rel, (Path *) create_append_path(rel, NIL, NIL, NULL, + add_path(rel, (Path *) create_append_path(NULL, rel, NIL, NIL, NULL, 0, false, NIL, -1)); /* diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c index 3f1c1b3477e..2e289d475ed 100644 --- a/src/backend/optimizer/path/joinrels.c +++ b/src/backend/optimizer/path/joinrels.c @@ -1230,7 +1230,7 @@ mark_dummy_rel(RelOptInfo *rel) rel->partial_pathlist = NIL; /* Set up the dummy path */ - add_path(rel, (Path *) create_append_path(rel, NIL, NIL, NULL, + add_path(rel, (Path *) create_append_path(NULL, rel, NIL, NIL, NULL, 0, false, NIL, -1)); /* Set or update cheapest_total_path and related fields */ diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 99d07360293..048bdf4ad1e 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -41,6 +41,7 @@ #include "optimizer/var.h" #include "parser/parse_clause.h" #include "parser/parsetree.h" +#include "partitioning/partprune.h" #include "utils/lsyscache.h" @@ -210,7 +211,7 @@ static NamedTuplestoreScan *make_namedtuplestorescan(List *qptlist, List *qpqual static WorkTableScan *make_worktablescan(List *qptlist, List *qpqual, Index scanrelid, int wtParam); static Append *make_append(List *appendplans, int first_partial_plan, - List *tlist, List *partitioned_rels); + List *tlist, List *partitioned_rels, List *partpruneinfos); static RecursiveUnion *make_recursive_union(List *tlist, Plan *lefttree, Plan *righttree, @@ -1041,6 +1042,8 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path) List *tlist = build_path_tlist(root, &best_path->path); List *subplans = NIL; ListCell *subpaths; + RelOptInfo *rel = best_path->path.parent; + List *partpruneinfos = NIL; /* * The subpaths list could be empty, if every child was proven empty by @@ -1078,6 +1081,38 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path) subplans = lappend(subplans, subplan); } + if (rel->reloptkind == RELOPT_BASEREL && + best_path->partitioned_rels != NIL) + { + List *prunequal; + + prunequal = extract_actual_clauses(rel->baserestrictinfo, false); + + if (best_path->path.param_info) + { + + List *prmquals = best_path->path.param_info->ppi_clauses; + + prmquals = extract_actual_clauses(prmquals, false); + prmquals = (List *) replace_nestloop_params(root, + (Node *) prmquals); + + prunequal = list_concat(prunequal, prmquals); + } + + /* + * If any quals exist, they may be useful to perform further partition + * pruning during execution. Generate a PartitionPruneInfo for each + * partitioned rel to store these quals and allow translation of + * partition indexes into subpath indexes. + */ + if (prunequal != NIL) + partpruneinfos = + make_partition_pruneinfo(root, + best_path->partitioned_rels, + best_path->subpaths, prunequal); + } + /* * XXX ideally, if there's just one child, we'd not bother to generate an * Append node but just return the single child. At the moment this does @@ -1086,7 +1121,8 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path) */ plan = make_append(subplans, best_path->first_partial_path, - tlist, best_path->partitioned_rels); + tlist, best_path->partitioned_rels, + partpruneinfos); copy_generic_path_info(&plan->plan, (Path *) best_path); @@ -5382,7 +5418,8 @@ make_foreignscan(List *qptlist, static Append * make_append(List *appendplans, int first_partial_plan, - List *tlist, List *partitioned_rels) + List *tlist, List *partitioned_rels, + List *partpruneinfos) { Append *node = makeNode(Append); Plan *plan = &node->plan; @@ -5394,7 +5431,7 @@ make_append(List *appendplans, int first_partial_plan, node->partitioned_rels = partitioned_rels; node->appendplans = appendplans; node->first_partial_plan = first_partial_plan; - + node->part_prune_infos = partpruneinfos; return node; } diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 008492bad5e..421dc79cc4e 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -3920,7 +3920,8 @@ create_degenerate_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, paths = lappend(paths, path); } path = (Path *) - create_append_path(grouped_rel, + create_append_path(root, + grouped_rel, paths, NIL, NULL, @@ -6852,8 +6853,9 @@ apply_scanjoin_target_to_paths(PlannerInfo *root, * node, which would cause this relation to stop appearing to be a * dummy rel.) */ - rel->pathlist = list_make1(create_append_path(rel, NIL, NIL, NULL, - 0, false, NIL, -1)); + rel->pathlist = list_make1(create_append_path(root, rel, NIL, NIL, + NULL, 0, false, NIL, + -1)); rel->partial_pathlist = NIL; set_cheapest(rel); Assert(IS_DUMMY_REL(rel)); diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index 67e47887fc8..2ce4d4496dc 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -648,7 +648,7 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root, /* * Append the child results together. */ - path = (Path *) create_append_path(result_rel, pathlist, NIL, + path = (Path *) create_append_path(root, result_rel, pathlist, NIL, NULL, 0, false, NIL, -1); /* @@ -703,7 +703,7 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root, Assert(parallel_workers > 0); ppath = (Path *) - create_append_path(result_rel, NIL, partial_pathlist, + create_append_path(root, result_rel, NIL, partial_pathlist, NULL, parallel_workers, enable_parallel_append, NIL, -1); ppath = (Path *) @@ -814,7 +814,7 @@ generate_nonunion_paths(SetOperationStmt *op, PlannerInfo *root, /* * Append the child results together. */ - path = (Path *) create_append_path(result_rel, pathlist, NIL, + path = (Path *) create_append_path(root, result_rel, pathlist, NIL, NULL, 0, false, NIL, -1); /* Identify the grouping semantics */ diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index 416b3f95786..bd9442c22d6 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -1210,7 +1210,8 @@ create_tidscan_path(PlannerInfo *root, RelOptInfo *rel, List *tidquals, * Note that we must handle subpaths = NIL, representing a dummy access path. */ AppendPath * -create_append_path(RelOptInfo *rel, +create_append_path(PlannerInfo *root, + RelOptInfo *rel, List *subpaths, List *partial_subpaths, Relids required_outer, int parallel_workers, bool parallel_aware, @@ -1224,8 +1225,25 @@ create_append_path(RelOptInfo *rel, pathnode->path.pathtype = T_Append; pathnode->path.parent = rel; pathnode->path.pathtarget = rel->reltarget; - pathnode->path.param_info = get_appendrel_parampathinfo(rel, - required_outer); + + /* + * When generating an Append path for a partitioned table, there may be + * parameters that are useful so we can eliminate certain partitions + * during execution. Here we'll go all the way and fully populate the + * parameter info data as we do for normal base relations. However, we + * need only bother doing this for RELOPT_BASEREL rels, as + * RELOPT_OTHER_MEMBER_REL's Append paths are merged into the base rel's + * Append subpaths. It would do no harm to do this, we just avoid it to + * save wasting effort. + */ + if (partitioned_rels != NIL && root && rel->reloptkind == RELOPT_BASEREL) + pathnode->path.param_info = get_baserel_parampathinfo(root, + rel, + required_outer); + else + pathnode->path.param_info = get_appendrel_parampathinfo(rel, + required_outer); + pathnode->path.parallel_aware = parallel_aware; pathnode->path.parallel_safe = rel->consider_parallel; pathnode->path.parallel_workers = parallel_workers; @@ -3574,7 +3592,7 @@ reparameterize_path(PlannerInfo *root, Path *path, i++; } return (Path *) - create_append_path(rel, childpaths, partialpaths, + create_append_path(root, rel, childpaths, partialpaths, required_outer, apath->path.parallel_workers, apath->path.parallel_aware, |