Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3255,6 +3255,9 @@ pub enum Statement {
or_alter: bool,
or_replace: bool,
materialized: bool,
/// Snowflake: SECURE view modifier
/// <https://docs.snowflake.com/en/sql-reference/sql/create-view#syntax>
secure: bool,
/// View name
name: ObjectName,
/// If `if_not_exists` is true, this flag is set to true if the view name comes before the `IF NOT EXISTS` clause.
Expand Down Expand Up @@ -5105,6 +5108,7 @@ impl fmt::Display for Statement {
columns,
query,
materialized,
secure,
options,
cluster_by,
comment,
Expand All @@ -5126,7 +5130,7 @@ impl fmt::Display for Statement {
}
write!(
f,
"{materialized}{temporary}VIEW {if_not_and_name}{to}",
"{secure}{materialized}{temporary}VIEW {if_not_and_name}{to}",
if_not_and_name = if *if_not_exists {
if *name_before_not_exists {
format!("{name} IF NOT EXISTS")
Expand All @@ -5136,6 +5140,7 @@ impl fmt::Display for Statement {
} else {
format!("{name}")
},
secure = if *secure { "SECURE " } else { "" },
materialized = if *materialized { "MATERIALIZED " } else { "" },
temporary = if *temporary { "TEMPORARY " } else { "" },
to = to
Expand Down
1 change: 1 addition & 0 deletions src/ast/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ impl Spanned for Statement {
or_alter: _,
or_replace: _,
materialized: _,
secure: _,
name,
columns,
query,
Expand Down
1 change: 1 addition & 0 deletions src/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,7 @@ define_keywords!(
SECONDARY_ENGINE_ATTRIBUTE,
SECONDS,
SECRET,
SECURE,
SECURITY,
SEED,
SELECT,
Expand Down
7 changes: 6 additions & 1 deletion src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4713,7 +4713,10 @@ impl<'a> Parser<'a> {
let create_view_params = self.parse_create_view_params()?;
if self.parse_keyword(Keyword::TABLE) {
self.parse_create_table(or_replace, temporary, global, transient)
} else if self.parse_keyword(Keyword::MATERIALIZED) || self.parse_keyword(Keyword::VIEW) {
} else if self.parse_keyword(Keyword::MATERIALIZED)
|| self.parse_keyword(Keyword::VIEW)
|| (dialect_of!(self is SnowflakeDialect) && self.parse_keyword(Keyword::SECURE))
{
self.prev_token();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
} else if self.parse_keyword(Keyword::MATERIALIZED)
|| self.parse_keyword(Keyword::VIEW)
|| (dialect_of!(self is SnowflakeDialect) && self.parse_keyword(Keyword::SECURE))
{
self.prev_token();
} else if self.peek_keyword(Keyword::MATERIALIZED)
|| self.peek_keyword(Keyword::VIEW)
|| self.peek_keywords(&[Keyword::SECURE, Keyword::MATERIALIZED])
|| self.peek_keywords(&[Keyword::SECURE, Keyword::VIEW])
|| (dialect_of!(self is SnowflakeDialect) && self.parse_keyword(Keyword::SECURE))
{

We could probably do something like this? also I imagine no need for the snowflakeDialect check since the syntax doesn't conflict with other dialects.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, done. snowflake dialect check was removed as well.

self.parse_create_view(or_alter, or_replace, temporary, create_view_params)
} else if self.parse_keyword(Keyword::POLICY) {
Expand Down Expand Up @@ -5834,6 +5837,7 @@ impl<'a> Parser<'a> {
temporary: bool,
create_view_params: Option<CreateViewParams>,
) -> Result<Statement, ParserError> {
let secure = self.parse_keyword(Keyword::SECURE);
let materialized = self.parse_keyword(Keyword::MATERIALIZED);
self.expect_keyword_is(Keyword::VIEW)?;
let allow_unquoted_hyphen = dialect_of!(self is BigQueryDialect);
Expand Down Expand Up @@ -5904,6 +5908,7 @@ impl<'a> Parser<'a> {
columns,
query,
materialized,
secure,
or_replace,
options,
cluster_by,
Expand Down
7 changes: 7 additions & 0 deletions tests/sqlparser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8078,6 +8078,7 @@ fn parse_create_view() {
to,
params,
name_before_not_exists: _,
secure: _,
} => {
assert_eq!(or_alter, false);
assert_eq!("myschema.myview", name.to_string());
Expand Down Expand Up @@ -8147,6 +8148,7 @@ fn parse_create_view_with_columns() {
to,
params,
name_before_not_exists: _,
secure: _,
} => {
assert_eq!(or_alter, false);
assert_eq!("v", name.to_string());
Expand Down Expand Up @@ -8197,6 +8199,7 @@ fn parse_create_view_temporary() {
to,
params,
name_before_not_exists: _,
secure: _,
} => {
assert_eq!(or_alter, false);
assert_eq!("myschema.myview", name.to_string());
Expand Down Expand Up @@ -8237,6 +8240,7 @@ fn parse_create_or_replace_view() {
to,
params,
name_before_not_exists: _,
secure: _,
} => {
assert_eq!(or_alter, false);
assert_eq!("v", name.to_string());
Expand Down Expand Up @@ -8281,6 +8285,7 @@ fn parse_create_or_replace_materialized_view() {
to,
params,
name_before_not_exists: _,
secure: _,
} => {
assert_eq!(or_alter, false);
assert_eq!("v", name.to_string());
Expand Down Expand Up @@ -8321,6 +8326,7 @@ fn parse_create_materialized_view() {
to,
params,
name_before_not_exists: _,
secure: _,
} => {
assert_eq!(or_alter, false);
assert_eq!("myschema.myview", name.to_string());
Expand Down Expand Up @@ -8361,6 +8367,7 @@ fn parse_create_materialized_view_with_cluster_by() {
to,
params,
name_before_not_exists: _,
secure: _,
} => {
assert_eq!(or_alter, false);
assert_eq!("myschema.myview", name.to_string());
Expand Down
27 changes: 27 additions & 0 deletions tests/sqlparser_snowflake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,33 @@ fn test_snowflake_create_table() {
}
}

#[test]
fn parse_sf_create_secure_view_and_materialized_view() {
for sql in [
"CREATE SECURE VIEW v AS SELECT 1",
"CREATE SECURE MATERIALIZED VIEW v AS SELECT 1",
"CREATE OR REPLACE SECURE VIEW v AS SELECT 1",
"CREATE OR REPLACE SECURE MATERIALIZED VIEW v AS SELECT 1",
] {
match snowflake().verified_stmt(sql) {
Statement::CreateView {
secure,
materialized,
..
} => {
assert!(secure);
if sql.contains("MATERIALIZED") {
assert!(materialized);
} else {
assert!(!materialized);
}
}
_ => unreachable!(),
}
assert_eq!(snowflake().verified_stmt(sql).to_string(), sql);
}
}

#[test]
fn test_snowflake_create_or_replace_table() {
let sql = "CREATE OR REPLACE TABLE my_table (a number)";
Expand Down