Skip to content

Commit bde8157

Browse files
yoavcloudDilovan Celik
authored and
Dilovan Celik
committed
Extend snowflake grant options support (apache#1794)
1 parent 445ec39 commit bde8157

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
@@ -6087,10 +6087,10 @@ pub enum Action {
60876087
ManageReleases,
60886088
ManageVersions,
60896089
Modify {
6090-
modify_type: ActionModifyType,
6090+
modify_type: Option<ActionModifyType>,
60916091
},
60926092
Monitor {
6093-
monitor_type: ActionMonitorType,
6093+
monitor_type: Option<ActionMonitorType>,
60946094
},
60956095
Operate,
60966096
OverrideShareRestrictions,
@@ -6123,7 +6123,7 @@ impl fmt::Display for Action {
61236123
match self {
61246124
Action::AddSearchOptimization => f.write_str("ADD SEARCH OPTIMIZATION")?,
61256125
Action::Apply { apply_type } => write!(f, "APPLY {apply_type}")?,
6126-
Action::ApplyBudget => f.write_str("APPLY BUDGET")?,
6126+
Action::ApplyBudget => f.write_str("APPLYBUDGET")?,
61276127
Action::AttachListing => f.write_str("ATTACH LISTING")?,
61286128
Action::AttachPolicy => f.write_str("ATTACH POLICY")?,
61296129
Action::Audit => f.write_str("AUDIT")?,
@@ -6151,8 +6151,18 @@ impl fmt::Display for Action {
61516151
Action::Manage { manage_type } => write!(f, "MANAGE {manage_type}")?,
61526152
Action::ManageReleases => f.write_str("MANAGE RELEASES")?,
61536153
Action::ManageVersions => f.write_str("MANAGE VERSIONS")?,
6154-
Action::Modify { modify_type } => write!(f, "MODIFY {modify_type}")?,
6155-
Action::Monitor { monitor_type } => write!(f, "MONITOR {monitor_type}")?,
6154+
Action::Modify { modify_type } => {
6155+
write!(f, "MODIFY")?;
6156+
if let Some(modify_type) = modify_type {
6157+
write!(f, " {modify_type}")?;
6158+
}
6159+
}
6160+
Action::Monitor { monitor_type } => {
6161+
write!(f, "MONITOR")?;
6162+
if let Some(monitor_type) = monitor_type {
6163+
write!(f, " {monitor_type}")?
6164+
}
6165+
}
61566166
Action::Operate => f.write_str("OPERATE")?,
61576167
Action::OverrideShareRestrictions => f.write_str("OVERRIDE SHARE RESTRICTIONS")?,
61586168
Action::Ownership => f.write_str("OWNERSHIP")?,
@@ -6470,6 +6480,20 @@ pub enum GrantObjects {
64706480
Warehouses(Vec<ObjectName>),
64716481
/// Grant privileges on specific integrations
64726482
Integrations(Vec<ObjectName>),
6483+
/// Grant privileges on resource monitors
6484+
ResourceMonitors(Vec<ObjectName>),
6485+
/// Grant privileges on users
6486+
Users(Vec<ObjectName>),
6487+
/// Grant privileges on compute pools
6488+
ComputePools(Vec<ObjectName>),
6489+
/// Grant privileges on connections
6490+
Connections(Vec<ObjectName>),
6491+
/// Grant privileges on failover groups
6492+
FailoverGroup(Vec<ObjectName>),
6493+
/// Grant privileges on replication group
6494+
ReplicationGroup(Vec<ObjectName>),
6495+
/// Grant privileges on external volumes
6496+
ExternalVolumes(Vec<ObjectName>),
64736497
}
64746498

64756499
impl fmt::Display for GrantObjects {
@@ -6510,6 +6534,27 @@ impl fmt::Display for GrantObjects {
65106534
display_comma_separated(schemas)
65116535
)
65126536
}
6537+
GrantObjects::ResourceMonitors(objects) => {
6538+
write!(f, "RESOURCE MONITOR {}", display_comma_separated(objects))
6539+
}
6540+
GrantObjects::Users(objects) => {
6541+
write!(f, "USER {}", display_comma_separated(objects))
6542+
}
6543+
GrantObjects::ComputePools(objects) => {
6544+
write!(f, "COMPUTE POOL {}", display_comma_separated(objects))
6545+
}
6546+
GrantObjects::Connections(objects) => {
6547+
write!(f, "CONNECTION {}", display_comma_separated(objects))
6548+
}
6549+
GrantObjects::FailoverGroup(objects) => {
6550+
write!(f, "FAILOVER GROUP {}", display_comma_separated(objects))
6551+
}
6552+
GrantObjects::ReplicationGroup(objects) => {
6553+
write!(f, "REPLICATION GROUP {}", display_comma_separated(objects))
6554+
}
6555+
GrantObjects::ExternalVolumes(objects) => {
6556+
write!(f, "EXTERNAL VOLUME {}", display_comma_separated(objects))
6557+
}
65136558
}
65146559
}
65156560
}

src/keywords.rs

+1
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,7 @@ define_keywords!(
739739
REPLICATION,
740740
RESET,
741741
RESOLVE,
742+
RESOURCE,
742743
RESPECT,
743744
RESTART,
744745
RESTRICT,

src/parser/mod.rs

+37-13
Original file line numberDiff line numberDiff line change
@@ -12864,6 +12864,26 @@ impl<'a> Parser<'a> {
1286412864
Some(GrantObjects::AllSequencesInSchema {
1286512865
schemas: self.parse_comma_separated(|p| p.parse_object_name(false))?,
1286612866
})
12867+
} else if self.parse_keywords(&[Keyword::RESOURCE, Keyword::MONITOR]) {
12868+
Some(GrantObjects::ResourceMonitors(self.parse_comma_separated(
12869+
|p| p.parse_object_name_with_wildcards(false, true),
12870+
)?))
12871+
} else if self.parse_keywords(&[Keyword::COMPUTE, Keyword::POOL]) {
12872+
Some(GrantObjects::ComputePools(self.parse_comma_separated(
12873+
|p| p.parse_object_name_with_wildcards(false, true),
12874+
)?))
12875+
} else if self.parse_keywords(&[Keyword::FAILOVER, Keyword::GROUP]) {
12876+
Some(GrantObjects::FailoverGroup(self.parse_comma_separated(
12877+
|p| p.parse_object_name_with_wildcards(false, true),
12878+
)?))
12879+
} else if self.parse_keywords(&[Keyword::REPLICATION, Keyword::GROUP]) {
12880+
Some(GrantObjects::ReplicationGroup(self.parse_comma_separated(
12881+
|p| p.parse_object_name_with_wildcards(false, true),
12882+
)?))
12883+
} else if self.parse_keywords(&[Keyword::EXTERNAL, Keyword::VOLUME]) {
12884+
Some(GrantObjects::ExternalVolumes(self.parse_comma_separated(
12885+
|p| p.parse_object_name_with_wildcards(false, true),
12886+
)?))
1286712887
} else {
1286812888
let object_type = self.parse_one_of_keywords(&[
1286912889
Keyword::SEQUENCE,
@@ -12877,6 +12897,8 @@ impl<'a> Parser<'a> {
1287712897
Keyword::VIEW,
1287812898
Keyword::WAREHOUSE,
1287912899
Keyword::INTEGRATION,
12900+
Keyword::USER,
12901+
Keyword::CONNECTION,
1288012902
]);
1288112903
let objects =
1288212904
self.parse_comma_separated(|p| p.parse_object_name_with_wildcards(false, true));
@@ -12887,6 +12909,8 @@ impl<'a> Parser<'a> {
1288712909
Some(Keyword::WAREHOUSE) => Some(GrantObjects::Warehouses(objects?)),
1288812910
Some(Keyword::INTEGRATION) => Some(GrantObjects::Integrations(objects?)),
1288912911
Some(Keyword::VIEW) => Some(GrantObjects::Views(objects?)),
12912+
Some(Keyword::USER) => Some(GrantObjects::Users(objects?)),
12913+
Some(Keyword::CONNECTION) => Some(GrantObjects::Connections(objects?)),
1289012914
Some(Keyword::TABLE) | None => Some(GrantObjects::Tables(objects?)),
1289112915
_ => unreachable!(),
1289212916
}
@@ -12972,10 +12996,10 @@ impl<'a> Parser<'a> {
1297212996
let manage_type = self.parse_action_manage_type()?;
1297312997
Ok(Action::Manage { manage_type })
1297412998
} else if self.parse_keyword(Keyword::MODIFY) {
12975-
let modify_type = self.parse_action_modify_type()?;
12999+
let modify_type = self.parse_action_modify_type();
1297613000
Ok(Action::Modify { modify_type })
1297713001
} else if self.parse_keyword(Keyword::MONITOR) {
12978-
let monitor_type = self.parse_action_monitor_type()?;
13002+
let monitor_type = self.parse_action_monitor_type();
1297913003
Ok(Action::Monitor { monitor_type })
1298013004
} else if self.parse_keyword(Keyword::OPERATE) {
1298113005
Ok(Action::Operate)
@@ -13116,29 +13140,29 @@ impl<'a> Parser<'a> {
1311613140
}
1311713141
}
1311813142

13119-
fn parse_action_modify_type(&mut self) -> Result<ActionModifyType, ParserError> {
13143+
fn parse_action_modify_type(&mut self) -> Option<ActionModifyType> {
1312013144
if self.parse_keywords(&[Keyword::LOG, Keyword::LEVEL]) {
13121-
Ok(ActionModifyType::LogLevel)
13145+
Some(ActionModifyType::LogLevel)
1312213146
} else if self.parse_keywords(&[Keyword::TRACE, Keyword::LEVEL]) {
13123-
Ok(ActionModifyType::TraceLevel)
13147+
Some(ActionModifyType::TraceLevel)
1312413148
} else if self.parse_keywords(&[Keyword::SESSION, Keyword::LOG, Keyword::LEVEL]) {
13125-
Ok(ActionModifyType::SessionLogLevel)
13149+
Some(ActionModifyType::SessionLogLevel)
1312613150
} else if self.parse_keywords(&[Keyword::SESSION, Keyword::TRACE, Keyword::LEVEL]) {
13127-
Ok(ActionModifyType::SessionTraceLevel)
13151+
Some(ActionModifyType::SessionTraceLevel)
1312813152
} else {
13129-
self.expected("GRANT MODIFY type", self.peek_token())
13153+
None
1313013154
}
1313113155
}
1313213156

13133-
fn parse_action_monitor_type(&mut self) -> Result<ActionMonitorType, ParserError> {
13157+
fn parse_action_monitor_type(&mut self) -> Option<ActionMonitorType> {
1313413158
if self.parse_keyword(Keyword::EXECUTION) {
13135-
Ok(ActionMonitorType::Execution)
13159+
Some(ActionMonitorType::Execution)
1313613160
} else if self.parse_keyword(Keyword::SECURITY) {
13137-
Ok(ActionMonitorType::Security)
13161+
Some(ActionMonitorType::Security)
1313813162
} else if self.parse_keyword(Keyword::USAGE) {
13139-
Ok(ActionMonitorType::Usage)
13163+
Some(ActionMonitorType::Usage)
1314013164
} else {
13141-
self.expected("GRANT MONITOR type", self.peek_token())
13165+
None
1314213166
}
1314313167
}
1314413168

tests/sqlparser_snowflake.rs

+38-1
Original file line numberDiff line numberDiff line change
@@ -3357,7 +3357,7 @@ fn test_timetravel_at_before() {
33573357
}
33583358

33593359
#[test]
3360-
fn test_grant_account_privileges() {
3360+
fn test_grant_account_global_privileges() {
33613361
let privileges = vec![
33623362
"ALL",
33633363
"ALL PRIVILEGES",
@@ -3462,6 +3462,43 @@ fn test_grant_account_privileges() {
34623462
}
34633463
}
34643464

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

0 commit comments

Comments
 (0)