8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -795,6 +795,7 @@ select_mergejoin_clauses(RelOptInfo *joinrel,
795
795
{
796
796
List * result_list = NIL ;
797
797
bool isouterjoin = IS_OUTER_JOIN (jointype );
798
+ bool have_nonmergeable_joinclause = false;
798
799
ListCell * l ;
799
800
800
801
foreach (l , restrictlist )
@@ -803,42 +804,19 @@ select_mergejoin_clauses(RelOptInfo *joinrel,
803
804
804
805
/*
805
806
* 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.)
814
810
*/
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 ;
838
813
839
814
if (!restrictinfo -> can_join ||
840
815
restrictinfo -> mergejoinoperator == InvalidOid )
816
+ {
817
+ have_nonmergeable_joinclause = true;
841
818
continue ; /* not mergejoinable */
819
+ }
842
820
843
821
/*
844
822
* Check if clause is usable with these input rels. All the vars
@@ -856,10 +834,37 @@ select_mergejoin_clauses(RelOptInfo *joinrel,
856
834
/* lefthand side is inner */
857
835
}
858
836
else
837
+ {
838
+ have_nonmergeable_joinclause = true;
859
839
continue ; /* no good for these input relations */
840
+ }
860
841
861
842
result_list = lcons (restrictinfo , result_list );
862
843
}
863
844
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
+
864
869
return result_list ;
865
870
}
0 commit comments