You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ag...@apache.org on 2020/08/12 02:32:07 UTC

[arrow] branch master updated: ARROW-9696: [Rust] [DataFusion] fix nested binary expressions

This is an automated email from the ASF dual-hosted git repository.

agrove pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/master by this push:
     new aec21b2  ARROW-9696: [Rust] [DataFusion] fix nested binary expressions
aec21b2 is described below

commit aec21b292a08a452cfc61a7050fbd4c7a2a753e5
Author: Morgan Cassels <mo...@urbanlogiq.com>
AuthorDate: Tue Aug 11 20:31:27 2020 -0600

    ARROW-9696: [Rust] [DataFusion] fix nested binary expressions
    
    Nested binary expressions like `(a+b)/2` were previously supported and were broken by the upgrade to sqlparser 0.6.1.
    
    Closes #7935 from mcassels/nested_binary_expr
    
    Authored-by: Morgan Cassels <mo...@urbanlogiq.com>
    Signed-off-by: Andy Grove <an...@gmail.com>
---
 rust/datafusion/src/logicalplan.rs             |  4 ++++
 rust/datafusion/src/optimizer/type_coercion.rs |  1 +
 rust/datafusion/src/optimizer/utils.rs         |  1 +
 rust/datafusion/src/sql/planner.rs             | 18 ++++++++++++++++++
 4 files changed, 24 insertions(+)

diff --git a/rust/datafusion/src/logicalplan.rs b/rust/datafusion/src/logicalplan.rs
index 57571b5..507e8b0 100644
--- a/rust/datafusion/src/logicalplan.rs
+++ b/rust/datafusion/src/logicalplan.rs
@@ -321,6 +321,8 @@ pub enum Expr {
         /// Right-hand side of the expression
         right: Box<Expr>,
     },
+    /// Nested expression e.g. `(foo > bar)` or `(1)`
+    Nested(Box<Expr>),
     /// unary NOT
     Not(Box<Expr>),
     /// unary IS NOT NULL
@@ -399,6 +401,7 @@ impl Expr {
             Expr::Wildcard => Err(ExecutionError::General(
                 "Wildcard expressions are not valid in a logical query plan".to_owned(),
             )),
+            Expr::Nested(e) => e.get_type(schema),
         }
     }
 
@@ -646,6 +649,7 @@ impl fmt::Debug for Expr {
                 write!(f, ")")
             }
             Expr::Wildcard => write!(f, "*"),
+            Expr::Nested(expr) => write!(f, "({:?})", expr),
         }
     }
 }
diff --git a/rust/datafusion/src/optimizer/type_coercion.rs b/rust/datafusion/src/optimizer/type_coercion.rs
index a03a92c..78fcf52 100644
--- a/rust/datafusion/src/optimizer/type_coercion.rs
+++ b/rust/datafusion/src/optimizer/type_coercion.rs
@@ -137,6 +137,7 @@ impl<'a> TypeCoercionRule<'a> {
             Expr::Wildcard { .. } => Err(ExecutionError::General(
                 "Wildcard expressions are not valid in a logical query plan".to_owned(),
             )),
+            Expr::Nested(e) => self.rewrite_expr(e, schema),
         }
     }
 }
diff --git a/rust/datafusion/src/optimizer/utils.rs b/rust/datafusion/src/optimizer/utils.rs
index 5c59803..6c9d409 100644
--- a/rust/datafusion/src/optimizer/utils.rs
+++ b/rust/datafusion/src/optimizer/utils.rs
@@ -64,6 +64,7 @@ pub fn expr_to_column_names(expr: &Expr, accum: &mut HashSet<String>) -> Result<
         Expr::Wildcard => Err(ExecutionError::General(
             "Wildcard expressions are not valid in a logical query plan".to_owned(),
         )),
+        Expr::Nested(e) => expr_to_column_names(e, accum),
     }
 }
 
diff --git a/rust/datafusion/src/sql/planner.rs b/rust/datafusion/src/sql/planner.rs
index d80a70f..a78f790 100644
--- a/rust/datafusion/src/sql/planner.rs
+++ b/rust/datafusion/src/sql/planner.rs
@@ -515,6 +515,8 @@ impl<S: SchemaProvider> SqlToRel<S> {
                 }
             }
 
+            SQLExpr::Nested(e) => self.sql_to_rex(&e, &schema),
+
             _ => Err(ExecutionError::General(format!(
                 "Unsupported ast node {:?} in sqltorel",
                 sql
@@ -636,6 +638,22 @@ mod tests {
     }
 
     #[test]
+    fn select_binary_expr() {
+        let sql = "SELECT age + salary from person";
+        let expected = "Projection: #age Plus #salary\
+                        \n  TableScan: person projection=None";
+        quick_test(sql, expected);
+    }
+
+    #[test]
+    fn select_binary_expr_nested() {
+        let sql = "SELECT (age + salary)/2 from person";
+        let expected = "Projection: #age Plus #salary Divide Int64(2)\
+                        \n  TableScan: person projection=None";
+        quick_test(sql, expected);
+    }
+
+    #[test]
     fn select_simple_aggregate() {
         quick_test(
             "SELECT MIN(age) FROM person",