aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-10-12 22:24:49 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-10-12 22:24:49 +0000
commit5bb46e7cd0b9de809486d074453fb320341a25b9 (patch)
treea0f59a0709d6e5f29a749b41460d6e36d945ad1d /src
parent8031b066fa7ccf7805eb428b7939dd192e8639d4 (diff)
downloadpostgresql-5bb46e7cd0b9de809486d074453fb320341a25b9.tar.gz
postgresql-5bb46e7cd0b9de809486d074453fb320341a25b9.zip
Fix for bug #795: two clauses that seem redundant are not really, if
one is pushed down into an outer join and the other is not.
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/util/relnode.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index 49e2f1f0a2d..a07a208ecff 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.39 2002/09/04 20:31:22 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.40 2002/10/12 22:24:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,7 +28,8 @@ static List *new_join_tlist(List *tlist, int first_resdomno);
static List *build_joinrel_restrictlist(Query *root,
RelOptInfo *joinrel,
RelOptInfo *outer_rel,
- RelOptInfo *inner_rel);
+ RelOptInfo *inner_rel,
+ JoinType jointype);
static void build_joinrel_joinlist(RelOptInfo *joinrel,
RelOptInfo *outer_rel,
RelOptInfo *inner_rel);
@@ -334,7 +335,8 @@ build_join_rel(Query *root,
*restrictlist_ptr = build_joinrel_restrictlist(root,
joinrel,
outer_rel,
- inner_rel);
+ inner_rel,
+ jointype);
return joinrel;
}
@@ -419,7 +421,8 @@ build_join_rel(Query *root,
restrictlist = build_joinrel_restrictlist(root,
joinrel,
outer_rel,
- inner_rel);
+ inner_rel,
+ jointype);
if (restrictlist_ptr)
*restrictlist_ptr = restrictlist;
build_joinrel_joinlist(joinrel, outer_rel, inner_rel);
@@ -508,6 +511,7 @@ new_join_tlist(List *tlist,
* 'joinrel' is a join relation node
* 'outer_rel' and 'inner_rel' are a pair of relations that can be joined
* to form joinrel.
+ * 'jointype' is the type of join used.
*
* build_joinrel_restrictlist() returns a list of relevant restrictinfos,
* whereas build_joinrel_joinlist() stores its results in the joinrel's
@@ -522,7 +526,8 @@ static List *
build_joinrel_restrictlist(Query *root,
RelOptInfo *joinrel,
RelOptInfo *outer_rel,
- RelOptInfo *inner_rel)
+ RelOptInfo *inner_rel,
+ JoinType jointype)
{
List *result = NIL;
List *rlist;
@@ -553,6 +558,11 @@ build_joinrel_restrictlist(Query *root,
* one clause that checks equality between any set member on the left
* and any member on the right; by transitivity, all the rest are then
* equal.
+ *
+ * Weird special case: if we have two clauses that seem redundant
+ * except one is pushed down into an outer join and the other isn't,
+ * then they're not really redundant, because one constrains the
+ * joined rows after addition of null fill rows, and the other doesn't.
*/
foreach(item, rlist)
{
@@ -576,7 +586,9 @@ build_joinrel_restrictlist(Query *root,
if (oldrinfo->mergejoinoperator != InvalidOid &&
rinfo->left_pathkey == oldrinfo->left_pathkey &&
- rinfo->right_pathkey == oldrinfo->right_pathkey)
+ rinfo->right_pathkey == oldrinfo->right_pathkey &&
+ (rinfo->ispusheddown == oldrinfo->ispusheddown ||
+ !IS_OUTER_JOIN(jointype)))
{
redundant = true;
break;