You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@arrow.apache.org by GitBox <gi...@apache.org> on 2020/11/24 17:54:29 UTC

[GitHub] [arrow] jorgecarleitao commented on a change in pull request #8749: ARROW-10689: [Rust] [DataFusion] Add SQL support for CASE WHEN

jorgecarleitao commented on a change in pull request #8749:
URL: https://github.com/apache/arrow/pull/8749#discussion_r529768333



##########
File path: rust/datafusion/src/sql/planner.rs
##########
@@ -446,6 +446,42 @@ impl<'a, S: SchemaProvider> SqlToRel<'a, S> {
 
             SQLExpr::Wildcard => Ok(Expr::Wildcard),
 
+            SQLExpr::Case {
+                operand,
+                conditions,
+                results,
+                else_result,
+            } => {
+                let expr = if let Some(e) = operand {
+                    Some(Box::new(self.sql_to_rex(e, schema)?))
+                } else {
+                    None
+                };
+                let when_expr = conditions
+                    .iter()
+                    .map(|e| self.sql_to_rex(e, schema))
+                    .collect::<Result<Vec<_>>>()?;
+                let then_expr = results
+                    .iter()
+                    .map(|e| self.sql_to_rex(e, schema))
+                    .collect::<Result<Vec<_>>>()?;
+                let else_expr = if let Some(e) = else_result {
+                    Some(Box::new(self.sql_to_rex(e, schema)?))
+                } else {
+                    None
+                };

Review comment:
       Very clean implementation! 💯 

##########
File path: rust/datafusion/tests/sql.rs
##########
@@ -910,6 +910,76 @@ async fn csv_query_count_one() {
     assert_eq!(expected, actual);
 }
 
+#[tokio::test]
+async fn case_when() {
+    let mut ctx = ExecutionContext::new();
+    register_aggregate_csv_by_sql(&mut ctx).await;
+    let sql = "SELECT \
+        CASE WHEN c1 = 'a' THEN 1 \
+             WHEN c1 = 'b' THEN 2 \
+             ELSE 999 END \
+        FROM aggregate_test_100 LIMIT 20";
+    let actual = execute(&mut ctx, sql).await;
+    let expected = vec![
+        vec!["999"],
+        vec!["999"],
+        vec!["2"],
+        vec!["1"],
+        vec!["2"],
+        vec!["2"],
+        vec!["999"],
+        vec!["1"],
+        vec!["999"],
+        vec!["1"],
+        vec!["999"],
+        vec!["1"],
+        vec!["999"],
+        vec!["999"],
+        vec!["2"],
+        vec!["999"],
+        vec!["999"],
+        vec!["999"],
+        vec!["999"],
+        vec!["999"],
+    ];

Review comment:
       It is a bit difficult for me to confirm that this is correct. What do you think if we just generate a table in memory with all possibilities and test against that? IMO it is a bit more explicit and also allows to verify the cases with null values.




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

For queries about this service, please contact Infrastructure at:
users@infra.apache.org