From c7b5eeaf27a6c1f1a707d0f4b9ac6dffe73d9101 Mon Sep 17 00:00:00 2001 From: Christian Salvati <81280761+src255@users.noreply.github.com> Date: Fri, 21 Oct 2022 02:06:16 -0400 Subject: [PATCH 1/2] Simplify redundant predicates Write rules to simplify both `a OR a` and `a AND a` to a. --- datafusion/optimizer/src/simplify_expressions.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/datafusion/optimizer/src/simplify_expressions.rs b/datafusion/optimizer/src/simplify_expressions.rs index 03f79feba336..7423d9d75213 100644 --- a/datafusion/optimizer/src/simplify_expressions.rs +++ b/datafusion/optimizer/src/simplify_expressions.rs @@ -741,6 +741,12 @@ impl<'a, S: SimplifyInfo> ExprRewriter for Simplifier<'a, S> { // Rules for OR // + // A OR A --> A + Expr::BinaryExpr(BinaryExpr { + left, + op: Or, + right, + }) if &left == &right => *left, // true OR A --> true (even if A is null) Expr::BinaryExpr(BinaryExpr { left, @@ -794,6 +800,12 @@ impl<'a, S: SimplifyInfo> ExprRewriter for Simplifier<'a, S> { // Rules for AND // + // A AND A --> A + Expr::BinaryExpr(BinaryExpr { + left, + op: And, + right, + }) if &left == &right => *left, // true AND A --> A Expr::BinaryExpr(BinaryExpr { left, From e243e2b841ba9056462b534a05e4ed781404a468 Mon Sep 17 00:00:00 2001 From: Christian Salvati <81280761+src255@users.noreply.github.com> Date: Sat, 22 Oct 2022 00:12:53 -0400 Subject: [PATCH 2/2] Add test for redudant `or` expression Test simplification of `a OR a` --> `a` and remove unnecessary rules introduced in the previous commit. --- .../optimizer/src/simplify_expressions.rs | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/datafusion/optimizer/src/simplify_expressions.rs b/datafusion/optimizer/src/simplify_expressions.rs index 7423d9d75213..bc3ac6e84b23 100644 --- a/datafusion/optimizer/src/simplify_expressions.rs +++ b/datafusion/optimizer/src/simplify_expressions.rs @@ -741,12 +741,6 @@ impl<'a, S: SimplifyInfo> ExprRewriter for Simplifier<'a, S> { // Rules for OR // - // A OR A --> A - Expr::BinaryExpr(BinaryExpr { - left, - op: Or, - right, - }) if &left == &right => *left, // true OR A --> true (even if A is null) Expr::BinaryExpr(BinaryExpr { left, @@ -800,12 +794,6 @@ impl<'a, S: SimplifyInfo> ExprRewriter for Simplifier<'a, S> { // Rules for AND // - // A AND A --> A - Expr::BinaryExpr(BinaryExpr { - left, - op: And, - right, - }) if &left == &right => *left, // true AND A --> A Expr::BinaryExpr(BinaryExpr { left, @@ -2164,6 +2152,26 @@ mod tests { ); } + #[test] + fn test_simplify_optimized_plan_with_or() { + let table_scan = test_table_scan(); + let plan = LogicalPlanBuilder::from(table_scan) + .project(vec![col("a")]) + .unwrap() + .filter(or(col("b").gt(lit(1)), col("b").gt(lit(1)))) + .unwrap() + .build() + .unwrap(); + + assert_optimized_plan_eq( + &plan, + "\ + Filter: test.b > Int32(1)\ + \n Projection: test.a\ + \n TableScan: test", + ); + } + #[test] fn test_simplify_optimized_plan_with_composed_and() { let table_scan = test_table_scan();