You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by gi...@apache.org on 2026/06/08 12:57:27 UTC
(datafusion-sqlparser-rs) branch main updated: Support aliased function arguments (expr AS name) (#2368)
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] 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 0bfafea4 Support aliased function arguments (expr AS name) (#2368)
0bfafea4 is described below
commit 0bfafea45f58adda22ee29dafe069db282769fed
Author: Luca Cappelletti <ca...@gmail.com>
AuthorDate: Mon Jun 8 14:14:20 2026 +0200
Support aliased function arguments (expr AS name) (#2368)
---
src/ast/mod.rs | 9 ++++-----
src/dialect/generic.rs | 4 ++++
src/dialect/mod.rs | 6 ++++++
src/dialect/postgresql.rs | 4 ++++
src/parser/mod.rs | 13 +++++++++++++
tests/sqlparser_common.rs | 14 ++++++++++++++
tests/sqlparser_postgres.rs | 18 ++++++++++++++++++
7 files changed, 63 insertions(+), 5 deletions(-)
diff --git a/src/ast/mod.rs b/src/ast/mod.rs
index e494553c..447d89bb 100644
--- a/src/ast/mod.rs
+++ b/src/ast/mod.rs
@@ -1285,13 +1285,12 @@ pub enum Expr {
/// Struct field definitions.
fields: Vec<StructField>,
},
- /// `BigQuery` specific: An named expression in a typeless struct [1]
+ /// A named expression: `1 AS A`. Used in `BigQuery` typeless structs [1]
+ /// and in aliased function arguments, e.g. `XMLFOREST(a AS x)` in
+ /// PostgreSQL [2].
///
- /// Syntax
- /// ```sql
- /// 1 AS A
- /// ```
/// [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type
+ /// [2]: https://www.postgresql.org/docs/current/functions-xml.html#FUNCTIONS-PRODUCING-XML-XMLFOREST
Named {
/// The expression being named.
expr: Box<Expr>,
diff --git a/src/dialect/generic.rs b/src/dialect/generic.rs
index 25f57e3d..7ee826c2 100644
--- a/src/dialect/generic.rs
+++ b/src/dialect/generic.rs
@@ -312,4 +312,8 @@ impl Dialect for GenericDialect {
fn supports_xml_expressions(&self) -> bool {
true
}
+
+ fn supports_aliased_function_args(&self) -> bool {
+ true
+ }
}
diff --git a/src/dialect/mod.rs b/src/dialect/mod.rs
index 9b2ede40..9515c5bd 100644
--- a/src/dialect/mod.rs
+++ b/src/dialect/mod.rs
@@ -1767,6 +1767,12 @@ pub trait Dialect: Debug + Any {
false
}
+ /// Returns true if the dialect supports aliased function arguments,
+ /// e.g. `XMLFOREST(a AS x)` in PostgreSQL.
+ fn supports_aliased_function_args(&self) -> bool {
+ false
+ }
+
/// Returns true if the dialect supports `USING <format>` in `CREATE TABLE`.
///
/// Example:
diff --git a/src/dialect/postgresql.rs b/src/dialect/postgresql.rs
index c40d6d67..8b52ef6e 100644
--- a/src/dialect/postgresql.rs
+++ b/src/dialect/postgresql.rs
@@ -323,6 +323,10 @@ impl Dialect for PostgreSqlDialect {
true
}
+ fn supports_aliased_function_args(&self) -> bool {
+ true
+ }
+
/// Postgres supports query optimizer hints via the `pg_hint_plan` extension,
/// using the same comment-prefixed-with-`+` syntax as MySQL and Oracle.
///
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 006a0c6f..a7e641f9 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -18496,6 +18496,19 @@ impl<'a> Parser<'a> {
}
other => other.into(),
};
+ // Aliased argument, e.g. `XMLFOREST(a AS x)` in PostgreSQL
+ let arg_expr = match arg_expr {
+ FunctionArgExpr::Expr(expr)
+ if self.dialect.supports_aliased_function_args()
+ && self.parse_keyword(Keyword::AS) =>
+ {
+ FunctionArgExpr::Expr(Expr::Named {
+ expr: expr.into(),
+ name: self.parse_identifier()?,
+ })
+ }
+ other => other,
+ };
Ok(FunctionArg::Unnamed(arg_expr))
}
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index 0d49d0fa..b561f893 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -19000,6 +19000,20 @@ fn parse_non_pg_dialects_keep_xml_names_as_regular_identifiers() {
dialects.verified_only_select("SELECT xml FROM t");
}
+#[test]
+fn parse_aliased_function_args() {
+ let dialects = all_dialects_where(|d| d.supports_aliased_function_args());
+ dialects.verified_only_select("SELECT foo(a AS x, b)");
+ dialects.verified_only_select("SELECT foo('bar' AS x)");
+ dialects.verified_only_select("SELECT foo(1 + 2 AS x)");
+ dialects.verified_only_select("SELECT foo(lower(a) AS x, b AS y)");
+ dialects.verified_only_select(r#"SELECT foo(a AS "x y")"#);
+ dialects.verified_only_select("SELECT foo(bar(a AS x) AS y)");
+ assert!(all_dialects_except(|d| d.supports_aliased_function_args())
+ .parse_sql_statements("SELECT foo(a AS x)")
+ .is_err());
+}
+
/// Regression test for the 2^N parse-time blowup in `parse_compound_expr` on
/// inputs like `IF a0.a1...aN.#`. The parse is run on a worker thread and the
/// main thread asserts that it reports back within a generous timeout. Post-fix
diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs
index 274988be..713d465a 100644
--- a/tests/sqlparser_postgres.rs
+++ b/tests/sqlparser_postgres.rs
@@ -3933,6 +3933,24 @@ fn parse_on_commit() {
pg_and_generic().verified_stmt("CREATE TEMPORARY TABLE table (COL INT) ON COMMIT DROP");
}
+#[test]
+fn parse_xmlforest_aliased_arguments() {
+ let select = pg_and_generic().verified_only_select("SELECT XMLFOREST(a AS x, b)");
+ assert_eq!(
+ expr_from_projection(&select.projection[0]),
+ &call(
+ "XMLFOREST",
+ [
+ Expr::Named {
+ expr: Expr::Identifier(Ident::new("a")).into(),
+ name: Ident::new("x"),
+ },
+ Expr::Identifier(Ident::new("b")),
+ ]
+ )
+ );
+}
+
#[test]
fn parse_xml_typed_string() {
// xml '...' should parse as a TypedString on PostgreSQL and Generic
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org