mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-12-10 06:19:36 +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 = "serde", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||||
pub enum Action {
|
pub enum Action {
|
||||||
|
AddSearchOptimization,
|
||||||
|
Apply {
|
||||||
|
apply_type: ActionApplyType,
|
||||||
|
},
|
||||||
|
ApplyBudget,
|
||||||
|
AttachListing,
|
||||||
|
AttachPolicy,
|
||||||
|
Audit,
|
||||||
|
BindServiceEndpoint,
|
||||||
Connect,
|
Connect,
|
||||||
Create,
|
Create {
|
||||||
|
obj_type: Option<ActionCreateObjectType>,
|
||||||
|
},
|
||||||
Delete,
|
Delete,
|
||||||
Execute,
|
EvolveSchema,
|
||||||
Insert { columns: Option<Vec<Ident>> },
|
Execute {
|
||||||
References { columns: Option<Vec<Ident>> },
|
obj_type: Option<ActionExecuteObjectType>,
|
||||||
Select { columns: Option<Vec<Ident>> },
|
},
|
||||||
|
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,
|
Temporary,
|
||||||
Trigger,
|
Trigger,
|
||||||
Truncate,
|
Truncate,
|
||||||
Update { columns: Option<Vec<Ident>> },
|
Update {
|
||||||
|
columns: Option<Vec<Ident>>,
|
||||||
|
},
|
||||||
Usage,
|
Usage,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Action {
|
impl fmt::Display for Action {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
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::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::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::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::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::Select { .. } => f.write_str("SELECT")?,
|
||||||
Action::Temporary => f.write_str("TEMPORARY")?,
|
Action::Temporary => f.write_str("TEMPORARY")?,
|
||||||
Action::Trigger => f.write_str("TRIGGER")?,
|
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
|
/// The principal that receives the privileges
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ define_keywords!(
|
||||||
AFTER,
|
AFTER,
|
||||||
AGAINST,
|
AGAINST,
|
||||||
AGGREGATION,
|
AGGREGATION,
|
||||||
|
ALERT,
|
||||||
ALGORITHM,
|
ALGORITHM,
|
||||||
ALIAS,
|
ALIAS,
|
||||||
ALL,
|
ALL,
|
||||||
|
|
@ -96,6 +97,7 @@ define_keywords!(
|
||||||
ANY,
|
ANY,
|
||||||
APPLICATION,
|
APPLICATION,
|
||||||
APPLY,
|
APPLY,
|
||||||
|
APPLYBUDGET,
|
||||||
ARCHIVE,
|
ARCHIVE,
|
||||||
ARE,
|
ARE,
|
||||||
ARRAY,
|
ARRAY,
|
||||||
|
|
@ -109,6 +111,8 @@ define_keywords!(
|
||||||
AT,
|
AT,
|
||||||
ATOMIC,
|
ATOMIC,
|
||||||
ATTACH,
|
ATTACH,
|
||||||
|
AUDIT,
|
||||||
|
AUTHENTICATION,
|
||||||
AUTHORIZATION,
|
AUTHORIZATION,
|
||||||
AUTO,
|
AUTO,
|
||||||
AUTOINCREMENT,
|
AUTOINCREMENT,
|
||||||
|
|
@ -127,6 +131,7 @@ define_keywords!(
|
||||||
BIGINT,
|
BIGINT,
|
||||||
BIGNUMERIC,
|
BIGNUMERIC,
|
||||||
BINARY,
|
BINARY,
|
||||||
|
BIND,
|
||||||
BINDING,
|
BINDING,
|
||||||
BIT,
|
BIT,
|
||||||
BLOB,
|
BLOB,
|
||||||
|
|
@ -150,6 +155,7 @@ define_keywords!(
|
||||||
CASCADE,
|
CASCADE,
|
||||||
CASCADED,
|
CASCADED,
|
||||||
CASE,
|
CASE,
|
||||||
|
CASES,
|
||||||
CAST,
|
CAST,
|
||||||
CATALOG,
|
CATALOG,
|
||||||
CATCH,
|
CATCH,
|
||||||
|
|
@ -305,12 +311,15 @@ define_keywords!(
|
||||||
ESTIMATE,
|
ESTIMATE,
|
||||||
EVENT,
|
EVENT,
|
||||||
EVERY,
|
EVERY,
|
||||||
|
EVOLVE,
|
||||||
EXCEPT,
|
EXCEPT,
|
||||||
EXCEPTION,
|
EXCEPTION,
|
||||||
|
EXCHANGE,
|
||||||
EXCLUDE,
|
EXCLUDE,
|
||||||
EXCLUSIVE,
|
EXCLUSIVE,
|
||||||
EXEC,
|
EXEC,
|
||||||
EXECUTE,
|
EXECUTE,
|
||||||
|
EXECUTION,
|
||||||
EXISTS,
|
EXISTS,
|
||||||
EXP,
|
EXP,
|
||||||
EXPANSION,
|
EXPANSION,
|
||||||
|
|
@ -322,6 +331,7 @@ define_keywords!(
|
||||||
EXTERNAL,
|
EXTERNAL,
|
||||||
EXTRACT,
|
EXTRACT,
|
||||||
FAIL,
|
FAIL,
|
||||||
|
FAILOVER,
|
||||||
FALSE,
|
FALSE,
|
||||||
FETCH,
|
FETCH,
|
||||||
FIELDS,
|
FIELDS,
|
||||||
|
|
@ -357,6 +367,7 @@ define_keywords!(
|
||||||
FREEZE,
|
FREEZE,
|
||||||
FROM,
|
FROM,
|
||||||
FSCK,
|
FSCK,
|
||||||
|
FULFILLMENT,
|
||||||
FULL,
|
FULL,
|
||||||
FULLTEXT,
|
FULLTEXT,
|
||||||
FUNCTION,
|
FUNCTION,
|
||||||
|
|
@ -394,6 +405,8 @@ define_keywords!(
|
||||||
ILIKE,
|
ILIKE,
|
||||||
IMMEDIATE,
|
IMMEDIATE,
|
||||||
IMMUTABLE,
|
IMMUTABLE,
|
||||||
|
IMPORT,
|
||||||
|
IMPORTED,
|
||||||
IN,
|
IN,
|
||||||
INCLUDE,
|
INCLUDE,
|
||||||
INCLUDE_NULL_VALUES,
|
INCLUDE_NULL_VALUES,
|
||||||
|
|
@ -421,6 +434,7 @@ define_keywords!(
|
||||||
INT64,
|
INT64,
|
||||||
INT8,
|
INT8,
|
||||||
INTEGER,
|
INTEGER,
|
||||||
|
INTEGRATION,
|
||||||
INTERPOLATE,
|
INTERPOLATE,
|
||||||
INTERSECT,
|
INTERSECT,
|
||||||
INTERSECTION,
|
INTERSECTION,
|
||||||
|
|
@ -460,6 +474,7 @@ define_keywords!(
|
||||||
LINES,
|
LINES,
|
||||||
LIST,
|
LIST,
|
||||||
LISTEN,
|
LISTEN,
|
||||||
|
LISTING,
|
||||||
LN,
|
LN,
|
||||||
LOAD,
|
LOAD,
|
||||||
LOCAL,
|
LOCAL,
|
||||||
|
|
@ -478,6 +493,8 @@ define_keywords!(
|
||||||
LOW_PRIORITY,
|
LOW_PRIORITY,
|
||||||
LS,
|
LS,
|
||||||
MACRO,
|
MACRO,
|
||||||
|
MANAGE,
|
||||||
|
MANAGED,
|
||||||
MANAGEDLOCATION,
|
MANAGEDLOCATION,
|
||||||
MAP,
|
MAP,
|
||||||
MASKING,
|
MASKING,
|
||||||
|
|
@ -499,6 +516,7 @@ define_keywords!(
|
||||||
MERGE,
|
MERGE,
|
||||||
METADATA,
|
METADATA,
|
||||||
METHOD,
|
METHOD,
|
||||||
|
METRIC,
|
||||||
MICROSECOND,
|
MICROSECOND,
|
||||||
MICROSECONDS,
|
MICROSECONDS,
|
||||||
MILLENIUM,
|
MILLENIUM,
|
||||||
|
|
@ -515,6 +533,7 @@ define_keywords!(
|
||||||
MODIFIES,
|
MODIFIES,
|
||||||
MODIFY,
|
MODIFY,
|
||||||
MODULE,
|
MODULE,
|
||||||
|
MONITOR,
|
||||||
MONTH,
|
MONTH,
|
||||||
MONTHS,
|
MONTHS,
|
||||||
MSCK,
|
MSCK,
|
||||||
|
|
@ -528,6 +547,7 @@ define_keywords!(
|
||||||
NCHAR,
|
NCHAR,
|
||||||
NCLOB,
|
NCLOB,
|
||||||
NESTED,
|
NESTED,
|
||||||
|
NETWORK,
|
||||||
NEW,
|
NEW,
|
||||||
NEXT,
|
NEXT,
|
||||||
NFC,
|
NFC,
|
||||||
|
|
@ -575,7 +595,9 @@ define_keywords!(
|
||||||
ONLY,
|
ONLY,
|
||||||
OPEN,
|
OPEN,
|
||||||
OPENJSON,
|
OPENJSON,
|
||||||
|
OPERATE,
|
||||||
OPERATOR,
|
OPERATOR,
|
||||||
|
OPTIMIZATION,
|
||||||
OPTIMIZE,
|
OPTIMIZE,
|
||||||
OPTIMIZER_COSTS,
|
OPTIMIZER_COSTS,
|
||||||
OPTION,
|
OPTION,
|
||||||
|
|
@ -584,6 +606,7 @@ define_keywords!(
|
||||||
ORC,
|
ORC,
|
||||||
ORDER,
|
ORDER,
|
||||||
ORDINALITY,
|
ORDINALITY,
|
||||||
|
ORGANIZATION,
|
||||||
OUT,
|
OUT,
|
||||||
OUTER,
|
OUTER,
|
||||||
OUTPUTFORMAT,
|
OUTPUTFORMAT,
|
||||||
|
|
@ -591,9 +614,13 @@ define_keywords!(
|
||||||
OVERFLOW,
|
OVERFLOW,
|
||||||
OVERLAPS,
|
OVERLAPS,
|
||||||
OVERLAY,
|
OVERLAY,
|
||||||
|
OVERRIDE,
|
||||||
OVERWRITE,
|
OVERWRITE,
|
||||||
OWNED,
|
OWNED,
|
||||||
OWNER,
|
OWNER,
|
||||||
|
OWNERSHIP,
|
||||||
|
PACKAGE,
|
||||||
|
PACKAGES,
|
||||||
PARALLEL,
|
PARALLEL,
|
||||||
PARAMETER,
|
PARAMETER,
|
||||||
PARQUET,
|
PARQUET,
|
||||||
|
|
@ -618,6 +645,7 @@ define_keywords!(
|
||||||
PLAN,
|
PLAN,
|
||||||
PLANS,
|
PLANS,
|
||||||
POLICY,
|
POLICY,
|
||||||
|
POOL,
|
||||||
PORTION,
|
PORTION,
|
||||||
POSITION,
|
POSITION,
|
||||||
POSITION_REGEX,
|
POSITION_REGEX,
|
||||||
|
|
@ -637,6 +665,7 @@ define_keywords!(
|
||||||
PROGRAM,
|
PROGRAM,
|
||||||
PROJECTION,
|
PROJECTION,
|
||||||
PUBLIC,
|
PUBLIC,
|
||||||
|
PURCHASE,
|
||||||
PURGE,
|
PURGE,
|
||||||
QUALIFY,
|
QUALIFY,
|
||||||
QUARTER,
|
QUARTER,
|
||||||
|
|
@ -670,6 +699,7 @@ define_keywords!(
|
||||||
RELATIVE,
|
RELATIVE,
|
||||||
RELAY,
|
RELAY,
|
||||||
RELEASE,
|
RELEASE,
|
||||||
|
RELEASES,
|
||||||
REMOTE,
|
REMOTE,
|
||||||
REMOVE,
|
REMOVE,
|
||||||
RENAME,
|
RENAME,
|
||||||
|
|
@ -678,12 +708,15 @@ define_keywords!(
|
||||||
REPEATABLE,
|
REPEATABLE,
|
||||||
REPLACE,
|
REPLACE,
|
||||||
REPLICA,
|
REPLICA,
|
||||||
|
REPLICATE,
|
||||||
REPLICATION,
|
REPLICATION,
|
||||||
RESET,
|
RESET,
|
||||||
|
RESOLVE,
|
||||||
RESPECT,
|
RESPECT,
|
||||||
RESTART,
|
RESTART,
|
||||||
RESTRICT,
|
RESTRICT,
|
||||||
RESTRICTED,
|
RESTRICTED,
|
||||||
|
RESTRICTIONS,
|
||||||
RESTRICTIVE,
|
RESTRICTIVE,
|
||||||
RESULT,
|
RESULT,
|
||||||
RESULTSET,
|
RESULTSET,
|
||||||
|
|
@ -732,6 +765,7 @@ define_keywords!(
|
||||||
SERDE,
|
SERDE,
|
||||||
SERDEPROPERTIES,
|
SERDEPROPERTIES,
|
||||||
SERIALIZABLE,
|
SERIALIZABLE,
|
||||||
|
SERVICE,
|
||||||
SESSION,
|
SESSION,
|
||||||
SESSION_USER,
|
SESSION_USER,
|
||||||
SET,
|
SET,
|
||||||
|
|
@ -739,6 +773,7 @@ define_keywords!(
|
||||||
SETS,
|
SETS,
|
||||||
SETTINGS,
|
SETTINGS,
|
||||||
SHARE,
|
SHARE,
|
||||||
|
SHARING,
|
||||||
SHOW,
|
SHOW,
|
||||||
SIMILAR,
|
SIMILAR,
|
||||||
SKIP,
|
SKIP,
|
||||||
|
|
@ -782,6 +817,7 @@ define_keywords!(
|
||||||
SUM,
|
SUM,
|
||||||
SUPER,
|
SUPER,
|
||||||
SUPERUSER,
|
SUPERUSER,
|
||||||
|
SUPPORT,
|
||||||
SUSPEND,
|
SUSPEND,
|
||||||
SWAP,
|
SWAP,
|
||||||
SYMMETRIC,
|
SYMMETRIC,
|
||||||
|
|
@ -794,6 +830,7 @@ define_keywords!(
|
||||||
TABLESAMPLE,
|
TABLESAMPLE,
|
||||||
TAG,
|
TAG,
|
||||||
TARGET,
|
TARGET,
|
||||||
|
TASK,
|
||||||
TBLPROPERTIES,
|
TBLPROPERTIES,
|
||||||
TEMP,
|
TEMP,
|
||||||
TEMPORARY,
|
TEMPORARY,
|
||||||
|
|
@ -819,6 +856,7 @@ define_keywords!(
|
||||||
TO,
|
TO,
|
||||||
TOP,
|
TOP,
|
||||||
TOTALS,
|
TOTALS,
|
||||||
|
TRACE,
|
||||||
TRAILING,
|
TRAILING,
|
||||||
TRANSACTION,
|
TRANSACTION,
|
||||||
TRANSIENT,
|
TRANSIENT,
|
||||||
|
|
@ -885,11 +923,14 @@ define_keywords!(
|
||||||
VERBOSE,
|
VERBOSE,
|
||||||
VERSION,
|
VERSION,
|
||||||
VERSIONING,
|
VERSIONING,
|
||||||
|
VERSIONS,
|
||||||
VIEW,
|
VIEW,
|
||||||
VIEWS,
|
VIEWS,
|
||||||
VIRTUAL,
|
VIRTUAL,
|
||||||
VOLATILE,
|
VOLATILE,
|
||||||
|
VOLUME,
|
||||||
WAREHOUSE,
|
WAREHOUSE,
|
||||||
|
WAREHOUSES,
|
||||||
WEEK,
|
WEEK,
|
||||||
WEEKS,
|
WEEKS,
|
||||||
WHEN,
|
WHEN,
|
||||||
|
|
|
||||||
|
|
@ -48,9 +48,6 @@ pub enum ParserError {
|
||||||
RecursionLimitExceeded,
|
RecursionLimitExceeded,
|
||||||
}
|
}
|
||||||
|
|
||||||
// avoid clippy type_complexity warnings
|
|
||||||
type ParsedAction = (Keyword, Option<Vec<Ident>>);
|
|
||||||
|
|
||||||
// Use `Parser::expected` instead, if possible
|
// Use `Parser::expected` instead, if possible
|
||||||
macro_rules! parser_err {
|
macro_rules! parser_err {
|
||||||
($MSG:expr, $loc:expr) => {
|
($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![];
|
let mut values = vec![];
|
||||||
loop {
|
loop {
|
||||||
values.push(self.parse_grant_permission()?);
|
values.push(self.parse_grant_permission()?);
|
||||||
|
|
@ -11980,37 +11977,8 @@ impl<'a> Parser<'a> {
|
||||||
with_privileges_keyword: self.parse_keyword(Keyword::PRIVILEGES),
|
with_privileges_keyword: self.parse_keyword(Keyword::PRIVILEGES),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let (actions, err): (Vec<_>, Vec<_>) = self
|
let actions = self.parse_actions_list()?;
|
||||||
.parse_actions_list()?
|
Privileges::Actions(actions)
|
||||||
.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)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.expect_keyword_is(Keyword::ON)?;
|
self.expect_keyword_is(Keyword::ON)?;
|
||||||
|
|
@ -12049,38 +12017,244 @@ impl<'a> Parser<'a> {
|
||||||
Ok((privileges, objects))
|
Ok((privileges, objects))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_grant_permission(&mut self) -> Result<ParsedAction, ParserError> {
|
pub fn parse_grant_permission(&mut self) -> Result<Action, ParserError> {
|
||||||
if let Some(kw) = self.parse_one_of_keywords(&[
|
fn parse_columns(parser: &mut Parser) -> Result<Option<Vec<Ident>>, ParserError> {
|
||||||
Keyword::CONNECT,
|
let columns = parser.parse_parenthesized_column_list(Optional, false)?;
|
||||||
Keyword::CREATE,
|
if columns.is_empty() {
|
||||||
Keyword::DELETE,
|
Ok(None)
|
||||||
Keyword::EXECUTE,
|
} else {
|
||||||
Keyword::INSERT,
|
Ok(Some(columns))
|
||||||
Keyword::REFERENCES,
|
}
|
||||||
Keyword::SELECT,
|
}
|
||||||
Keyword::TEMPORARY,
|
|
||||||
Keyword::TRIGGER,
|
// Multi-word privileges
|
||||||
Keyword::TRUNCATE,
|
if self.parse_keywords(&[Keyword::IMPORTED, Keyword::PRIVILEGES]) {
|
||||||
Keyword::UPDATE,
|
Ok(Action::ImportedPrivileges)
|
||||||
Keyword::USAGE,
|
} 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 {
|
Ok(Action::PurchaseDataExchangeListing)
|
||||||
Keyword::INSERT | Keyword::REFERENCES | Keyword::SELECT | Keyword::UPDATE => {
|
} else if self.parse_keywords(&[Keyword::RESOLVE, Keyword::ALL]) {
|
||||||
let columns = self.parse_parenthesized_column_list(Optional, false)?;
|
Ok(Action::ResolveAll)
|
||||||
if columns.is_empty() {
|
} else if self.parse_keywords(&[Keyword::READ, Keyword::SESSION]) {
|
||||||
None
|
Ok(Action::ReadSession)
|
||||||
} else {
|
|
||||||
Some(columns)
|
// Single-word privileges
|
||||||
}
|
} else if self.parse_keyword(Keyword::APPLY) {
|
||||||
}
|
let apply_type = self.parse_action_apply_type()?;
|
||||||
_ => None,
|
Ok(Action::Apply { apply_type })
|
||||||
};
|
} else if self.parse_keyword(Keyword::APPLYBUDGET) {
|
||||||
Ok((kw, columns))
|
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 {
|
} else {
|
||||||
self.expected("a privilege keyword", self.peek_token())?
|
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> {
|
pub fn parse_grantee_name(&mut self) -> Result<GranteeName, ParserError> {
|
||||||
let mut name = self.parse_object_name(false)?;
|
let mut name = self.parse_object_name(false)?;
|
||||||
if self.dialect.supports_user_host_grantee()
|
if self.dialect.supports_user_host_grantee()
|
||||||
|
|
|
||||||
|
|
@ -8500,8 +8500,8 @@ fn parse_grant() {
|
||||||
Action::References { columns: None },
|
Action::References { columns: None },
|
||||||
Action::Trigger,
|
Action::Trigger,
|
||||||
Action::Connect,
|
Action::Connect,
|
||||||
Action::Create,
|
Action::Create { obj_type: None },
|
||||||
Action::Execute,
|
Action::Execute { obj_type: None },
|
||||||
Action::Temporary,
|
Action::Temporary,
|
||||||
],
|
],
|
||||||
actions
|
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 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 a:b");
|
||||||
verified_stmt("GRANT USAGE ON SCHEMA sc1 TO GROUP group1");
|
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]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -3058,3 +3058,109 @@ fn test_timetravel_at_before() {
|
||||||
snowflake()
|
snowflake()
|
||||||
.verified_only_select("SELECT * FROM tbl BEFORE(TIMESTAMP => '2024-12-15 00:00:00')");
|
.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