@@ -18357,19 +18357,8 @@ impl<'a> Parser<'a> {
1835718357
1835818358 /// Parse a single function argument, handling named and unnamed variants.
1835918359 pub fn parse_function_args(&mut self) -> Result<FunctionArg, ParserError> {
18360- let arg = if self.dialect.supports_named_fn_args_with_expr_name() {
18361- self.maybe_parse(|p| {
18362- let name = p.parse_expr()?;
18363- let operator = p.parse_function_named_arg_operator()?;
18364- let arg = p.parse_wildcard_expr()?.into();
18365- Ok(FunctionArg::ExprNamed {
18366- name,
18367- arg,
18368- operator,
18369- })
18370- })?
18371- } else {
18372- self.maybe_parse(|p| {
18360+ if !self.dialect.supports_named_fn_args_with_expr_name() {
18361+ if let Some(arg) = self.maybe_parse(|p| {
1837318362 let name = p.parse_identifier()?;
1837418363 let operator = p.parse_function_named_arg_operator()?;
1837518364 let arg = p.parse_wildcard_expr()?.into();
@@ -18378,12 +18367,35 @@ impl<'a> Parser<'a> {
1837818367 arg,
1837918368 operator,
1838018369 })
18381- })?
18382- };
18383- if let Some(arg) = arg {
18384- return Ok(arg);
18370+ })? {
18371+ return Ok(arg);
18372+ }
1838518373 }
18374+
18375+ // Parse the leading expression once, then speculatively parse the
18376+ // named-arg tail `<op> <expr>`. The previous implementation also
18377+ // speculated on the name itself via `maybe_parse(parse_expr ...)`,
18378+ // which produced ~2^N work on chains like
18379+ // `SELECT Y\n.foo(t--\n.foo(t--\n...` because rollback re-walked
18380+ // deeply nested function calls. Same family of bug as #2344.
1838618381 let wildcard_expr = self.parse_wildcard_expr()?;
18382+ if self.dialect.supports_named_fn_args_with_expr_name()
18383+ && !matches!(wildcard_expr, Expr::Wildcard(_))
18384+ {
18385+ if let Some((operator, arg)) = self.maybe_parse(|p| {
18386+ Ok((
18387+ p.parse_function_named_arg_operator()?,
18388+ p.parse_wildcard_expr()?,
18389+ ))
18390+ })? {
18391+ return Ok(FunctionArg::ExprNamed {
18392+ name: wildcard_expr,
18393+ arg: arg.into(),
18394+ operator,
18395+ });
18396+ }
18397+ }
18398+
1838718399 let arg_expr: FunctionArgExpr = match wildcard_expr {
1838818400 Expr::Wildcard(ref token) if self.dialect.supports_select_wildcard_exclude() => {
1838918401 // Support `* EXCLUDE(col1, col2, ...)` inside function calls (e.g. Snowflake's
0 commit comments