@@ -45,7 +45,9 @@ use datafusion_expr::{
4545
4646use crate :: optimizer:: ApplyOrder ;
4747use crate :: simplify_expressions:: simplify_predicates;
48- use crate :: utils:: { has_all_column_refs, is_restrict_null_predicate} ;
48+ use crate :: utils:: {
49+ ColumnReference , has_all_column_refs, is_restrict_null_predicate, schema_columns,
50+ } ;
4951use crate :: { OptimizerConfig , OptimizerRule } ;
5052use datafusion_expr:: ExpressionPlacement ;
5153
@@ -190,11 +192,11 @@ struct ColumnChecker<'a> {
190192 /// schema of left join input
191193 left_schema : & ' a DFSchema ,
192194 /// columns in left_schema, computed on demand
193- left_columns : Option < HashSet < Column > > ,
195+ left_columns : Option < HashSet < ColumnReference < ' a > > > ,
194196 /// schema of right join input
195197 right_schema : & ' a DFSchema ,
196198 /// columns in left_schema, computed on demand
197- right_columns : Option < HashSet < Column > > ,
199+ right_columns : Option < HashSet < ColumnReference < ' a > > > ,
198200}
199201
200202impl < ' a > ColumnChecker < ' a > {
@@ -224,20 +226,6 @@ impl<'a> ColumnChecker<'a> {
224226 }
225227}
226228
227- /// Returns all columns in the schema
228- fn schema_columns ( schema : & DFSchema ) -> HashSet < Column > {
229- schema
230- . iter ( )
231- . flat_map ( |( qualifier, field) | {
232- [
233- Column :: new ( qualifier. cloned ( ) , field. name ( ) ) ,
234- // we need to push down filter using unqualified column as well
235- Column :: new_unqualified ( field. name ( ) ) ,
236- ]
237- } )
238- . collect :: < HashSet < _ > > ( )
239- }
240-
241229/// Determine whether the predicate can evaluate as the join conditions
242230fn can_evaluate_as_join_condition ( predicate : & Expr ) -> Result < bool > {
243231 let mut is_evaluate = true ;
@@ -320,10 +308,8 @@ fn can_evaluate_as_join_condition(predicate: &Expr) -> Result<bool> {
320308/// * do nothing.
321309fn extract_or_clauses_for_join < ' a > (
322310 filters : & ' a [ Expr ] ,
323- schema : & ' a DFSchema ,
311+ schema_cols : & ' a HashSet < ColumnReference > ,
324312) -> impl Iterator < Item = Expr > + ' a {
325- let schema_columns = schema_columns ( schema) ;
326-
327313 // new formed OR clauses and their column references
328314 filters. iter ( ) . filter_map ( move |expr| {
329315 if let Expr :: BinaryExpr ( BinaryExpr {
@@ -332,8 +318,8 @@ fn extract_or_clauses_for_join<'a>(
332318 right,
333319 } ) = expr
334320 {
335- let left_expr = extract_or_clause ( left. as_ref ( ) , & schema_columns ) ;
336- let right_expr = extract_or_clause ( right. as_ref ( ) , & schema_columns ) ;
321+ let left_expr = extract_or_clause ( left. as_ref ( ) , schema_cols ) ;
322+ let right_expr = extract_or_clause ( right. as_ref ( ) , schema_cols ) ;
337323
338324 // If nothing can be extracted from any sub clauses, do nothing for this OR clause.
339325 if let ( Some ( left_expr) , Some ( right_expr) ) = ( left_expr, right_expr) {
@@ -355,7 +341,10 @@ fn extract_or_clauses_for_join<'a>(
355341/// Otherwise, return None.
356342///
357343/// For other clause, apply the rule above to extract clause.
358- fn extract_or_clause ( expr : & Expr , schema_columns : & HashSet < Column > ) -> Option < Expr > {
344+ fn extract_or_clause (
345+ expr : & Expr ,
346+ schema_columns : & HashSet < ColumnReference > ,
347+ ) -> Option < Expr > {
359348 let mut predicate = None ;
360349
361350 match expr {
@@ -421,6 +410,10 @@ fn push_down_all_join(
421410 // 3) should be kept as filter conditions
422411 let left_schema = join. left . schema ( ) ;
423412 let right_schema = join. right . schema ( ) ;
413+
414+ let left_schema_columns = schema_columns ( left_schema. as_ref ( ) ) ;
415+ let right_schema_columns = schema_columns ( right_schema. as_ref ( ) ) ;
416+
424417 let mut left_push = vec ! [ ] ;
425418 let mut right_push = vec ! [ ] ;
426419 let mut keep_predicates = vec ! [ ] ;
@@ -467,26 +460,38 @@ fn push_down_all_join(
467460 // Extract from OR clause, generate new predicates for both side of join if possible.
468461 // We only track the unpushable predicates above.
469462 if left_preserved {
470- left_push. extend ( extract_or_clauses_for_join ( & keep_predicates, left_schema) ) ;
471- left_push. extend ( extract_or_clauses_for_join ( & join_conditions, left_schema) ) ;
463+ left_push. extend ( extract_or_clauses_for_join (
464+ & keep_predicates,
465+ & left_schema_columns,
466+ ) ) ;
467+ left_push. extend ( extract_or_clauses_for_join (
468+ & join_conditions,
469+ & left_schema_columns,
470+ ) ) ;
472471 }
473472 if right_preserved {
474- right_push. extend ( extract_or_clauses_for_join ( & keep_predicates, right_schema) ) ;
475- right_push. extend ( extract_or_clauses_for_join ( & join_conditions, right_schema) ) ;
473+ right_push. extend ( extract_or_clauses_for_join (
474+ & keep_predicates,
475+ & right_schema_columns,
476+ ) ) ;
477+ right_push. extend ( extract_or_clauses_for_join (
478+ & join_conditions,
479+ & right_schema_columns,
480+ ) ) ;
476481 }
477482
478483 // For predicates from join filter, we should check with if a join side is preserved
479484 // in term of join filtering.
480485 if on_left_preserved {
481486 left_push. extend ( extract_or_clauses_for_join (
482487 & on_filter_join_conditions,
483- left_schema ,
488+ & left_schema_columns ,
484489 ) ) ;
485490 }
486491 if on_right_preserved {
487492 right_push. extend ( extract_or_clauses_for_join (
488493 & on_filter_join_conditions,
489- right_schema ,
494+ & right_schema_columns ,
490495 ) ) ;
491496 }
492497
0 commit comments