Skip to content

Commit 3781460

Browse files
Snowflake: parse IDENTIFIER('f')(args) call-by-name in expression position
1 parent 29ada78 commit 3781460

1 file changed

Lines changed: 21 additions & 2 deletions

File tree

src/parser/mod.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1880,8 +1880,27 @@ impl<'a> Parser<'a> {
18801880
let is_outer_join = self.peek_outer_join_operator();
18811881
match &self.peek_token_ref().token {
18821882
Token::LParen if !is_outer_join => {
1883-
let id_parts = vec![w.to_ident(w_span)];
1884-
self.parse_function(ObjectName::from(id_parts))
1883+
let ident = w.to_ident(w_span);
1884+
// Snowflake call-by-name in expression position:
1885+
// `IDENTIFIER('f')(args)`. The `IDENTIFIER('f')` forms the
1886+
// callee name (an `ObjectNamePart::Function`) and the trailing
1887+
// `(args)` is the actual call — mirror the object-name grammar
1888+
// so the resulting `Expr::Function` matches the CALL path shape.
1889+
if self.dialect.is_identifier_generating_function_name(&ident, &[]) {
1890+
let checkpoint = self.index;
1891+
self.expect_token(&Token::LParen)?;
1892+
let args = self
1893+
.parse_comma_separated0(Self::parse_function_args, Token::RParen)?;
1894+
self.expect_token(&Token::RParen)?;
1895+
if self.peek_token_ref().token == Token::LParen {
1896+
let name = ObjectName(vec![ObjectNamePart::Function(
1897+
ObjectNamePartFunction { name: ident, args },
1898+
)]);
1899+
return self.parse_function(name);
1900+
}
1901+
self.index = checkpoint;
1902+
}
1903+
self.parse_function(ObjectName::from(vec![ident]))
18851904
}
18861905
// string introducer https://dev.mysql.com/doc/refman/8.0/en/charset-introducer.html
18871906
Token::SingleQuotedString(_)

0 commit comments

Comments
 (0)