iffyio commented on code in PR #1961: URL: https://github.com/apache/datafusion-sqlparser-rs/pull/1961#discussion_r2236532850
########## src/parser/mod.rs: ########## @@ -5768,12 +5768,25 @@ impl<'a> Parser<'a> { ) -> Result<Statement, ParserError> { let materialized = self.parse_keyword(Keyword::MATERIALIZED); self.expect_keyword_is(Keyword::VIEW)?; - let if_not_exists = dialect_of!(self is BigQueryDialect|SQLiteDialect|GenericDialect) - && self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]); + let allow_unquoted_hyphen = dialect_of!(self is BigQueryDialect); + let mut if_not_exists = false; + let name: ObjectName; + let mut name_before_not_exists = false; + if self.peek_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]) { + // Possible syntax -> ... IF NOT EXISTS <name> + if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]); + name = self.parse_object_name(allow_unquoted_hyphen)?; + } else { + // Possible syntax -> ... <name> IF NOT EXISTS + // Supported by snowflake but is undocumented + name = self.parse_object_name(allow_unquoted_hyphen)?; + if self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]) { + if_not_exists = true; + name_before_not_exists = true; + } + } // Many dialects support `OR ALTER` right after `CREATE`, but we don't (yet). // ANSI SQL and Postgres support RECURSIVE here, but we don't support it either. - let allow_unquoted_hyphen = dialect_of!(self is BigQueryDialect); - let name = self.parse_object_name(allow_unquoted_hyphen)?; Review Comment: Would it work to only put something like this line after we've parsed? `name` ```rust let name_before_not_exists = !if_not_exists && self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]); let if_not_exists = if_not_exists || name_before_not_exists; ``` thinking if so that would let us avoid the if/else and `mut` ########## src/ast/mod.rs: ########## @@ -3263,6 +3263,8 @@ pub enum Statement { materialized: bool, /// View name name: ObjectName, + // Name IF NOT EXIST instead of IF NOT EXIST name Review Comment: ```suggestion /// If `if_not_exists` is true, this flag is set to true if the view name comes before the `IF NOT EXISTS` clause. /// Example: /// ```sql /// CREATE VIEW myview IF NOT EXISTS AS SELECT 1` /// ``` /// Otherwise, the flag is set to false if the view name comes after the clause /// Example: /// ```sql /// CREATE VIEW IF NOT EXISTS myview AS SELECT 1` /// ``` ``` we could say something descriptive like this? ########## tests/sqlparser_common.rs: ########## @@ -16377,3 +16384,11 @@ fn parse_drop_stream() { } verified_stmt("DROP STREAM IF EXISTS s1"); } + +#[test] +fn parse_create_view_if_not_exists() { + let sql: &'static str = "CREATE VIEW IF NOT EXISTS v AS SELECT 1"; + let _ = all_dialects().verified_stmt(sql); + let sql = "CREATE VIEW v IF NOT EXISTS AS SELECT 1"; + let _ = all_dialects().verified_stmt(sql); Review Comment: Can we add a test case for `CREATE VIEW IF NOT EXISTS AS SELECT 1` to verify how the parser behaves in that scenario? -- 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