Skip to content

Commit cfd8bf1

Browse files
Vedinayman-sigma
authored andcommitted
Add SECURE keyword for views in Snowflake (apache#2004)
1 parent 8f024f7 commit cfd8bf1

6 files changed

Lines changed: 49 additions & 3 deletions

File tree

src/ast/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3285,6 +3285,9 @@ pub enum Statement {
32853285
or_alter: bool,
32863286
or_replace: bool,
32873287
materialized: bool,
3288+
/// Snowflake: SECURE view modifier
3289+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-view#syntax>
3290+
secure: bool,
32883291
/// View name
32893292
name: ObjectName,
32903293
/// If `if_not_exists` is true, this flag is set to true if the view name comes before the `IF NOT EXISTS` clause.
@@ -5147,6 +5150,7 @@ impl fmt::Display for Statement {
51475150
columns,
51485151
query,
51495152
materialized,
5153+
secure,
51505154
options,
51515155
cluster_by,
51525156
comment,
@@ -5168,7 +5172,7 @@ impl fmt::Display for Statement {
51685172
}
51695173
write!(
51705174
f,
5171-
"{materialized}{temporary}VIEW {if_not_and_name}{to}",
5175+
"{secure}{materialized}{temporary}VIEW {if_not_and_name}{to}",
51725176
if_not_and_name = if *if_not_exists {
51735177
if *name_before_not_exists {
51745178
format!("{name} IF NOT EXISTS")
@@ -5178,6 +5182,7 @@ impl fmt::Display for Statement {
51785182
} else {
51795183
format!("{name}")
51805184
},
5185+
secure = if *secure { "SECURE " } else { "" },
51815186
materialized = if *materialized { "MATERIALIZED " } else { "" },
51825187
temporary = if *temporary { "TEMPORARY " } else { "" },
51835188
to = to

src/ast/spans.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ impl Spanned for Statement {
395395
or_alter: _,
396396
or_replace: _,
397397
materialized: _,
398+
secure: _,
398399
name,
399400
columns,
400401
query,

src/keywords.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,7 @@ define_keywords!(
833833
SECONDARY_ENGINE_ATTRIBUTE,
834834
SECONDS,
835835
SECRET,
836+
SECURE,
836837
SECURITY,
837838
SEED,
838839
SELECT,

src/parser/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4763,8 +4763,11 @@ impl<'a> Parser<'a> {
47634763
let create_view_params = self.parse_create_view_params()?;
47644764
if self.parse_keyword(Keyword::TABLE) {
47654765
self.parse_create_table(or_replace, temporary, global, transient)
4766-
} else if self.parse_keyword(Keyword::MATERIALIZED) || self.parse_keyword(Keyword::VIEW) {
4767-
self.prev_token();
4766+
} else if self.peek_keyword(Keyword::MATERIALIZED)
4767+
|| self.peek_keyword(Keyword::VIEW)
4768+
|| self.peek_keywords(&[Keyword::SECURE, Keyword::MATERIALIZED, Keyword::VIEW])
4769+
|| self.peek_keywords(&[Keyword::SECURE, Keyword::VIEW])
4770+
{
47684771
self.parse_create_view(or_alter, or_replace, temporary, create_view_params)
47694772
} else if self.parse_keyword(Keyword::POLICY) {
47704773
self.parse_create_policy()
@@ -5884,6 +5887,7 @@ impl<'a> Parser<'a> {
58845887
temporary: bool,
58855888
create_view_params: Option<CreateViewParams>,
58865889
) -> Result<Statement, ParserError> {
5890+
let secure = self.parse_keyword(Keyword::SECURE);
58875891
let materialized = self.parse_keyword(Keyword::MATERIALIZED);
58885892
self.expect_keyword_is(Keyword::VIEW)?;
58895893
let allow_unquoted_hyphen = dialect_of!(self is BigQueryDialect);
@@ -5954,6 +5958,7 @@ impl<'a> Parser<'a> {
59545958
columns,
59555959
query,
59565960
materialized,
5961+
secure,
59575962
or_replace,
59585963
options,
59595964
cluster_by,

tests/sqlparser_common.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8079,6 +8079,7 @@ fn parse_create_view() {
80798079
to,
80808080
params,
80818081
name_before_not_exists: _,
8082+
secure: _,
80828083
} => {
80838084
assert_eq!(or_alter, false);
80848085
assert_eq!("myschema.myview", name.to_string());
@@ -8148,6 +8149,7 @@ fn parse_create_view_with_columns() {
81488149
to,
81498150
params,
81508151
name_before_not_exists: _,
8152+
secure: _,
81518153
} => {
81528154
assert_eq!(or_alter, false);
81538155
assert_eq!("v", name.to_string());
@@ -8198,6 +8200,7 @@ fn parse_create_view_temporary() {
81988200
to,
81998201
params,
82008202
name_before_not_exists: _,
8203+
secure: _,
82018204
} => {
82028205
assert_eq!(or_alter, false);
82038206
assert_eq!("myschema.myview", name.to_string());
@@ -8238,6 +8241,7 @@ fn parse_create_or_replace_view() {
82388241
to,
82398242
params,
82408243
name_before_not_exists: _,
8244+
secure: _,
82418245
} => {
82428246
assert_eq!(or_alter, false);
82438247
assert_eq!("v", name.to_string());
@@ -8282,6 +8286,7 @@ fn parse_create_or_replace_materialized_view() {
82828286
to,
82838287
params,
82848288
name_before_not_exists: _,
8289+
secure: _,
82858290
} => {
82868291
assert_eq!(or_alter, false);
82878292
assert_eq!("v", name.to_string());
@@ -8322,6 +8327,7 @@ fn parse_create_materialized_view() {
83228327
to,
83238328
params,
83248329
name_before_not_exists: _,
8330+
secure: _,
83258331
} => {
83268332
assert_eq!(or_alter, false);
83278333
assert_eq!("myschema.myview", name.to_string());
@@ -8362,6 +8368,7 @@ fn parse_create_materialized_view_with_cluster_by() {
83628368
to,
83638369
params,
83648370
name_before_not_exists: _,
8371+
secure: _,
83658372
} => {
83668373
assert_eq!(or_alter, false);
83678374
assert_eq!("myschema.myview", name.to_string());

tests/sqlparser_snowflake.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,33 @@ fn test_snowflake_create_table() {
4444
}
4545
}
4646

47+
#[test]
48+
fn parse_sf_create_secure_view_and_materialized_view() {
49+
for sql in [
50+
"CREATE SECURE VIEW v AS SELECT 1",
51+
"CREATE SECURE MATERIALIZED VIEW v AS SELECT 1",
52+
"CREATE OR REPLACE SECURE VIEW v AS SELECT 1",
53+
"CREATE OR REPLACE SECURE MATERIALIZED VIEW v AS SELECT 1",
54+
] {
55+
match snowflake().verified_stmt(sql) {
56+
Statement::CreateView {
57+
secure,
58+
materialized,
59+
..
60+
} => {
61+
assert!(secure);
62+
if sql.contains("MATERIALIZED") {
63+
assert!(materialized);
64+
} else {
65+
assert!(!materialized);
66+
}
67+
}
68+
_ => unreachable!(),
69+
}
70+
assert_eq!(snowflake().verified_stmt(sql).to_string(), sql);
71+
}
72+
}
73+
4774
#[test]
4875
fn test_snowflake_create_or_replace_table() {
4976
let sql = "CREATE OR REPLACE TABLE my_table (a number)";

0 commit comments

Comments
 (0)