Skip to content

Commit 08030f3

Browse files
authored
Implement rewrite for EliminateOneUnion and EliminateJoin (#10184)
* implement rewrite for EliminateJoin * implement rewrite for eliminate_on_union
1 parent c96182b commit 08030f3

File tree

3 files changed

+54
-29
lines changed

3 files changed

+54
-29
lines changed

datafusion/expr/src/logical_plan/tree_node.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ impl TreeNode for LogicalPlan {
363363

364364
/// Converts a `Arc<LogicalPlan>` without copying, if possible. Copies the plan
365365
/// if there is a shared reference
366-
fn unwrap_arc(plan: Arc<LogicalPlan>) -> LogicalPlan {
366+
pub fn unwrap_arc(plan: Arc<LogicalPlan>) -> LogicalPlan {
367367
Arc::try_unwrap(plan)
368368
// if None is returned, there is another reference to this
369369
// LogicalPlan, so we can not own it, and must clone instead

datafusion/optimizer/src/eliminate_join.rs

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
//! [`EliminateJoin`] rewrites `INNER JOIN` with `true`/`null`
1919
use crate::optimizer::ApplyOrder;
2020
use crate::{OptimizerConfig, OptimizerRule};
21-
use datafusion_common::{Result, ScalarValue};
21+
use datafusion_common::tree_node::Transformed;
22+
use datafusion_common::{internal_err, Result, ScalarValue};
2223
use datafusion_expr::JoinType::Inner;
2324
use datafusion_expr::{
2425
logical_plan::{EmptyRelation, LogicalPlan},
@@ -39,38 +40,50 @@ impl EliminateJoin {
3940
impl OptimizerRule for EliminateJoin {
4041
fn try_optimize(
4142
&self,
42-
plan: &LogicalPlan,
43+
_plan: &LogicalPlan,
4344
_config: &dyn OptimizerConfig,
4445
) -> Result<Option<LogicalPlan>> {
46+
internal_err!("Should have called EliminateJoin::rewrite")
47+
}
48+
49+
fn name(&self) -> &str {
50+
"eliminate_join"
51+
}
52+
53+
fn apply_order(&self) -> Option<ApplyOrder> {
54+
Some(ApplyOrder::TopDown)
55+
}
56+
57+
fn rewrite(
58+
&self,
59+
plan: LogicalPlan,
60+
_config: &dyn OptimizerConfig,
61+
) -> Result<Transformed<LogicalPlan>> {
4562
match plan {
4663
LogicalPlan::Join(join) if join.join_type == Inner && join.on.is_empty() => {
4764
match join.filter {
4865
Some(Expr::Literal(ScalarValue::Boolean(Some(true)))) => {
49-
Ok(Some(LogicalPlan::CrossJoin(CrossJoin {
50-
left: join.left.clone(),
51-
right: join.right.clone(),
52-
schema: join.schema.clone(),
66+
Ok(Transformed::yes(LogicalPlan::CrossJoin(CrossJoin {
67+
left: join.left,
68+
right: join.right,
69+
schema: join.schema,
5370
})))
5471
}
55-
Some(Expr::Literal(ScalarValue::Boolean(Some(false)))) => {
56-
Ok(Some(LogicalPlan::EmptyRelation(EmptyRelation {
72+
Some(Expr::Literal(ScalarValue::Boolean(Some(false)))) => Ok(
73+
Transformed::yes(LogicalPlan::EmptyRelation(EmptyRelation {
5774
produce_one_row: false,
58-
schema: join.schema.clone(),
59-
})))
60-
}
61-
_ => Ok(None),
75+
schema: join.schema,
76+
})),
77+
),
78+
_ => Ok(Transformed::no(LogicalPlan::Join(join))),
6279
}
6380
}
64-
_ => Ok(None),
81+
_ => Ok(Transformed::no(plan)),
6582
}
6683
}
6784

68-
fn name(&self) -> &str {
69-
"eliminate_join"
70-
}
71-
72-
fn apply_order(&self) -> Option<ApplyOrder> {
73-
Some(ApplyOrder::TopDown)
85+
fn supports_rewrite(&self) -> bool {
86+
true
7487
}
7588
}
7689

datafusion/optimizer/src/eliminate_one_union.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717

1818
//! [`EliminateOneUnion`] eliminates single element `Union`
1919
use crate::{OptimizerConfig, OptimizerRule};
20-
use datafusion_common::Result;
21-
use datafusion_expr::logical_plan::{LogicalPlan, Union};
20+
use datafusion_common::{internal_err, tree_node::Transformed, Result};
21+
use datafusion_expr::logical_plan::{tree_node::unwrap_arc, LogicalPlan, Union};
2222

2323
use crate::optimizer::ApplyOrder;
2424

@@ -36,21 +36,33 @@ impl EliminateOneUnion {
3636
impl OptimizerRule for EliminateOneUnion {
3737
fn try_optimize(
3838
&self,
39-
plan: &LogicalPlan,
39+
_plan: &LogicalPlan,
4040
_config: &dyn OptimizerConfig,
4141
) -> Result<Option<LogicalPlan>> {
42-
match plan {
43-
LogicalPlan::Union(Union { inputs, .. }) if inputs.len() == 1 => {
44-
Ok(inputs.first().map(|input| input.as_ref().clone()))
45-
}
46-
_ => Ok(None),
47-
}
42+
internal_err!("Should have called EliminateOneUnion::rewrite")
4843
}
4944

5045
fn name(&self) -> &str {
5146
"eliminate_one_union"
5247
}
5348

49+
fn supports_rewrite(&self) -> bool {
50+
true
51+
}
52+
53+
fn rewrite(
54+
&self,
55+
plan: LogicalPlan,
56+
_config: &dyn OptimizerConfig,
57+
) -> Result<Transformed<LogicalPlan>> {
58+
match plan {
59+
LogicalPlan::Union(Union { mut inputs, .. }) if inputs.len() == 1 => {
60+
Ok(Transformed::yes(unwrap_arc(inputs.pop().unwrap())))
61+
}
62+
_ => Ok(Transformed::no(plan)),
63+
}
64+
}
65+
5466
fn apply_order(&self) -> Option<ApplyOrder> {
5567
Some(ApplyOrder::TopDown)
5668
}

0 commit comments

Comments
 (0)