Skip to content

Commit c61828c

Browse files
Lordwormsccciudatu
authored andcommitted
implement rewrite for FilterNullJoinKeys (apache#10166)
1 parent 34a9bf1 commit c61828c

File tree

1 file changed

+32
-29
lines changed

1 file changed

+32
-29
lines changed

datafusion/optimizer/src/filter_null_join_keys.rs

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919
2020
use crate::optimizer::ApplyOrder;
2121
use crate::{OptimizerConfig, OptimizerRule};
22-
use datafusion_common::Result;
22+
use datafusion_common::tree_node::Transformed;
23+
use datafusion_common::{internal_err, Result};
24+
use datafusion_expr::utils::conjunction;
2325
use datafusion_expr::{
24-
and, logical_plan::Filter, logical_plan::JoinType, Expr, ExprSchemable, LogicalPlan,
26+
logical_plan::Filter, logical_plan::JoinType, Expr, ExprSchemable, LogicalPlan,
2527
};
2628
use std::sync::Arc;
2729

@@ -32,24 +34,34 @@ use std::sync::Arc;
3234
#[derive(Default)]
3335
pub struct FilterNullJoinKeys {}
3436

35-
impl FilterNullJoinKeys {
36-
pub const NAME: &'static str = "filter_null_join_keys";
37-
}
38-
3937
impl OptimizerRule for FilterNullJoinKeys {
4038
fn try_optimize(
4139
&self,
42-
plan: &LogicalPlan,
43-
config: &dyn OptimizerConfig,
40+
_plan: &LogicalPlan,
41+
_config: &dyn OptimizerConfig,
4442
) -> Result<Option<LogicalPlan>> {
43+
internal_err!("Should have called FilterNullJoinKeys::rewrite")
44+
}
45+
46+
fn supports_rewrite(&self) -> bool {
47+
true
48+
}
49+
50+
fn apply_order(&self) -> Option<ApplyOrder> {
51+
Some(ApplyOrder::BottomUp)
52+
}
53+
54+
fn rewrite(
55+
&self,
56+
plan: LogicalPlan,
57+
config: &dyn OptimizerConfig,
58+
) -> Result<Transformed<LogicalPlan>> {
4559
if !config.options().optimizer.filter_null_join_keys {
46-
return Ok(None);
60+
return Ok(Transformed::no(plan));
4761
}
4862

4963
match plan {
50-
LogicalPlan::Join(join) if join.join_type == JoinType::Inner => {
51-
let mut join = join.clone();
52-
64+
LogicalPlan::Join(mut join) if join.join_type == JoinType::Inner => {
5365
let left_schema = join.left.schema();
5466
let right_schema = join.right.schema();
5567

@@ -69,29 +81,22 @@ impl OptimizerRule for FilterNullJoinKeys {
6981
if !left_filters.is_empty() {
7082
let predicate = create_not_null_predicate(left_filters);
7183
join.left = Arc::new(LogicalPlan::Filter(Filter::try_new(
72-
predicate,
73-
join.left.clone(),
84+
predicate, join.left,
7485
)?));
7586
}
7687
if !right_filters.is_empty() {
7788
let predicate = create_not_null_predicate(right_filters);
7889
join.right = Arc::new(LogicalPlan::Filter(Filter::try_new(
79-
predicate,
80-
join.right.clone(),
90+
predicate, join.right,
8191
)?));
8292
}
83-
Ok(Some(LogicalPlan::Join(join)))
93+
Ok(Transformed::yes(LogicalPlan::Join(join)))
8494
}
85-
_ => Ok(None),
95+
_ => Ok(Transformed::no(plan)),
8696
}
8797
}
88-
8998
fn name(&self) -> &str {
90-
Self::NAME
91-
}
92-
93-
fn apply_order(&self) -> Option<ApplyOrder> {
94-
Some(ApplyOrder::BottomUp)
99+
"filter_null_join_keys"
95100
}
96101
}
97102

@@ -100,11 +105,9 @@ fn create_not_null_predicate(filters: Vec<Expr>) -> Expr {
100105
.into_iter()
101106
.map(|c| Expr::IsNotNull(Box::new(c)))
102107
.collect();
103-
// combine the IsNotNull expressions with AND
104-
not_null_exprs
105-
.iter()
106-
.skip(1)
107-
.fold(not_null_exprs[0].clone(), |a, b| and(a, b.clone()))
108+
109+
// directly unwrap since it should always have a value
110+
conjunction(not_null_exprs).unwrap()
108111
}
109112

110113
#[cfg(test)]

0 commit comments

Comments
 (0)