mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-07-07 17:04:59 +00:00
Add support for Snowflake account privileges (#1666)
This commit is contained in:
parent
e5bc3dfad8
commit
183274e274
5 changed files with 651 additions and 71 deletions
274
src/ast/mod.rs
274
src/ast/mod.rs
|
@ -5453,29 +5453,107 @@ impl fmt::Display for FetchDirection {
|
|||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||
pub enum Action {
|
||||
AddSearchOptimization,
|
||||
Apply {
|
||||
apply_type: ActionApplyType,
|
||||
},
|
||||
ApplyBudget,
|
||||
AttachListing,
|
||||
AttachPolicy,
|
||||
Audit,
|
||||
BindServiceEndpoint,
|
||||
Connect,
|
||||
Create,
|
||||
Create {
|
||||
obj_type: Option<ActionCreateObjectType>,
|
||||
},
|
||||
Delete,
|
||||
Execute,
|
||||
Insert { columns: Option<Vec<Ident>> },
|
||||
References { columns: Option<Vec<Ident>> },
|
||||
Select { columns: Option<Vec<Ident>> },
|
||||
EvolveSchema,
|
||||
Execute {
|
||||
obj_type: Option<ActionExecuteObjectType>,
|
||||
},
|
||||
Failover,
|
||||
ImportedPrivileges,
|
||||
ImportShare,
|
||||
Insert {
|
||||
columns: Option<Vec<Ident>>,
|
||||
},
|
||||
Manage {
|
||||
manage_type: ActionManageType,
|
||||
},
|
||||
ManageReleases,
|
||||
ManageVersions,
|
||||
Modify {
|
||||
modify_type: ActionModifyType,
|
||||
},
|
||||
Monitor {
|
||||
monitor_type: ActionMonitorType,
|
||||
},
|
||||
Operate,
|
||||
OverrideShareRestrictions,
|
||||
Ownership,
|
||||
PurchaseDataExchangeListing,
|
||||
Read,
|
||||
ReadSession,
|
||||
References {
|
||||
columns: Option<Vec<Ident>>,
|
||||
},
|
||||
Replicate,
|
||||
ResolveAll,
|
||||
Select {
|
||||
columns: Option<Vec<Ident>>,
|
||||
},
|
||||
Temporary,
|
||||
Trigger,
|
||||
Truncate,
|
||||
Update { columns: Option<Vec<Ident>> },
|
||||
Update {
|
||||
columns: Option<Vec<Ident>>,
|
||||
},
|
||||
Usage,
|
||||
}
|
||||
|
||||
impl fmt::Display for Action {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Action::AddSearchOptimization => f.write_str("ADD SEARCH OPTIMIZATION")?,
|
||||
Action::Apply { apply_type } => write!(f, "APPLY {apply_type}")?,
|
||||
Action::ApplyBudget => f.write_str("APPLY BUDGET")?,
|
||||
Action::AttachListing => f.write_str("ATTACH LISTING")?,
|
||||
Action::AttachPolicy => f.write_str("ATTACH POLICY")?,
|
||||
Action::Audit => f.write_str("AUDIT")?,
|
||||
Action::BindServiceEndpoint => f.write_str("BIND SERVICE ENDPOINT")?,
|
||||
Action::Connect => f.write_str("CONNECT")?,
|
||||
Action::Create => f.write_str("CREATE")?,
|
||||
Action::Create { obj_type } => {
|
||||
f.write_str("CREATE")?;
|
||||
if let Some(obj_type) = obj_type {
|
||||
write!(f, " {obj_type}")?
|
||||
}
|
||||
}
|
||||
Action::Delete => f.write_str("DELETE")?,
|
||||
Action::Execute => f.write_str("EXECUTE")?,
|
||||
Action::EvolveSchema => f.write_str("EVOLVE SCHEMA")?,
|
||||
Action::Execute { obj_type } => {
|
||||
f.write_str("EXECUTE")?;
|
||||
if let Some(obj_type) = obj_type {
|
||||
write!(f, " {obj_type}")?
|
||||
}
|
||||
}
|
||||
Action::Failover => f.write_str("FAILOVER")?,
|
||||
Action::ImportedPrivileges => f.write_str("IMPORTED PRIVILEGES")?,
|
||||
Action::ImportShare => f.write_str("IMPORT SHARE")?,
|
||||
Action::Insert { .. } => f.write_str("INSERT")?,
|
||||
Action::Manage { manage_type } => write!(f, "MANAGE {manage_type}")?,
|
||||
Action::ManageReleases => f.write_str("MANAGE RELEASES")?,
|
||||
Action::ManageVersions => f.write_str("MANAGE VERSIONS")?,
|
||||
Action::Modify { modify_type } => write!(f, "MODIFY {modify_type}")?,
|
||||
Action::Monitor { monitor_type } => write!(f, "MONITOR {monitor_type}")?,
|
||||
Action::Operate => f.write_str("OPERATE")?,
|
||||
Action::OverrideShareRestrictions => f.write_str("OVERRIDE SHARE RESTRICTIONS")?,
|
||||
Action::Ownership => f.write_str("OWNERSHIP")?,
|
||||
Action::PurchaseDataExchangeListing => f.write_str("PURCHASE DATA EXCHANGE LISTING")?,
|
||||
Action::Read => f.write_str("READ")?,
|
||||
Action::ReadSession => f.write_str("READ SESSION")?,
|
||||
Action::References { .. } => f.write_str("REFERENCES")?,
|
||||
Action::Replicate => f.write_str("REPLICATE")?,
|
||||
Action::ResolveAll => f.write_str("RESOLVE ALL")?,
|
||||
Action::Select { .. } => f.write_str("SELECT")?,
|
||||
Action::Temporary => f.write_str("TEMPORARY")?,
|
||||
Action::Trigger => f.write_str("TRIGGER")?,
|
||||
|
@ -5498,6 +5576,186 @@ impl fmt::Display for Action {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||
/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
|
||||
/// under `globalPrivileges` in the `CREATE` privilege.
|
||||
pub enum ActionCreateObjectType {
|
||||
Account,
|
||||
Application,
|
||||
ApplicationPackage,
|
||||
ComputePool,
|
||||
DataExchangeListing,
|
||||
Database,
|
||||
ExternalVolume,
|
||||
FailoverGroup,
|
||||
Integration,
|
||||
NetworkPolicy,
|
||||
OrganiationListing,
|
||||
ReplicationGroup,
|
||||
Role,
|
||||
Share,
|
||||
User,
|
||||
Warehouse,
|
||||
}
|
||||
|
||||
impl fmt::Display for ActionCreateObjectType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
ActionCreateObjectType::Account => write!(f, "ACCOUNT"),
|
||||
ActionCreateObjectType::Application => write!(f, "APPLICATION"),
|
||||
ActionCreateObjectType::ApplicationPackage => write!(f, "APPLICATION PACKAGE"),
|
||||
ActionCreateObjectType::ComputePool => write!(f, "COMPUTE POOL"),
|
||||
ActionCreateObjectType::DataExchangeListing => write!(f, "DATA EXCHANGE LISTING"),
|
||||
ActionCreateObjectType::Database => write!(f, "DATABASE"),
|
||||
ActionCreateObjectType::ExternalVolume => write!(f, "EXTERNAL VOLUME"),
|
||||
ActionCreateObjectType::FailoverGroup => write!(f, "FAILOVER GROUP"),
|
||||
ActionCreateObjectType::Integration => write!(f, "INTEGRATION"),
|
||||
ActionCreateObjectType::NetworkPolicy => write!(f, "NETWORK POLICY"),
|
||||
ActionCreateObjectType::OrganiationListing => write!(f, "ORGANIZATION LISTING"),
|
||||
ActionCreateObjectType::ReplicationGroup => write!(f, "REPLICATION GROUP"),
|
||||
ActionCreateObjectType::Role => write!(f, "ROLE"),
|
||||
ActionCreateObjectType::Share => write!(f, "SHARE"),
|
||||
ActionCreateObjectType::User => write!(f, "USER"),
|
||||
ActionCreateObjectType::Warehouse => write!(f, "WAREHOUSE"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||
/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
|
||||
/// under `globalPrivileges` in the `APPLY` privilege.
|
||||
pub enum ActionApplyType {
|
||||
AggregationPolicy,
|
||||
AuthenticationPolicy,
|
||||
JoinPolicy,
|
||||
MaskingPolicy,
|
||||
PackagesPolicy,
|
||||
PasswordPolicy,
|
||||
ProjectionPolicy,
|
||||
RowAccessPolicy,
|
||||
SessionPolicy,
|
||||
Tag,
|
||||
}
|
||||
|
||||
impl fmt::Display for ActionApplyType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
ActionApplyType::AggregationPolicy => write!(f, "AGGREGATION POLICY"),
|
||||
ActionApplyType::AuthenticationPolicy => write!(f, "AUTHENTICATION POLICY"),
|
||||
ActionApplyType::JoinPolicy => write!(f, "JOIN POLICY"),
|
||||
ActionApplyType::MaskingPolicy => write!(f, "MASKING POLICY"),
|
||||
ActionApplyType::PackagesPolicy => write!(f, "PACKAGES POLICY"),
|
||||
ActionApplyType::PasswordPolicy => write!(f, "PASSWORD POLICY"),
|
||||
ActionApplyType::ProjectionPolicy => write!(f, "PROJECTION POLICY"),
|
||||
ActionApplyType::RowAccessPolicy => write!(f, "ROW ACCESS POLICY"),
|
||||
ActionApplyType::SessionPolicy => write!(f, "SESSION POLICY"),
|
||||
ActionApplyType::Tag => write!(f, "TAG"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||
/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
|
||||
/// under `globalPrivileges` in the `EXECUTE` privilege.
|
||||
pub enum ActionExecuteObjectType {
|
||||
Alert,
|
||||
DataMetricFunction,
|
||||
ManagedAlert,
|
||||
ManagedTask,
|
||||
Task,
|
||||
}
|
||||
|
||||
impl fmt::Display for ActionExecuteObjectType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
ActionExecuteObjectType::Alert => write!(f, "ALERT"),
|
||||
ActionExecuteObjectType::DataMetricFunction => write!(f, "DATA METRIC FUNCTION"),
|
||||
ActionExecuteObjectType::ManagedAlert => write!(f, "MANAGED ALERT"),
|
||||
ActionExecuteObjectType::ManagedTask => write!(f, "MANAGED TASK"),
|
||||
ActionExecuteObjectType::Task => write!(f, "TASK"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||
/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
|
||||
/// under `globalPrivileges` in the `MANAGE` privilege.
|
||||
pub enum ActionManageType {
|
||||
AccountSupportCases,
|
||||
EventSharing,
|
||||
Grants,
|
||||
ListingAutoFulfillment,
|
||||
OrganizationSupportCases,
|
||||
UserSupportCases,
|
||||
Warehouses,
|
||||
}
|
||||
|
||||
impl fmt::Display for ActionManageType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
ActionManageType::AccountSupportCases => write!(f, "ACCOUNT SUPPORT CASES"),
|
||||
ActionManageType::EventSharing => write!(f, "EVENT SHARING"),
|
||||
ActionManageType::Grants => write!(f, "GRANTS"),
|
||||
ActionManageType::ListingAutoFulfillment => write!(f, "LISTING AUTO FULFILLMENT"),
|
||||
ActionManageType::OrganizationSupportCases => write!(f, "ORGANIZATION SUPPORT CASES"),
|
||||
ActionManageType::UserSupportCases => write!(f, "USER SUPPORT CASES"),
|
||||
ActionManageType::Warehouses => write!(f, "WAREHOUSES"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||
/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
|
||||
/// under `globalPrivileges` in the `MODIFY` privilege.
|
||||
pub enum ActionModifyType {
|
||||
LogLevel,
|
||||
TraceLevel,
|
||||
SessionLogLevel,
|
||||
SessionTraceLevel,
|
||||
}
|
||||
|
||||
impl fmt::Display for ActionModifyType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
ActionModifyType::LogLevel => write!(f, "LOG LEVEL"),
|
||||
ActionModifyType::TraceLevel => write!(f, "TRACE LEVEL"),
|
||||
ActionModifyType::SessionLogLevel => write!(f, "SESSION LOG LEVEL"),
|
||||
ActionModifyType::SessionTraceLevel => write!(f, "SESSION TRACE LEVEL"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||
/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
|
||||
/// under `globalPrivileges` in the `MONITOR` privilege.
|
||||
pub enum ActionMonitorType {
|
||||
Execution,
|
||||
Security,
|
||||
Usage,
|
||||
}
|
||||
|
||||
impl fmt::Display for ActionMonitorType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
ActionMonitorType::Execution => write!(f, "EXECUTION"),
|
||||
ActionMonitorType::Security => write!(f, "SECURITY"),
|
||||
ActionMonitorType::Usage => write!(f, "USAGE"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The principal that receives the privileges
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
|
|
|
@ -84,6 +84,7 @@ define_keywords!(
|
|||
AFTER,
|
||||
AGAINST,
|
||||
AGGREGATION,
|
||||
ALERT,
|
||||
ALGORITHM,
|
||||
ALIAS,
|
||||
ALL,
|
||||
|
@ -96,6 +97,7 @@ define_keywords!(
|
|||
ANY,
|
||||
APPLICATION,
|
||||
APPLY,
|
||||
APPLYBUDGET,
|
||||
ARCHIVE,
|
||||
ARE,
|
||||
ARRAY,
|
||||
|
@ -109,6 +111,8 @@ define_keywords!(
|
|||
AT,
|
||||
ATOMIC,
|
||||
ATTACH,
|
||||
AUDIT,
|
||||
AUTHENTICATION,
|
||||
AUTHORIZATION,
|
||||
AUTO,
|
||||
AUTOINCREMENT,
|
||||
|
@ -127,6 +131,7 @@ define_keywords!(
|
|||
BIGINT,
|
||||
BIGNUMERIC,
|
||||
BINARY,
|
||||
BIND,
|
||||
BINDING,
|
||||
BIT,
|
||||
BLOB,
|
||||
|
@ -150,6 +155,7 @@ define_keywords!(
|
|||
CASCADE,
|
||||
CASCADED,
|
||||
CASE,
|
||||
CASES,
|
||||
CAST,
|
||||
CATALOG,
|
||||
CATCH,
|
||||
|
@ -305,12 +311,15 @@ define_keywords!(
|
|||
ESTIMATE,
|
||||
EVENT,
|
||||
EVERY,
|
||||
EVOLVE,
|
||||
EXCEPT,
|
||||
EXCEPTION,
|
||||
EXCHANGE,
|
||||
EXCLUDE,
|
||||
EXCLUSIVE,
|
||||
EXEC,
|
||||
EXECUTE,
|
||||
EXECUTION,
|
||||
EXISTS,
|
||||
EXP,
|
||||
EXPANSION,
|
||||
|
@ -322,6 +331,7 @@ define_keywords!(
|
|||
EXTERNAL,
|
||||
EXTRACT,
|
||||
FAIL,
|
||||
FAILOVER,
|
||||
FALSE,
|
||||
FETCH,
|
||||
FIELDS,
|
||||
|
@ -357,6 +367,7 @@ define_keywords!(
|
|||
FREEZE,
|
||||
FROM,
|
||||
FSCK,
|
||||
FULFILLMENT,
|
||||
FULL,
|
||||
FULLTEXT,
|
||||
FUNCTION,
|
||||
|
@ -394,6 +405,8 @@ define_keywords!(
|
|||
ILIKE,
|
||||
IMMEDIATE,
|
||||
IMMUTABLE,
|
||||
IMPORT,
|
||||
IMPORTED,
|
||||
IN,
|
||||
INCLUDE,
|
||||
INCLUDE_NULL_VALUES,
|
||||
|
@ -421,6 +434,7 @@ define_keywords!(
|
|||
INT64,
|
||||
INT8,
|
||||
INTEGER,
|
||||
INTEGRATION,
|
||||
INTERPOLATE,
|
||||
INTERSECT,
|
||||
INTERSECTION,
|
||||
|
@ -460,6 +474,7 @@ define_keywords!(
|
|||
LINES,
|
||||
LIST,
|
||||
LISTEN,
|
||||
LISTING,
|
||||
LN,
|
||||
LOAD,
|
||||
LOCAL,
|
||||
|
@ -478,6 +493,8 @@ define_keywords!(
|
|||
LOW_PRIORITY,
|
||||
LS,
|
||||
MACRO,
|
||||
MANAGE,
|
||||
MANAGED,
|
||||
MANAGEDLOCATION,
|
||||
MAP,
|
||||
MASKING,
|
||||
|
@ -499,6 +516,7 @@ define_keywords!(
|
|||
MERGE,
|
||||
METADATA,
|
||||
METHOD,
|
||||
METRIC,
|
||||
MICROSECOND,
|
||||
MICROSECONDS,
|
||||
MILLENIUM,
|
||||
|
@ -515,6 +533,7 @@ define_keywords!(
|
|||
MODIFIES,
|
||||
MODIFY,
|
||||
MODULE,
|
||||
MONITOR,
|
||||
MONTH,
|
||||
MONTHS,
|
||||
MSCK,
|
||||
|
@ -528,6 +547,7 @@ define_keywords!(
|
|||
NCHAR,
|
||||
NCLOB,
|
||||
NESTED,
|
||||
NETWORK,
|
||||
NEW,
|
||||
NEXT,
|
||||
NFC,
|
||||
|
@ -575,7 +595,9 @@ define_keywords!(
|
|||
ONLY,
|
||||
OPEN,
|
||||
OPENJSON,
|
||||
OPERATE,
|
||||
OPERATOR,
|
||||
OPTIMIZATION,
|
||||
OPTIMIZE,
|
||||
OPTIMIZER_COSTS,
|
||||
OPTION,
|
||||
|
@ -584,6 +606,7 @@ define_keywords!(
|
|||
ORC,
|
||||
ORDER,
|
||||
ORDINALITY,
|
||||
ORGANIZATION,
|
||||
OUT,
|
||||
OUTER,
|
||||
OUTPUTFORMAT,
|
||||
|
@ -591,9 +614,13 @@ define_keywords!(
|
|||
OVERFLOW,
|
||||
OVERLAPS,
|
||||
OVERLAY,
|
||||
OVERRIDE,
|
||||
OVERWRITE,
|
||||
OWNED,
|
||||
OWNER,
|
||||
OWNERSHIP,
|
||||
PACKAGE,
|
||||
PACKAGES,
|
||||
PARALLEL,
|
||||
PARAMETER,
|
||||
PARQUET,
|
||||
|
@ -618,6 +645,7 @@ define_keywords!(
|
|||
PLAN,
|
||||
PLANS,
|
||||
POLICY,
|
||||
POOL,
|
||||
PORTION,
|
||||
POSITION,
|
||||
POSITION_REGEX,
|
||||
|
@ -637,6 +665,7 @@ define_keywords!(
|
|||
PROGRAM,
|
||||
PROJECTION,
|
||||
PUBLIC,
|
||||
PURCHASE,
|
||||
PURGE,
|
||||
QUALIFY,
|
||||
QUARTER,
|
||||
|
@ -670,6 +699,7 @@ define_keywords!(
|
|||
RELATIVE,
|
||||
RELAY,
|
||||
RELEASE,
|
||||
RELEASES,
|
||||
REMOTE,
|
||||
REMOVE,
|
||||
RENAME,
|
||||
|
@ -678,12 +708,15 @@ define_keywords!(
|
|||
REPEATABLE,
|
||||
REPLACE,
|
||||
REPLICA,
|
||||
REPLICATE,
|
||||
REPLICATION,
|
||||
RESET,
|
||||
RESOLVE,
|
||||
RESPECT,
|
||||
RESTART,
|
||||
RESTRICT,
|
||||
RESTRICTED,
|
||||
RESTRICTIONS,
|
||||
RESTRICTIVE,
|
||||
RESULT,
|
||||
RESULTSET,
|
||||
|
@ -732,6 +765,7 @@ define_keywords!(
|
|||
SERDE,
|
||||
SERDEPROPERTIES,
|
||||
SERIALIZABLE,
|
||||
SERVICE,
|
||||
SESSION,
|
||||
SESSION_USER,
|
||||
SET,
|
||||
|
@ -739,6 +773,7 @@ define_keywords!(
|
|||
SETS,
|
||||
SETTINGS,
|
||||
SHARE,
|
||||
SHARING,
|
||||
SHOW,
|
||||
SIMILAR,
|
||||
SKIP,
|
||||
|
@ -782,6 +817,7 @@ define_keywords!(
|
|||
SUM,
|
||||
SUPER,
|
||||
SUPERUSER,
|
||||
SUPPORT,
|
||||
SUSPEND,
|
||||
SWAP,
|
||||
SYMMETRIC,
|
||||
|
@ -794,6 +830,7 @@ define_keywords!(
|
|||
TABLESAMPLE,
|
||||
TAG,
|
||||
TARGET,
|
||||
TASK,
|
||||
TBLPROPERTIES,
|
||||
TEMP,
|
||||
TEMPORARY,
|
||||
|
@ -819,6 +856,7 @@ define_keywords!(
|
|||
TO,
|
||||
TOP,
|
||||
TOTALS,
|
||||
TRACE,
|
||||
TRAILING,
|
||||
TRANSACTION,
|
||||
TRANSIENT,
|
||||
|
@ -885,11 +923,14 @@ define_keywords!(
|
|||
VERBOSE,
|
||||
VERSION,
|
||||
VERSIONING,
|
||||
VERSIONS,
|
||||
VIEW,
|
||||
VIEWS,
|
||||
VIRTUAL,
|
||||
VOLATILE,
|
||||
VOLUME,
|
||||
WAREHOUSE,
|
||||
WAREHOUSES,
|
||||
WEEK,
|
||||
WEEKS,
|
||||
WHEN,
|
||||
|
|
|
@ -48,9 +48,6 @@ pub enum ParserError {
|
|||
RecursionLimitExceeded,
|
||||
}
|
||||
|
||||
// avoid clippy type_complexity warnings
|
||||
type ParsedAction = (Keyword, Option<Vec<Ident>>);
|
||||
|
||||
// Use `Parser::expected` instead, if possible
|
||||
macro_rules! parser_err {
|
||||
($MSG:expr, $loc:expr) => {
|
||||
|
@ -3950,7 +3947,7 @@ impl<'a> Parser<'a> {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn parse_actions_list(&mut self) -> Result<Vec<ParsedAction>, ParserError> {
|
||||
pub fn parse_actions_list(&mut self) -> Result<Vec<Action>, ParserError> {
|
||||
let mut values = vec![];
|
||||
loop {
|
||||
values.push(self.parse_grant_permission()?);
|
||||
|
@ -11980,37 +11977,8 @@ impl<'a> Parser<'a> {
|
|||
with_privileges_keyword: self.parse_keyword(Keyword::PRIVILEGES),
|
||||
}
|
||||
} else {
|
||||
let (actions, err): (Vec<_>, Vec<_>) = self
|
||||
.parse_actions_list()?
|
||||
.into_iter()
|
||||
.map(|(kw, columns)| match kw {
|
||||
Keyword::DELETE => Ok(Action::Delete),
|
||||
Keyword::INSERT => Ok(Action::Insert { columns }),
|
||||
Keyword::REFERENCES => Ok(Action::References { columns }),
|
||||
Keyword::SELECT => Ok(Action::Select { columns }),
|
||||
Keyword::TRIGGER => Ok(Action::Trigger),
|
||||
Keyword::TRUNCATE => Ok(Action::Truncate),
|
||||
Keyword::UPDATE => Ok(Action::Update { columns }),
|
||||
Keyword::USAGE => Ok(Action::Usage),
|
||||
Keyword::CONNECT => Ok(Action::Connect),
|
||||
Keyword::CREATE => Ok(Action::Create),
|
||||
Keyword::EXECUTE => Ok(Action::Execute),
|
||||
Keyword::TEMPORARY => Ok(Action::Temporary),
|
||||
// This will cover all future added keywords to
|
||||
// parse_grant_permission and unhandled in this
|
||||
// match
|
||||
_ => Err(kw),
|
||||
})
|
||||
.partition(Result::is_ok);
|
||||
|
||||
if !err.is_empty() {
|
||||
let errors: Vec<Keyword> = err.into_iter().filter_map(|x| x.err()).collect();
|
||||
return Err(ParserError::ParserError(format!(
|
||||
"INTERNAL ERROR: GRANT/REVOKE unexpected keyword(s) - {errors:?}"
|
||||
)));
|
||||
}
|
||||
let act = actions.into_iter().filter_map(|x| x.ok()).collect();
|
||||
Privileges::Actions(act)
|
||||
let actions = self.parse_actions_list()?;
|
||||
Privileges::Actions(actions)
|
||||
};
|
||||
|
||||
self.expect_keyword_is(Keyword::ON)?;
|
||||
|
@ -12049,38 +12017,244 @@ impl<'a> Parser<'a> {
|
|||
Ok((privileges, objects))
|
||||
}
|
||||
|
||||
pub fn parse_grant_permission(&mut self) -> Result<ParsedAction, ParserError> {
|
||||
if let Some(kw) = self.parse_one_of_keywords(&[
|
||||
Keyword::CONNECT,
|
||||
Keyword::CREATE,
|
||||
Keyword::DELETE,
|
||||
Keyword::EXECUTE,
|
||||
Keyword::INSERT,
|
||||
Keyword::REFERENCES,
|
||||
Keyword::SELECT,
|
||||
Keyword::TEMPORARY,
|
||||
Keyword::TRIGGER,
|
||||
Keyword::TRUNCATE,
|
||||
Keyword::UPDATE,
|
||||
Keyword::USAGE,
|
||||
pub fn parse_grant_permission(&mut self) -> Result<Action, ParserError> {
|
||||
fn parse_columns(parser: &mut Parser) -> Result<Option<Vec<Ident>>, ParserError> {
|
||||
let columns = parser.parse_parenthesized_column_list(Optional, false)?;
|
||||
if columns.is_empty() {
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(columns))
|
||||
}
|
||||
}
|
||||
|
||||
// Multi-word privileges
|
||||
if self.parse_keywords(&[Keyword::IMPORTED, Keyword::PRIVILEGES]) {
|
||||
Ok(Action::ImportedPrivileges)
|
||||
} else if self.parse_keywords(&[Keyword::ADD, Keyword::SEARCH, Keyword::OPTIMIZATION]) {
|
||||
Ok(Action::AddSearchOptimization)
|
||||
} else if self.parse_keywords(&[Keyword::ATTACH, Keyword::LISTING]) {
|
||||
Ok(Action::AttachListing)
|
||||
} else if self.parse_keywords(&[Keyword::ATTACH, Keyword::POLICY]) {
|
||||
Ok(Action::AttachPolicy)
|
||||
} else if self.parse_keywords(&[Keyword::BIND, Keyword::SERVICE, Keyword::ENDPOINT]) {
|
||||
Ok(Action::BindServiceEndpoint)
|
||||
} else if self.parse_keywords(&[Keyword::EVOLVE, Keyword::SCHEMA]) {
|
||||
Ok(Action::EvolveSchema)
|
||||
} else if self.parse_keywords(&[Keyword::IMPORT, Keyword::SHARE]) {
|
||||
Ok(Action::ImportShare)
|
||||
} else if self.parse_keywords(&[Keyword::MANAGE, Keyword::VERSIONS]) {
|
||||
Ok(Action::ManageVersions)
|
||||
} else if self.parse_keywords(&[Keyword::MANAGE, Keyword::RELEASES]) {
|
||||
Ok(Action::ManageReleases)
|
||||
} else if self.parse_keywords(&[Keyword::OVERRIDE, Keyword::SHARE, Keyword::RESTRICTIONS]) {
|
||||
Ok(Action::OverrideShareRestrictions)
|
||||
} else if self.parse_keywords(&[
|
||||
Keyword::PURCHASE,
|
||||
Keyword::DATA,
|
||||
Keyword::EXCHANGE,
|
||||
Keyword::LISTING,
|
||||
]) {
|
||||
let columns = match kw {
|
||||
Keyword::INSERT | Keyword::REFERENCES | Keyword::SELECT | Keyword::UPDATE => {
|
||||
let columns = self.parse_parenthesized_column_list(Optional, false)?;
|
||||
if columns.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(columns)
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
Ok((kw, columns))
|
||||
Ok(Action::PurchaseDataExchangeListing)
|
||||
} else if self.parse_keywords(&[Keyword::RESOLVE, Keyword::ALL]) {
|
||||
Ok(Action::ResolveAll)
|
||||
} else if self.parse_keywords(&[Keyword::READ, Keyword::SESSION]) {
|
||||
Ok(Action::ReadSession)
|
||||
|
||||
// Single-word privileges
|
||||
} else if self.parse_keyword(Keyword::APPLY) {
|
||||
let apply_type = self.parse_action_apply_type()?;
|
||||
Ok(Action::Apply { apply_type })
|
||||
} else if self.parse_keyword(Keyword::APPLYBUDGET) {
|
||||
Ok(Action::ApplyBudget)
|
||||
} else if self.parse_keyword(Keyword::AUDIT) {
|
||||
Ok(Action::Audit)
|
||||
} else if self.parse_keyword(Keyword::CONNECT) {
|
||||
Ok(Action::Connect)
|
||||
} else if self.parse_keyword(Keyword::CREATE) {
|
||||
let obj_type = self.maybe_parse_action_create_object_type();
|
||||
Ok(Action::Create { obj_type })
|
||||
} else if self.parse_keyword(Keyword::DELETE) {
|
||||
Ok(Action::Delete)
|
||||
} else if self.parse_keyword(Keyword::EXECUTE) {
|
||||
let obj_type = self.maybe_parse_action_execute_obj_type();
|
||||
Ok(Action::Execute { obj_type })
|
||||
} else if self.parse_keyword(Keyword::FAILOVER) {
|
||||
Ok(Action::Failover)
|
||||
} else if self.parse_keyword(Keyword::INSERT) {
|
||||
Ok(Action::Insert {
|
||||
columns: parse_columns(self)?,
|
||||
})
|
||||
} else if self.parse_keyword(Keyword::MANAGE) {
|
||||
let manage_type = self.parse_action_manage_type()?;
|
||||
Ok(Action::Manage { manage_type })
|
||||
} else if self.parse_keyword(Keyword::MODIFY) {
|
||||
let modify_type = self.parse_action_modify_type()?;
|
||||
Ok(Action::Modify { modify_type })
|
||||
} else if self.parse_keyword(Keyword::MONITOR) {
|
||||
let monitor_type = self.parse_action_monitor_type()?;
|
||||
Ok(Action::Monitor { monitor_type })
|
||||
} else if self.parse_keyword(Keyword::OPERATE) {
|
||||
Ok(Action::Operate)
|
||||
} else if self.parse_keyword(Keyword::REFERENCES) {
|
||||
Ok(Action::References {
|
||||
columns: parse_columns(self)?,
|
||||
})
|
||||
} else if self.parse_keyword(Keyword::READ) {
|
||||
Ok(Action::Read)
|
||||
} else if self.parse_keyword(Keyword::REPLICATE) {
|
||||
Ok(Action::Replicate)
|
||||
} else if self.parse_keyword(Keyword::SELECT) {
|
||||
Ok(Action::Select {
|
||||
columns: parse_columns(self)?,
|
||||
})
|
||||
} else if self.parse_keyword(Keyword::TEMPORARY) {
|
||||
Ok(Action::Temporary)
|
||||
} else if self.parse_keyword(Keyword::TRIGGER) {
|
||||
Ok(Action::Trigger)
|
||||
} else if self.parse_keyword(Keyword::TRUNCATE) {
|
||||
Ok(Action::Truncate)
|
||||
} else if self.parse_keyword(Keyword::UPDATE) {
|
||||
Ok(Action::Update {
|
||||
columns: parse_columns(self)?,
|
||||
})
|
||||
} else if self.parse_keyword(Keyword::USAGE) {
|
||||
Ok(Action::Usage)
|
||||
} else if self.parse_keyword(Keyword::OWNERSHIP) {
|
||||
Ok(Action::Ownership)
|
||||
} else {
|
||||
self.expected("a privilege keyword", self.peek_token())?
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_parse_action_create_object_type(&mut self) -> Option<ActionCreateObjectType> {
|
||||
// Multi-word object types
|
||||
if self.parse_keywords(&[Keyword::APPLICATION, Keyword::PACKAGE]) {
|
||||
Some(ActionCreateObjectType::ApplicationPackage)
|
||||
} else if self.parse_keywords(&[Keyword::COMPUTE, Keyword::POOL]) {
|
||||
Some(ActionCreateObjectType::ComputePool)
|
||||
} else if self.parse_keywords(&[Keyword::DATA, Keyword::EXCHANGE, Keyword::LISTING]) {
|
||||
Some(ActionCreateObjectType::DataExchangeListing)
|
||||
} else if self.parse_keywords(&[Keyword::EXTERNAL, Keyword::VOLUME]) {
|
||||
Some(ActionCreateObjectType::ExternalVolume)
|
||||
} else if self.parse_keywords(&[Keyword::FAILOVER, Keyword::GROUP]) {
|
||||
Some(ActionCreateObjectType::FailoverGroup)
|
||||
} else if self.parse_keywords(&[Keyword::NETWORK, Keyword::POLICY]) {
|
||||
Some(ActionCreateObjectType::NetworkPolicy)
|
||||
} else if self.parse_keywords(&[Keyword::ORGANIZATION, Keyword::LISTING]) {
|
||||
Some(ActionCreateObjectType::OrganiationListing)
|
||||
} else if self.parse_keywords(&[Keyword::REPLICATION, Keyword::GROUP]) {
|
||||
Some(ActionCreateObjectType::ReplicationGroup)
|
||||
}
|
||||
// Single-word object types
|
||||
else if self.parse_keyword(Keyword::ACCOUNT) {
|
||||
Some(ActionCreateObjectType::Account)
|
||||
} else if self.parse_keyword(Keyword::APPLICATION) {
|
||||
Some(ActionCreateObjectType::Application)
|
||||
} else if self.parse_keyword(Keyword::DATABASE) {
|
||||
Some(ActionCreateObjectType::Database)
|
||||
} else if self.parse_keyword(Keyword::INTEGRATION) {
|
||||
Some(ActionCreateObjectType::Integration)
|
||||
} else if self.parse_keyword(Keyword::ROLE) {
|
||||
Some(ActionCreateObjectType::Role)
|
||||
} else if self.parse_keyword(Keyword::SHARE) {
|
||||
Some(ActionCreateObjectType::Share)
|
||||
} else if self.parse_keyword(Keyword::USER) {
|
||||
Some(ActionCreateObjectType::User)
|
||||
} else if self.parse_keyword(Keyword::WAREHOUSE) {
|
||||
Some(ActionCreateObjectType::Warehouse)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_action_apply_type(&mut self) -> Result<ActionApplyType, ParserError> {
|
||||
if self.parse_keywords(&[Keyword::AGGREGATION, Keyword::POLICY]) {
|
||||
Ok(ActionApplyType::AggregationPolicy)
|
||||
} else if self.parse_keywords(&[Keyword::AUTHENTICATION, Keyword::POLICY]) {
|
||||
Ok(ActionApplyType::AuthenticationPolicy)
|
||||
} else if self.parse_keywords(&[Keyword::JOIN, Keyword::POLICY]) {
|
||||
Ok(ActionApplyType::JoinPolicy)
|
||||
} else if self.parse_keywords(&[Keyword::MASKING, Keyword::POLICY]) {
|
||||
Ok(ActionApplyType::MaskingPolicy)
|
||||
} else if self.parse_keywords(&[Keyword::PACKAGES, Keyword::POLICY]) {
|
||||
Ok(ActionApplyType::PackagesPolicy)
|
||||
} else if self.parse_keywords(&[Keyword::PASSWORD, Keyword::POLICY]) {
|
||||
Ok(ActionApplyType::PasswordPolicy)
|
||||
} else if self.parse_keywords(&[Keyword::PROJECTION, Keyword::POLICY]) {
|
||||
Ok(ActionApplyType::ProjectionPolicy)
|
||||
} else if self.parse_keywords(&[Keyword::ROW, Keyword::ACCESS, Keyword::POLICY]) {
|
||||
Ok(ActionApplyType::RowAccessPolicy)
|
||||
} else if self.parse_keywords(&[Keyword::SESSION, Keyword::POLICY]) {
|
||||
Ok(ActionApplyType::SessionPolicy)
|
||||
} else if self.parse_keyword(Keyword::TAG) {
|
||||
Ok(ActionApplyType::Tag)
|
||||
} else {
|
||||
self.expected("GRANT APPLY type", self.peek_token())
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_parse_action_execute_obj_type(&mut self) -> Option<ActionExecuteObjectType> {
|
||||
if self.parse_keywords(&[Keyword::DATA, Keyword::METRIC, Keyword::FUNCTION]) {
|
||||
Some(ActionExecuteObjectType::DataMetricFunction)
|
||||
} else if self.parse_keywords(&[Keyword::MANAGED, Keyword::ALERT]) {
|
||||
Some(ActionExecuteObjectType::ManagedAlert)
|
||||
} else if self.parse_keywords(&[Keyword::MANAGED, Keyword::TASK]) {
|
||||
Some(ActionExecuteObjectType::ManagedTask)
|
||||
} else if self.parse_keyword(Keyword::ALERT) {
|
||||
Some(ActionExecuteObjectType::Alert)
|
||||
} else if self.parse_keyword(Keyword::TASK) {
|
||||
Some(ActionExecuteObjectType::Task)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_action_manage_type(&mut self) -> Result<ActionManageType, ParserError> {
|
||||
if self.parse_keywords(&[Keyword::ACCOUNT, Keyword::SUPPORT, Keyword::CASES]) {
|
||||
Ok(ActionManageType::AccountSupportCases)
|
||||
} else if self.parse_keywords(&[Keyword::EVENT, Keyword::SHARING]) {
|
||||
Ok(ActionManageType::EventSharing)
|
||||
} else if self.parse_keywords(&[Keyword::LISTING, Keyword::AUTO, Keyword::FULFILLMENT]) {
|
||||
Ok(ActionManageType::ListingAutoFulfillment)
|
||||
} else if self.parse_keywords(&[Keyword::ORGANIZATION, Keyword::SUPPORT, Keyword::CASES]) {
|
||||
Ok(ActionManageType::OrganizationSupportCases)
|
||||
} else if self.parse_keywords(&[Keyword::USER, Keyword::SUPPORT, Keyword::CASES]) {
|
||||
Ok(ActionManageType::UserSupportCases)
|
||||
} else if self.parse_keyword(Keyword::GRANTS) {
|
||||
Ok(ActionManageType::Grants)
|
||||
} else if self.parse_keyword(Keyword::WAREHOUSES) {
|
||||
Ok(ActionManageType::Warehouses)
|
||||
} else {
|
||||
self.expected("GRANT MANAGE type", self.peek_token())
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_action_modify_type(&mut self) -> Result<ActionModifyType, ParserError> {
|
||||
if self.parse_keywords(&[Keyword::LOG, Keyword::LEVEL]) {
|
||||
Ok(ActionModifyType::LogLevel)
|
||||
} else if self.parse_keywords(&[Keyword::TRACE, Keyword::LEVEL]) {
|
||||
Ok(ActionModifyType::TraceLevel)
|
||||
} else if self.parse_keywords(&[Keyword::SESSION, Keyword::LOG, Keyword::LEVEL]) {
|
||||
Ok(ActionModifyType::SessionLogLevel)
|
||||
} else if self.parse_keywords(&[Keyword::SESSION, Keyword::TRACE, Keyword::LEVEL]) {
|
||||
Ok(ActionModifyType::SessionTraceLevel)
|
||||
} else {
|
||||
self.expected("GRANT MODIFY type", self.peek_token())
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_action_monitor_type(&mut self) -> Result<ActionMonitorType, ParserError> {
|
||||
if self.parse_keyword(Keyword::EXECUTION) {
|
||||
Ok(ActionMonitorType::Execution)
|
||||
} else if self.parse_keyword(Keyword::SECURITY) {
|
||||
Ok(ActionMonitorType::Security)
|
||||
} else if self.parse_keyword(Keyword::USAGE) {
|
||||
Ok(ActionMonitorType::Usage)
|
||||
} else {
|
||||
self.expected("GRANT MONITOR type", self.peek_token())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_grantee_name(&mut self) -> Result<GranteeName, ParserError> {
|
||||
let mut name = self.parse_object_name(false)?;
|
||||
if self.dialect.supports_user_host_grantee()
|
||||
|
|
|
@ -8500,8 +8500,8 @@ fn parse_grant() {
|
|||
Action::References { columns: None },
|
||||
Action::Trigger,
|
||||
Action::Connect,
|
||||
Action::Create,
|
||||
Action::Execute,
|
||||
Action::Create { obj_type: None },
|
||||
Action::Execute { obj_type: None },
|
||||
Action::Temporary,
|
||||
],
|
||||
actions
|
||||
|
@ -8616,6 +8616,7 @@ fn parse_grant() {
|
|||
verified_stmt("GRANT SELECT ON ALL TABLES IN SCHEMA db1.sc1 TO SHARE share1");
|
||||
verified_stmt("GRANT USAGE ON SCHEMA sc1 TO a:b");
|
||||
verified_stmt("GRANT USAGE ON SCHEMA sc1 TO GROUP group1");
|
||||
verified_stmt("GRANT OWNERSHIP ON ALL TABLES IN SCHEMA DEV_STAS_ROGOZHIN TO ROLE ANALYST");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -3058,3 +3058,109 @@ fn test_timetravel_at_before() {
|
|||
snowflake()
|
||||
.verified_only_select("SELECT * FROM tbl BEFORE(TIMESTAMP => '2024-12-15 00:00:00')");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_grant_account_privileges() {
|
||||
let privileges = vec![
|
||||
"ALL",
|
||||
"ALL PRIVILEGES",
|
||||
"ATTACH POLICY",
|
||||
"AUDIT",
|
||||
"BIND SERVICE ENDPOINT",
|
||||
"IMPORT SHARE",
|
||||
"OVERRIDE SHARE RESTRICTIONS",
|
||||
"PURCHASE DATA EXCHANGE LISTING",
|
||||
"RESOLVE ALL",
|
||||
"READ SESSION",
|
||||
];
|
||||
let with_grant_options = vec!["", " WITH GRANT OPTION"];
|
||||
|
||||
for p in &privileges {
|
||||
for wgo in &with_grant_options {
|
||||
let sql = format!("GRANT {p} ON ACCOUNT TO ROLE role1{wgo}");
|
||||
snowflake_and_generic().verified_stmt(&sql);
|
||||
}
|
||||
}
|
||||
|
||||
let create_object_types = vec![
|
||||
"ACCOUNT",
|
||||
"APPLICATION",
|
||||
"APPLICATION PACKAGE",
|
||||
"COMPUTE POOL",
|
||||
"DATA EXCHANGE LISTING",
|
||||
"DATABASE",
|
||||
"EXTERNAL VOLUME",
|
||||
"FAILOVER GROUP",
|
||||
"INTEGRATION",
|
||||
"NETWORK POLICY",
|
||||
"ORGANIZATION LISTING",
|
||||
"REPLICATION GROUP",
|
||||
"ROLE",
|
||||
"SHARE",
|
||||
"USER",
|
||||
"WAREHOUSE",
|
||||
];
|
||||
for t in &create_object_types {
|
||||
for wgo in &with_grant_options {
|
||||
let sql = format!("GRANT CREATE {t} ON ACCOUNT TO ROLE role1{wgo}");
|
||||
snowflake_and_generic().verified_stmt(&sql);
|
||||
}
|
||||
}
|
||||
|
||||
let apply_types = vec![
|
||||
"AGGREGATION POLICY",
|
||||
"AUTHENTICATION POLICY",
|
||||
"JOIN POLICY",
|
||||
"MASKING POLICY",
|
||||
"PACKAGES POLICY",
|
||||
"PASSWORD POLICY",
|
||||
"PROJECTION POLICY",
|
||||
"ROW ACCESS POLICY",
|
||||
"SESSION POLICY",
|
||||
"TAG",
|
||||
];
|
||||
for t in &apply_types {
|
||||
for wgo in &with_grant_options {
|
||||
let sql = format!("GRANT APPLY {t} ON ACCOUNT TO ROLE role1{wgo}");
|
||||
snowflake_and_generic().verified_stmt(&sql);
|
||||
}
|
||||
}
|
||||
|
||||
let execute_types = vec![
|
||||
"ALERT",
|
||||
"DATA METRIC FUNCTION",
|
||||
"MANAGED ALERT",
|
||||
"MANAGED TASK",
|
||||
"TASK",
|
||||
];
|
||||
for t in &execute_types {
|
||||
for wgo in &with_grant_options {
|
||||
let sql = format!("GRANT EXECUTE {t} ON ACCOUNT TO ROLE role1{wgo}");
|
||||
snowflake_and_generic().verified_stmt(&sql);
|
||||
}
|
||||
}
|
||||
|
||||
let manage_types = vec![
|
||||
"ACCOUNT SUPPORT CASES",
|
||||
"EVENT SHARING",
|
||||
"GRANTS",
|
||||
"LISTING AUTO FULFILLMENT",
|
||||
"ORGANIZATION SUPPORT CASES",
|
||||
"USER SUPPORT CASES",
|
||||
"WAREHOUSES",
|
||||
];
|
||||
for t in &manage_types {
|
||||
for wgo in &with_grant_options {
|
||||
let sql = format!("GRANT MANAGE {t} ON ACCOUNT TO ROLE role1{wgo}");
|
||||
snowflake_and_generic().verified_stmt(&sql);
|
||||
}
|
||||
}
|
||||
|
||||
let monitor_types = vec!["EXECUTION", "SECURITY", "USAGE"];
|
||||
for t in &monitor_types {
|
||||
for wgo in &with_grant_options {
|
||||
let sql = format!("GRANT MONITOR {t} ON ACCOUNT TO ROLE role1{wgo}");
|
||||
snowflake_and_generic().verified_stmt(&sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue