aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-04-04 01:43:12 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-04-04 01:43:12 +0000
commit280de290d79490c9f552c53f492127c8066d2e50 (patch)
tree85706b1d4549ea48f7ab3952fb487c5ef50ab0b1
parent503edbdbffe5584282ad33866fe6f3b72a2c02ae (diff)
downloadpostgresql-280de290d79490c9f552c53f492127c8066d2e50.tar.gz
postgresql-280de290d79490c9f552c53f492127c8066d2e50.zip
In cost_mergejoin, the early-exit effect should not apply to the
outer side of an outer join. Per andrew@supernews.
-rw-r--r--src/backend/optimizer/path/costsize.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index edde32d12df..967536393ee 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -49,7 +49,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.140 2005/03/27 23:53:02 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.141 2005/04/04 01:43:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -917,16 +917,17 @@ cost_mergejoin(MergePath *path, Query *root)
rescanratio = 1.0 + (rescannedtuples / inner_path_rows);
/*
- * A merge join will stop as soon as it exhausts either input stream.
- * Estimate fraction of the left and right inputs that will actually
- * need to be scanned. We use only the first (most significant) merge
- * clause for this purpose.
+ * A merge join will stop as soon as it exhausts either input stream
+ * (unless it's an outer join, in which case the outer side has to be
+ * scanned all the way anyway). Estimate fraction of the left and right
+ * inputs that will actually need to be scanned. We use only the first
+ * (most significant) merge clause for this purpose.
*
* Since this calculation is somewhat expensive, and will be the same for
* all mergejoin paths associated with the merge clause, we cache the
* results in the RestrictInfo node.
*/
- if (mergeclauses)
+ if (mergeclauses && path->jpath.jointype != JOIN_FULL)
{
firstclause = (RestrictInfo *) linitial(mergeclauses);
if (firstclause->left_mergescansel < 0) /* not computed yet? */
@@ -946,10 +947,14 @@ cost_mergejoin(MergePath *path, Query *root)
outerscansel = firstclause->right_mergescansel;
innerscansel = firstclause->left_mergescansel;
}
+ if (path->jpath.jointype == JOIN_LEFT)
+ outerscansel = 1.0;
+ else if (path->jpath.jointype == JOIN_RIGHT)
+ innerscansel = 1.0;
}
else
{
- /* cope with clauseless mergejoin */
+ /* cope with clauseless or full mergejoin */
outerscansel = innerscansel = 1.0;
}