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

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


The following commit(s) were added to refs/heads/main by this push:
     new aeaafbe6 Extend lambda support for ClickHouse and DuckDB dialects 
(#1686)
aeaafbe6 is described below

commit aeaafbe6e4f44e21851e13a4d4a8de8518df2263
Author: gstvg <[email protected]>
AuthorDate: Fri Jan 31 02:59:16 2025 -0300

    Extend lambda support for ClickHouse and DuckDB dialects (#1686)
---
 src/ast/mod.rs                |  4 ++-
 src/dialect/clickhouse.rs     |  5 ++++
 src/dialect/duckdb.rs         |  5 ++++
 tests/sqlparser_common.rs     | 65 +++++++++++++++++++++++++++++++++++++++++++
 tests/sqlparser_databricks.rs | 63 -----------------------------------------
 5 files changed, 78 insertions(+), 64 deletions(-)

diff --git a/src/ast/mod.rs b/src/ast/mod.rs
index d3a028b0..5a1be773 100644
--- a/src/ast/mod.rs
+++ b/src/ast/mod.rs
@@ -1045,7 +1045,9 @@ pub enum Expr {
     /// param -> expr | (param1, ...) -> expr
     /// ```
     ///
-    /// See 
<https://docs.databricks.com/en/sql/language-manual/sql-ref-lambda-functions.html>.
+    /// 
[ClickHouse](https://clickhouse.com/docs/en/sql-reference/functions#higher-order-functions---operator-and-lambdaparams-expr-function)
+    /// 
[Databricks](https://docs.databricks.com/en/sql/language-manual/sql-ref-lambda-functions.html)
+    /// [DuckDb](https://duckdb.org/docs/sql/functions/lambda.html)
     Lambda(LambdaFunction),
 }
 
diff --git a/src/dialect/clickhouse.rs b/src/dialect/clickhouse.rs
index 830b3da9..9a0884a5 100644
--- a/src/dialect/clickhouse.rs
+++ b/src/dialect/clickhouse.rs
@@ -70,4 +70,9 @@ impl Dialect for ClickHouseDialect {
     fn supports_dictionary_syntax(&self) -> bool {
         true
     }
+
+    /// See 
<https://clickhouse.com/docs/en/sql-reference/functions#higher-order-functions---operator-and-lambdaparams-expr-function>
+    fn supports_lambda_functions(&self) -> bool {
+        true
+    }
 }
diff --git a/src/dialect/duckdb.rs b/src/dialect/duckdb.rs
index a2699d85..c41aec81 100644
--- a/src/dialect/duckdb.rs
+++ b/src/dialect/duckdb.rs
@@ -65,6 +65,11 @@ impl Dialect for DuckDbDialect {
         true
     }
 
+    /// See <https://duckdb.org/docs/sql/functions/lambda.html>
+    fn supports_lambda_functions(&self) -> bool {
+        true
+    }
+
     // DuckDB is compatible with PostgreSQL syntax for this statement,
     // although not all features may be implemented.
     fn supports_explain_with_utility_options(&self) -> bool {
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index 6f6eccfd..a695204c 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -13332,3 +13332,68 @@ fn test_trailing_commas_in_from() {
         "SELECT 1, 2 FROM (SELECT * FROM t1), (SELECT * FROM t2)",
     );
 }
+
+#[test]
+fn test_lambdas() {
+    let dialects = all_dialects_where(|d| d.supports_lambda_functions());
+
+    #[rustfmt::skip]
+    let sql = concat!(
+        "SELECT array_sort(array('Hello', 'World'), ",
+            "(p1, p2) -> CASE WHEN p1 = p2 THEN 0 ",
+                        "WHEN reverse(p1) < reverse(p2) THEN -1 ",
+                        "ELSE 1 END)",
+    );
+    pretty_assertions::assert_eq!(
+        SelectItem::UnnamedExpr(call(
+            "array_sort",
+            [
+                call(
+                    "array",
+                    [
+                        
Expr::Value(Value::SingleQuotedString("Hello".to_owned())),
+                        
Expr::Value(Value::SingleQuotedString("World".to_owned()))
+                    ]
+                ),
+                Expr::Lambda(LambdaFunction {
+                    params: OneOrManyWithParens::Many(vec![Ident::new("p1"), 
Ident::new("p2")]),
+                    body: Box::new(Expr::Case {
+                        operand: None,
+                        conditions: vec![
+                            Expr::BinaryOp {
+                                left: 
Box::new(Expr::Identifier(Ident::new("p1"))),
+                                op: BinaryOperator::Eq,
+                                right: 
Box::new(Expr::Identifier(Ident::new("p2")))
+                            },
+                            Expr::BinaryOp {
+                                left: Box::new(call(
+                                    "reverse",
+                                    [Expr::Identifier(Ident::new("p1"))]
+                                )),
+                                op: BinaryOperator::Lt,
+                                right: Box::new(call(
+                                    "reverse",
+                                    [Expr::Identifier(Ident::new("p2"))]
+                                ))
+                            }
+                        ],
+                        results: vec![
+                            Expr::Value(number("0")),
+                            Expr::UnaryOp {
+                                op: UnaryOperator::Minus,
+                                expr: Box::new(Expr::Value(number("1")))
+                            }
+                        ],
+                        else_result: Some(Box::new(Expr::Value(number("1"))))
+                    })
+                })
+            ]
+        )),
+        dialects.verified_only_select(sql).projection[0]
+    );
+
+    dialects.verified_expr(
+        "map_zip_with(map(1, 'a', 2, 'b'), map(1, 'x', 2, 'y'), (k, v1, v2) -> 
concat(v1, v2))",
+    );
+    dialects.verified_expr("transform(array(1, 2, 3), x -> x + 1)");
+}
diff --git a/tests/sqlparser_databricks.rs b/tests/sqlparser_databricks.rs
index be7588de..8338a0e7 100644
--- a/tests/sqlparser_databricks.rs
+++ b/tests/sqlparser_databricks.rs
@@ -83,69 +83,6 @@ fn test_databricks_exists() {
     );
 }
 
-#[test]
-fn test_databricks_lambdas() {
-    #[rustfmt::skip]
-    let sql = concat!(
-        "SELECT array_sort(array('Hello', 'World'), ",
-            "(p1, p2) -> CASE WHEN p1 = p2 THEN 0 ",
-                        "WHEN reverse(p1) < reverse(p2) THEN -1 ",
-                        "ELSE 1 END)",
-    );
-    pretty_assertions::assert_eq!(
-        SelectItem::UnnamedExpr(call(
-            "array_sort",
-            [
-                call(
-                    "array",
-                    [
-                        
Expr::Value(Value::SingleQuotedString("Hello".to_owned())),
-                        
Expr::Value(Value::SingleQuotedString("World".to_owned()))
-                    ]
-                ),
-                Expr::Lambda(LambdaFunction {
-                    params: OneOrManyWithParens::Many(vec![Ident::new("p1"), 
Ident::new("p2")]),
-                    body: Box::new(Expr::Case {
-                        operand: None,
-                        conditions: vec![
-                            Expr::BinaryOp {
-                                left: 
Box::new(Expr::Identifier(Ident::new("p1"))),
-                                op: BinaryOperator::Eq,
-                                right: 
Box::new(Expr::Identifier(Ident::new("p2")))
-                            },
-                            Expr::BinaryOp {
-                                left: Box::new(call(
-                                    "reverse",
-                                    [Expr::Identifier(Ident::new("p1"))]
-                                )),
-                                op: BinaryOperator::Lt,
-                                right: Box::new(call(
-                                    "reverse",
-                                    [Expr::Identifier(Ident::new("p2"))]
-                                ))
-                            }
-                        ],
-                        results: vec![
-                            Expr::Value(number("0")),
-                            Expr::UnaryOp {
-                                op: UnaryOperator::Minus,
-                                expr: Box::new(Expr::Value(number("1")))
-                            }
-                        ],
-                        else_result: Some(Box::new(Expr::Value(number("1"))))
-                    })
-                })
-            ]
-        )),
-        databricks().verified_only_select(sql).projection[0]
-    );
-
-    databricks().verified_expr(
-        "map_zip_with(map(1, 'a', 2, 'b'), map(1, 'x', 2, 'y'), (k, v1, v2) -> 
concat(v1, v2))",
-    );
-    databricks().verified_expr("transform(array(1, 2, 3), x -> x + 1)");
-}
-
 #[test]
 fn test_values_clause() {
     let values = Values {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to