diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 2125ff034f3644f52f80b6cedf810d06042b1a79..114e879885639d06ef5403b412abaf2f83f2e177 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -42,7 +42,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.94 2002/12/12 15:49:28 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.95 2002/12/13 17:29:25 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -672,12 +672,22 @@ cost_nestloop(Path *path, Query *root, */ startup_cost += outer_path->startup_cost + inner_path->startup_cost; run_cost += outer_path->total_cost - outer_path->startup_cost; - run_cost += outer_path->parent->rows * - (inner_path->total_cost - inner_path->startup_cost); - if (!(IsA(inner_path, MaterialPath) || - IsA(inner_path, HashPath)) && - outer_path->parent->rows > 1) - run_cost += (outer_path->parent->rows - 1) * inner_path->startup_cost; + if (IsA(inner_path, MaterialPath) || + IsA(inner_path, HashPath)) + { + /* charge only run cost for each iteration of inner path */ + run_cost += outer_path->parent->rows * + (inner_path->total_cost - inner_path->startup_cost); + } + else + { + /* + * charge total cost for each iteration of inner path, except we + * already charged the first startup_cost in our own startup + */ + run_cost += outer_path->parent->rows * inner_path->total_cost + - inner_path->startup_cost; + } /* * Number of tuples processed (not number emitted!). If inner path is @@ -768,8 +778,8 @@ cost_mergejoin(Path *path, Query *root, innerscansel = firstclause->left_mergescansel; } - outer_rows = outer_path->parent->rows * outerscansel; - inner_rows = inner_path->parent->rows * innerscansel; + outer_rows = ceil(outer_path->parent->rows * outerscansel); + inner_rows = ceil(inner_path->parent->rows * innerscansel); /* cost of source data */ @@ -1343,10 +1353,12 @@ approx_selectivity(Query *root, List *quals) void set_baserel_size_estimates(Query *root, RelOptInfo *rel) { + double temp; + /* Should only be applied to base relations */ Assert(length(rel->relids) == 1); - rel->rows = rel->tuples * + temp = rel->tuples * restrictlist_selectivity(root, rel->baserestrictinfo, lfirsti(rel->relids)); @@ -1354,10 +1366,14 @@ set_baserel_size_estimates(Query *root, RelOptInfo *rel) /* * Force estimate to be at least one row, to make explain output look * better and to avoid possible divide-by-zero when interpolating - * cost. + * cost. Make it an integer, too. */ - if (rel->rows < 1.0) - rel->rows = 1.0; + if (temp < 1.0) + temp = 1.0; + else + temp = ceil(temp); + + rel->rows = temp; rel->baserestrictcost = cost_qual_eval(rel->baserestrictinfo); @@ -1437,10 +1453,12 @@ set_joinrel_size_estimates(Query *root, RelOptInfo *rel, /* * Force estimate to be at least one row, to make explain output look * better and to avoid possible divide-by-zero when interpolating - * cost. + * cost. Make it an integer, too. */ if (temp < 1.0) temp = 1.0; + else + temp = ceil(temp); rel->rows = temp; @@ -1470,6 +1488,8 @@ set_joinrel_size_estimates(Query *root, RelOptInfo *rel, void set_function_size_estimates(Query *root, RelOptInfo *rel) { + double temp; + /* Should only be applied to base relations that are functions */ Assert(length(rel->relids) == 1); Assert(rel->rtekind == RTE_FUNCTION); @@ -1483,7 +1503,7 @@ set_function_size_estimates(Query *root, RelOptInfo *rel) rel->tuples = 1000; /* Now estimate number of output rows */ - rel->rows = rel->tuples * + temp = rel->tuples * restrictlist_selectivity(root, rel->baserestrictinfo, lfirsti(rel->relids)); @@ -1491,10 +1511,14 @@ set_function_size_estimates(Query *root, RelOptInfo *rel) /* * Force estimate to be at least one row, to make explain output look * better and to avoid possible divide-by-zero when interpolating - * cost. + * cost. Make it an integer, too. */ - if (rel->rows < 1.0) - rel->rows = 1.0; + if (temp < 1.0) + temp = 1.0; + else + temp = ceil(temp); + + rel->rows = temp; rel->baserestrictcost = cost_qual_eval(rel->baserestrictinfo);