88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.96 2005/10/15 02:49:20 momjian Exp $
11+ * $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.97 2005/10/25 20:30:30 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -795,6 +795,7 @@ select_mergejoin_clauses(RelOptInfo *joinrel,
795795{
796796List * result_list = NIL ;
797797bool isouterjoin = IS_OUTER_JOIN (jointype );
798+ bool have_nonmergeable_joinclause = false;
798799ListCell * l ;
799800
800801foreach (l ,restrictlist )
@@ -803,42 +804,19 @@ select_mergejoin_clauses(RelOptInfo *joinrel,
803804
804805/*
805806 * If processing an outer join, only use its own join clauses in the
806- * merge. For inner joins we need not be so picky.
807- *
808- * Furthermore, if it is a right/full join then *all* the explicit join
809- * clauses must be mergejoinable, else the executor will fail. If we
810- * are asked for a right join then just return NIL to indicate no
811- * mergejoin is possible (we can handle it as a left join instead). If
812- * we are asked for a full join then emit an error, because there is
813- * no fallback.
807+ * merge. For inner joins we can use pushed-down clauses too.
808+ * (Note: we don't set have_nonmergeable_joinclause here because
809+ * pushed-down clauses will become otherquals not joinquals.)
814810 */
815- if (isouterjoin )
816- {
817- if (restrictinfo -> is_pushed_down )
818- continue ;
819- switch (jointype )
820- {
821- case JOIN_RIGHT :
822- if (!restrictinfo -> can_join ||
823- restrictinfo -> mergejoinoperator == InvalidOid )
824- return NIL ;/* not mergejoinable */
825- break ;
826- case JOIN_FULL :
827- if (!restrictinfo -> can_join ||
828- restrictinfo -> mergejoinoperator == InvalidOid )
829- ereport (ERROR ,
830- (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
831- errmsg ("FULL JOIN is only supported with merge-joinable join conditions" )));
832- break ;
833- default :
834- /* otherwise, it's OK to have nonmergeable join quals */
835- break ;
836- }
837- }
811+ if (isouterjoin && restrictinfo -> is_pushed_down )
812+ continue ;
838813
839814if (!restrictinfo -> can_join ||
840815restrictinfo -> mergejoinoperator == InvalidOid )
816+ {
817+ have_nonmergeable_joinclause = true;
841818continue ;/* not mergejoinable */
819+ }
842820
843821/*
844822 * Check if clause is usable with these input rels. All the vars
@@ -856,10 +834,37 @@ select_mergejoin_clauses(RelOptInfo *joinrel,
856834/* lefthand side is inner */
857835}
858836else
837+ {
838+ have_nonmergeable_joinclause = true;
859839continue ;/* no good for these input relations */
840+ }
860841
861842result_list = lcons (restrictinfo ,result_list );
862843}
863844
845+ /*
846+ * If it is a right/full join then *all* the explicit join clauses must be
847+ * mergejoinable, else the executor will fail. If we are asked for a right
848+ * join then just return NIL to indicate no mergejoin is possible (we can
849+ * handle it as a left join instead). If we are asked for a full join then
850+ * emit an error, because there is no fallback.
851+ */
852+ if (have_nonmergeable_joinclause )
853+ {
854+ switch (jointype )
855+ {
856+ case JOIN_RIGHT :
857+ return NIL ;/* not mergejoinable */
858+ case JOIN_FULL :
859+ ereport (ERROR ,
860+ (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
861+ errmsg ("FULL JOIN is only supported with merge-joinable join conditions" )));
862+ break ;
863+ default :
864+ /* otherwise, it's OK to have nonmergeable join quals */
865+ break ;
866+ }
867+ }
868+
864869return result_list ;
865870}