Skip to content

Commit

Permalink
refactor: Incorporate RewriteDisjunctivePredicate rule into SimplifyE…
Browse files Browse the repository at this point in the history
…xpressions (#13032)

* Elliminate common factors in disjunctions

This adds a rewrite rule that elliminates common factors in OR. This is
already implmented in RewriteDisjunctivePredicate but this
implementation is simpler and will apply in more cases.

* Remove RewriteDisjunctivePredicate rule

* Fix cse test

* Update datafusion/optimizer/src/simplify_expressions/expr_simplifier.rs

Co-authored-by: Andrew Lamb <[email protected]>

---------

Co-authored-by: Andrew Lamb <[email protected]>
  • Loading branch information
eejbyfeldt and alamb authored Oct 22, 2024
1 parent 91d2886 commit 818ce3f
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 442 deletions.
48 changes: 48 additions & 0 deletions datafusion/expr/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,54 @@ fn split_conjunction_impl<'a>(expr: &'a Expr, mut exprs: Vec<&'a Expr>) -> Vec<&
}
}

/// Iteratate parts in a conjunctive [`Expr`] such as `A AND B AND C` => `[A, B, C]`
///
/// See [`split_conjunction_owned`] for more details and an example.
pub fn iter_conjunction(expr: &Expr) -> impl Iterator<Item = &Expr> {
let mut stack = vec![expr];
std::iter::from_fn(move || {
while let Some(expr) = stack.pop() {
match expr {
Expr::BinaryExpr(BinaryExpr {
right,
op: Operator::And,
left,
}) => {
stack.push(right);
stack.push(left);
}
Expr::Alias(Alias { expr, .. }) => stack.push(expr),
other => return Some(other),
}
}
None
})
}

/// Iteratate parts in a conjunctive [`Expr`] such as `A AND B AND C` => `[A, B, C]`
///
/// See [`split_conjunction_owned`] for more details and an example.
pub fn iter_conjunction_owned(expr: Expr) -> impl Iterator<Item = Expr> {
let mut stack = vec![expr];
std::iter::from_fn(move || {
while let Some(expr) = stack.pop() {
match expr {
Expr::BinaryExpr(BinaryExpr {
right,
op: Operator::And,
left,
}) => {
stack.push(*right);
stack.push(*left);
}
Expr::Alias(Alias { expr, .. }) => stack.push(*expr),
other => return Some(other),
}
}
None
})
}

/// Splits an owned conjunctive [`Expr`] such as `A AND B AND C` => `[A, B, C]`
///
/// This is often used to "split" filter expressions such as `col1 = 5
Expand Down
1 change: 0 additions & 1 deletion datafusion/optimizer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ pub mod propagate_empty_relation;
pub mod push_down_filter;
pub mod push_down_limit;
pub mod replace_distinct_aggregate;
pub mod rewrite_disjunctive_predicate;
pub mod scalar_subquery_to_join;
pub mod simplify_expressions;
pub mod single_distinct_to_groupby;
Expand Down
2 changes: 0 additions & 2 deletions datafusion/optimizer/src/optimizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ use crate::propagate_empty_relation::PropagateEmptyRelation;
use crate::push_down_filter::PushDownFilter;
use crate::push_down_limit::PushDownLimit;
use crate::replace_distinct_aggregate::ReplaceDistinctWithAggregate;
use crate::rewrite_disjunctive_predicate::RewriteDisjunctivePredicate;
use crate::scalar_subquery_to_join::ScalarSubqueryToJoin;
use crate::simplify_expressions::SimplifyExpressions;
use crate::single_distinct_to_groupby::SingleDistinctToGroupBy;
Expand Down Expand Up @@ -255,7 +254,6 @@ impl Optimizer {
// run it again after running the optimizations that potentially converted
// subqueries to joins
Arc::new(SimplifyExpressions::new()),
Arc::new(RewriteDisjunctivePredicate::new()),
Arc::new(EliminateDuplicatedExpr::new()),
Arc::new(EliminateFilter::new()),
Arc::new(EliminateCrossJoin::new()),
Expand Down
4 changes: 2 additions & 2 deletions datafusion/optimizer/src/push_down_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1213,7 +1213,7 @@ mod tests {
};

use crate::optimizer::Optimizer;
use crate::rewrite_disjunctive_predicate::RewriteDisjunctivePredicate;
use crate::simplify_expressions::SimplifyExpressions;
use crate::test::*;
use crate::OptimizerContext;
use datafusion_expr::test::function_stub::sum;
Expand All @@ -1235,7 +1235,7 @@ mod tests {
expected: &str,
) -> Result<()> {
let optimizer = Optimizer::with_rules(vec![
Arc::new(RewriteDisjunctivePredicate::new()),
Arc::new(SimplifyExpressions::new()),
Arc::new(PushDownFilter::new()),
]);
let optimized_plan =
Expand Down
Loading

0 comments on commit 818ce3f

Please sign in to comment.