alamb commented on a change in pull request #1172:
URL: https://github.com/apache/arrow-datafusion/pull/1172#discussion_r735498709



##########
File path: README.md
##########
@@ -191,7 +192,7 @@ DataFusion also includes a simple command-line interactive 
SQL utility. See the
 - Miscellaneous/Boolean functions
   - [x] nullif
 - Approximation functions
-  - [ ] approx_distinct
+  - [x] approx_distinct

Review comment:
       ❤️ 

##########
File path: datafusion/src/sql/planner.rs
##########
@@ -1069,24 +1069,107 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
         }
     }
 
+    fn parse_sql_binary_op(
+        &self,
+        left: &SQLExpr,
+        op: &BinaryOperator,
+        right: &SQLExpr,
+        schema: &DFSchema,
+    ) -> Result<Expr> {
+        let operator = match *op {
+            BinaryOperator::Gt => Ok(Operator::Gt),
+            BinaryOperator::GtEq => Ok(Operator::GtEq),
+            BinaryOperator::Lt => Ok(Operator::Lt),
+            BinaryOperator::LtEq => Ok(Operator::LtEq),
+            BinaryOperator::Eq => Ok(Operator::Eq),
+            BinaryOperator::NotEq => Ok(Operator::NotEq),
+            BinaryOperator::Plus => Ok(Operator::Plus),
+            BinaryOperator::Minus => Ok(Operator::Minus),
+            BinaryOperator::Multiply => Ok(Operator::Multiply),
+            BinaryOperator::Divide => Ok(Operator::Divide),
+            BinaryOperator::Modulo => Ok(Operator::Modulo),
+            BinaryOperator::And => Ok(Operator::And),
+            BinaryOperator::Or => Ok(Operator::Or),
+            BinaryOperator::Like => Ok(Operator::Like),
+            BinaryOperator::NotLike => Ok(Operator::NotLike),
+            BinaryOperator::PGRegexMatch => Ok(Operator::RegexMatch),
+            BinaryOperator::PGRegexIMatch => Ok(Operator::RegexIMatch),
+            BinaryOperator::PGRegexNotMatch => Ok(Operator::RegexNotMatch),
+            BinaryOperator::PGRegexNotIMatch => Ok(Operator::RegexNotIMatch),
+            _ => Err(DataFusionError::NotImplemented(format!(
+                "Unsupported SQL binary operator {:?}",
+                op
+            ))),
+        }?;
+
+        Ok(Expr::BinaryExpr {
+            left: Box::new(self.sql_expr_to_logical_expr(left, schema)?),
+            op: operator,
+            right: Box::new(self.sql_expr_to_logical_expr(right, schema)?),
+        })
+    }
+
+    fn parse_sql_unary_op(
+        &self,
+        op: &UnaryOperator,
+        expr: &SQLExpr,
+        schema: &DFSchema,
+    ) -> Result<Expr> {
+        match op {
+            UnaryOperator::Not => Ok(Expr::Not(Box::new(
+                self.sql_expr_to_logical_expr(expr, schema)?,
+            ))),
+            UnaryOperator::Plus => Ok(self.sql_expr_to_logical_expr(expr, 
schema)?),
+            UnaryOperator::Minus => {
+                match expr {
+                    // optimization: if it's a number literal, we apply the 
negative operator
+                    // here directly to calculate the new literal.
+                    SQLExpr::Value(Value::Number(n,_)) => match 
n.parse::<i64>() {
+                        Ok(n) => Ok(lit(-n)),
+                        Err(_) => Ok(lit(-n
+                            .parse::<f64>()
+                            .map_err(|_e| {
+                                DataFusionError::Internal(format!(
+                                    "negative operator can be only applied to 
integer and float operands, got: {}",
+                                n))
+                            })?)),
+                    },
+                    // not a literal, apply negative operator on expression
+                    _ => 
Ok(Expr::Negative(Box::new(self.sql_expr_to_logical_expr(expr, schema)?))),
+                }
+            }
+            _ => Err(DataFusionError::NotImplemented(format!(
+                "Unsupported SQL unary operator {:?}",
+                op
+            ))),
+        }
+    }
+
     fn sql_values_to_plan(&self, values: &SQLValues) -> Result<LogicalPlan> {
+        // values should not be based on any other schema
+        let schema = DFSchema::empty();
         let values = values
             .0
             .iter()
             .map(|row| {
                 row.iter()
                     .map(|v| match v {
-                        SQLExpr::Value(Value::Number(n, _)) => match 
n.parse::<i64>() {
-                            Ok(n) => Ok(lit(n)),
-                            Err(_) => Ok(lit(n.parse::<f64>().unwrap())),
-                        },
+                        SQLExpr::Value(Value::Number(n, _)) => 
parse_sql_number(n),

Review comment:
       I wonder if we could just call `sql_to_logical_expr` here (rather than 
repeating part of the parsing) so that any expression in the values list could 
be supported
   
   That would allow things like `CASE .. WHEN .. END` type expressions in the 
`VALUES` lists as well
   
   Although if we went with that approach, we probably would have to then do a 
post creation check for unsupported expressions (like `Column`, `Aggregate`, 
etc)
   
   




-- 
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