@@ -286,21 +286,26 @@ fn can_evaluate_as_join_condition(predicate: &Expr) -> Result<bool> {
286286}
287287
288288fn is_scalar_subquery_cross_join ( join : & Join ) -> bool {
289- fn classify ( plan : & LogicalPlan ) -> ( bool , bool ) {
289+ fn is_scalar_aggregate_or_derived_relation ( plan : & LogicalPlan ) -> ( bool , bool ) {
290290 match plan {
291291 LogicalPlan :: SubqueryAlias ( subquery_alias) => {
292- let ( is_scalar_aggregate, _) = classify ( subquery_alias. input . as_ref ( ) ) ;
292+ let ( is_scalar_aggregate, _) = is_scalar_aggregate_or_derived_relation (
293+ subquery_alias. input . as_ref ( ) ,
294+ ) ;
293295 ( is_scalar_aggregate, true )
294296 }
295- LogicalPlan :: Projection ( projection) => classify ( projection. input . as_ref ( ) ) ,
297+ LogicalPlan :: Projection ( projection) => {
298+ is_scalar_aggregate_or_derived_relation ( projection. input . as_ref ( ) )
299+ }
296300 LogicalPlan :: Aggregate ( aggregate) => ( aggregate. group_expr . is_empty ( ) , false ) ,
297301 _ => ( false , false ) ,
298302 }
299303 }
300304
301- let ( left_scalar_aggregate, left_is_derived_relation) = classify ( join. left . as_ref ( ) ) ;
305+ let ( left_scalar_aggregate, left_is_derived_relation) =
306+ is_scalar_aggregate_or_derived_relation ( join. left . as_ref ( ) ) ;
302307 let ( right_scalar_aggregate, right_is_derived_relation) =
303- classify ( join. right . as_ref ( ) ) ;
308+ is_scalar_aggregate_or_derived_relation ( join. right . as_ref ( ) ) ;
304309 join. on . is_empty ( )
305310 && join. filter . is_none ( )
306311 && ( ( left_scalar_aggregate && right_is_derived_relation)
@@ -451,9 +456,12 @@ fn push_down_all_join(
451456 let keep_mixed_scalar_subquery_filters =
452457 is_inner_join && is_scalar_subquery_cross_join ( & join) ;
453458 for predicate in predicates {
454- if left_preserved && checker. is_left_only ( & predicate) {
459+ let left_only = left_preserved && checker. is_left_only ( & predicate) ;
460+ let right_only =
461+ !left_only && right_preserved && checker. is_right_only ( & predicate) ;
462+ if left_only {
455463 left_push. push ( predicate) ;
456- } else if right_preserved && checker . is_right_only ( & predicate ) {
464+ } else if right_only {
457465 right_push. push ( predicate) ;
458466 } else if is_inner_join
459467 && !keep_mixed_scalar_subquery_filters
@@ -479,43 +487,63 @@ fn push_down_all_join(
479487 let mut on_filter_join_conditions = vec ! [ ] ;
480488 let ( on_left_preserved, on_right_preserved) = on_lr_is_preserved ( join. join_type ) ;
481489
482- if !on_filter. is_empty ( ) {
483- for on in on_filter {
484- if on_left_preserved && checker. is_left_only ( & on) {
485- left_push. push ( on)
486- } else if on_right_preserved && checker. is_right_only ( & on) {
487- right_push. push ( on)
488- } else {
489- on_filter_join_conditions. push ( on)
490- }
490+ for on in on_filter {
491+ if on_left_preserved && checker. is_left_only ( & on) {
492+ left_push. push ( on)
493+ } else if on_right_preserved && checker. is_right_only ( & on) {
494+ right_push. push ( on)
495+ } else {
496+ on_filter_join_conditions. push ( on)
491497 }
492498 }
493499
494500 // Extract from OR clause, generate new predicates for both side of join if possible.
495501 // We only track the unpushable predicates above.
496- if left_preserved {
497- left_push. extend ( extract_or_clauses_for_join ( & keep_predicates, left_schema) ) ;
498- left_push. extend ( extract_or_clauses_for_join ( & join_conditions, left_schema) ) ;
499- }
500- if right_preserved {
501- right_push. extend ( extract_or_clauses_for_join ( & keep_predicates, right_schema) ) ;
502- right_push. extend ( extract_or_clauses_for_join ( & join_conditions, right_schema) ) ;
503- }
502+ let extend_or_clauses =
503+ |target : & mut Vec < Expr > , filters : & [ Expr ] , schema : & DFSchema , preserved| {
504+ if preserved {
505+ target. extend ( extract_or_clauses_for_join ( filters, schema) ) ;
506+ }
507+ } ;
508+ extend_or_clauses (
509+ & mut left_push,
510+ & keep_predicates,
511+ left_schema,
512+ left_preserved,
513+ ) ;
514+ extend_or_clauses (
515+ & mut left_push,
516+ & join_conditions,
517+ left_schema,
518+ left_preserved,
519+ ) ;
520+ extend_or_clauses (
521+ & mut right_push,
522+ & keep_predicates,
523+ right_schema,
524+ right_preserved,
525+ ) ;
526+ extend_or_clauses (
527+ & mut right_push,
528+ & join_conditions,
529+ right_schema,
530+ right_preserved,
531+ ) ;
504532
505533 // For predicates from join filter, we should check with if a join side is preserved
506534 // in term of join filtering.
507- if on_left_preserved {
508- left_push. extend ( extract_or_clauses_for_join (
509- & on_filter_join_conditions,
510- left_schema,
511- ) ) ;
512- }
513- if on_right_preserved {
514- right_push. extend ( extract_or_clauses_for_join (
515- & on_filter_join_conditions,
516- right_schema,
517- ) ) ;
518- }
535+ extend_or_clauses (
536+ & mut left_push,
537+ & on_filter_join_conditions,
538+ left_schema,
539+ on_left_preserved ,
540+ ) ;
541+ extend_or_clauses (
542+ & mut right_push,
543+ & on_filter_join_conditions,
544+ right_schema,
545+ on_right_preserved ,
546+ ) ;
519547
520548 if let Some ( predicate) = conjunction ( left_push) {
521549 join. left = Arc :: new ( LogicalPlan :: Filter ( Filter :: try_new ( predicate, join. left ) ?) ) ;
0 commit comments