Skip to content

Commit

Permalink
Support subquery as function arg w/o parens in Snowflake dialect (apa…
Browse files Browse the repository at this point in the history
  • Loading branch information
jmhain authored and serprex committed Nov 6, 2023
1 parent f358f84 commit e2fa7bb
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
20 changes: 19 additions & 1 deletion src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1511,7 +1511,7 @@ impl<'a> Parser<'a> {
within_group: false,
}));
}
// Snowflake defines ORDERY BY in within group instead of inside the function like
// Snowflake defines ORDER BY in within group instead of inside the function like
// ANSI SQL.
self.expect_token(&Token::RParen)?;
let within_group = if self.parse_keywords(&[Keyword::WITHIN, Keyword::GROUP]) {
Expand Down Expand Up @@ -6957,6 +6957,24 @@ impl<'a> Parser<'a> {
if self.consume_token(&Token::RParen) {
Ok((vec![], vec![]))
} else {
// Snowflake permits a subquery to be passed as an argument without
// an enclosing set of parens if it's the only argument.
if dialect_of!(self is SnowflakeDialect)
&& self
.parse_one_of_keywords(&[Keyword::WITH, Keyword::SELECT])
.is_some()
{
self.prev_token();
let subquery = self.parse_query()?;
self.expect_token(&Token::RParen)?;
return Ok((
vec![FunctionArg::Unnamed(FunctionArgExpr::from(
WildcardExpr::Expr(Expr::Subquery(Box::new(subquery))),
))],
vec![],
));
}

let args = self.parse_comma_separated(Parser::parse_function_args)?;
let order_by = if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
self.parse_comma_separated(Parser::parse_order_by_expr)?
Expand Down
20 changes: 20 additions & 0 deletions tests/sqlparser_snowflake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1065,3 +1065,23 @@ fn test_snowflake_trim() {
snowflake().parse_sql_statements(error_sql).unwrap_err()
);
}

#[test]
fn parse_subquery_function_argument() {
// Snowflake allows passing an unparenthesized subquery as the single
// argument to a function.
snowflake().one_statement_parses_to(
"SELECT parse_json(SELECT '{}')",
"SELECT parse_json((SELECT '{}'))",
);

// Subqueries that begin with WITH work too.
snowflake().one_statement_parses_to(
"SELECT parse_json(WITH q AS (SELECT '{}' AS foo) SELECT foo FROM q)",
"SELECT parse_json((WITH q AS (SELECT '{}' AS foo) SELECT foo FROM q))",
);

// Commas are parsed as part of the subquery, not additional arguments to
// the function.
snowflake().one_statement_parses_to("SELECT func(SELECT 1, 2)", "SELECT func((SELECT 1, 2))");
}

0 comments on commit e2fa7bb

Please sign in to comment.