File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -1285,13 +1285,12 @@ pub enum Expr {
12851285 /// Struct field definitions.
12861286 fields : Vec < StructField > ,
12871287 } ,
1288- /// `BigQuery` specific: An named expression in a typeless struct [1]
1288+ /// A named expression: `1 AS A`. Used in `BigQuery` typeless structs [1]
1289+ /// and in aliased function arguments, e.g. `XMLFOREST(a AS x)` in
1290+ /// PostgreSQL [2].
12891291 ///
1290- /// Syntax
1291- /// ```sql
1292- /// 1 AS A
1293- /// ```
12941292 /// [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type
1293+ /// [2]: https://www.postgresql.org/docs/current/functions-xml.html#FUNCTIONS-PRODUCING-XML-XMLFOREST
12951294 Named {
12961295 /// The expression being named.
12971296 expr : Box < Expr > ,
Original file line number Diff line number Diff line change @@ -312,4 +312,8 @@ impl Dialect for GenericDialect {
312312 fn supports_xml_expressions ( & self ) -> bool {
313313 true
314314 }
315+
316+ fn supports_aliased_function_args ( & self ) -> bool {
317+ true
318+ }
315319}
Original file line number Diff line number Diff line change @@ -1767,6 +1767,12 @@ pub trait Dialect: Debug + Any {
17671767 false
17681768 }
17691769
1770+ /// Returns true if the dialect supports aliased function arguments,
1771+ /// e.g. `XMLFOREST(a AS x)` in PostgreSQL.
1772+ fn supports_aliased_function_args ( & self ) -> bool {
1773+ false
1774+ }
1775+
17701776 /// Returns true if the dialect supports `USING <format>` in `CREATE TABLE`.
17711777 ///
17721778 /// Example:
Original file line number Diff line number Diff line change @@ -323,6 +323,10 @@ impl Dialect for PostgreSqlDialect {
323323 true
324324 }
325325
326+ fn supports_aliased_function_args ( & self ) -> bool {
327+ true
328+ }
329+
326330 /// Postgres supports query optimizer hints via the `pg_hint_plan` extension,
327331 /// using the same comment-prefixed-with-`+` syntax as MySQL and Oracle.
328332 ///
Original file line number Diff line number Diff line change @@ -18496,6 +18496,19 @@ impl<'a> Parser<'a> {
1849618496 }
1849718497 other => other.into(),
1849818498 };
18499+ // Aliased argument, e.g. `XMLFOREST(a AS x)` in PostgreSQL
18500+ let arg_expr = match arg_expr {
18501+ FunctionArgExpr::Expr(expr)
18502+ if self.dialect.supports_aliased_function_args()
18503+ && self.parse_keyword(Keyword::AS) =>
18504+ {
18505+ FunctionArgExpr::Expr(Expr::Named {
18506+ expr: expr.into(),
18507+ name: self.parse_identifier()?,
18508+ })
18509+ }
18510+ other => other,
18511+ };
1849918512 Ok(FunctionArg::Unnamed(arg_expr))
1850018513 }
1850118514
Original file line number Diff line number Diff line change @@ -19000,6 +19000,20 @@ fn parse_non_pg_dialects_keep_xml_names_as_regular_identifiers() {
1900019000 dialects.verified_only_select("SELECT xml FROM t");
1900119001}
1900219002
19003+ #[test]
19004+ fn parse_aliased_function_args() {
19005+ let dialects = all_dialects_where(|d| d.supports_aliased_function_args());
19006+ dialects.verified_only_select("SELECT foo(a AS x, b)");
19007+ dialects.verified_only_select("SELECT foo('bar' AS x)");
19008+ dialects.verified_only_select("SELECT foo(1 + 2 AS x)");
19009+ dialects.verified_only_select("SELECT foo(lower(a) AS x, b AS y)");
19010+ dialects.verified_only_select(r#"SELECT foo(a AS "x y")"#);
19011+ dialects.verified_only_select("SELECT foo(bar(a AS x) AS y)");
19012+ assert!(all_dialects_except(|d| d.supports_aliased_function_args())
19013+ .parse_sql_statements("SELECT foo(a AS x)")
19014+ .is_err());
19015+ }
19016+
1900319017/// Regression test for the 2^N parse-time blowup in `parse_compound_expr` on
1900419018/// inputs like `IF a0.a1...aN.#`. The parse is run on a worker thread and the
1900519019/// main thread asserts that it reports back within a generous timeout. Post-fix
Original file line number Diff line number Diff line change @@ -3933,6 +3933,24 @@ fn parse_on_commit() {
39333933 pg_and_generic ( ) . verified_stmt ( "CREATE TEMPORARY TABLE table (COL INT) ON COMMIT DROP" ) ;
39343934}
39353935
3936+ #[ test]
3937+ fn parse_xmlforest_aliased_arguments ( ) {
3938+ let select = pg_and_generic ( ) . verified_only_select ( "SELECT XMLFOREST(a AS x, b)" ) ;
3939+ assert_eq ! (
3940+ expr_from_projection( & select. projection[ 0 ] ) ,
3941+ & call(
3942+ "XMLFOREST" ,
3943+ [
3944+ Expr :: Named {
3945+ expr: Expr :: Identifier ( Ident :: new( "a" ) ) . into( ) ,
3946+ name: Ident :: new( "x" ) ,
3947+ } ,
3948+ Expr :: Identifier ( Ident :: new( "b" ) ) ,
3949+ ]
3950+ )
3951+ ) ;
3952+ }
3953+
39363954#[ test]
39373955fn parse_xml_typed_string ( ) {
39383956 // xml '...' should parse as a TypedString on PostgreSQL and Generic
You can’t perform that action at this time.
0 commit comments