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]