iffyio commented on code in PR #1808:
URL: 
https://github.com/apache/datafusion-sqlparser-rs/pull/1808#discussion_r2050170398


##########
src/ast/spans.rs:
##########
@@ -2280,6 +2277,12 @@ impl Spanned for TableObject {
     }
 }
 
+impl Spanned for BeginEndStatements {
+    fn span(&self) -> Span {
+        union_spans([self.begin_token.0.span, 
self.end_token.0.span].into_iter())

Review Comment:
   We can do an exhausitve match here, so that the code is revisite if fields 
get added or changed
   ```rust
   let BeginEndStatements {
       begin,
       statements,
       end
   } = self;
   union_spans(begin, statements, end)
   ```
   we can probably include statements in the union spans call if only for 
completeness



##########
tests/sqlparser_mssql.rs:
##########
@@ -187,6 +188,386 @@ fn parse_mssql_create_procedure() {
     let _ = ms().verified_stmt("CREATE PROCEDURE [foo] AS BEGIN UPDATE bar SET 
col = 'test'; SELECT [foo] FROM BAR WHERE [FOO] > 10 END");
 }
 
+#[test]
+fn parse_create_function() {
+    let return_expression_function = "CREATE FUNCTION some_scalar_udf(@foo 
INT, @bar VARCHAR(256)) RETURNS INT AS BEGIN RETURN 1; END";
+    assert_eq!(
+        ms().verified_stmt(return_expression_function),
+        sqlparser::ast::Statement::CreateFunction(CreateFunction {
+            or_alter: false,
+            or_replace: false,
+            temporary: false,
+            if_not_exists: false,
+            name: ObjectName::from(vec![Ident {
+                value: "some_scalar_udf".into(),
+                quote_style: None,
+                span: Span::empty(),
+            }]),
+            args: Some(vec![
+                OperateFunctionArg {
+                    mode: None,
+                    name: Some(Ident {
+                        value: "@foo".into(),
+                        quote_style: None,
+                        span: Span::empty(),
+                    }),
+                    data_type: DataType::Int(None),
+                    default_expr: None,
+                },
+                OperateFunctionArg {
+                    mode: None,
+                    name: Some(Ident {
+                        value: "@bar".into(),
+                        quote_style: None,
+                        span: Span::empty(),
+                    }),
+                    data_type: 
DataType::Varchar(Some(CharacterLength::IntegerLength {
+                        length: 256,
+                        unit: None
+                    })),
+                    default_expr: None,
+                },
+            ]),
+            return_type: Some(DataType::Int(None)),
+            function_body: 
Some(CreateFunctionBody::AsBeginEnd(BeginEndStatements {
+                begin_token: 
AttachedToken(TokenWithSpan::wrap(sqlparser::tokenizer::Token::Word(
+                    sqlparser::tokenizer::Word {
+                        value: "BEGIN".to_string(),
+                        quote_style: None,
+                        keyword: Keyword::BEGIN
+                    }
+                ))),
+                statements: vec![Statement::Return(ReturnStatement {
+                    value: Some(ReturnStatementValue::Expr(Expr::Value(
+                        (number("1")).with_empty_span()
+                    ))),
+                }),],
+                end_token: 
AttachedToken(TokenWithSpan::wrap(sqlparser::tokenizer::Token::Word(
+                    sqlparser::tokenizer::Word {
+                        value: "END".to_string(),
+                        quote_style: None,
+                        keyword: Keyword::END
+                    }
+                ))),
+            })),
+            behavior: None,
+            called_on_null: None,
+            parallel: None,
+            using: None,
+            language: None,
+            determinism_specifier: None,
+            options: None,
+            remote_connection: None,
+        }),
+    );
+
+    let multi_statement_function = "\

Review Comment:
   Yeah that's correct!



##########
tests/sqlparser_common.rs:
##########
@@ -15015,3 +15015,8 @@ fn parse_set_time_zone_alias() {
         _ => unreachable!(),
     }
 }
+
+#[test]
+fn parse_return() {
+    all_dialects().verified_stmt("RETURN");

Review Comment:
   Can we have this check assert the AST? Also we can add another test case 
that includes a return statement having an expression



##########
src/parser/mod.rs:
##########
@@ -5135,6 +5146,63 @@ impl<'a> Parser<'a> {
         }))
     }
 
+    /// Parse `CREATE FUNCTION` for [SQL Server]
+    ///
+    /// [SQL Server]: 
https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql
+    fn parse_mssql_create_function(
+        &mut self,
+        or_alter: bool,
+        or_replace: bool,
+        temporary: bool,
+    ) -> Result<Statement, ParserError> {
+        let name = self.parse_object_name(false)?;
+
+        let parse_function_param =
+            |parser: &mut Parser| -> Result<OperateFunctionArg, ParserError> {
+                let name = parser.parse_identifier()?;
+                let data_type = parser.parse_data_type()?;
+                Ok(OperateFunctionArg {
+                    mode: None,
+                    name: Some(name),
+                    data_type,
+                    default_expr: None,
+                })
+            };
+        self.expect_token(&Token::LParen)?;
+        let args = self.parse_comma_separated0(parse_function_param, 
Token::RParen)?;
+        self.expect_token(&Token::RParen)?;
+
+        let return_type = if self.parse_keyword(Keyword::RETURNS) {
+            Some(self.parse_data_type()?)
+        } else {
+            None
+        };
+
+        self.expect_keyword_is(Keyword::AS)?;
+        self.expect_keyword_is(Keyword::BEGIN)?;
+        let function_body = 
Some(CreateFunctionBody::MultiStatement(self.parse_statements()?));

Review Comment:
   does something like in [this 
suggestion](https://github.com/apache/datafusion-sqlparser-rs/pull/1808#discussion_r2040592844)
 work just as well? its currently unclear to me why the semicolon handling is a 
special case of an `IfCondition` statement 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscr...@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscr...@datafusion.apache.org
For additional commands, e-mail: github-h...@datafusion.apache.org

Reply via email to