Commit 92c651f8 authored by Tom Lane's avatar Tom Lane

Fix an oversight in mergejoin planning: the planner would reject a

mergejoin possibility where the inner rel was less well sorted than
the outer (ie, it matches some but not all of the merge clauses that
can work with the outer), if the inner path in question is also the
overall cheapest path for its rel.  This is an old bug, but I'm not
sure it's worth back-patching, because it's such a corner case.
Noted while investigating a test case from Peter Hardman.
parent 144b0ae8
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.105 2006/07/14 14:52:20 momjian Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.106 2006/08/17 17:06:37 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -542,8 +542,11 @@ match_unsorted_outer(PlannerInfo *root, ...@@ -542,8 +542,11 @@ match_unsorted_outer(PlannerInfo *root,
* Look for presorted inner paths that satisfy the innersortkey list * Look for presorted inner paths that satisfy the innersortkey list
* --- or any truncation thereof, if we are allowed to build a * --- or any truncation thereof, if we are allowed to build a
* mergejoin using a subset of the merge clauses. Here, we consider * mergejoin using a subset of the merge clauses. Here, we consider
* both cheap startup cost and cheap total cost. Ignore * both cheap startup cost and cheap total cost. We can ignore
* inner_cheapest_total, since we already made a path with it. * inner_cheapest_total on the first iteration, since we already made
* a path with it --- but not on later iterations with shorter
* sort keys, because then we are considering a different situation,
* viz using a simpler mergejoin to avoid a sort of the inner rel.
*/ */
num_sortkeys = list_length(innersortkeys); num_sortkeys = list_length(innersortkeys);
if (num_sortkeys > 1 && !useallclauses) if (num_sortkeys > 1 && !useallclauses)
...@@ -568,7 +571,8 @@ match_unsorted_outer(PlannerInfo *root, ...@@ -568,7 +571,8 @@ match_unsorted_outer(PlannerInfo *root,
trialsortkeys, trialsortkeys,
TOTAL_COST); TOTAL_COST);
if (innerpath != NULL && if (innerpath != NULL &&
innerpath != inner_cheapest_total && (innerpath != inner_cheapest_total ||
sortkeycnt < num_sortkeys) &&
(cheapest_total_inner == NULL || (cheapest_total_inner == NULL ||
compare_path_costs(innerpath, cheapest_total_inner, compare_path_costs(innerpath, cheapest_total_inner,
TOTAL_COST) < 0)) TOTAL_COST) < 0))
...@@ -603,7 +607,8 @@ match_unsorted_outer(PlannerInfo *root, ...@@ -603,7 +607,8 @@ match_unsorted_outer(PlannerInfo *root,
trialsortkeys, trialsortkeys,
STARTUP_COST); STARTUP_COST);
if (innerpath != NULL && if (innerpath != NULL &&
innerpath != inner_cheapest_total && (innerpath != inner_cheapest_total ||
sortkeycnt < num_sortkeys) &&
(cheapest_startup_inner == NULL || (cheapest_startup_inner == NULL ||
compare_path_costs(innerpath, cheapest_startup_inner, compare_path_costs(innerpath, cheapest_startup_inner,
STARTUP_COST) < 0)) STARTUP_COST) < 0))
......
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