Skip to content

Commit 41080eb

Browse files
authored
[SIG-43614] Fix SQL parsing for select statement as function argument (#12)
* fix parsing on select statements as function arguments * add tests * remove whitespace * fix next token no skip * format fix * restore next_token_no_skip and add fix me
1 parent e174e14 commit 41080eb

2 files changed

Lines changed: 46 additions & 0 deletions

File tree

src/parser.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,7 @@ impl<'a> Parser<'a> {
12201220
}
12211221

12221222
/// Return the first unprocessed token, possibly whitespace.
1223+
/// FIXME: This function skips the token
12231224
pub fn next_token_no_skip(&mut self) -> Option<&Token> {
12241225
self.index += 1;
12251226
self.tokens.get(self.index - 1)
@@ -2783,6 +2784,13 @@ impl<'a> Parser<'a> {
27832784

27842785
Ok(FunctionArg::Named { name, arg })
27852786
} else {
2787+
// subqueries can be used in snowflake function calls without parantheses
2788+
if dialect_of!(self is SnowflakeDialect) &&
2789+
(self.parse_keyword(Keyword::SELECT) || self.parse_keyword(Keyword::WITH)) {
2790+
self.prev_token();
2791+
let expr = Expr::Subquery(Box::new(self.parse_query()?));
2792+
return Ok(FunctionArg::Unnamed(expr))
2793+
}
27862794
Ok(FunctionArg::Unnamed(self.parse_expr()?))
27872795
}
27882796
}

tests/sqlparser_snowflake.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,44 @@ fn test_single_table_in_parenthesis_with_alias() {
151151
);
152152
}
153153

154+
155+
#[test]
156+
fn parse_select_as_func_argument() {
157+
// subquery without parantheses in function call should work
158+
snowflake().one_statement_parses_to(
159+
"SELECT parse_json(SELECT column2 FROM values(1, 'null'))",
160+
"SELECT parse_json((SELECT column2 FROM values(1, 'null')))",
161+
);
162+
// subquery with parantheses in function call should also work
163+
snowflake().one_statement_parses_to(
164+
"SELECT parse_json((SELECT column2 FROM values(1, 'null')))",
165+
"SELECT parse_json((SELECT column2 FROM values(1, 'null')))",
166+
);
167+
// subquery with comma in function call should be interpreted as function with one argument
168+
// Ex: func(select 1, 2) === fun((select 1, 2))
169+
snowflake().one_statement_parses_to(
170+
"SELECT func(SELECT 1, 2)",
171+
"SELECT func((SELECT 1, 2))",
172+
);
173+
174+
// subquery starting with WITH should also work
175+
snowflake().one_statement_parses_to(
176+
"SELECT func(WITH foo AS (SELECT 1) SELECT 1)",
177+
"SELECT func((WITH foo AS (SELECT 1) SELECT 1))",
178+
);
179+
180+
// named function arguments should not work
181+
let res = snowflake().parse_sql_statements(
182+
"SELECT func(expr => SELECT 1)",
183+
);
184+
assert_eq!(
185+
res.unwrap_err(),
186+
ParserError::ParserError(
187+
"SELECT func(expr => SELECT".to_string(),
188+
"Expected ), found: 1".to_string()
189+
));
190+
}
191+
154192
fn snowflake() -> TestedDialects {
155193
TestedDialects {
156194
dialects: vec![Box::new(SnowflakeDialect {})],

0 commit comments

Comments
 (0)