aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/planner.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/planner.c')
-rw-r--r--src/backend/optimizer/plan/planner.c67
1 files changed, 40 insertions, 27 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index f77c804b702..65b99e2af38 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -98,14 +98,16 @@ static List *reorder_grouping_sets(List *groupingSets, List *sortclause);
static void standard_qp_callback(PlannerInfo *root, void *extra);
static bool choose_hashed_grouping(PlannerInfo *root,
double tuple_fraction, double limit_tuples,
- double path_rows, int path_width,
+ double path_rows,
Path *cheapest_path, Path *sorted_path,
double dNumGroups, AggClauseCosts *agg_costs);
static bool choose_hashed_distinct(PlannerInfo *root,
double tuple_fraction, double limit_tuples,
- double path_rows, int path_width,
+ double path_rows,
Cost cheapest_startup_cost, Cost cheapest_total_cost,
+ int cheapest_path_width,
Cost sorted_startup_cost, Cost sorted_total_cost,
+ int sorted_path_width,
List *sorted_pathkeys,
double dNumDistinctRows);
static List *make_subplanTargetList(PlannerInfo *root, List *tlist,
@@ -1467,7 +1469,6 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
AggClauseCosts agg_costs;
int numGroupCols;
double path_rows;
- int path_width;
bool use_hashed_grouping = false;
WindowFuncLists *wflists = NULL;
List *activeWindows = NIL;
@@ -1672,12 +1673,11 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
standard_qp_callback, &qp_extra);
/*
- * Extract rowcount and width estimates for use below. If final_rel
- * has been proven dummy, its rows estimate will be zero; clamp it to
- * one to avoid zero-divide in subsequent calculations.
+ * Extract rowcount estimate for use below. If final_rel has been
+ * proven dummy, its rows estimate will be zero; clamp it to one to
+ * avoid zero-divide in subsequent calculations.
*/
path_rows = clamp_row_est(final_rel->rows);
- path_width = final_rel->width;
/*
* If there's grouping going on, estimate the number of result groups.
@@ -1849,7 +1849,7 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
/* Figure cost for sorting */
cost_sort(&sort_path, root, root->query_pathkeys,
cheapest_path->total_cost,
- path_rows, path_width,
+ path_rows, cheapest_path->pathtarget->width,
0.0, work_mem, root->limit_tuples);
}
@@ -1881,7 +1881,7 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
use_hashed_grouping =
choose_hashed_grouping(root,
tuple_fraction, limit_tuples,
- path_rows, path_width,
+ path_rows,
cheapest_path, sorted_path,
dNumGroups, &agg_costs);
}
@@ -1900,11 +1900,13 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
use_hashed_distinct =
choose_hashed_distinct(root,
tuple_fraction, limit_tuples,
- path_rows, path_width,
+ path_rows,
cheapest_path->startup_cost,
cheapest_path->total_cost,
+ cheapest_path->pathtarget->width,
sorted_path->startup_cost,
sorted_path->total_cost,
+ sorted_path->pathtarget->width,
sorted_path->pathkeys,
dNumGroups);
tested_hashed_distinct = true;
@@ -2343,11 +2345,12 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
choose_hashed_distinct(root,
tuple_fraction, limit_tuples,
result_plan->plan_rows,
- result_plan->plan_width,
result_plan->startup_cost,
result_plan->total_cost,
+ result_plan->plan_width,
result_plan->startup_cost,
result_plan->total_cost,
+ result_plan->plan_width,
current_pathkeys,
dNumDistinctRows);
}
@@ -2678,10 +2681,13 @@ build_grouping_chain(PlannerInfo *root,
* any logic that uses plan_rows to, eg, estimate qual evaluation costs.)
*
* Note: during initial stages of planning, we mostly consider plan nodes with
- * "flat" tlists, containing just Vars. So their evaluation cost is zero
- * according to the model used by cost_qual_eval() (or if you prefer, the cost
- * is factored into cpu_tuple_cost). Thus we can avoid accounting for tlist
- * cost throughout query_planner() and subroutines. But once we apply a
+ * "flat" tlists, containing just Vars and PlaceHolderVars. The evaluation
+ * cost of Vars is zero according to the model used by cost_qual_eval() (or if
+ * you prefer, the cost is factored into cpu_tuple_cost). The evaluation cost
+ * of a PHV's expression is charged as part of the scan cost of whichever plan
+ * node first computes it, and then subsequent references to the PHV can be
+ * taken as having cost zero. Thus we can avoid worrying about tlist cost
+ * as such throughout query_planner() and subroutines. But once we apply a
* tlist that might contain actual operators, sub-selects, etc, we'd better
* account for its cost. Any set-returning functions in the tlist must also
* affect the estimated rowcount.
@@ -3840,7 +3846,7 @@ standard_qp_callback(PlannerInfo *root, void *extra)
static bool
choose_hashed_grouping(PlannerInfo *root,
double tuple_fraction, double limit_tuples,
- double path_rows, int path_width,
+ double path_rows,
Path *cheapest_path, Path *sorted_path,
double dNumGroups, AggClauseCosts *agg_costs)
{
@@ -3853,6 +3859,7 @@ choose_hashed_grouping(PlannerInfo *root,
List *current_pathkeys;
Path hashed_p;
Path sorted_p;
+ int sorted_p_width;
/*
* Executor doesn't support hashed aggregation with DISTINCT or ORDER BY
@@ -3890,7 +3897,8 @@ choose_hashed_grouping(PlannerInfo *root,
*/
/* Estimate per-hash-entry space at tuple width... */
- hashentrysize = MAXALIGN(path_width) + MAXALIGN(SizeofMinimalTupleHeader);
+ hashentrysize = MAXALIGN(cheapest_path->pathtarget->width) +
+ MAXALIGN(SizeofMinimalTupleHeader);
/* plus space for pass-by-ref transition values... */
hashentrysize += agg_costs->transitionSpace;
/* plus the per-hash-entry overhead */
@@ -3935,25 +3943,27 @@ choose_hashed_grouping(PlannerInfo *root,
/* Result of hashed agg is always unsorted */
if (target_pathkeys)
cost_sort(&hashed_p, root, target_pathkeys, hashed_p.total_cost,
- dNumGroups, path_width,
+ dNumGroups, cheapest_path->pathtarget->width,
0.0, work_mem, limit_tuples);
if (sorted_path)
{
sorted_p.startup_cost = sorted_path->startup_cost;
sorted_p.total_cost = sorted_path->total_cost;
+ sorted_p_width = sorted_path->pathtarget->width;
current_pathkeys = sorted_path->pathkeys;
}
else
{
sorted_p.startup_cost = cheapest_path->startup_cost;
sorted_p.total_cost = cheapest_path->total_cost;
+ sorted_p_width = cheapest_path->pathtarget->width;
current_pathkeys = cheapest_path->pathkeys;
}
if (!pathkeys_contained_in(root->group_pathkeys, current_pathkeys))
{
cost_sort(&sorted_p, root, root->group_pathkeys, sorted_p.total_cost,
- path_rows, path_width,
+ path_rows, sorted_p_width,
0.0, work_mem, -1.0);
current_pathkeys = root->group_pathkeys;
}
@@ -3971,7 +3981,7 @@ choose_hashed_grouping(PlannerInfo *root,
if (target_pathkeys &&
!pathkeys_contained_in(target_pathkeys, current_pathkeys))
cost_sort(&sorted_p, root, target_pathkeys, sorted_p.total_cost,
- dNumGroups, path_width,
+ dNumGroups, sorted_p_width,
0.0, work_mem, limit_tuples);
/*
@@ -4008,9 +4018,11 @@ choose_hashed_grouping(PlannerInfo *root,
static bool
choose_hashed_distinct(PlannerInfo *root,
double tuple_fraction, double limit_tuples,
- double path_rows, int path_width,
+ double path_rows,
Cost cheapest_startup_cost, Cost cheapest_total_cost,
+ int cheapest_path_width,
Cost sorted_startup_cost, Cost sorted_total_cost,
+ int sorted_path_width,
List *sorted_pathkeys,
double dNumDistinctRows)
{
@@ -4058,7 +4070,8 @@ choose_hashed_distinct(PlannerInfo *root,
*/
/* Estimate per-hash-entry space at tuple width... */
- hashentrysize = MAXALIGN(path_width) + MAXALIGN(SizeofMinimalTupleHeader);
+ hashentrysize = MAXALIGN(cheapest_path_width) +
+ MAXALIGN(SizeofMinimalTupleHeader);
/* plus the per-hash-entry overhead */
hashentrysize += hash_agg_entry_size(0);
@@ -4089,7 +4102,7 @@ choose_hashed_distinct(PlannerInfo *root,
*/
if (parse->sortClause)
cost_sort(&hashed_p, root, root->sort_pathkeys, hashed_p.total_cost,
- dNumDistinctRows, path_width,
+ dNumDistinctRows, cheapest_path_width,
0.0, work_mem, limit_tuples);
/*
@@ -4113,7 +4126,7 @@ choose_hashed_distinct(PlannerInfo *root,
else
current_pathkeys = root->sort_pathkeys;
cost_sort(&sorted_p, root, current_pathkeys, sorted_p.total_cost,
- path_rows, path_width,
+ path_rows, sorted_path_width,
0.0, work_mem, -1.0);
}
cost_group(&sorted_p, root, numDistinctCols, dNumDistinctRows,
@@ -4122,7 +4135,7 @@ choose_hashed_distinct(PlannerInfo *root,
if (parse->sortClause &&
!pathkeys_contained_in(root->sort_pathkeys, current_pathkeys))
cost_sort(&sorted_p, root, root->sort_pathkeys, sorted_p.total_cost,
- dNumDistinctRows, path_width,
+ dNumDistinctRows, sorted_path_width,
0.0, work_mem, limit_tuples);
/*
@@ -4896,7 +4909,7 @@ plan_cluster_use_sort(Oid tableOid, Oid indexOid)
* set_baserel_size_estimates, just do a quick hack for rows and width.
*/
rel->rows = rel->tuples;
- rel->width = get_relation_data_width(tableOid, NULL);
+ rel->reltarget.width = get_relation_data_width(tableOid, NULL);
root->total_table_pages = rel->pages;
@@ -4912,7 +4925,7 @@ plan_cluster_use_sort(Oid tableOid, Oid indexOid)
/* Estimate the cost of seq scan + sort */
seqScanPath = create_seqscan_path(root, rel, NULL, 0);
cost_sort(&seqScanAndSortPath, root, NIL,
- seqScanPath->total_cost, rel->tuples, rel->width,
+ seqScanPath->total_cost, rel->tuples, rel->reltarget.width,
comparisonCost, maintenance_work_mem, -1.0);
/* Estimate the cost of index scan */