Jefffrey commented on code in PR #8780:
URL: https://github.com/apache/arrow-datafusion/pull/8780#discussion_r1448501687


##########
datafusion/optimizer/src/simplify_expressions/expr_simplifier.rs:
##########
@@ -224,6 +226,52 @@ impl<S: SimplifyInfo> ExprSimplifier<S> {
     }
 }
 
+/// Canonicalize any BinaryExprs that are not in canonical form
+///
+/// `<literal> <op> <col>` is rewritten to `<col> <op> <literal>`
+///
+/// `<col1> <op> <col2>` is rewritten so that the name of `col1` sorts higher
+/// than `col2` (`b > a` would be canonicalized to `a < b`)
+struct Canonicalizer {}
+
+impl Canonicalizer {
+    fn new() -> Self {
+        Self {}
+    }
+}
+
+impl TreeNodeRewriter for Canonicalizer {
+    type N = Expr;
+
+    fn mutate(&mut self, expr: Expr) -> Result<Expr> {
+        let Expr::BinaryExpr(BinaryExpr { left, op, right }) = expr else {
+            return Ok(expr);
+        };
+        match (left.as_ref(), right.as_ref(), op.swap()) {
+            // <col1> <op> <col2>
+            (Expr::Column(left_col), Expr::Column(right_col), 
Some(swapped_op)) => {
+                if right_col > left_col {
+                    return Ok(Expr::BinaryExpr(BinaryExpr {
+                        left: right,
+                        op: swapped_op,
+                        right: left,
+                    }));
+                }
+            }
+            // <literal> <op> <col>
+            (Expr::Literal(_a), Expr::Column(_b), Some(swapped_op)) => {
+                return Ok(Expr::BinaryExpr(BinaryExpr {
+                    left: right,
+                    op: swapped_op,
+                    right: left,
+                }));
+            }
+            _ => {}
+        }
+        Ok(Expr::BinaryExpr(BinaryExpr { left, op, right }))

Review Comment:
   ```suggestion
           match (left.as_ref(), right.as_ref(), op.swap()) {
               // <col1> <op> <col2>
               (Expr::Column(left_col), Expr::Column(right_col), 
Some(swapped_op)) if right_col > left_col => {
                   Ok(Expr::BinaryExpr(BinaryExpr {
                       left: right,
                       op: swapped_op,
                       right: left,
                   }))
               }
               // <literal> <op> <col>
               (Expr::Literal(_a), Expr::Column(_b), Some(swapped_op)) => {
                   Ok(Expr::BinaryExpr(BinaryExpr {
                       left: right,
                       op: swapped_op,
                       right: left,
                   }))
               }
               _ => Ok(Expr::BinaryExpr(BinaryExpr { left, op, right })),
           }
   ```
   
   One last suggestion for code structure, to take better advantage of how Rust 
enables expressions to simplify things
   
   Essentially pushing the if condition into that first match arm, and then 
removing the need to have a `return` keyword as all the match arms will have 
implicit return



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to