Skip to content

Commit 818ce3f

Browse files
eejbyfeldtalamb
andauthored
refactor: Incorporate RewriteDisjunctivePredicate rule into SimplifyExpressions (#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]>
1 parent 91d2886 commit 818ce3f

File tree

8 files changed

+126
-442
lines changed

8 files changed

+126
-442
lines changed

datafusion/expr/src/utils.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,54 @@ fn split_conjunction_impl<'a>(expr: &'a Expr, mut exprs: Vec<&'a Expr>) -> Vec<&
11011101
}
11021102
}
11031103

1104+
/// Iteratate parts in a conjunctive [`Expr`] such as `A AND B AND C` => `[A, B, C]`
1105+
///
1106+
/// See [`split_conjunction_owned`] for more details and an example.
1107+
pub fn iter_conjunction(expr: &Expr) -> impl Iterator<Item = &Expr> {
1108+
let mut stack = vec![expr];
1109+
std::iter::from_fn(move || {
1110+
while let Some(expr) = stack.pop() {
1111+
match expr {
1112+
Expr::BinaryExpr(BinaryExpr {
1113+
right,
1114+
op: Operator::And,
1115+
left,
1116+
}) => {
1117+
stack.push(right);
1118+
stack.push(left);
1119+
}
1120+
Expr::Alias(Alias { expr, .. }) => stack.push(expr),
1121+
other => return Some(other),
1122+
}
1123+
}
1124+
None
1125+
})
1126+
}
1127+
1128+
/// Iteratate parts in a conjunctive [`Expr`] such as `A AND B AND C` => `[A, B, C]`
1129+
///
1130+
/// See [`split_conjunction_owned`] for more details and an example.
1131+
pub fn iter_conjunction_owned(expr: Expr) -> impl Iterator<Item = Expr> {
1132+
let mut stack = vec![expr];
1133+
std::iter::from_fn(move || {
1134+
while let Some(expr) = stack.pop() {
1135+
match expr {
1136+
Expr::BinaryExpr(BinaryExpr {
1137+
right,
1138+
op: Operator::And,
1139+
left,
1140+
}) => {
1141+
stack.push(*right);
1142+
stack.push(*left);
1143+
}
1144+
Expr::Alias(Alias { expr, .. }) => stack.push(*expr),
1145+
other => return Some(other),
1146+
}
1147+
}
1148+
None
1149+
})
1150+
}
1151+
11041152
/// Splits an owned conjunctive [`Expr`] such as `A AND B AND C` => `[A, B, C]`
11051153
///
11061154
/// This is often used to "split" filter expressions such as `col1 = 5

datafusion/optimizer/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ pub mod propagate_empty_relation;
5151
pub mod push_down_filter;
5252
pub mod push_down_limit;
5353
pub mod replace_distinct_aggregate;
54-
pub mod rewrite_disjunctive_predicate;
5554
pub mod scalar_subquery_to_join;
5655
pub mod simplify_expressions;
5756
pub mod single_distinct_to_groupby;

datafusion/optimizer/src/optimizer.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ use crate::propagate_empty_relation::PropagateEmptyRelation;
5151
use crate::push_down_filter::PushDownFilter;
5252
use crate::push_down_limit::PushDownLimit;
5353
use crate::replace_distinct_aggregate::ReplaceDistinctWithAggregate;
54-
use crate::rewrite_disjunctive_predicate::RewriteDisjunctivePredicate;
5554
use crate::scalar_subquery_to_join::ScalarSubqueryToJoin;
5655
use crate::simplify_expressions::SimplifyExpressions;
5756
use crate::single_distinct_to_groupby::SingleDistinctToGroupBy;
@@ -255,7 +254,6 @@ impl Optimizer {
255254
// run it again after running the optimizations that potentially converted
256255
// subqueries to joins
257256
Arc::new(SimplifyExpressions::new()),
258-
Arc::new(RewriteDisjunctivePredicate::new()),
259257
Arc::new(EliminateDuplicatedExpr::new()),
260258
Arc::new(EliminateFilter::new()),
261259
Arc::new(EliminateCrossJoin::new()),

datafusion/optimizer/src/push_down_filter.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,7 +1213,7 @@ mod tests {
12131213
};
12141214

12151215
use crate::optimizer::Optimizer;
1216-
use crate::rewrite_disjunctive_predicate::RewriteDisjunctivePredicate;
1216+
use crate::simplify_expressions::SimplifyExpressions;
12171217
use crate::test::*;
12181218
use crate::OptimizerContext;
12191219
use datafusion_expr::test::function_stub::sum;
@@ -1235,7 +1235,7 @@ mod tests {
12351235
expected: &str,
12361236
) -> Result<()> {
12371237
let optimizer = Optimizer::with_rules(vec![
1238-
Arc::new(RewriteDisjunctivePredicate::new()),
1238+
Arc::new(SimplifyExpressions::new()),
12391239
Arc::new(PushDownFilter::new()),
12401240
]);
12411241
let optimized_plan =

0 commit comments

Comments
 (0)