Skip to content

Commit 1b92ede

Browse files
committed
Add support for un-parenthesized "RETURN SELECT" syntax
- rename `AsReturn` to `AsReturnSubquery` for clarity between these two variants
1 parent 84e543c commit 1b92ede

File tree

4 files changed

+41
-6
lines changed

4 files changed

+41
-6
lines changed

src/ast/ddl.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -2313,7 +2313,10 @@ impl fmt::Display for CreateFunction {
23132313
if let Some(CreateFunctionBody::Return(function_body)) = &self.function_body {
23142314
write!(f, " RETURN {function_body}")?;
23152315
}
2316-
if let Some(CreateFunctionBody::AsReturn(function_body)) = &self.function_body {
2316+
if let Some(CreateFunctionBody::AsReturnSubquery(function_body)) = &self.function_body {
2317+
write!(f, " AS RETURN {function_body}")?;
2318+
}
2319+
if let Some(CreateFunctionBody::AsReturnSelect(function_body)) = &self.function_body {
23172320
write!(f, " AS RETURN {function_body}")?;
23182321
}
23192322
if let Some(using) = &self.using {

src/ast/mod.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -8671,7 +8671,17 @@ pub enum CreateFunctionBody {
86718671
/// ```
86728672
///
86738673
/// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql
8674-
AsReturn(Expr),
8674+
AsReturnSubquery(Expr),
8675+
8676+
/// Function body expression using the 'AS RETURN' keywords, with an un-parenthesized SELECT query
8677+
///
8678+
/// Example:
8679+
/// ```sql
8680+
/// CREATE FUNCTION myfunc(a INT, b INT)
8681+
/// RETURNS TABLE
8682+
/// AS RETURN SELECT a + b AS sum;
8683+
/// ```
8684+
AsReturnSelect(Select),
86758685
}
86768686

86778687
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]

src/parser/mod.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -5248,11 +5248,25 @@ impl<'a> Parser<'a> {
52485248
}))
52495249
} else if self.peek_keyword(Keyword::RETURN) {
52505250
self.expect_keyword(Keyword::RETURN)?;
5251-
let expr = self.parse_expr()?;
5252-
if !matches!(expr, Expr::Subquery(_)) {
5253-
parser_err!("Expected a subquery after RETURN", expr.span().start)?;
5251+
5252+
if self.peek_token() == Token::LParen {
5253+
let expr = self.parse_expr()?;
5254+
if !matches!(expr, Expr::Subquery(_)) {
5255+
parser_err!(
5256+
"Expected a subquery after RETURN",
5257+
self.peek_token().span.start
5258+
)?
5259+
}
5260+
Some(CreateFunctionBody::AsReturnSubquery(expr))
5261+
} else if self.peek_keyword(Keyword::SELECT) {
5262+
let select = self.parse_select()?;
5263+
Some(CreateFunctionBody::AsReturnSelect(select))
5264+
} else {
5265+
parser_err!(
5266+
"Expected a subquery (or bare SELECT statement) after RETURN",
5267+
self.peek_token().span.start
5268+
)?
52545269
}
5255-
Some(CreateFunctionBody::AsReturn(expr))
52565270
} else {
52575271
parser_err!("Unparsable function body", self.peek_token().span.start)?
52585272
};

tests/sqlparser_mssql.rs

+8
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,14 @@ fn parse_create_function() {
303303
";
304304
let _ = ms().verified_stmt(create_inline_table_value_function);
305305

306+
let create_inline_table_value_function_without_parentheses = "\
307+
CREATE FUNCTION some_inline_tvf(@foo INT, @bar VARCHAR(256)) \
308+
RETURNS TABLE \
309+
AS \
310+
RETURN SELECT 1 AS col_1\
311+
";
312+
let _ = ms().verified_stmt(create_inline_table_value_function_without_parentheses);
313+
306314
let create_inline_table_value_function_without_as =
307315
create_inline_table_value_function.replace(" AS", "");
308316
let _ = ms().one_statement_parses_to(

0 commit comments

Comments
 (0)