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


##########
src/ast/ddl.rs:
##########
@@ -2002,22 +2002,45 @@ impl fmt::Display for DropBehavior {
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
 #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
 pub enum UserDefinedTypeRepresentation {
+    /// Composite type: `CREATE TYPE name AS (attributes)`
     Composite {
         attributes: Vec<UserDefinedTypeCompositeAttributeDef>,
     },
+    /// Enum type: `CREATE TYPE name AS ENUM (labels)`
+    ///
     /// Note: this is PostgreSQL-specific. See 
<https://www.postgresql.org/docs/current/sql-createtype.html>
     Enum { labels: Vec<Ident> },
+    /// Range type: `CREATE TYPE name AS RANGE (options)`
+    Range {
+        options: Vec<UserDefinedTypeRangeOption>,
+    },
+    /// Base type (SQL definition): `CREATE TYPE name (options)`
+    ///
+    /// Note the lack of `AS` keyword
+    SqlDefinition {
+        options: Vec<UserDefinedTypeSqlDefinitionOption>,
+    },

Review Comment:
   Could we include a link to the postgres docs for the new variants?



##########
src/parser/mod.rs:
##########
@@ -17387,6 +17425,254 @@ impl<'a> Parser<'a> {
         })
     }
 
+    /// Parse remainder of `CREATE TYPE AS RANGE` statement
+    ///
+    /// See 
[PostgreSQL](https://www.postgresql.org/docs/current/sql-createtype.html)
+    pub fn parse_create_type_range(&mut self, name: ObjectName) -> 
Result<Statement, ParserError> {
+        self.expect_token(&Token::LParen)?;
+        let options = self.parse_comma_separated0(|p| p.parse_range_option(), 
Token::RParen)?;
+        self.expect_token(&Token::RParen)?;
+
+        Ok(Statement::CreateType {
+            name,
+            representation: UserDefinedTypeRepresentation::Range { options },
+        })
+    }
+
+    /// Parse a single range option for CREATE TYPE AS RANGE
+    fn parse_range_option(&mut self) -> Result<UserDefinedTypeRangeOption, 
ParserError> {
+        let keyword = self.parse_one_of_keywords(&[
+            Keyword::SUBTYPE,
+            Keyword::SUBTYPE_OPCLASS,

Review Comment:
   can we add tests for `SUBTYPE_OPCLASS`,`SUBTYPE_DIFF` and any other variants 
that are missing coverage?



##########
src/parser/mod.rs:
##########
@@ -17387,6 +17425,254 @@ impl<'a> Parser<'a> {
         })
     }
 
+    /// Parse remainder of `CREATE TYPE AS RANGE` statement
+    ///
+    /// See 
[PostgreSQL](https://www.postgresql.org/docs/current/sql-createtype.html)
+    pub fn parse_create_type_range(&mut self, name: ObjectName) -> 
Result<Statement, ParserError> {

Review Comment:
   ```suggestion
       fn parse_create_type_range(&mut self, name: ObjectName) -> 
Result<Statement, ParserError> {
   ```



##########
src/parser/mod.rs:
##########
@@ -17387,6 +17425,254 @@ impl<'a> Parser<'a> {
         })
     }
 
+    /// Parse remainder of `CREATE TYPE AS RANGE` statement
+    ///
+    /// See 
[PostgreSQL](https://www.postgresql.org/docs/current/sql-createtype.html)
+    pub fn parse_create_type_range(&mut self, name: ObjectName) -> 
Result<Statement, ParserError> {
+        self.expect_token(&Token::LParen)?;
+        let options = self.parse_comma_separated0(|p| p.parse_range_option(), 
Token::RParen)?;
+        self.expect_token(&Token::RParen)?;
+
+        Ok(Statement::CreateType {
+            name,
+            representation: UserDefinedTypeRepresentation::Range { options },
+        })
+    }
+
+    /// Parse a single range option for CREATE TYPE AS RANGE

Review Comment:
   ```suggestion
       /// Parse a single range option for a `CREATE TYPE AS RANGE` statement
   ```



##########
src/ast/ddl.rs:
##########
@@ -2002,22 +2002,45 @@ impl fmt::Display for DropBehavior {
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
 #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
 pub enum UserDefinedTypeRepresentation {
+    /// Composite type: `CREATE TYPE name AS (attributes)`
     Composite {
         attributes: Vec<UserDefinedTypeCompositeAttributeDef>,
     },
+    /// Enum type: `CREATE TYPE name AS ENUM (labels)`
+    ///
     /// Note: this is PostgreSQL-specific. See 
<https://www.postgresql.org/docs/current/sql-createtype.html>
     Enum { labels: Vec<Ident> },
+    /// Range type: `CREATE TYPE name AS RANGE (options)`
+    Range {
+        options: Vec<UserDefinedTypeRangeOption>,
+    },
+    /// Base type (SQL definition): `CREATE TYPE name (options)`
+    ///
+    /// Note the lack of `AS` keyword
+    SqlDefinition {
+        options: Vec<UserDefinedTypeSqlDefinitionOption>,
+    },
+    /// When the representation of the type is not specified.
+    /// This is used in `CREATE TYPE <name>;` statements.
+    None,

Review Comment:
   Instead of having a special `None` variant, ideally the usage becomes an 
optional field, would that work here? i.e `representation: 
Option<UserDefinedTypeRepresentation>`



##########
src/parser/mod.rs:
##########
@@ -17331,20 +17331,60 @@ impl<'a> Parser<'a> {
 
     pub fn parse_create_type(&mut self) -> Result<Statement, ParserError> {
         let name = self.parse_object_name(false)?;
-        self.expect_keyword_is(Keyword::AS)?;
 
+        // Check if we have AS keyword
+        let has_as = self.parse_keyword(Keyword::AS);
+
+        if !has_as {
+            // Two cases: CREATE TYPE name; or CREATE TYPE name (options);
+            if self.consume_token(&Token::LParen) {
+                // CREATE TYPE name (options) - SQL definition without AS
+                let options = self.parse_create_type_sql_definition_options()?;
+                self.expect_token(&Token::RParen)?;
+                return Ok(Statement::CreateType {
+                    name,
+                    representation: 
UserDefinedTypeRepresentation::SqlDefinition { options },
+                });
+            }
+
+            // CREATE TYPE name; - no representation
+            return Ok(Statement::CreateType {
+                name,
+                representation: UserDefinedTypeRepresentation::None,
+            });
+        }
+
+        // We have AS keyword
         if self.parse_keyword(Keyword::ENUM) {
-            return self.parse_create_type_enum(name);
+            // CREATE TYPE name AS ENUM (labels)
+            self.parse_create_type_enum(name)
+        } else if self.parse_keyword(Keyword::RANGE) {
+            // CREATE TYPE name AS RANGE (options)
+            self.parse_create_type_range(name)
+        } else if self.consume_token(&Token::LParen) {
+            // CREATE TYPE name AS (attributes) - Composite
+            self.parse_create_type_composite(name)
+        } else {
+            self.expected("ENUM, RANGE, or '(' after AS", self.peek_token())
         }
+    }
 
-        let mut attributes = vec![];
-        if !self.consume_token(&Token::LParen) || 
self.consume_token(&Token::RParen) {
+    /// Parse remainder of `CREATE TYPE AS (attributes)` statement (composite 
type)
+    ///
+    /// See 
[PostgreSQL](https://www.postgresql.org/docs/current/sql-createtype.html)
+    pub fn parse_create_type_composite(

Review Comment:
   ```suggestion
       fn parse_create_type_composite(
   ```



-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to