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


##########
src/parser/mod.rs:
##########
@@ -5204,19 +5204,79 @@ impl<'a> Parser<'a> {
         let (name, args) = self.parse_create_function_name_and_params()?;
 
         self.expect_keyword(Keyword::RETURNS)?;
-        let return_type = Some(self.parse_data_type()?);
 
-        self.expect_keyword_is(Keyword::AS)?;
+        let return_table = self.maybe_parse(|p| {
+            let return_table_name = p.parse_identifier()?;
+
+            if !p.peek_keyword(Keyword::TABLE) {
+                parser_err!(
+                    "Expected TABLE keyword after return type",
+                    p.peek_token().span.start
+                )?
+            }
+
+            let table_column_defs = match p.parse_data_type()? {
+                DataType::Table(maybe_table_column_defs) => match 
maybe_table_column_defs {
+                    Some(table_column_defs) => {
+                        if table_column_defs.is_empty() {
+                            parser_err!(
+                                "Expected table column definitions after TABLE 
keyword",
+                                p.peek_token().span.start
+                            )?
+                        }
+
+                        table_column_defs
+                    }
+                    None => parser_err!(
+                        "Expected table column definitions after TABLE 
keyword",
+                        p.peek_token().span.start
+                    )?,
+                },
+                _ => parser_err!(
+                    "Expected table data type after TABLE keyword",
+                    p.peek_token().span.start
+                )?,
+            };
+
+            Ok(DataType::NamedTable {
+                name: 
ObjectName(vec![ObjectNamePart::Identifier(return_table_name)]),
+                columns: table_column_defs,
+            })
+        })?;
+
+        let return_type = if return_table.is_some() {
+            return_table
+        } else {
+            Some(self.parse_data_type()?)
+        };
 
-        let begin_token = self.expect_keyword(Keyword::BEGIN)?;
-        let statements = self.parse_statement_list(&[Keyword::END])?;
-        let end_token = self.expect_keyword(Keyword::END)?;
+        let _ = self.parse_keyword(Keyword::AS);
 
-        let function_body = 
Some(CreateFunctionBody::AsBeginEnd(BeginEndStatements {
-            begin_token: AttachedToken(begin_token),
-            statements,
-            end_token: AttachedToken(end_token),
-        }));
+        let function_body = if self.peek_keyword(Keyword::BEGIN) {
+            let begin_token = self.expect_keyword(Keyword::BEGIN)?;
+            let statements = self.parse_statement_list(&[Keyword::END])?;
+            let end_token = self.expect_keyword(Keyword::END)?;
+
+            Some(CreateFunctionBody::AsBeginEnd(BeginEndStatements {
+                begin_token: AttachedToken(begin_token),
+                statements,
+                end_token: AttachedToken(end_token),
+            }))
+        } else if self.parse_keyword(Keyword::RETURN) {
+            if self.peek_token() == Token::LParen {
+                Some(CreateFunctionBody::AsReturnExpr(self.parse_expr()?))
+            } else if self.peek_keyword(Keyword::SELECT) {
+                let select = self.parse_select()?;
+                Some(CreateFunctionBody::AsReturnSelect(select))
+            } else {
+                parser_err!(
+                    "Expected a subquery (or bare SELECT statement) after 
RETURN",
+                    self.peek_token().span.start
+                )?
+            }

Review Comment:
   can we add a test for this behavior? (e.g. one that passes a regular 
expression and the verifies that the parser rejects it)



##########
src/parser/mod.rs:
##########
@@ -5204,19 +5204,79 @@ impl<'a> Parser<'a> {
         let (name, args) = self.parse_create_function_name_and_params()?;
 
         self.expect_keyword(Keyword::RETURNS)?;
-        let return_type = Some(self.parse_data_type()?);
 
-        self.expect_keyword_is(Keyword::AS)?;
+        let return_table = self.maybe_parse(|p| {
+            let return_table_name = p.parse_identifier()?;
+
+            if !p.peek_keyword(Keyword::TABLE) {
+                parser_err!(
+                    "Expected TABLE keyword after return type",
+                    p.peek_token().span.start
+                )?
+            }
+
+            let table_column_defs = match p.parse_data_type()? {
+                DataType::Table(maybe_table_column_defs) => match 
maybe_table_column_defs {
+                    Some(table_column_defs) => {
+                        if table_column_defs.is_empty() {
+                            parser_err!(
+                                "Expected table column definitions after TABLE 
keyword",
+                                p.peek_token().span.start
+                            )?
+                        }
+
+                        table_column_defs
+                    }
+                    None => parser_err!(
+                        "Expected table column definitions after TABLE 
keyword",
+                        p.peek_token().span.start
+                    )?,
+                },
+                _ => parser_err!(
+                    "Expected table data type after TABLE keyword",
+                    p.peek_token().span.start
+                )?,
+            };

Review Comment:
   ```suggestion
                   DataType::Table(Some(table_column_defs)) !if 
table_column_defs.is_empty() => table_column_defs,
                   _ => parser_err!(
                       "Expected table data type after TABLE keyword",
                       p.peek_token().span.start
                   )?,
               };
   ```
   looks like this condition can be simplified?
   Also could we add a negative test to assert the behavior on invalid 
data_types, noticed it seems to be lacking coverage in the PR tests



##########
src/parser/mod.rs:
##########
@@ -5204,19 +5204,79 @@ impl<'a> Parser<'a> {
         let (name, args) = self.parse_create_function_name_and_params()?;
 
         self.expect_keyword(Keyword::RETURNS)?;
-        let return_type = Some(self.parse_data_type()?);
 
-        self.expect_keyword_is(Keyword::AS)?;
+        let return_table = self.maybe_parse(|p| {
+            let return_table_name = p.parse_identifier()?;
+
+            if !p.peek_keyword(Keyword::TABLE) {
+                parser_err!(
+                    "Expected TABLE keyword after return type",
+                    p.peek_token().span.start
+                )?
+            }

Review Comment:
   ```suggestion
               p.expect_keyword(Keyword::TABLE)?;
   ```



-- 
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