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

alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-datafusion.git


The following commit(s) were added to refs/heads/main by this push:
     new 9a30cbb876 Add Expr->String for Exists, Sort (#9936)
9a30cbb876 is described below

commit 9a30cbb87604d404fcd6909e492519551d6a9112
Author: Kevin Mingtarja <[email protected]>
AuthorDate: Fri Apr 5 02:35:34 2024 +0800

    Add Expr->String for Exists, Sort (#9936)
---
 datafusion/sql/src/unparser/expr.rs | 47 +++++++++++++++++++++++++++++++++----
 1 file changed, 43 insertions(+), 4 deletions(-)

diff --git a/datafusion/sql/src/unparser/expr.rs 
b/datafusion/sql/src/unparser/expr.rs
index 07b077eb50..623f61fb60 100644
--- a/datafusion/sql/src/unparser/expr.rs
+++ b/datafusion/sql/src/unparser/expr.rs
@@ -21,7 +21,10 @@ use datafusion_common::{
     internal_datafusion_err, not_impl_err, plan_err, Column, Result, 
ScalarValue,
 };
 use datafusion_expr::{
-    expr::{AggregateFunctionDefinition, Alias, InList, ScalarFunction, 
WindowFunction},
+    expr::{
+        AggregateFunctionDefinition, Alias, Exists, InList, ScalarFunction, 
Sort,
+        WindowFunction,
+    },
     Between, BinaryExpr, Case, Cast, Expr, Like, Operator,
 };
 use sqlparser::ast::{
@@ -264,6 +267,26 @@ impl Unparser<'_> {
                     negated: insubq.negated,
                 })
             }
+            Expr::Exists(Exists { subquery, negated }) => {
+                let sub_statement = 
self.plan_to_sql(subquery.subquery.as_ref())?;
+                let sub_query = if let ast::Statement::Query(inner_query) = 
sub_statement
+                {
+                    inner_query
+                } else {
+                    return plan_err!(
+                        "Subquery must be a Query, but found {sub_statement:?}"
+                    );
+                };
+                Ok(ast::Expr::Exists {
+                    subquery: sub_query,
+                    negated: *negated,
+                })
+            }
+            Expr::Sort(Sort {
+                expr,
+                asc: _,
+                nulls_first: _,
+            }) => self.expr_to_sql(expr),
             Expr::IsNotNull(expr) => {
                 Ok(ast::Expr::IsNotNull(Box::new(self.expr_to_sql(expr)?)))
             }
@@ -644,12 +667,13 @@ impl Unparser<'_> {
 
 #[cfg(test)]
 mod tests {
-    use std::any::Any;
+    use std::{any::Any, sync::Arc, vec};
 
+    use arrow::datatypes::{Field, Schema};
     use datafusion_common::TableReference;
     use datafusion_expr::{
-        case, col, expr::AggregateFunction, lit, not, ColumnarValue, ScalarUDF,
-        ScalarUDFImpl, Signature, Volatility,
+        case, col, exists, expr::AggregateFunction, lit, not, not_exists, 
table_scan,
+        ColumnarValue, ScalarUDF, ScalarUDFImpl, Signature, Volatility,
     };
 
     use crate::unparser::dialect::CustomDialect;
@@ -695,6 +719,12 @@ mod tests {
 
     #[test]
     fn expr_to_sql_ok() -> Result<()> {
+        let dummy_schema = Schema::new(vec![Field::new("a", DataType::Int32, 
false)]);
+        let dummy_logical_plan = table_scan(Some("t"), &dummy_schema, None)?
+            .project(vec![Expr::Wildcard { qualifier: None }])?
+            .filter(col("a").eq(lit(1)))?
+            .build()?;
+
         let tests: Vec<(Expr, &str)> = vec![
             ((col("a") + col("b")).gt(lit(4)), r#"(("a" + "b") > 4)"#),
             (
@@ -835,6 +865,15 @@ mod tests {
                 r#"("a" BETWEEN 1 AND 7)"#,
             ),
             (Expr::Negative(Box::new(col("a"))), r#"-"a""#),
+            (
+                exists(Arc::new(dummy_logical_plan.clone())),
+                r#"EXISTS (SELECT "t"."a" FROM "t" WHERE ("t"."a" = 1))"#,
+            ),
+            (
+                not_exists(Arc::new(dummy_logical_plan.clone())),
+                r#"NOT EXISTS (SELECT "t"."a" FROM "t" WHERE ("t"."a" = 1))"#,
+            ),
+            (col("a").sort(true, true), r#""a""#),
         ];
 
         for (expr, expected) in tests {

Reply via email to