Skip to content

Commit 0288177

Browse files
committed
Add multi-statement table valued function support for SQL Server
1 parent e2c8b8b commit 0288177

File tree

3 files changed

+46
-1
lines changed

3 files changed

+46
-1
lines changed

src/ast/data_type.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ pub enum DataType {
5050
/// [PostgreSQL]: https://www.postgresql.org/docs/15/sql-createfunction.html
5151
/// [MsSQL]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql?view=sql-server-ver16#c-create-a-multi-statement-table-valued-function
5252
Table(Vec<ColumnDef>),
53+
/// Table type with a name, e.g. CREATE FUNCTION RETURNS @result TABLE(...).
54+
NamedTable(
55+
/// Table name.
56+
ObjectName,
57+
/// Table columns.
58+
Vec<ColumnDef>,
59+
),
5360
/// Fixed-length character type, e.g. CHARACTER(10).
5461
Character(Option<CharacterLength>),
5562
/// Fixed-length char type, e.g. CHAR(10).
@@ -723,6 +730,9 @@ impl fmt::Display for DataType {
723730
}
724731
write!(f, "TABLE({})", display_comma_separated(fields))
725732
}
733+
DataType::NamedTable(name, fields) => {
734+
write!(f, "{} TABLE ({})", name, display_comma_separated(fields))
735+
}
726736
DataType::GeometricType(kind) => write!(f, "{}", kind),
727737
}
728738
}

src/parser/mod.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5204,7 +5204,31 @@ impl<'a> Parser<'a> {
52045204
let (name, args) = self.parse_create_function_name_and_params()?;
52055205

52065206
self.expect_keyword(Keyword::RETURNS)?;
5207-
let return_type = Some(self.parse_data_type()?);
5207+
5208+
let return_table = self.maybe_parse(|p| {
5209+
let return_table_name = p.parse_identifier()?;
5210+
let table_column_defs = if p.peek_keyword(Keyword::TABLE) {
5211+
match p.parse_data_type()? {
5212+
DataType::Table(t) => t,
5213+
_ => parser_err!(
5214+
"Expected table data type after TABLE keyword",
5215+
p.peek_token().span.start
5216+
)?,
5217+
}
5218+
} else {
5219+
parser_err!("Expected TABLE keyword after return type", p.peek_token().span.start)?
5220+
};
5221+
Ok(DataType::NamedTable(
5222+
ObjectName(vec![ObjectNamePart::Identifier(return_table_name)]),
5223+
table_column_defs.clone(),
5224+
))
5225+
})?;
5226+
5227+
let return_type = if return_table.is_some() {
5228+
return_table
5229+
} else {
5230+
Some(self.parse_data_type()?)
5231+
};
52085232

52095233
self.expect_keyword_is(Keyword::AS)?;
52105234

tests/sqlparser_mssql.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,17 @@ fn parse_create_function() {
296296
RETURN (SELECT 1 AS col_1)\
297297
";
298298
let _ = ms().verified_stmt(create_inline_table_value_function);
299+
300+
let create_multi_statement_table_value_function = "\
301+
CREATE FUNCTION some_multi_statement_tvf(@foo INT, @bar VARCHAR(256)) \
302+
RETURNS @t TABLE (col_1 INT) \
303+
AS \
304+
BEGIN \
305+
INSERT INTO @t SELECT 1; \
306+
RETURN; \
307+
END\
308+
";
309+
let _ = ms().verified_stmt(create_multi_statement_table_value_function);
299310
}
300311

301312
#[test]

0 commit comments

Comments
 (0)