Skip to content

Commit 74c7e52

Browse files
authored
Refactor EliminateOuterJoin to use rewrite() (#10081)
1 parent 671cef8 commit 74c7e52

2 files changed

Lines changed: 42 additions & 31 deletions

File tree

datafusion/optimizer/src/eliminate_outer_join.rs

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717

1818
//! [`EliminateOuterJoin`] converts `LEFT/RIGHT/FULL` joins to `INNER` joins
1919
use crate::{OptimizerConfig, OptimizerRule};
20-
use datafusion_common::{Column, DFSchema, Result};
20+
use datafusion_common::{internal_err, Column, DFSchema, Result};
2121
use datafusion_expr::logical_plan::{Join, JoinType, LogicalPlan};
22-
use datafusion_expr::{Expr, Operator};
22+
use datafusion_expr::{Expr, Filter, Operator};
2323

2424
use crate::optimizer::ApplyOrder;
25+
use datafusion_common::tree_node::Transformed;
2526
use datafusion_expr::expr::{BinaryExpr, Cast, TryCast};
2627
use std::sync::Arc;
2728

@@ -61,9 +62,29 @@ impl EliminateOuterJoin {
6162
impl OptimizerRule for EliminateOuterJoin {
6263
fn try_optimize(
6364
&self,
64-
plan: &LogicalPlan,
65+
_plan: &LogicalPlan,
6566
_config: &dyn OptimizerConfig,
6667
) -> Result<Option<LogicalPlan>> {
68+
internal_err!("Should have called EliminateOuterJoin::rewrite")
69+
}
70+
71+
fn name(&self) -> &str {
72+
"eliminate_outer_join"
73+
}
74+
75+
fn apply_order(&self) -> Option<ApplyOrder> {
76+
Some(ApplyOrder::TopDown)
77+
}
78+
79+
fn supports_rewrite(&self) -> bool {
80+
true
81+
}
82+
83+
fn rewrite(
84+
&self,
85+
plan: LogicalPlan,
86+
_config: &dyn OptimizerConfig,
87+
) -> Result<Transformed<LogicalPlan>> {
6788
match plan {
6889
LogicalPlan::Filter(filter) => match filter.input.as_ref() {
6990
LogicalPlan::Join(join) => {
@@ -75,7 +96,7 @@ impl OptimizerRule for EliminateOuterJoin {
7596
join.left.schema(),
7697
join.right.schema(),
7798
true,
78-
)?;
99+
);
79100

80101
let new_join_type = if join.join_type.is_outer() {
81102
let mut left_non_nullable = false;
@@ -96,7 +117,7 @@ impl OptimizerRule for EliminateOuterJoin {
96117
} else {
97118
join.join_type
98119
};
99-
let new_join = LogicalPlan::Join(Join {
120+
let new_join = Arc::new(LogicalPlan::Join(Join {
100121
left: Arc::new((*join.left).clone()),
101122
right: Arc::new((*join.right).clone()),
102123
join_type: new_join_type,
@@ -105,23 +126,15 @@ impl OptimizerRule for EliminateOuterJoin {
105126
filter: join.filter.clone(),
106127
schema: join.schema.clone(),
107128
null_equals_null: join.null_equals_null,
108-
});
109-
let exprs = plan.expressions();
110-
plan.with_new_exprs(exprs, vec![new_join]).map(Some)
129+
}));
130+
Filter::try_new(filter.predicate, new_join)
131+
.map(|f| Transformed::yes(LogicalPlan::Filter(f)))
111132
}
112-
_ => Ok(None),
133+
_ => Ok(Transformed::no(LogicalPlan::Filter(filter))),
113134
},
114-
_ => Ok(None),
135+
_ => Ok(Transformed::no(plan)),
115136
}
116137
}
117-
118-
fn name(&self) -> &str {
119-
"eliminate_outer_join"
120-
}
121-
122-
fn apply_order(&self) -> Option<ApplyOrder> {
123-
Some(ApplyOrder::TopDown)
124-
}
125138
}
126139

127140
pub fn eliminate_outer(
@@ -169,11 +182,10 @@ fn extract_non_nullable_columns(
169182
left_schema: &Arc<DFSchema>,
170183
right_schema: &Arc<DFSchema>,
171184
top_level: bool,
172-
) -> Result<()> {
185+
) {
173186
match expr {
174187
Expr::Column(col) => {
175188
non_nullable_cols.push(col.clone());
176-
Ok(())
177189
}
178190
Expr::BinaryExpr(BinaryExpr { left, op, right }) => match op {
179191
// If one of the inputs are null for these operators, the results should be false.
@@ -189,7 +201,7 @@ fn extract_non_nullable_columns(
189201
left_schema,
190202
right_schema,
191203
false,
192-
)?;
204+
);
193205
extract_non_nullable_columns(
194206
right,
195207
non_nullable_cols,
@@ -208,15 +220,15 @@ fn extract_non_nullable_columns(
208220
left_schema,
209221
right_schema,
210222
top_level,
211-
)?;
223+
);
212224
extract_non_nullable_columns(
213225
right,
214226
non_nullable_cols,
215227
left_schema,
216228
right_schema,
217229
top_level,
218-
)?;
219-
return Ok(());
230+
);
231+
return;
220232
}
221233

222234
let mut left_non_nullable_cols: Vec<Column> = vec![];
@@ -228,14 +240,14 @@ fn extract_non_nullable_columns(
228240
left_schema,
229241
right_schema,
230242
top_level,
231-
)?;
243+
);
232244
extract_non_nullable_columns(
233245
right,
234246
&mut right_non_nullable_cols,
235247
left_schema,
236248
right_schema,
237249
top_level,
238-
)?;
250+
);
239251

240252
// for query: select *** from a left join b where b.c1 ... or b.c2 ...
241253
// this can be eliminated to inner join.
@@ -259,9 +271,8 @@ fn extract_non_nullable_columns(
259271
}
260272
}
261273
}
262-
Ok(())
263274
}
264-
_ => Ok(()),
275+
_ => {}
265276
},
266277
Expr::Not(arg) => extract_non_nullable_columns(
267278
arg,
@@ -272,7 +283,7 @@ fn extract_non_nullable_columns(
272283
),
273284
Expr::IsNotNull(arg) => {
274285
if !top_level {
275-
return Ok(());
286+
return;
276287
}
277288
extract_non_nullable_columns(
278289
arg,
@@ -290,7 +301,7 @@ fn extract_non_nullable_columns(
290301
right_schema,
291302
false,
292303
),
293-
_ => Ok(()),
304+
_ => {}
294305
}
295306
}
296307

datafusion/optimizer/src/simplify_expressions/simplify_exprs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ impl OptimizerRule for SimplifyExpressions {
5353
_plan: &LogicalPlan,
5454
_config: &dyn OptimizerConfig,
5555
) -> Result<Option<LogicalPlan>> {
56-
internal_err!("Should have called SimplifyExpressions::try_optimize_owned")
56+
internal_err!("Should have called SimplifyExpressions::rewrite")
5757
}
5858

5959
fn name(&self) -> &str {

0 commit comments

Comments
 (0)