88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.39 2002/09/04 20:31:22 momjian Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.40 2002/10/12 22:24:49 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -28,7 +28,8 @@ static List *new_join_tlist(List *tlist, int first_resdomno);
2828static List * build_joinrel_restrictlist (Query * root ,
2929RelOptInfo * joinrel ,
3030RelOptInfo * outer_rel ,
31- RelOptInfo * inner_rel );
31+ RelOptInfo * inner_rel ,
32+ JoinType jointype );
3233static void build_joinrel_joinlist (RelOptInfo * joinrel ,
3334RelOptInfo * outer_rel ,
3435RelOptInfo * inner_rel );
@@ -334,7 +335,8 @@ build_join_rel(Query *root,
334335* restrictlist_ptr = build_joinrel_restrictlist (root ,
335336joinrel ,
336337outer_rel ,
337- inner_rel );
338+ inner_rel ,
339+ jointype );
338340return joinrel ;
339341}
340342
@@ -419,7 +421,8 @@ build_join_rel(Query *root,
419421restrictlist = build_joinrel_restrictlist (root ,
420422joinrel ,
421423outer_rel ,
422- inner_rel );
424+ inner_rel ,
425+ jointype );
423426if (restrictlist_ptr )
424427* restrictlist_ptr = restrictlist ;
425428build_joinrel_joinlist (joinrel ,outer_rel ,inner_rel );
@@ -508,6 +511,7 @@ new_join_tlist(List *tlist,
508511 * 'joinrel' is a join relation node
509512 * 'outer_rel' and 'inner_rel' are a pair of relations that can be joined
510513 *to form joinrel.
514+ * 'jointype' is the type of join used.
511515 *
512516 * build_joinrel_restrictlist() returns a list of relevant restrictinfos,
513517 * whereas build_joinrel_joinlist() stores its results in the joinrel's
@@ -522,7 +526,8 @@ static List *
522526build_joinrel_restrictlist (Query * root ,
523527RelOptInfo * joinrel ,
524528RelOptInfo * outer_rel ,
525- RelOptInfo * inner_rel )
529+ RelOptInfo * inner_rel ,
530+ JoinType jointype )
526531{
527532List * result = NIL ;
528533List * rlist ;
@@ -553,6 +558,11 @@ build_joinrel_restrictlist(Query *root,
553558 * one clause that checks equality between any set member on the left
554559 * and any member on the right; by transitivity, all the rest are then
555560 * equal.
561+ *
562+ * Weird special case: if we have two clauses that seem redundant
563+ * except one is pushed down into an outer join and the other isn't,
564+ * then they're not really redundant, because one constrains the
565+ * joined rows after addition of null fill rows, and the other doesn't.
556566 */
557567foreach (item ,rlist )
558568{
@@ -576,7 +586,9 @@ build_joinrel_restrictlist(Query *root,
576586
577587if (oldrinfo -> mergejoinoperator != InvalidOid &&
578588rinfo -> left_pathkey == oldrinfo -> left_pathkey &&
579- rinfo -> right_pathkey == oldrinfo -> right_pathkey )
589+ rinfo -> right_pathkey == oldrinfo -> right_pathkey &&
590+ (rinfo -> ispusheddown == oldrinfo -> ispusheddown ||
591+ !IS_OUTER_JOIN (jointype )))
580592{
581593redundant = true;
582594break ;