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


##########
src/parser/mod.rs:
##########
@@ -12315,6 +12310,124 @@ impl<'a> Parser<'a> {
         }
         false
     }
+
+    /// Look for all of the expected keywords in sequence, without consuming 
them
+    fn peek_keywords(&mut self, expected: &[Keyword]) -> bool {
+        let index = self.index;
+        for kw in expected {
+            if !self.parse_keyword(*kw) {
+                self.index = index;
+                return false;
+            }
+        }
+        self.index = index;
+        true
+    }
+
+    fn parse_show_stmt_options(&mut self) -> Result<ShowStatementOptions, 
ParserError> {
+        let show_in;
+        let mut filter_position = None;
+        if self.dialect.supports_show_like_before_in() {
+            if let Some(filter) = self.parse_show_statement_filter()? {
+                filter_position = 
Some(ShowStatementFilterPosition::Infix(filter));
+            }
+            show_in = self.maybe_parse_show_stmt_in()?;
+        } else {
+            show_in = self.maybe_parse_show_stmt_in()?;
+            if let Some(filter) = self.parse_show_statement_filter()? {
+                filter_position = 
Some(ShowStatementFilterPosition::Suffix(filter));
+            }
+        }
+        let starts_with = self.maybe_parse_show_stmt_starts_with()?;
+        let limit = self.maybe_parse_show_stmt_limit()?;
+        let from = self.maybe_parse_show_stmt_from()?;
+        Ok(ShowStatementOptions {
+            filter_position,
+            show_in,
+            starts_with,
+            limit,
+            limit_from: from,
+        })
+    }
+
+    fn maybe_parse_show_stmt_in(&mut self) -> Result<Option<ShowStatementIn>, 
ParserError> {
+        let clause = match self.parse_one_of_keywords(&[Keyword::FROM, 
Keyword::IN]) {
+            Some(Keyword::FROM) => ShowStatementInClause::FROM,
+            Some(Keyword::IN) => ShowStatementInClause::IN,
+            _ => return Ok(None),
+        };
+
+        let (parent_type, parent_name) = match self.parse_one_of_keywords(&[
+            Keyword::ACCOUNT,
+            Keyword::DATABASE,
+            Keyword::SCHEMA,
+            Keyword::TABLE,
+            Keyword::VIEW,
+        ]) {
+            Some(Keyword::DATABASE) if self.peek_keywords(&[Keyword::STARTS, 
Keyword::WITH]) => {
+                (Some(ShowStatementInParentType::Database), None)
+            }
+            Some(Keyword::SCHEMA) if self.peek_keywords(&[Keyword::STARTS, 
Keyword::WITH]) => {
+                (Some(ShowStatementInParentType::Schema), None)
+            }
+            Some(parent_kw) => {
+                let parent_name = match self.parse_object_name(false) {
+                    Ok(n) => Some(n),
+                    _ => None,
+                };
+                match parent_kw {
+                    Keyword::ACCOUNT => 
(Some(ShowStatementInParentType::Account), parent_name),
+                    Keyword::DATABASE => 
(Some(ShowStatementInParentType::Database), parent_name),
+                    Keyword::SCHEMA => 
(Some(ShowStatementInParentType::Schema), parent_name),
+                    Keyword::TABLE => (Some(ShowStatementInParentType::Table), 
parent_name),
+                    Keyword::VIEW => (Some(ShowStatementInParentType::View), 
parent_name),
+                    _ => unreachable!(),
+                }
+            }
+            None => {
+                // Parsing MySQL style FROM tbl_name FROM db_name
+                // which is equivalent to FROM tbl_name.db_name
+                let mut parent_name = self.parse_object_name(false)?;
+                if self
+                    .parse_one_of_keywords(&[Keyword::FROM, Keyword::IN])
+                    .is_some()
+                {
+                    parent_name.0.insert(0, self.parse_identifier(false)?);

Review Comment:
   Ah I see, that's interesting



##########
src/dialect/mod.rs:
##########
@@ -606,6 +606,12 @@ pub trait Dialect: Debug + Any {
     fn supports_top_before_distinct(&self) -> bool {
         false
     }
+
+    /// Returns true if this dialect support the `LIKE 'pattern'` option in

Review Comment:
   ```suggestion
       /// Returns true if this dialect supports the `LIKE 'pattern'` option in
   ```



##########
tests/sqlparser_snowflake.rs:
##########
@@ -2781,3 +2781,68 @@ fn test_parentheses_overflow() {
         
snowflake_with_recursion_limit(max_nesting_level).parse_sql_statements(sql.as_str());
     assert_eq!(parsed.err(), Some(ParserError::RecursionLimitExceeded));
 }
+
+#[test]
+fn test_show_databases() {
+    snowflake().verified_stmt("SHOW DATABASES");
+    snowflake().verified_stmt("SHOW DATABASES HISTORY");
+    snowflake().verified_stmt("SHOW DATABASES LIKE '%abc%'");
+    snowflake().verified_stmt("SHOW DATABASES STARTS WITH 'demo_db'");
+    snowflake().verified_stmt("SHOW DATABASES LIMIT 12");
+    snowflake()
+        .verified_stmt("SHOW DATABASES HISTORY LIKE '%aa' STARTS WITH 'demo' 
LIMIT 20 FROM 'abc'");
+    snowflake().verified_stmt("SHOW DATABASES IN ACCOUNT abc");
+}
+
+#[test]
+fn test_parse_show_schemas() {
+    snowflake().verified_stmt("SHOW SCHEMAS");
+    snowflake().verified_stmt("SHOW SCHEMAS IN ACCOUNT");
+    snowflake().verified_stmt("SHOW SCHEMAS IN ACCOUNT abc");
+    snowflake().verified_stmt("SHOW SCHEMAS IN DATABASE");
+    snowflake().verified_stmt("SHOW SCHEMAS IN DATABASE xyz");
+    snowflake().verified_stmt("SHOW SCHEMAS HISTORY LIKE '%xa%'");
+    snowflake().verified_stmt("SHOW SCHEMAS STARTS WITH 'abc' LIMIT 20");
+    snowflake().verified_stmt("SHOW SCHEMAS IN DATABASE STARTS WITH 'abc' 
LIMIT 20 FROM 'xyz'");
+}
+
+#[test]
+fn test_parse_show_tables() {
+    snowflake().verified_stmt("SHOW TABLES");

Review Comment:
   Ah I see, yeah having them here would've meant those tests have to be 
snowflake agnostic to some degree which wouldn't be ideal either. I think 
moving some of them to common as is done currently is reasonable thanks!



##########
src/parser/mod.rs:
##########
@@ -12315,6 +12310,124 @@ impl<'a> Parser<'a> {
         }
         false
     }
+
+    /// Look for all of the expected keywords in sequence, without consuming 
them
+    fn peek_keywords(&mut self, expected: &[Keyword]) -> bool {
+        let index = self.index;
+        for kw in expected {
+            if !self.parse_keyword(*kw) {
+                self.index = index;
+                return false;
+            }
+        }
+        self.index = index;
+        true
+    }
+
+    fn parse_show_stmt_options(&mut self) -> Result<ShowStatementOptions, 
ParserError> {
+        let show_in;
+        let mut filter_position = None;
+        if self.dialect.supports_show_like_before_in() {
+            if let Some(filter) = self.parse_show_statement_filter()? {
+                filter_position = 
Some(ShowStatementFilterPosition::Infix(filter));
+            }
+            show_in = self.maybe_parse_show_stmt_in()?;
+        } else {
+            show_in = self.maybe_parse_show_stmt_in()?;
+            if let Some(filter) = self.parse_show_statement_filter()? {
+                filter_position = 
Some(ShowStatementFilterPosition::Suffix(filter));
+            }
+        }
+        let starts_with = self.maybe_parse_show_stmt_starts_with()?;
+        let limit = self.maybe_parse_show_stmt_limit()?;
+        let from = self.maybe_parse_show_stmt_from()?;
+        Ok(ShowStatementOptions {
+            filter_position,
+            show_in,
+            starts_with,
+            limit,
+            limit_from: from,
+        })
+    }
+
+    fn maybe_parse_show_stmt_in(&mut self) -> Result<Option<ShowStatementIn>, 
ParserError> {
+        let clause = match self.parse_one_of_keywords(&[Keyword::FROM, 
Keyword::IN]) {
+            Some(Keyword::FROM) => ShowStatementInClause::FROM,
+            Some(Keyword::IN) => ShowStatementInClause::IN,
+            _ => return Ok(None),
+        };
+
+        let (parent_type, parent_name) = match self.parse_one_of_keywords(&[
+            Keyword::ACCOUNT,
+            Keyword::DATABASE,
+            Keyword::SCHEMA,
+            Keyword::TABLE,
+            Keyword::VIEW,
+        ]) {
+            Some(Keyword::DATABASE) if self.peek_keywords(&[Keyword::STARTS, 
Keyword::WITH]) => {
+                (Some(ShowStatementInParentType::Database), None)
+            }
+            Some(Keyword::SCHEMA) if self.peek_keywords(&[Keyword::STARTS, 
Keyword::WITH]) => {
+                (Some(ShowStatementInParentType::Schema), None)
+            }
+            Some(parent_kw) => {
+                let parent_name = match self.parse_object_name(false) {
+                    Ok(n) => Some(n),
+                    _ => None,

Review Comment:
   Ah if its optional then we could use maybe_parse in that case?
   ```rust
   let parent_name = self.maybe_parse(|p| p.parse_object_name(false))?;
   ```



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