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


##########
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:
   Done 👍 



##########
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:
   I consolidated this per your suggestion, and I added a test to assert a 
parser error for an incorrect table definition 👍 



##########
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:
   Done 👍 



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