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


##########
src/parser/mod.rs:
##########
@@ -16514,6 +16547,83 @@ impl<'a> Parser<'a> {
             Ok(None)
         }
     }
+
+    /// Parses options provided in key-value format.
+    ///
+    /// * `parenthesized` - true if the options are enclosed in parenthesis
+    /// * `end_words` - a list of keywords that any of them indicates the end 
of the options section
+    pub(crate) fn parse_key_value_options(
+        &mut self,
+        parenthesized: bool,
+        end_words: &[Keyword],
+    ) -> Result<Vec<KeyValueOption>, ParserError> {
+        let mut options: Vec<KeyValueOption> = Vec::new();
+        if parenthesized {
+            self.expect_token(&Token::LParen)?;
+        }
+        loop {
+            match self.next_token().token {
+                Token::RParen => {
+                    if parenthesized {
+                        break;
+                    } else {
+                        return self.expected(" another option or EOF", 
self.peek_token());
+                    }
+                }
+                Token::EOF => break,
+                Token::Comma => continue,
+                Token::Word(w) if !end_words.contains(&w.keyword) => {
+                    options.push(self.parse_key_value_option(w)?)
+                }
+                Token::Word(w) if end_words.contains(&w.keyword) => {
+                    self.prev_token();
+                    break;
+                }
+                _ => return self.expected("another option, EOF, Comma or ')'", 
self.peek_token()),
+            };
+        }
+        Ok(options)
+    }
+
+    // Parses a `KEY = VALUE` construct based on the specified key
+    pub(crate) fn parse_key_value_option(
+        &mut self,
+        key: Word,
+    ) -> Result<KeyValueOption, ParserError> {
+        self.expect_token(&Token::Eq)?;
+        if self.parse_keyword(Keyword::TRUE) {
+            Ok(KeyValueOption {
+                option_name: key.value,
+                option_type: KeyValueOptionType::BOOLEAN,
+                value: "TRUE".to_string(),
+            })
+        } else if self.parse_keyword(Keyword::FALSE) {
+            Ok(KeyValueOption {
+                option_name: key.value,
+                option_type: KeyValueOptionType::BOOLEAN,
+                value: "FALSE".to_string(),
+            })
+        } else {

Review Comment:
   would something like this be equivalent and simplify the if/elseif branches?
   ```rust
   if let Some(kw) = self.parse_one_of_keywords(&[Keyword::TRUE, 
Keyword::FALSE]) {
       Ok(KeyValueOption{ ..., kw.to_string() })
   } else {
       // ...
   }
   ```



##########
src/parser/mod.rs:
##########
@@ -16514,6 +16547,83 @@ impl<'a> Parser<'a> {
             Ok(None)
         }
     }
+
+    /// Parses options provided in key-value format.
+    ///
+    /// * `parenthesized` - true if the options are enclosed in parenthesis
+    /// * `end_words` - a list of keywords that any of them indicates the end 
of the options section
+    pub(crate) fn parse_key_value_options(
+        &mut self,
+        parenthesized: bool,
+        end_words: &[Keyword],
+    ) -> Result<Vec<KeyValueOption>, ParserError> {
+        let mut options: Vec<KeyValueOption> = Vec::new();
+        if parenthesized {
+            self.expect_token(&Token::LParen)?;
+        }
+        loop {
+            match self.next_token().token {
+                Token::RParen => {
+                    if parenthesized {
+                        break;
+                    } else {
+                        return self.expected(" another option or EOF", 
self.peek_token());
+                    }
+                }
+                Token::EOF => break,
+                Token::Comma => continue,
+                Token::Word(w) if !end_words.contains(&w.keyword) => {
+                    options.push(self.parse_key_value_option(w)?)
+                }
+                Token::Word(w) if end_words.contains(&w.keyword) => {
+                    self.prev_token();
+                    break;
+                }
+                _ => return self.expected("another option, EOF, Comma or ')'", 
self.peek_token()),
+            };
+        }
+        Ok(options)
+    }
+
+    // Parses a `KEY = VALUE` construct based on the specified key

Review Comment:
   ```suggestion
       /// Parses a `KEY = VALUE` construct based on the specified key
   ```



##########
src/ast/mod.rs:
##########
@@ -10074,6 +10080,42 @@ impl fmt::Display for MemberOf {
     }
 }
 
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub struct CreateUser {

Review Comment:
   Could we add a description and link to the snowflake docs here as well? I 
think its usually more visible on the struct than on the enum variant since the 
struct is usually referenced in different contexts



##########
tests/sqlparser_common.rs:
##########
@@ -16156,3 +16156,16 @@ fn test_identifier_unicode_start() {
     ]);
     let _ = dialects.verified_stmt(sql);
 }
+
+#[test]
+fn parse_create_user() {
+    verified_stmt("CREATE USER u1");

Review Comment:
   Can we include in one of the scenarios an assertion on the returned AST?



##########
src/parser/mod.rs:
##########
@@ -4689,6 +4696,32 @@ impl<'a> Parser<'a> {
         }
     }
 
+    pub fn parse_create_user(&mut self, or_replace: bool) -> Result<Statement, 
ParserError> {

Review Comment:
   ```suggestion
       fn parse_create_user(&mut self, or_replace: bool) -> Result<Statement, 
ParserError> {
   ```



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