Skip to content

Commit 2abde6d

Browse files
yoavcloudayman-sigma
authored andcommitted
Extend snowflake grant options support (apache#1794)
1 parent f986002 commit 2abde6d

File tree

4 files changed

+126
-19
lines changed

4 files changed

+126
-19
lines changed

src/ast/mod.rs

+50-5
Original file line numberDiff line numberDiff line change
@@ -6097,10 +6097,10 @@ pub enum Action {
60976097
ManageReleases,
60986098
ManageVersions,
60996099
Modify {
6100-
modify_type: ActionModifyType,
6100+
modify_type: Option<ActionModifyType>,
61016101
},
61026102
Monitor {
6103-
monitor_type: ActionMonitorType,
6103+
monitor_type: Option<ActionMonitorType>,
61046104
},
61056105
Operate,
61066106
OverrideShareRestrictions,
@@ -6133,7 +6133,7 @@ impl fmt::Display for Action {
61336133
match self {
61346134
Action::AddSearchOptimization => f.write_str("ADD SEARCH OPTIMIZATION")?,
61356135
Action::Apply { apply_type } => write!(f, "APPLY {apply_type}")?,
6136-
Action::ApplyBudget => f.write_str("APPLY BUDGET")?,
6136+
Action::ApplyBudget => f.write_str("APPLYBUDGET")?,
61376137
Action::AttachListing => f.write_str("ATTACH LISTING")?,
61386138
Action::AttachPolicy => f.write_str("ATTACH POLICY")?,
61396139
Action::Audit => f.write_str("AUDIT")?,
@@ -6161,8 +6161,18 @@ impl fmt::Display for Action {
61616161
Action::Manage { manage_type } => write!(f, "MANAGE {manage_type}")?,
61626162
Action::ManageReleases => f.write_str("MANAGE RELEASES")?,
61636163
Action::ManageVersions => f.write_str("MANAGE VERSIONS")?,
6164-
Action::Modify { modify_type } => write!(f, "MODIFY {modify_type}")?,
6165-
Action::Monitor { monitor_type } => write!(f, "MONITOR {monitor_type}")?,
6164+
Action::Modify { modify_type } => {
6165+
write!(f, "MODIFY")?;
6166+
if let Some(modify_type) = modify_type {
6167+
write!(f, " {modify_type}")?;
6168+
}
6169+
}
6170+
Action::Monitor { monitor_type } => {
6171+
write!(f, "MONITOR")?;
6172+
if let Some(monitor_type) = monitor_type {
6173+
write!(f, " {monitor_type}")?
6174+
}
6175+
}
61666176
Action::Operate => f.write_str("OPERATE")?,
61676177
Action::OverrideShareRestrictions => f.write_str("OVERRIDE SHARE RESTRICTIONS")?,
61686178
Action::Ownership => f.write_str("OWNERSHIP")?,
@@ -6480,6 +6490,20 @@ pub enum GrantObjects {
64806490
Warehouses(Vec<ObjectName>),
64816491
/// Grant privileges on specific integrations
64826492
Integrations(Vec<ObjectName>),
6493+
/// Grant privileges on resource monitors
6494+
ResourceMonitors(Vec<ObjectName>),
6495+
/// Grant privileges on users
6496+
Users(Vec<ObjectName>),
6497+
/// Grant privileges on compute pools
6498+
ComputePools(Vec<ObjectName>),
6499+
/// Grant privileges on connections
6500+
Connections(Vec<ObjectName>),
6501+
/// Grant privileges on failover groups
6502+
FailoverGroup(Vec<ObjectName>),
6503+
/// Grant privileges on replication group
6504+
ReplicationGroup(Vec<ObjectName>),
6505+
/// Grant privileges on external volumes
6506+
ExternalVolumes(Vec<ObjectName>),
64836507
}
64846508

64856509
impl fmt::Display for GrantObjects {
@@ -6520,6 +6544,27 @@ impl fmt::Display for GrantObjects {
65206544
display_comma_separated(schemas)
65216545
)
65226546
}
6547+
GrantObjects::ResourceMonitors(objects) => {
6548+
write!(f, "RESOURCE MONITOR {}", display_comma_separated(objects))
6549+
}
6550+
GrantObjects::Users(objects) => {
6551+
write!(f, "USER {}", display_comma_separated(objects))
6552+
}
6553+
GrantObjects::ComputePools(objects) => {
6554+
write!(f, "COMPUTE POOL {}", display_comma_separated(objects))
6555+
}
6556+
GrantObjects::Connections(objects) => {
6557+
write!(f, "CONNECTION {}", display_comma_separated(objects))
6558+
}
6559+
GrantObjects::FailoverGroup(objects) => {
6560+
write!(f, "FAILOVER GROUP {}", display_comma_separated(objects))
6561+
}
6562+
GrantObjects::ReplicationGroup(objects) => {
6563+
write!(f, "REPLICATION GROUP {}", display_comma_separated(objects))
6564+
}
6565+
GrantObjects::ExternalVolumes(objects) => {
6566+
write!(f, "EXTERNAL VOLUME {}", display_comma_separated(objects))
6567+
}
65236568
}
65246569
}
65256570
}

src/keywords.rs

+1
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,7 @@ define_keywords!(
738738
REPLICATION,
739739
RESET,
740740
RESOLVE,
741+
RESOURCE,
741742
RESPECT,
742743
RESTART,
743744
RESTRICT,

src/parser/mod.rs

+37-13
Original file line numberDiff line numberDiff line change
@@ -12885,6 +12885,26 @@ impl<'a> Parser<'a> {
1288512885
Some(GrantObjects::AllSequencesInSchema {
1288612886
schemas: self.parse_comma_separated(|p| p.parse_object_name(false))?,
1288712887
})
12888+
} else if self.parse_keywords(&[Keyword::RESOURCE, Keyword::MONITOR]) {
12889+
Some(GrantObjects::ResourceMonitors(self.parse_comma_separated(
12890+
|p| p.parse_object_name_with_wildcards(false, true),
12891+
)?))
12892+
} else if self.parse_keywords(&[Keyword::COMPUTE, Keyword::POOL]) {
12893+
Some(GrantObjects::ComputePools(self.parse_comma_separated(
12894+
|p| p.parse_object_name_with_wildcards(false, true),
12895+
)?))
12896+
} else if self.parse_keywords(&[Keyword::FAILOVER, Keyword::GROUP]) {
12897+
Some(GrantObjects::FailoverGroup(self.parse_comma_separated(
12898+
|p| p.parse_object_name_with_wildcards(false, true),
12899+
)?))
12900+
} else if self.parse_keywords(&[Keyword::REPLICATION, Keyword::GROUP]) {
12901+
Some(GrantObjects::ReplicationGroup(self.parse_comma_separated(
12902+
|p| p.parse_object_name_with_wildcards(false, true),
12903+
)?))
12904+
} else if self.parse_keywords(&[Keyword::EXTERNAL, Keyword::VOLUME]) {
12905+
Some(GrantObjects::ExternalVolumes(self.parse_comma_separated(
12906+
|p| p.parse_object_name_with_wildcards(false, true),
12907+
)?))
1288812908
} else {
1288912909
let object_type = self.parse_one_of_keywords(&[
1289012910
Keyword::SEQUENCE,
@@ -12898,6 +12918,8 @@ impl<'a> Parser<'a> {
1289812918
Keyword::VIEW,
1289912919
Keyword::WAREHOUSE,
1290012920
Keyword::INTEGRATION,
12921+
Keyword::USER,
12922+
Keyword::CONNECTION,
1290112923
]);
1290212924
let objects =
1290312925
self.parse_comma_separated(|p| p.parse_object_name_with_wildcards(false, true));
@@ -12908,6 +12930,8 @@ impl<'a> Parser<'a> {
1290812930
Some(Keyword::WAREHOUSE) => Some(GrantObjects::Warehouses(objects?)),
1290912931
Some(Keyword::INTEGRATION) => Some(GrantObjects::Integrations(objects?)),
1291012932
Some(Keyword::VIEW) => Some(GrantObjects::Views(objects?)),
12933+
Some(Keyword::USER) => Some(GrantObjects::Users(objects?)),
12934+
Some(Keyword::CONNECTION) => Some(GrantObjects::Connections(objects?)),
1291112935
Some(Keyword::TABLE) | None => Some(GrantObjects::Tables(objects?)),
1291212936
_ => unreachable!(),
1291312937
}
@@ -12993,10 +13017,10 @@ impl<'a> Parser<'a> {
1299313017
let manage_type = self.parse_action_manage_type()?;
1299413018
Ok(Action::Manage { manage_type })
1299513019
} else if self.parse_keyword(Keyword::MODIFY) {
12996-
let modify_type = self.parse_action_modify_type()?;
13020+
let modify_type = self.parse_action_modify_type();
1299713021
Ok(Action::Modify { modify_type })
1299813022
} else if self.parse_keyword(Keyword::MONITOR) {
12999-
let monitor_type = self.parse_action_monitor_type()?;
13023+
let monitor_type = self.parse_action_monitor_type();
1300013024
Ok(Action::Monitor { monitor_type })
1300113025
} else if self.parse_keyword(Keyword::OPERATE) {
1300213026
Ok(Action::Operate)
@@ -13137,29 +13161,29 @@ impl<'a> Parser<'a> {
1313713161
}
1313813162
}
1313913163

13140-
fn parse_action_modify_type(&mut self) -> Result<ActionModifyType, ParserError> {
13164+
fn parse_action_modify_type(&mut self) -> Option<ActionModifyType> {
1314113165
if self.parse_keywords(&[Keyword::LOG, Keyword::LEVEL]) {
13142-
Ok(ActionModifyType::LogLevel)
13166+
Some(ActionModifyType::LogLevel)
1314313167
} else if self.parse_keywords(&[Keyword::TRACE, Keyword::LEVEL]) {
13144-
Ok(ActionModifyType::TraceLevel)
13168+
Some(ActionModifyType::TraceLevel)
1314513169
} else if self.parse_keywords(&[Keyword::SESSION, Keyword::LOG, Keyword::LEVEL]) {
13146-
Ok(ActionModifyType::SessionLogLevel)
13170+
Some(ActionModifyType::SessionLogLevel)
1314713171
} else if self.parse_keywords(&[Keyword::SESSION, Keyword::TRACE, Keyword::LEVEL]) {
13148-
Ok(ActionModifyType::SessionTraceLevel)
13172+
Some(ActionModifyType::SessionTraceLevel)
1314913173
} else {
13150-
self.expected("GRANT MODIFY type", self.peek_token())
13174+
None
1315113175
}
1315213176
}
1315313177

13154-
fn parse_action_monitor_type(&mut self) -> Result<ActionMonitorType, ParserError> {
13178+
fn parse_action_monitor_type(&mut self) -> Option<ActionMonitorType> {
1315513179
if self.parse_keyword(Keyword::EXECUTION) {
13156-
Ok(ActionMonitorType::Execution)
13180+
Some(ActionMonitorType::Execution)
1315713181
} else if self.parse_keyword(Keyword::SECURITY) {
13158-
Ok(ActionMonitorType::Security)
13182+
Some(ActionMonitorType::Security)
1315913183
} else if self.parse_keyword(Keyword::USAGE) {
13160-
Ok(ActionMonitorType::Usage)
13184+
Some(ActionMonitorType::Usage)
1316113185
} else {
13162-
self.expected("GRANT MONITOR type", self.peek_token())
13186+
None
1316313187
}
1316413188
}
1316513189

tests/sqlparser_snowflake.rs

+38-1
Original file line numberDiff line numberDiff line change
@@ -3364,7 +3364,7 @@ fn test_timetravel_at_before() {
33643364
}
33653365

33663366
#[test]
3367-
fn test_grant_account_privileges() {
3367+
fn test_grant_account_global_privileges() {
33683368
let privileges = vec![
33693369
"ALL",
33703370
"ALL PRIVILEGES",
@@ -3469,6 +3469,43 @@ fn test_grant_account_privileges() {
34693469
}
34703470
}
34713471

3472+
#[test]
3473+
fn test_grant_account_object_privileges() {
3474+
let privileges = vec![
3475+
"ALL",
3476+
"ALL PRIVILEGES",
3477+
"APPLYBUDGET",
3478+
"MODIFY",
3479+
"MONITOR",
3480+
"USAGE",
3481+
"OPERATE",
3482+
];
3483+
3484+
let objects_types = vec![
3485+
"USER",
3486+
"RESOURCE MONITOR",
3487+
"WAREHOUSE",
3488+
"COMPUTE POOL",
3489+
"DATABASE",
3490+
"INTEGRATION",
3491+
"CONNECTION",
3492+
"FAILOVER GROUP",
3493+
"REPLICATION GROUP",
3494+
"EXTERNAL VOLUME",
3495+
];
3496+
3497+
let with_grant_options = vec!["", " WITH GRANT OPTION"];
3498+
3499+
for t in &objects_types {
3500+
for p in &privileges {
3501+
for wgo in &with_grant_options {
3502+
let sql = format!("GRANT {p} ON {t} obj1 TO ROLE role1{wgo}");
3503+
snowflake_and_generic().verified_stmt(&sql);
3504+
}
3505+
}
3506+
}
3507+
}
3508+
34723509
#[test]
34733510
fn test_grant_role_to() {
34743511
snowflake_and_generic().verified_stmt("GRANT ROLE r1 TO ROLE r2");

0 commit comments

Comments
 (0)