@@ -577,13 +577,7 @@ impl<'a> Parser<'a> {
577577 Keyword::GRANT => self.parse_grant(),
578578 Keyword::REVOKE => self.parse_revoke(),
579579 Keyword::START => self.parse_start_transaction(),
580- // `BEGIN` is a nonstandard but common alias for the
581- // standard `START TRANSACTION` statement. It is supported
582- // by at least PostgreSQL and MySQL.
583580 Keyword::BEGIN => self.parse_begin(),
584- // `END` is a nonstandard but common alias for the
585- // standard `COMMIT TRANSACTION` statement. It is supported
586- // by PostgreSQL.
587581 Keyword::END => self.parse_end(),
588582 Keyword::SAVEPOINT => self.parse_savepoint(),
589583 Keyword::RELEASE => self.parse_release(),
@@ -617,6 +611,7 @@ impl<'a> Parser<'a> {
617611 }
618612 // `COMMENT` is snowflake specific https://docs.snowflake.com/en/sql-reference/sql/comment
619613 Keyword::COMMENT if self.dialect.supports_comment_on() => self.parse_comment(),
614+ Keyword::RETURN => self.parse_return(),
620615 _ => self.expected("an SQL statement", next_token),
621616 },
622617 Token::LParen => {
@@ -4881,6 +4876,8 @@ impl<'a> Parser<'a> {
48814876 self.parse_create_macro(or_replace, temporary)
48824877 } else if dialect_of!(self is BigQueryDialect) {
48834878 self.parse_bigquery_create_function(or_replace, temporary)
4879+ } else if dialect_of!(self is MsSqlDialect) {
4880+ self.parse_mssql_create_function(or_replace, temporary)
48844881 } else {
48854882 self.prev_token();
48864883 self.expected("an object type after CREATE", self.peek_token())
@@ -5135,6 +5132,72 @@ impl<'a> Parser<'a> {
51355132 }))
51365133 }
51375134
5135+ /// Parse `CREATE FUNCTION` for [MsSql]
5136+ ///
5137+ /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql
5138+ fn parse_mssql_create_function(
5139+ &mut self,
5140+ or_replace: bool,
5141+ temporary: bool,
5142+ ) -> Result<Statement, ParserError> {
5143+ let name = self.parse_object_name(false)?;
5144+
5145+ let parse_function_param =
5146+ |parser: &mut Parser| -> Result<OperateFunctionArg, ParserError> {
5147+ let name = parser.parse_identifier()?;
5148+ let data_type = parser.parse_data_type()?;
5149+ Ok(OperateFunctionArg {
5150+ mode: None,
5151+ name: Some(name),
5152+ data_type,
5153+ default_expr: None,
5154+ })
5155+ };
5156+ self.expect_token(&Token::LParen)?;
5157+ let args = self.parse_comma_separated0(parse_function_param, Token::RParen)?;
5158+ self.expect_token(&Token::RParen)?;
5159+
5160+ let return_type = if self.parse_keyword(Keyword::RETURNS) {
5161+ Some(self.parse_data_type()?)
5162+ } else {
5163+ return parser_err!("Expected RETURNS keyword", self.peek_token().span.start);
5164+ };
5165+
5166+ self.expect_keyword_is(Keyword::AS)?;
5167+ self.expect_keyword_is(Keyword::BEGIN)?;
5168+ let mut result = self.parse_statements()?;
5169+ // note: `parse_statements` will consume the `END` token & produce a Commit statement...
5170+ if let Some(Statement::Commit {
5171+ chain,
5172+ end,
5173+ modifier,
5174+ }) = result.last()
5175+ {
5176+ if *chain == false && *end == true && *modifier == None {
5177+ result = result[..result.len() - 1].to_vec();
5178+ }
5179+ }
5180+ let function_body = Some(CreateFunctionBody::MultiStatement(result));
5181+
5182+ Ok(Statement::CreateFunction(CreateFunction {
5183+ or_replace,
5184+ temporary,
5185+ if_not_exists: false,
5186+ name,
5187+ args: Some(args),
5188+ return_type,
5189+ function_body,
5190+ language: None,
5191+ determinism_specifier: None,
5192+ options: None,
5193+ remote_connection: None,
5194+ using: None,
5195+ behavior: None,
5196+ called_on_null: None,
5197+ parallel: None,
5198+ }))
5199+ }
5200+
51385201 fn parse_function_arg(&mut self) -> Result<OperateFunctionArg, ParserError> {
51395202 let mode = if self.parse_keyword(Keyword::IN) {
51405203 Some(ArgMode::In)
@@ -15058,6 +15121,14 @@ impl<'a> Parser<'a> {
1505815121 }
1505915122 }
1506015123
15124+ /// Parse [Statement::Return]
15125+ fn parse_return(&mut self) -> Result<Statement, ParserError> {
15126+ let expr = self.parse_expr()?;
15127+ Ok(Statement::Return(ReturnStatement {
15128+ value: Some(ReturnStatementValue::Expr(expr)),
15129+ }))
15130+ }
15131+
1506115132 /// Consume the parser and return its underlying token buffer
1506215133 pub fn into_tokens(self) -> Vec<TokenWithSpan> {
1506315134 self.tokens
0 commit comments