Skip to content

Commit 77b7a74

Browse files
committed
Adjust costsize calculations to avoid introducing unnecessary roundoff
error. This seems to explain the differing choice of plan that's been causing geometry regress test to fail for the last few days.
1 parent 023ff17 commit 77b7a74

File tree

1 file changed

+42
-18
lines changed

1 file changed

+42
-18
lines changed

src/backend/optimizer/path/costsize.c

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
* Portions Copyright (c) 1994, Regents of the University of California
4343
*
4444
* IDENTIFICATION
45-
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.94 2002/12/12 15:49:28 tgl Exp $
45+
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.95 2002/12/13 17:29:25 tgl Exp $
4646
*
4747
*-------------------------------------------------------------------------
4848
*/
@@ -672,12 +672,22 @@ cost_nestloop(Path *path, Query *root,
672672
*/
673673
startup_cost += outer_path->startup_cost + inner_path->startup_cost;
674674
run_cost += outer_path->total_cost - outer_path->startup_cost;
675-
run_cost += outer_path->parent->rows *
676-
(inner_path->total_cost - inner_path->startup_cost);
677-
if (!(IsA(inner_path, MaterialPath) ||
678-
IsA(inner_path, HashPath)) &&
679-
outer_path->parent->rows > 1)
680-
run_cost += (outer_path->parent->rows - 1) * inner_path->startup_cost;
675+
if (IsA(inner_path, MaterialPath) ||
676+
IsA(inner_path, HashPath))
677+
{
678+
/* charge only run cost for each iteration of inner path */
679+
run_cost += outer_path->parent->rows *
680+
(inner_path->total_cost - inner_path->startup_cost);
681+
}
682+
else
683+
{
684+
/*
685+
* charge total cost for each iteration of inner path, except we
686+
* already charged the first startup_cost in our own startup
687+
*/
688+
run_cost += outer_path->parent->rows * inner_path->total_cost
689+
- inner_path->startup_cost;
690+
}
681691

682692
/*
683693
* Number of tuples processed (not number emitted!). If inner path is
@@ -768,8 +778,8 @@ cost_mergejoin(Path *path, Query *root,
768778
innerscansel = firstclause->left_mergescansel;
769779
}
770780

771-
outer_rows = outer_path->parent->rows * outerscansel;
772-
inner_rows = inner_path->parent->rows * innerscansel;
781+
outer_rows = ceil(outer_path->parent->rows * outerscansel);
782+
inner_rows = ceil(inner_path->parent->rows * innerscansel);
773783

774784
/* cost of source data */
775785

@@ -1343,21 +1353,27 @@ approx_selectivity(Query *root, List *quals)
13431353
void
13441354
set_baserel_size_estimates(Query *root, RelOptInfo *rel)
13451355
{
1356+
double temp;
1357+
13461358
/* Should only be applied to base relations */
13471359
Assert(length(rel->relids) == 1);
13481360

1349-
rel->rows = rel->tuples *
1361+
temp = rel->tuples *
13501362
restrictlist_selectivity(root,
13511363
rel->baserestrictinfo,
13521364
lfirsti(rel->relids));
13531365

13541366
/*
13551367
* Force estimate to be at least one row, to make explain output look
13561368
* better and to avoid possible divide-by-zero when interpolating
1357-
* cost.
1369+
* cost. Make it an integer, too.
13581370
*/
1359-
if (rel->rows < 1.0)
1360-
rel->rows = 1.0;
1371+
if (temp < 1.0)
1372+
temp = 1.0;
1373+
else
1374+
temp = ceil(temp);
1375+
1376+
rel->rows = temp;
13611377

13621378
rel->baserestrictcost = cost_qual_eval(rel->baserestrictinfo);
13631379

@@ -1437,10 +1453,12 @@ set_joinrel_size_estimates(Query *root, RelOptInfo *rel,
14371453
/*
14381454
* Force estimate to be at least one row, to make explain output look
14391455
* better and to avoid possible divide-by-zero when interpolating
1440-
* cost.
1456+
* cost. Make it an integer, too.
14411457
*/
14421458
if (temp < 1.0)
14431459
temp = 1.0;
1460+
else
1461+
temp = ceil(temp);
14441462

14451463
rel->rows = temp;
14461464

@@ -1470,6 +1488,8 @@ set_joinrel_size_estimates(Query *root, RelOptInfo *rel,
14701488
void
14711489
set_function_size_estimates(Query *root, RelOptInfo *rel)
14721490
{
1491+
double temp;
1492+
14731493
/* Should only be applied to base relations that are functions */
14741494
Assert(length(rel->relids) == 1);
14751495
Assert(rel->rtekind == RTE_FUNCTION);
@@ -1483,18 +1503,22 @@ set_function_size_estimates(Query *root, RelOptInfo *rel)
14831503
rel->tuples = 1000;
14841504

14851505
/* Now estimate number of output rows */
1486-
rel->rows = rel->tuples *
1506+
temp = rel->tuples *
14871507
restrictlist_selectivity(root,
14881508
rel->baserestrictinfo,
14891509
lfirsti(rel->relids));
14901510

14911511
/*
14921512
* Force estimate to be at least one row, to make explain output look
14931513
* better and to avoid possible divide-by-zero when interpolating
1494-
* cost.
1514+
* cost. Make it an integer, too.
14951515
*/
1496-
if (rel->rows < 1.0)
1497-
rel->rows = 1.0;
1516+
if (temp < 1.0)
1517+
temp = 1.0;
1518+
else
1519+
temp = ceil(temp);
1520+
1521+
rel->rows = temp;
14981522

14991523
rel->baserestrictcost = cost_qual_eval(rel->baserestrictinfo);
15001524

0 commit comments

Comments
 (0)