summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/path
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/path')
-rw-r--r--src/backend/optimizer/path/costsize.c35
-rw-r--r--src/backend/optimizer/path/joinrels.c4
2 files changed, 35 insertions, 4 deletions
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index cc9e49b9e22..8e88e46d571 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -41,7 +41,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.67 2001/02/15 17:46:40 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.68 2001/02/16 00:03:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -837,11 +837,12 @@ void
set_joinrel_size_estimates(Query *root, RelOptInfo *rel,
RelOptInfo *outer_rel,
RelOptInfo *inner_rel,
+ JoinType jointype,
List *restrictlist)
{
double temp;
- /* cartesian product */
+ /* Start with the Cartesian product */
temp = outer_rel->rows * inner_rel->rows;
/*
@@ -855,12 +856,42 @@ set_joinrel_size_estimates(Query *root, RelOptInfo *rel,
0);
/*
+ * If we are doing an outer join, take that into account: the output
+ * must be at least as large as the non-nullable input. (Is there any
+ * chance of being even smarter?)
+ */
+ switch (jointype)
+ {
+ case JOIN_INNER:
+ break;
+ case JOIN_LEFT:
+ if (temp < outer_rel->rows)
+ temp = outer_rel->rows;
+ break;
+ case JOIN_RIGHT:
+ if (temp < inner_rel->rows)
+ temp = inner_rel->rows;
+ break;
+ case JOIN_FULL:
+ if (temp < outer_rel->rows)
+ temp = outer_rel->rows;
+ if (temp < inner_rel->rows)
+ temp = inner_rel->rows;
+ break;
+ default:
+ elog(ERROR, "set_joinrel_size_estimates: unsupported join type %d",
+ (int) jointype);
+ break;
+ }
+
+ /*
* Force estimate to be at least one row, to make explain output look
* better and to avoid possible divide-by-zero when interpolating
* cost.
*/
if (temp < 1.0)
temp = 1.0;
+
rel->rows = temp;
/*
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index 2a59ed43e48..2492f17ea9b 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.50 2001/01/24 19:42:58 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.51 2001/02/16 00:03:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -394,7 +394,7 @@ make_join_rel(Query *root, RelOptInfo *rel1, RelOptInfo *rel2,
* Find or build the join RelOptInfo, and compute the restrictlist
* that goes with this particular joining.
*/
- joinrel = get_join_rel(root, rel1, rel2, &restrictlist);
+ joinrel = get_join_rel(root, rel1, rel2, jointype, &restrictlist);
/*
* Consider paths using each rel as both outer and inner.