@@ -64,17 +64,12 @@ fn physical_join(join: &Join, s_expr: &SExpr) -> Result<PhysicalJoinType> {
6464
6565 let left_prop = left_rel_expr. derive_relational_prop ( ) ?;
6666 let right_prop = right_rel_expr. derive_relational_prop ( ) ?;
67- let mut range_conditions = vec ! [ ] ;
68- let mut other_conditions = vec ! [ ] ;
69- for condition in join. non_equi_conditions . iter ( ) {
70- check_condition (
71- condition,
72- & left_prop,
73- & right_prop,
74- & mut range_conditions,
75- & mut other_conditions,
76- )
77- }
67+ let ( range_conditions, other_conditions) = join
68+ . non_equi_conditions
69+ . iter ( )
70+ . cloned ( )
71+ . partition :: < Vec < _ > , _ > ( |condition| is_range_condition ( condition, & left_prop, & right_prop) ) ;
72+
7873 if !range_conditions. is_empty ( ) && matches ! ( join. join_type, JoinType :: Inner | JoinType :: Cross ) {
7974 return Ok ( PhysicalJoinType :: RangeJoin (
8075 range_conditions,
@@ -85,38 +80,28 @@ fn physical_join(join: &Join, s_expr: &SExpr) -> Result<PhysicalJoinType> {
8580 Ok ( PhysicalJoinType :: Hash )
8681}
8782
88- fn check_condition (
83+ fn is_range_condition (
8984 expr : & ScalarExpr ,
9085 left_prop : & RelationalProperty ,
9186 right_prop : & RelationalProperty ,
92- range_conditions : & mut Vec < ScalarExpr > ,
93- other_conditions : & mut Vec < ScalarExpr > ,
94- ) {
95- if let ScalarExpr :: FunctionCall ( func) = expr {
96- if func. arguments . len ( ) != 2
97- || !matches ! ( func. func_name. as_str( ) , "gt" | "lt" | "gte" | "lte" )
98- {
99- other_conditions. push ( expr. clone ( ) ) ;
100- return ;
101- }
102- let mut left = false ;
103- let mut right = false ;
104- for arg in func. arguments . iter ( ) {
105- let join_predicate = JoinPredicate :: new ( arg, left_prop, right_prop) ;
106- match join_predicate {
107- JoinPredicate :: Left ( _) => left = true ,
108- JoinPredicate :: Right ( _) => right = true ,
109- JoinPredicate :: Both { .. } | JoinPredicate :: Other ( _) | JoinPredicate :: ALL ( _) => {
110- return ;
111- }
112- }
113- }
114- if left && right {
115- range_conditions. push ( expr. clone ( ) ) ;
116- return ;
117- }
87+ ) -> bool {
88+ let ScalarExpr :: FunctionCall ( func) = expr else {
89+ return false ;
90+ } ;
91+ if !matches ! ( func. func_name. as_str( ) , "gt" | "lt" | "gte" | "lte" ) {
92+ return false ;
11893 }
119- other_conditions. push ( expr. clone ( ) ) ;
94+ let [ left, right] = func. arguments . as_slice ( ) else {
95+ unreachable ! ( )
96+ } ;
97+
98+ matches ! (
99+ (
100+ JoinPredicate :: new( left, left_prop, right_prop) ,
101+ JoinPredicate :: new( right, left_prop, right_prop) ,
102+ ) ,
103+ ( JoinPredicate :: Left ( _) , JoinPredicate :: Right ( _) )
104+ )
120105}
121106
122107impl PhysicalPlanBuilder {
@@ -165,33 +150,23 @@ impl PhysicalPlanBuilder {
165150 // 2. Build physical plan.
166151 // Choose physical join type by join conditions
167152 if join. join_type . is_asof_join ( ) {
168- let left_rel_expr = RelExpr :: with_s_expr ( s_expr. left_child ( ) ) ;
169- let right_rel_expr = RelExpr :: with_s_expr ( s_expr. right_child ( ) ) ;
170- let left_prop = left_rel_expr. derive_relational_prop ( ) ?;
171- let right_prop = right_rel_expr. derive_relational_prop ( ) ?;
172- let mut range_conditions = vec ! [ ] ;
173- let mut other_conditions = vec ! [ ] ;
174-
175- for condition in join. equi_conditions . iter ( ) . cloned ( ) {
176- other_conditions. push (
153+ let left_prop = s_expr. left_child ( ) . derive_relational_prop ( ) ?;
154+ let right_prop = s_expr. right_child ( ) . derive_relational_prop ( ) ?;
155+
156+ let ( range_conditions, other_conditions) = join
157+ . non_equi_conditions
158+ . iter ( )
159+ . cloned ( )
160+ . chain ( join. equi_conditions . iter ( ) . cloned ( ) . map ( |condition| {
177161 FunctionCall {
178162 span : condition. left . span ( ) ,
179163 func_name : "eq" . to_string ( ) ,
180164 params : vec ! [ ] ,
181165 arguments : vec ! [ condition. left, condition. right] ,
182166 }
183- . into ( ) ,
184- ) ;
185- }
186- for condition in join. non_equi_conditions . iter ( ) {
187- check_condition (
188- condition,
189- & left_prop,
190- & right_prop,
191- & mut range_conditions,
192- & mut other_conditions,
193- )
194- }
167+ . into ( )
168+ } ) )
169+ . partition ( |condition| is_range_condition ( condition, & left_prop, & right_prop) ) ;
195170
196171 self . build_range_join (
197172 join. join_type ,
0 commit comments