Commit 54f7f62d authored by Tom Lane's avatar Tom Lane

Fix thinko: cost_mergejoin must pay attention to which side of the

mergeclause is which when extracting selectivity info.
parent ed6986d3
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.81 2002/03/01 06:01:19 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.82 2002/03/01 20:50:20 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -467,10 +467,11 @@ cost_sort(Path *path, Query *root, ...@@ -467,10 +467,11 @@ cost_sort(Path *path, Query *root,
} }
/* /*
* Note: should we bother to assign a nonzero run_cost to reflect the * Also charge a small amount (arbitrarily set equal to operator cost)
* overhead of extracting tuples from the sort result? Probably not * per extracted tuple.
* worth worrying about.
*/ */
run_cost += cpu_operator_cost * tuples;
path->startup_cost = startup_cost; path->startup_cost = startup_cost;
path->total_cost = startup_cost + run_cost; path->total_cost = startup_cost + run_cost;
} }
...@@ -567,11 +568,12 @@ cost_mergejoin(Path *path, Query *root, ...@@ -567,11 +568,12 @@ cost_mergejoin(Path *path, Query *root,
Cost run_cost = 0; Cost run_cost = 0;
Cost cpu_per_tuple; Cost cpu_per_tuple;
RestrictInfo *firstclause; RestrictInfo *firstclause;
Var *leftvar;
double outer_rows, double outer_rows,
inner_rows; inner_rows;
double ntuples; double ntuples;
Selectivity leftscan, Selectivity outerscansel,
rightscan; innerscansel;
Path sort_path; /* dummy for result of cost_sort */ Path sort_path; /* dummy for result of cost_sort */
if (!enable_mergejoin) if (!enable_mergejoin)
...@@ -592,11 +594,24 @@ cost_mergejoin(Path *path, Query *root, ...@@ -592,11 +594,24 @@ cost_mergejoin(Path *path, Query *root,
mergejoinscansel(root, (Node *) firstclause->clause, mergejoinscansel(root, (Node *) firstclause->clause,
&firstclause->left_mergescansel, &firstclause->left_mergescansel,
&firstclause->right_mergescansel); &firstclause->right_mergescansel);
leftscan = firstclause->left_mergescansel;
rightscan = firstclause->right_mergescansel;
outer_rows = outer_path->parent->rows * leftscan; leftvar = get_leftop(firstclause->clause);
inner_rows = inner_path->parent->rows * rightscan; Assert(IsA(leftvar, Var));
if (intMember(leftvar->varno, outer_path->parent->relids))
{
/* left side of clause is outer */
outerscansel = firstclause->left_mergescansel;
innerscansel = firstclause->right_mergescansel;
}
else
{
/* left side of clause is inner */
outerscansel = firstclause->right_mergescansel;
innerscansel = firstclause->left_mergescansel;
}
outer_rows = outer_path->parent->rows * outerscansel;
inner_rows = inner_path->parent->rows * innerscansel;
/* cost of source data */ /* cost of source data */
...@@ -616,13 +631,13 @@ cost_mergejoin(Path *path, Query *root, ...@@ -616,13 +631,13 @@ cost_mergejoin(Path *path, Query *root,
outer_path->parent->width); outer_path->parent->width);
startup_cost += sort_path.startup_cost; startup_cost += sort_path.startup_cost;
run_cost += (sort_path.total_cost - sort_path.startup_cost) run_cost += (sort_path.total_cost - sort_path.startup_cost)
* leftscan; * outerscansel;
} }
else else
{ {
startup_cost += outer_path->startup_cost; startup_cost += outer_path->startup_cost;
run_cost += (outer_path->total_cost - outer_path->startup_cost) run_cost += (outer_path->total_cost - outer_path->startup_cost)
* leftscan; * outerscansel;
} }
if (innersortkeys) /* do we need to sort inner? */ if (innersortkeys) /* do we need to sort inner? */
...@@ -635,13 +650,13 @@ cost_mergejoin(Path *path, Query *root, ...@@ -635,13 +650,13 @@ cost_mergejoin(Path *path, Query *root,
inner_path->parent->width); inner_path->parent->width);
startup_cost += sort_path.startup_cost; startup_cost += sort_path.startup_cost;
run_cost += (sort_path.total_cost - sort_path.startup_cost) run_cost += (sort_path.total_cost - sort_path.startup_cost)
* rightscan; * innerscansel;
} }
else else
{ {
startup_cost += inner_path->startup_cost; startup_cost += inner_path->startup_cost;
run_cost += (inner_path->total_cost - inner_path->startup_cost) run_cost += (inner_path->total_cost - inner_path->startup_cost)
* rightscan; * innerscansel;
} }
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment