-
Notifications
You must be signed in to change notification settings - Fork 668
Snowflake: Support CREATE VIEW myview IF NOT EXISTS
#1961
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The head ref may contain hidden characters: "\u201Ccreate-view-name-before-if-not-exists\u201D"
Changes from 2 commits
26f2680
46ce27f
ce9864d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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)?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it work to only put something like this line after we've parsed? 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 |
||
let columns = self.parse_view_columns()?; | ||
let mut options = CreateTableOptions::None; | ||
let with_options = self.parse_options(Keyword::WITH)?; | ||
|
@@ -5840,6 +5853,7 @@ impl<'a> Parser<'a> { | |
temporary, | ||
to, | ||
params: create_view_params, | ||
name_before_not_exists, | ||
}) | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8040,6 +8040,7 @@ fn parse_create_view() { | |
temporary, | ||
to, | ||
params, | ||
name_before_not_exists: _, | ||
} => { | ||
assert_eq!(or_alter, false); | ||
assert_eq!("myschema.myview", name.to_string()); | ||
|
@@ -8108,6 +8109,7 @@ fn parse_create_view_with_columns() { | |
temporary, | ||
to, | ||
params, | ||
name_before_not_exists: _, | ||
} => { | ||
assert_eq!(or_alter, false); | ||
assert_eq!("v", name.to_string()); | ||
|
@@ -8157,6 +8159,7 @@ fn parse_create_view_temporary() { | |
temporary, | ||
to, | ||
params, | ||
name_before_not_exists: _, | ||
} => { | ||
assert_eq!(or_alter, false); | ||
assert_eq!("myschema.myview", name.to_string()); | ||
|
@@ -8196,6 +8199,7 @@ fn parse_create_or_replace_view() { | |
temporary, | ||
to, | ||
params, | ||
name_before_not_exists: _, | ||
} => { | ||
assert_eq!(or_alter, false); | ||
assert_eq!("v", name.to_string()); | ||
|
@@ -8239,6 +8243,7 @@ fn parse_create_or_replace_materialized_view() { | |
temporary, | ||
to, | ||
params, | ||
name_before_not_exists: _, | ||
} => { | ||
assert_eq!(or_alter, false); | ||
assert_eq!("v", name.to_string()); | ||
|
@@ -8278,6 +8283,7 @@ fn parse_create_materialized_view() { | |
temporary, | ||
to, | ||
params, | ||
name_before_not_exists: _, | ||
} => { | ||
assert_eq!(or_alter, false); | ||
assert_eq!("myschema.myview", name.to_string()); | ||
|
@@ -8317,6 +8323,7 @@ fn parse_create_materialized_view_with_cluster_by() { | |
temporary, | ||
to, | ||
params, | ||
name_before_not_exists: _, | ||
} => { | ||
assert_eq!(or_alter, false); | ||
assert_eq!("myschema.myview", name.to_string()); | ||
|
@@ -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"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From a quick look I couldn't find which dialects in practice support this syntax? Do you have a link to documentation for one such dialect? related the MR not super sure it would be necessary to have this behavior covered by a flag and the parser can always look to accept There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right, I couldn't find official documentation for this syntax, though we have confirmed it works in practice on Snowflake. I'm happy to remove the dialect flag and update the parser to support both forms for all dialects. Let me know if you'd like me to proceed with that change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yeah in that case I think we can remove the dialect flags, not sure that we need to support both forms if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's supported in snowflake, but not officially documented. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah alright, in that case yeah I think we could skip the dialect methods entirely and let the parser accept either format if they show up? Also we can add a comment flagging that the second format is supported by snowflake but is undocumented |
||
let _ = all_dialects().verified_stmt(sql); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add a test case for |
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could say something descriptive like this?