This is an automated email from the ASF dual-hosted git repository.

iffyio pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git


The following commit(s) were added to refs/heads/main by this push:
     new 257da5a8 Add RETURNS TABLE() support for CREATE FUNCTION in Postgresql 
(#1687)
257da5a8 is described below

commit 257da5a82c8a1e6c565abfa52bd490b211775069
Author: Rémy SAISSY <[email protected]>
AuthorDate: Mon Feb 3 08:27:37 2025 +0100

    Add RETURNS TABLE() support for CREATE FUNCTION in Postgresql (#1687)
    
    Co-authored-by: Ifeanyi Ubah <[email protected]>
---
 src/ast/data_type.rs        |  5 +++++
 src/parser/mod.rs           | 22 ++++++++++++++++++++++
 tests/sqlparser_postgres.rs |  1 +
 3 files changed, 28 insertions(+)

diff --git a/src/ast/data_type.rs b/src/ast/data_type.rs
index 02aa6cc9..1f2b6be9 100644
--- a/src/ast/data_type.rs
+++ b/src/ast/data_type.rs
@@ -45,6 +45,10 @@ pub enum EnumMember {
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
 #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
 pub enum DataType {
+    /// Table type in [postgresql]. e.g. CREATE FUNCTION RETURNS TABLE(...)
+    ///
+    /// [postgresql]: 
https://www.postgresql.org/docs/15/sql-createfunction.html
+    Table(Vec<ColumnDef>),
     /// Fixed-length character type e.g. CHARACTER(10)
     Character(Option<CharacterLength>),
     /// Fixed-length char type e.g. CHAR(10)
@@ -630,6 +634,7 @@ impl fmt::Display for DataType {
             DataType::Unspecified => Ok(()),
             DataType::Trigger => write!(f, "TRIGGER"),
             DataType::AnyType => write!(f, "ANY TYPE"),
+            DataType::Table(fields) => write!(f, "TABLE({})", 
display_comma_separated(fields)),
         }
     }
 }
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 7d2d407d..931d9700 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -8867,6 +8867,10 @@ impl<'a> Parser<'a> {
                     let _ = self.parse_keyword(Keyword::TYPE);
                     Ok(DataType::AnyType)
                 }
+                Keyword::TABLE => {
+                    let columns = self.parse_returns_table_columns()?;
+                    Ok(DataType::Table(columns))
+                }
                 _ => {
                     self.prev_token();
                     let type_name = self.parse_object_name(false)?;
@@ -8894,6 +8898,24 @@ impl<'a> Parser<'a> {
         Ok((data, trailing_bracket))
     }
 
+    fn parse_returns_table_column(&mut self) -> Result<ColumnDef, ParserError> 
{
+        let name = self.parse_identifier()?;
+        let data_type = self.parse_data_type()?;
+        Ok(ColumnDef {
+            name,
+            data_type,
+            collation: None,
+            options: Vec::new(), // No constraints expected here
+        })
+    }
+
+    fn parse_returns_table_columns(&mut self) -> Result<Vec<ColumnDef>, 
ParserError> {
+        self.expect_token(&Token::LParen)?;
+        let columns = 
self.parse_comma_separated(Parser::parse_returns_table_column)?;
+        self.expect_token(&Token::RParen)?;
+        Ok(columns)
+    }
+
     pub fn parse_string_values(&mut self) -> Result<Vec<String>, ParserError> {
         self.expect_token(&Token::LParen)?;
         let mut values = Vec::new();
diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs
index ee4aa2a0..62da0f57 100644
--- a/tests/sqlparser_postgres.rs
+++ b/tests/sqlparser_postgres.rs
@@ -3803,6 +3803,7 @@ fn parse_create_function_detailed() {
     pg_and_generic().verified_stmt("CREATE OR REPLACE FUNCTION add(a INTEGER, 
IN b INTEGER = 1) RETURNS INTEGER LANGUAGE SQL STABLE CALLED ON NULL INPUT 
PARALLEL UNSAFE RETURN a + b");
     pg_and_generic().verified_stmt(r#"CREATE OR REPLACE FUNCTION increment(i 
INTEGER) RETURNS INTEGER LANGUAGE plpgsql AS $$ BEGIN RETURN i + 1; END; $$"#);
     pg_and_generic().verified_stmt(r#"CREATE OR REPLACE FUNCTION no_arg() 
RETURNS VOID LANGUAGE plpgsql AS $$ BEGIN DELETE FROM my_table; END; $$"#);
+    pg_and_generic().verified_stmt(r#"CREATE OR REPLACE FUNCTION 
return_table(i INTEGER) RETURNS TABLE(id UUID, is_active BOOLEAN) LANGUAGE 
plpgsql AS $$ BEGIN RETURN QUERY SELECT NULL::UUID, NULL::BOOLEAN; END; $$"#);
 }
 #[test]
 fn parse_incorrect_create_function_parallel() {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to