@@ -18676,37 +18676,59 @@ impl<'a> Parser<'a> {
1867618676
1867718677 /// Parse a single function argument, handling named and unnamed variants.
1867818678 pub fn parse_function_args(&mut self) -> Result<FunctionArg, ParserError> {
18679- let arg = if self.dialect.supports_named_fn_args_with_expr_name() {
18680- self.maybe_parse(|p| {
18681- let name = p.parse_expr()?;
18682- let operator = p.parse_function_named_arg_operator()?;
18683- let arg = p.parse_wildcard_expr()?.into();
18684- Ok(FunctionArg::ExprNamed {
18685- name,
18686- arg,
18687- operator,
18688- })
18689- })?
18690- } else {
18691- self.maybe_parse(|p| {
18692- let name = p.parse_identifier()?;
18693- let operator = p.parse_function_named_arg_operator()?;
18694- let arg = p.parse_wildcard_expr()?.into();
18695- Ok(FunctionArg::Named {
18696- name,
18697- arg,
18698- operator,
18699- })
18700- })?
18701- };
18679+ // Parse the argument expression once, then check for a named-arg
18680+ // operator. Parsing it speculatively and re-parsing on the unnamed
18681+ // path is O(2^depth) on nested calls like `CAST(CASE (CAST(CASE (…`.
18682+ if self.dialect.supports_named_fn_args_with_expr_name() {
18683+ let expr = self.parse_wildcard_expr()?;
18684+ // A wildcard is never a named-arg name; only the unnamed form applies.
18685+ if !matches!(expr, Expr::Wildcard(_) | Expr::QualifiedWildcard(..)) {
18686+ if let Some(operator) =
18687+ self.maybe_parse(|p| p.parse_function_named_arg_operator())?
18688+ {
18689+ let arg = self.parse_wildcard_expr()?.into();
18690+ return Ok(FunctionArg::ExprNamed {
18691+ name: expr,
18692+ arg,
18693+ operator,
18694+ });
18695+ }
18696+ }
18697+ let arg_expr = self.function_arg_expr_from_wildcard(expr)?;
18698+ return Ok(FunctionArg::Unnamed(
18699+ self.maybe_parse_aliased_function_arg(arg_expr)?,
18700+ ));
18701+ }
18702+
18703+ let arg = self.maybe_parse(|p| {
18704+ let name = p.parse_identifier()?;
18705+ let operator = p.parse_function_named_arg_operator()?;
18706+ let arg = p.parse_wildcard_expr()?.into();
18707+ Ok(FunctionArg::Named {
18708+ name,
18709+ arg,
18710+ operator,
18711+ })
18712+ })?;
1870218713 if let Some(arg) = arg {
1870318714 return Ok(arg);
1870418715 }
1870518716 let wildcard_expr = self.parse_wildcard_expr()?;
18706- let arg_expr: FunctionArgExpr = match wildcard_expr {
18717+ let arg_expr = self.function_arg_expr_from_wildcard(wildcard_expr)?;
18718+ Ok(FunctionArg::Unnamed(
18719+ self.maybe_parse_aliased_function_arg(arg_expr)?,
18720+ ))
18721+ }
18722+
18723+ /// Wrap an already-parsed expression as a function argument, parsing any
18724+ /// trailing wildcard options (e.g. Snowflake's `HASH(* EXCLUDE(col))`).
18725+ fn function_arg_expr_from_wildcard(
18726+ &mut self,
18727+ wildcard_expr: Expr,
18728+ ) -> Result<FunctionArgExpr, ParserError> {
18729+ Ok(match wildcard_expr {
1870718730 Expr::Wildcard(ref token) if self.dialect.supports_select_wildcard_exclude() => {
18708- // Support `* EXCLUDE(col1, col2, ...)` inside function calls (e.g. Snowflake's
18709- // `HASH(* EXCLUDE(col))`). Parse the options the same way SELECT items do.
18731+ // Parse the options the same way SELECT items do.
1871018732 let opts = self.parse_wildcard_additional_options(token.0.clone())?;
1871118733 if opts.opt_exclude.is_some()
1871218734 || opts.opt_except.is_some()
@@ -18720,9 +18742,16 @@ impl<'a> Parser<'a> {
1872018742 }
1872118743 }
1872218744 other => other.into(),
18723- };
18724- // Aliased argument, e.g. `XMLFOREST(a AS x)` in PostgreSQL
18725- let arg_expr = match arg_expr {
18745+ })
18746+ }
18747+
18748+ /// Parse an optional `AS <alias>` on an unnamed function argument
18749+ /// (e.g. `XMLFOREST(a AS x)` in PostgreSQL).
18750+ fn maybe_parse_aliased_function_arg(
18751+ &mut self,
18752+ arg_expr: FunctionArgExpr,
18753+ ) -> Result<FunctionArgExpr, ParserError> {
18754+ Ok(match arg_expr {
1872618755 FunctionArgExpr::Expr(expr)
1872718756 if self.dialect.supports_aliased_function_args()
1872818757 && self.parse_keyword(Keyword::AS) =>
@@ -18733,8 +18762,7 @@ impl<'a> Parser<'a> {
1873318762 })
1873418763 }
1873518764 other => other,
18736- };
18737- Ok(FunctionArg::Unnamed(arg_expr))
18765+ })
1873818766 }
1873918767
1874018768 fn parse_function_named_arg_operator(&mut self) -> Result<FunctionArgOperator, ParserError> {
0 commit comments