Skip to content

Commit b6003eb

Browse files
authored
Fixed COPY GRANTS clause parsing for snowflake (#2267)
1 parent 13b88a3 commit b6003eb

File tree

4 files changed

+25
-0
lines changed

4 files changed

+25
-0
lines changed

src/ast/ddl.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4293,6 +4293,9 @@ pub struct CreateView {
42934293
pub if_not_exists: bool,
42944294
/// if true, has SQLite `TEMP` or `TEMPORARY` clause <https://www.sqlite.org/lang_createview.html>
42954295
pub temporary: bool,
4296+
/// Snowflake: `COPY GRANTS` clause
4297+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-view>
4298+
pub copy_grants: bool,
42964299
/// if not None, has Clickhouse `TO` clause, specify the table into which to insert results
42974300
/// <https://clickhouse.com/docs/en/sql-reference/statements/create/view#materialized-view>
42984301
pub to: Option<ObjectName>,
@@ -4336,6 +4339,9 @@ impl fmt::Display for CreateView {
43364339
.map(|to| format!(" TO {to}"))
43374340
.unwrap_or_default()
43384341
)?;
4342+
if self.copy_grants {
4343+
write!(f, " COPY GRANTS")?;
4344+
}
43394345
if !self.columns.is_empty() {
43404346
write!(f, " ({})", display_comma_separated(&self.columns))?;
43414347
}

src/parser/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6375,6 +6375,7 @@ impl<'a> Parser<'a> {
63756375
let name_before_not_exists = !if_not_exists_first
63766376
&& self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
63776377
let if_not_exists = if_not_exists_first || name_before_not_exists;
6378+
let copy_grants = self.parse_keywords(&[Keyword::COPY, Keyword::GRANTS]);
63786379
// Many dialects support `OR ALTER` right after `CREATE`, but we don't (yet).
63796380
// ANSI SQL and Postgres support RECURSIVE here, but we don't support it either.
63806381
let columns = self.parse_view_columns()?;
@@ -6442,6 +6443,7 @@ impl<'a> Parser<'a> {
64426443
with_no_schema_binding,
64436444
if_not_exists,
64446445
temporary,
6446+
copy_grants,
64456447
to,
64466448
params: create_view_params,
64476449
name_before_not_exists,

tests/sqlparser_common.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8317,6 +8317,7 @@ fn parse_create_view() {
83178317
params,
83188318
name_before_not_exists: _,
83198319
secure: _,
8320+
copy_grants: _,
83208321
}) => {
83218322
assert_eq!(or_alter, false);
83228323
assert_eq!("myschema.myview", name.to_string());
@@ -8435,6 +8436,7 @@ fn parse_create_view_temporary() {
84358436
params,
84368437
name_before_not_exists: _,
84378438
secure: _,
8439+
copy_grants: _,
84388440
}) => {
84398441
assert_eq!(or_alter, false);
84408442
assert_eq!("myschema.myview", name.to_string());
@@ -8476,6 +8478,7 @@ fn parse_create_or_replace_view() {
84768478
params,
84778479
name_before_not_exists: _,
84788480
secure: _,
8481+
copy_grants: _,
84798482
}) => {
84808483
assert_eq!(or_alter, false);
84818484
assert_eq!("v", name.to_string());
@@ -8521,6 +8524,7 @@ fn parse_create_or_replace_materialized_view() {
85218524
params,
85228525
name_before_not_exists: _,
85238526
secure: _,
8527+
copy_grants: _,
85248528
}) => {
85258529
assert_eq!(or_alter, false);
85268530
assert_eq!("v", name.to_string());
@@ -8562,6 +8566,7 @@ fn parse_create_materialized_view() {
85628566
params,
85638567
name_before_not_exists: _,
85648568
secure: _,
8569+
copy_grants: _,
85658570
}) => {
85668571
assert_eq!(or_alter, false);
85678572
assert_eq!("myschema.myview", name.to_string());
@@ -8603,6 +8608,7 @@ fn parse_create_materialized_view_with_cluster_by() {
86038608
params,
86048609
name_before_not_exists: _,
86058610
secure: _,
8611+
copy_grants: _,
86068612
}) => {
86078613
assert_eq!(or_alter, false);
86088614
assert_eq!("myschema.myview", name.to_string());

tests/sqlparser_snowflake.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4671,6 +4671,17 @@ fn test_snowflake_create_view_with_composite_policy_name() {
46714671
snowflake().verified_stmt(create_view_with_tag);
46724672
}
46734673

4674+
#[test]
4675+
fn test_snowflake_create_view_copy_grants() {
4676+
snowflake().verified_stmt("CREATE OR REPLACE VIEW bla COPY GRANTS AS (SELECT * FROM source)");
4677+
snowflake()
4678+
.verified_stmt("CREATE OR REPLACE SECURE VIEW bla COPY GRANTS AS (SELECT * FROM source)");
4679+
// COPY GRANTS with column list
4680+
snowflake().verified_stmt(
4681+
"CREATE OR REPLACE VIEW bla COPY GRANTS (a, b) AS (SELECT a, b FROM source)",
4682+
);
4683+
}
4684+
46744685
#[test]
46754686
fn test_snowflake_identifier_function() {
46764687
// Using IDENTIFIER to reference a column

0 commit comments

Comments
 (0)