diff --git a/src/ast/dcl.rs b/src/ast/dcl.rs index 7183bc3fb..3c50a81c0 100644 --- a/src/ast/dcl.rs +++ b/src/ast/dcl.rs @@ -29,7 +29,10 @@ use serde::{Deserialize, Serialize}; use sqlparser_derive::{Visit, VisitMut}; use super::{display_comma_separated, Expr, Ident, Password, Spanned}; -use crate::ast::{display_separated, ObjectName}; +use crate::ast::{ + display_separated, CascadeOption, CurrentGrantsKind, GrantObjects, Grantee, ObjectName, + Privileges, +}; use crate::tokenizer::Span; /// An option in `ROLE` statement. @@ -427,3 +430,99 @@ impl Spanned for CreateRole { Span::empty() } } + +/// GRANT privileges ON objects TO grantees +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] +pub struct Grant { + /// Privileges being granted. + pub privileges: Privileges, + /// Optional objects the privileges apply to. + pub objects: Option, + /// List of grantees receiving the privileges. + pub grantees: Vec, + /// Whether `WITH GRANT OPTION` is present. + pub with_grant_option: bool, + /// Optional `AS GRANTOR` identifier. + pub as_grantor: Option, + /// Optional `GRANTED BY` identifier. + /// + /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/dcl-statements) + pub granted_by: Option, + /// Optional `CURRENT GRANTS` modifier. + /// + /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/grant-privilege) + pub current_grants: Option, +} + +impl fmt::Display for Grant { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "GRANT {privileges}", privileges = self.privileges)?; + if let Some(ref objects) = self.objects { + write!(f, " ON {objects}")?; + } + write!(f, " TO {}", display_comma_separated(&self.grantees))?; + if let Some(ref current_grants) = self.current_grants { + write!(f, " {current_grants}")?; + } + if self.with_grant_option { + write!(f, " WITH GRANT OPTION")?; + } + if let Some(ref as_grantor) = self.as_grantor { + write!(f, " AS {as_grantor}")?; + } + if let Some(ref granted_by) = self.granted_by { + write!(f, " GRANTED BY {granted_by}")?; + } + Ok(()) + } +} + +impl From for crate::ast::Statement { + fn from(v: Grant) -> Self { + crate::ast::Statement::Grant(v) + } +} + +/// REVOKE privileges ON objects FROM grantees +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] +pub struct Revoke { + /// Privileges to revoke. + pub privileges: Privileges, + /// Optional objects from which to revoke. + pub objects: Option, + /// Grantees affected by the revoke. + pub grantees: Vec, + /// Optional `GRANTED BY` identifier. + /// + /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/dcl-statements) + pub granted_by: Option, + /// Optional `CASCADE`/`RESTRICT` behavior. + pub cascade: Option, +} + +impl fmt::Display for Revoke { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "REVOKE {privileges}", privileges = self.privileges)?; + if let Some(ref objects) = self.objects { + write!(f, " ON {objects}")?; + } + write!(f, " FROM {}", display_comma_separated(&self.grantees))?; + if let Some(ref granted_by) = self.granted_by { + write!(f, " GRANTED BY {granted_by}")?; + } + if let Some(ref cascade) = self.cascade { + write!(f, " {cascade}")?; + } + Ok(()) + } +} + +impl From for crate::ast::Statement { + fn from(v: Revoke) -> Self { + crate::ast::Statement::Revoke(v) + } +} diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index 1d0059db8..0c4f93e64 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -5120,3 +5120,194 @@ impl Spanned for AlterOperatorClass { Span::empty() } } + +/// CREATE POLICY statement. +/// +/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html) +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] +pub struct CreatePolicy { + /// Name of the policy. + pub name: Ident, + /// Table the policy is defined on. + #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))] + pub table_name: ObjectName, + /// Optional policy type (e.g., `PERMISSIVE` / `RESTRICTIVE`). + pub policy_type: Option, + /// Optional command the policy applies to (e.g., `SELECT`). + pub command: Option, + /// Optional list of grantee owners. + pub to: Option>, + /// Optional expression for the `USING` clause. + pub using: Option, + /// Optional expression for the `WITH CHECK` clause. + pub with_check: Option, +} + +impl fmt::Display for CreatePolicy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "CREATE POLICY {name} ON {table_name}", + name = self.name, + table_name = self.table_name, + )?; + if let Some(ref policy_type) = self.policy_type { + write!(f, " AS {policy_type}")?; + } + if let Some(ref command) = self.command { + write!(f, " FOR {command}")?; + } + if let Some(ref to) = self.to { + write!(f, " TO {}", display_comma_separated(to))?; + } + if let Some(ref using) = self.using { + write!(f, " USING ({using})")?; + } + if let Some(ref with_check) = self.with_check { + write!(f, " WITH CHECK ({with_check})")?; + } + Ok(()) + } +} + +/// Policy type for a `CREATE POLICY` statement. +/// ```sql +/// AS [ PERMISSIVE | RESTRICTIVE ] +/// ``` +/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html) +#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] +pub enum CreatePolicyType { + /// Policy allows operations unless explicitly denied. + Permissive, + /// Policy denies operations unless explicitly allowed. + Restrictive, +} + +impl fmt::Display for CreatePolicyType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + CreatePolicyType::Permissive => write!(f, "PERMISSIVE"), + CreatePolicyType::Restrictive => write!(f, "RESTRICTIVE"), + } + } +} + +/// Command that a policy can apply to (FOR clause). +/// ```sql +/// FOR [ALL | SELECT | INSERT | UPDATE | DELETE] +/// ``` +/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html) +#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] +pub enum CreatePolicyCommand { + /// Applies to all commands. + All, + /// Applies to SELECT. + Select, + /// Applies to INSERT. + Insert, + /// Applies to UPDATE. + Update, + /// Applies to DELETE. + Delete, +} + +impl fmt::Display for CreatePolicyCommand { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + CreatePolicyCommand::All => write!(f, "ALL"), + CreatePolicyCommand::Select => write!(f, "SELECT"), + CreatePolicyCommand::Insert => write!(f, "INSERT"), + CreatePolicyCommand::Update => write!(f, "UPDATE"), + CreatePolicyCommand::Delete => write!(f, "DELETE"), + } + } +} + +/// DROP POLICY statement. +/// +/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-droppolicy.html) +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] +pub struct DropPolicy { + /// `true` when `IF EXISTS` was present. + pub if_exists: bool, + /// Name of the policy to drop. + pub name: Ident, + /// Name of the table the policy applies to. + #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))] + pub table_name: ObjectName, + /// Optional drop behavior (`CASCADE` or `RESTRICT`). + pub drop_behavior: Option, +} + +impl fmt::Display for DropPolicy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "DROP POLICY {if_exists}{name} ON {table_name}", + if_exists = if self.if_exists { "IF EXISTS " } else { "" }, + name = self.name, + table_name = self.table_name + )?; + if let Some(ref behavior) = self.drop_behavior { + write!(f, " {behavior}")?; + } + Ok(()) + } +} + +impl From for crate::ast::Statement { + fn from(v: CreatePolicy) -> Self { + crate::ast::Statement::CreatePolicy(v) + } +} + +impl From for crate::ast::Statement { + fn from(v: DropPolicy) -> Self { + crate::ast::Statement::DropPolicy(v) + } +} + +/// ALTER POLICY statement. +/// +/// ```sql +/// ALTER POLICY ON [] +/// ``` +/// (Postgresql-specific) +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] +pub struct AlterPolicy { + /// Policy name to alter. + pub name: Ident, + /// Target table name the policy is defined on. + #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))] + pub table_name: ObjectName, + /// Optional operation specific to the policy alteration. + pub operation: AlterPolicyOperation, +} + +impl fmt::Display for AlterPolicy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "ALTER POLICY {name} ON {table_name}{operation}", + name = self.name, + table_name = self.table_name, + operation = self.operation + ) + } +} + +impl From for crate::ast::Statement { + fn from(v: AlterPolicy) -> Self { + crate::ast::Statement::AlterPolicy(v) + } +} diff --git a/src/ast/mod.rs b/src/ast/mod.rs index f255e5f3f..ce5a67e12 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -56,20 +56,22 @@ pub use self::data_type::{ ExactNumberInfo, IntervalFields, StructBracketKind, TimezoneInfo, }; pub use self::dcl::{ - AlterRoleOperation, CreateRole, ResetConfig, RoleOption, SecondaryRoles, SetConfigValue, Use, + AlterRoleOperation, CreateRole, Grant, ResetConfig, Revoke, RoleOption, SecondaryRoles, + SetConfigValue, Use, }; pub use self::ddl::{ Alignment, AlterColumnOperation, AlterConnectorOwner, AlterIndexOperation, AlterOperator, AlterOperatorClass, AlterOperatorClassOperation, AlterOperatorFamily, - AlterOperatorFamilyOperation, AlterOperatorOperation, AlterPolicyOperation, AlterSchema, - AlterSchemaOperation, AlterTable, AlterTableAlgorithm, AlterTableLock, AlterTableOperation, - AlterTableType, AlterType, AlterTypeAddValue, AlterTypeAddValuePosition, AlterTypeOperation, - AlterTypeRename, AlterTypeRenameValue, ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, - ColumnOptions, ColumnPolicy, ColumnPolicyProperty, ConstraintCharacteristics, CreateConnector, - CreateDomain, CreateExtension, CreateFunction, CreateIndex, CreateOperator, - CreateOperatorClass, CreateOperatorFamily, CreateTable, CreateTrigger, CreateView, Deduplicate, + AlterOperatorFamilyOperation, AlterOperatorOperation, AlterPolicy, AlterPolicyOperation, + AlterSchema, AlterSchemaOperation, AlterTable, AlterTableAlgorithm, AlterTableLock, + AlterTableOperation, AlterTableType, AlterType, AlterTypeAddValue, AlterTypeAddValuePosition, + AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue, ClusteredBy, ColumnDef, + ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy, ColumnPolicyProperty, + ConstraintCharacteristics, CreateConnector, CreateDomain, CreateExtension, CreateFunction, + CreateIndex, CreateOperator, CreateOperatorClass, CreateOperatorFamily, CreatePolicy, + CreatePolicyCommand, CreatePolicyType, CreateTable, CreateTrigger, CreateView, Deduplicate, DeferrableInitial, DropBehavior, DropExtension, DropFunction, DropOperator, DropOperatorClass, - DropOperatorFamily, DropOperatorSignature, DropTrigger, ForValues, GeneratedAs, + DropOperatorFamily, DropOperatorSignature, DropPolicy, DropTrigger, ForValues, GeneratedAs, GeneratedExpressionMode, IdentityParameters, IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder, IndexColumn, IndexOption, IndexType, KeyOrIndexDisplay, Msck, NullsDistinctOption, OperatorArgTypes, OperatorClassItem, @@ -3098,44 +3100,6 @@ impl Display for FromTable { } } -/// Policy type for a `CREATE POLICY` statement. -/// ```sql -/// AS [ PERMISSIVE | RESTRICTIVE ] -/// ``` -/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html) -#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] -/// Type of `CREATE POLICY` (permissive or restrictive). -pub enum CreatePolicyType { - /// Policy allows operations unless explicitly denied. - Permissive, - /// Policy denies operations unless explicitly allowed. - Restrictive, -} - -/// Policy command for a `CREATE POLICY` statement. -/// ```sql -/// FOR [ALL | SELECT | INSERT | UPDATE | DELETE] -/// ``` -/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html) -#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] -/// Commands that a policy can apply to (FOR clause). -pub enum CreatePolicyCommand { - /// Applies to all commands. - All, - /// Applies to SELECT. - Select, - /// Applies to INSERT. - Insert, - /// Applies to UPDATE. - Update, - /// Applies to DELETE. - Delete, -} - #[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] @@ -3634,23 +3598,7 @@ pub enum Statement { /// CREATE POLICY /// ``` /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html) - CreatePolicy { - /// Name of the policy. - name: Ident, - /// Table the policy is defined on. - #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))] - table_name: ObjectName, - /// Optional policy type (e.g., `PERMISSIVE` / `RESTRICTIVE`). - policy_type: Option, - /// Optional command the policy applies to (e.g., `SELECT`). - command: Option, - /// Optional list of grantee owners. - to: Option>, - /// Optional expression for the `USING` clause. - using: Option, - /// Optional expression for the `WITH CHECK` clause. - with_check: Option, - }, + CreatePolicy(CreatePolicy), /// ```sql /// CREATE CONNECTOR /// ``` @@ -3736,15 +3684,7 @@ pub enum Statement { /// ALTER POLICY ON
[] /// ``` /// (Postgresql-specific) - AlterPolicy { - /// Policy name to alter. - name: Ident, - /// Target table name the policy is defined on. - #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))] - table_name: ObjectName, - /// Optional operation specific to the policy alteration. - operation: AlterPolicyOperation, - }, + AlterPolicy(AlterPolicy), /// ```sql /// ALTER CONNECTOR connector_name SET DCPROPERTIES(property_name=property_value, ...); /// or @@ -3881,16 +3821,7 @@ pub enum Statement { /// DROP POLICY /// ``` /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-droppolicy.html) - DropPolicy { - /// `true` when `IF EXISTS` was present. - if_exists: bool, - /// Name of the policy to drop. - name: Ident, - /// Name of the table the policy applies to. - table_name: ObjectName, - /// Optional drop behavior (`CASCADE` or `RESTRICT`). - drop_behavior: Option, - }, + DropPolicy(DropPolicy), /// ```sql /// DROP CONNECTOR /// ``` @@ -4389,22 +4320,7 @@ pub enum Statement { /// ```sql /// GRANT privileges ON objects TO grantees /// ``` - Grant { - /// Privileges being granted. - privileges: Privileges, - /// Optional objects the privileges apply to. - objects: Option, - /// List of grantees receiving the privileges. - grantees: Vec, - /// Whether `WITH GRANT OPTION` is present. - with_grant_option: bool, - /// Optional `AS GRANTOR` identifier. - as_grantor: Option, - /// Optional `GRANTED BY` identifier. - granted_by: Option, - /// Optional `CURRENT GRANTS` modifier. - current_grants: Option, - }, + Grant(Grant), /// ```sql /// DENY privileges ON object TO grantees /// ``` @@ -4412,18 +4328,7 @@ pub enum Statement { /// ```sql /// REVOKE privileges ON objects FROM grantees /// ``` - Revoke { - /// Privileges to revoke. - privileges: Privileges, - /// Optional objects from which to revoke. - objects: Option, - /// Grantees affected by the revoke. - grantees: Vec, - /// Optional `GRANTED BY` identifier. - granted_by: Option, - /// Optional `CASCADE`/`RESTRICT` behavior. - cascade: Option, - }, + Revoke(Revoke), /// ```sql /// DEALLOCATE [ PREPARE ] { name | ALL } /// ``` @@ -5406,48 +5311,7 @@ impl fmt::Display for Statement { Statement::CreateServer(stmt) => { write!(f, "{stmt}") } - Statement::CreatePolicy { - name, - table_name, - policy_type, - command, - to, - using, - with_check, - } => { - write!(f, "CREATE POLICY {name} ON {table_name}")?; - - if let Some(policy_type) = policy_type { - match policy_type { - CreatePolicyType::Permissive => write!(f, " AS PERMISSIVE")?, - CreatePolicyType::Restrictive => write!(f, " AS RESTRICTIVE")?, - } - } - - if let Some(command) = command { - match command { - CreatePolicyCommand::All => write!(f, " FOR ALL")?, - CreatePolicyCommand::Select => write!(f, " FOR SELECT")?, - CreatePolicyCommand::Insert => write!(f, " FOR INSERT")?, - CreatePolicyCommand::Update => write!(f, " FOR UPDATE")?, - CreatePolicyCommand::Delete => write!(f, " FOR DELETE")?, - } - } - - if let Some(to) = to { - write!(f, " TO {}", display_comma_separated(to))?; - } - - if let Some(using) = using { - write!(f, " USING ({using})")?; - } - - if let Some(with_check) = with_check { - write!(f, " WITH CHECK ({with_check})")?; - } - - Ok(()) - } + Statement::CreatePolicy(policy) => write!(f, "{policy}"), Statement::CreateConnector(create_connector) => create_connector.fmt(f), Statement::CreateOperator(create_operator) => create_operator.fmt(f), Statement::CreateOperatorFamily(create_operator_family) => { @@ -5486,13 +5350,7 @@ impl fmt::Display for Statement { Statement::AlterRole { name, operation } => { write!(f, "ALTER ROLE {name} {operation}") } - Statement::AlterPolicy { - name, - table_name, - operation, - } => { - write!(f, "ALTER POLICY {name} ON {table_name}{operation}") - } + Statement::AlterPolicy(alter_policy) => write!(f, "{alter_policy}"), Statement::AlterConnector { name, properties, @@ -5616,22 +5474,7 @@ impl fmt::Display for Statement { } Ok(()) } - Statement::DropPolicy { - if_exists, - name, - table_name, - drop_behavior, - } => { - write!(f, "DROP POLICY")?; - if *if_exists { - write!(f, " IF EXISTS")?; - } - write!(f, " {name} ON {table_name}")?; - if let Some(drop_behavior) = drop_behavior { - write!(f, " {drop_behavior}")?; - } - Ok(()) - } + Statement::DropPolicy(policy) => write!(f, "{policy}"), Statement::DropConnector { if_exists, name } => { write!( f, @@ -5899,55 +5742,9 @@ impl fmt::Display for Statement { } Ok(()) } - Statement::Grant { - privileges, - objects, - grantees, - with_grant_option, - as_grantor, - granted_by, - current_grants, - } => { - write!(f, "GRANT {privileges} ")?; - if let Some(objects) = objects { - write!(f, "ON {objects} ")?; - } - write!(f, "TO {}", display_comma_separated(grantees))?; - if *with_grant_option { - write!(f, " WITH GRANT OPTION")?; - } - if let Some(current_grants) = current_grants { - write!(f, " {current_grants}")?; - } - if let Some(grantor) = as_grantor { - write!(f, " AS {grantor}")?; - } - if let Some(grantor) = granted_by { - write!(f, " GRANTED BY {grantor}")?; - } - Ok(()) - } + Statement::Grant(grant) => write!(f, "{grant}"), Statement::Deny(s) => write!(f, "{s}"), - Statement::Revoke { - privileges, - objects, - grantees, - granted_by, - cascade, - } => { - write!(f, "REVOKE {privileges} ")?; - if let Some(objects) = objects { - write!(f, "ON {objects} ")?; - } - write!(f, "FROM {}", display_comma_separated(grantees))?; - if let Some(grantor) = granted_by { - write!(f, " GRANTED BY {grantor}")?; - } - if let Some(cascade) = cascade { - write!(f, " {cascade}")?; - } - Ok(()) - } + Statement::Revoke(revoke) => write!(f, "{revoke}"), Statement::Deallocate { name, prepare } => write!( f, "DEALLOCATE {prepare}{name}", diff --git a/src/parser/alter.rs b/src/parser/alter.rs index 8ef712ef7..c64c4a409 100644 --- a/src/parser/alter.rs +++ b/src/parser/alter.rs @@ -19,7 +19,7 @@ use super::{Parser, ParserError}; use crate::{ ast::{ helpers::key_value_options::{KeyValueOptions, KeyValueOptionsDelimiter}, - AlterConnectorOwner, AlterPolicyOperation, AlterRoleOperation, AlterUser, + AlterConnectorOwner, AlterPolicy, AlterPolicyOperation, AlterRoleOperation, AlterUser, AlterUserAddMfaMethodOtp, AlterUserAddRoleDelegation, AlterUserModifyMfaMethod, AlterUserPassword, AlterUserRemoveRoleDelegation, AlterUserSetPolicy, Expr, MfaMethodKind, Password, ResetConfig, RoleOption, SetConfigValue, Statement, UserPolicyKind, @@ -54,7 +54,7 @@ impl Parser<'_> { /// ``` /// /// [PostgreSQL](https://www.postgresql.org/docs/current/sql-alterpolicy.html) - pub fn parse_alter_policy(&mut self) -> Result { + pub fn parse_alter_policy(&mut self) -> Result { let name = self.parse_identifier()?; self.expect_keyword_is(Keyword::ON)?; let table_name = self.parse_object_name(false)?; @@ -62,7 +62,7 @@ impl Parser<'_> { if self.parse_keyword(Keyword::RENAME) { self.expect_keyword_is(Keyword::TO)?; let new_name = self.parse_identifier()?; - Ok(Statement::AlterPolicy { + Ok(AlterPolicy { name, table_name, operation: AlterPolicyOperation::Rename { new_name }, @@ -91,7 +91,7 @@ impl Parser<'_> { } else { None }; - Ok(Statement::AlterPolicy { + Ok(AlterPolicy { name, table_name, operation: AlterPolicyOperation::Apply { diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 276311431..5b8d85f9c 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -32,7 +32,6 @@ use recursion::RecursionCounter; use IsLateral::*; use IsOptional::*; -use crate::ast::Statement::CreatePolicy; use crate::ast::*; use crate::ast::{ comments, @@ -659,12 +658,12 @@ impl<'a> Parser<'a> { Keyword::SET => self.parse_set(), Keyword::SHOW => self.parse_show(), Keyword::USE => self.parse_use(), - Keyword::GRANT => self.parse_grant(), + Keyword::GRANT => self.parse_grant().map(Into::into), Keyword::DENY => { self.prev_token(); self.parse_deny() } - Keyword::REVOKE => self.parse_revoke(), + Keyword::REVOKE => self.parse_revoke().map(Into::into), Keyword::START => self.parse_start_transaction(), Keyword::BEGIN => self.parse_begin(), Keyword::END => self.parse_end(), @@ -4972,7 +4971,7 @@ impl<'a> Parser<'a> { self.parse_create_view(or_alter, or_replace, temporary, create_view_params) .map(Into::into) } else if self.parse_keyword(Keyword::POLICY) { - self.parse_create_policy() + self.parse_create_policy().map(Into::into) } else if self.parse_keyword(Keyword::EXTERNAL) { self.parse_create_external_table(or_replace).map(Into::into) } else if self.parse_keyword(Keyword::FUNCTION) { @@ -6621,7 +6620,7 @@ impl<'a> Parser<'a> { /// ``` /// /// [PostgreSQL Documentation](https://www.postgresql.org/docs/current/sql-createpolicy.html) - pub fn parse_create_policy(&mut self) -> Result { + pub fn parse_create_policy(&mut self) -> Result { let name = self.parse_identifier()?; self.expect_keyword_is(Keyword::ON)?; let table_name = self.parse_object_name(false)?; @@ -7053,7 +7052,7 @@ impl<'a> Parser<'a> { } else if self.parse_keyword(Keyword::FUNCTION) { return self.parse_drop_function().map(Into::into); } else if self.parse_keyword(Keyword::POLICY) { - return self.parse_drop_policy(); + return self.parse_drop_policy().map(Into::into); } else if self.parse_keyword(Keyword::CONNECTOR) { return self.parse_drop_connector(); } else if self.parse_keyword(Keyword::DOMAIN) { @@ -7144,13 +7143,13 @@ impl<'a> Parser<'a> { /// ``` /// /// [PostgreSQL Documentation](https://www.postgresql.org/docs/current/sql-droppolicy.html) - fn parse_drop_policy(&mut self) -> Result { + fn parse_drop_policy(&mut self) -> Result { let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]); let name = self.parse_identifier()?; self.expect_keyword_is(Keyword::ON)?; let table_name = self.parse_object_name(false)?; let drop_behavior = self.parse_optional_drop_behavior(); - Ok(Statement::DropPolicy { + Ok(DropPolicy { if_exists, name, table_name, @@ -10279,7 +10278,7 @@ impl<'a> Parser<'a> { } } Keyword::ROLE => self.parse_alter_role(), - Keyword::POLICY => self.parse_alter_policy(), + Keyword::POLICY => self.parse_alter_policy().map(Into::into), Keyword::CONNECTOR => self.parse_alter_connector(), Keyword::USER => self.parse_alter_user().map(Into::into), // unreachable because expect_one_of_keywords used above @@ -16157,7 +16156,7 @@ impl<'a> Parser<'a> { } /// Parse a GRANT statement. - pub fn parse_grant(&mut self) -> Result { + pub fn parse_grant(&mut self) -> Result { let (privileges, objects) = self.parse_grant_deny_revoke_privileges_objects()?; self.expect_keyword_is(Keyword::TO)?; @@ -16187,7 +16186,7 @@ impl<'a> Parser<'a> { None }; - Ok(Statement::Grant { + Ok(Grant { privileges, objects, grantees, @@ -16782,7 +16781,7 @@ impl<'a> Parser<'a> { } /// Parse a REVOKE statement - pub fn parse_revoke(&mut self) -> Result { + pub fn parse_revoke(&mut self) -> Result { let (privileges, objects) = self.parse_grant_deny_revoke_privileges_objects()?; self.expect_keyword_is(Keyword::FROM)?; @@ -16796,7 +16795,7 @@ impl<'a> Parser<'a> { let cascade = self.parse_cascade_option(); - Ok(Statement::Revoke { + Ok(Revoke { privileges, objects, grantees, diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 69524ff99..5be16f4aa 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -9605,14 +9605,14 @@ fn parse_drop_role() { fn parse_grant() { let sql = "GRANT SELECT, INSERT, UPDATE (shape, size), USAGE, DELETE, TRUNCATE, REFERENCES, TRIGGER, CONNECT, CREATE, EXECUTE, TEMPORARY, DROP ON abc, def TO xyz, m WITH GRANT OPTION GRANTED BY jj"; match verified_stmt(sql) { - Statement::Grant { + Statement::Grant(Grant { privileges, objects, grantees, with_grant_option, granted_by, .. - } => match (privileges, objects) { + }) => match (privileges, objects) { (Privileges::Actions(actions), Some(GrantObjects::Tables(objects))) => { assert_eq!( vec![ @@ -9657,13 +9657,13 @@ fn parse_grant() { let sql2 = "GRANT INSERT ON ALL TABLES IN SCHEMA public TO browser"; match verified_stmt(sql2) { - Statement::Grant { + Statement::Grant(Grant { privileges, objects, grantees, with_grant_option, .. - } => match (privileges, objects) { + }) => match (privileges, objects) { (Privileges::Actions(actions), Some(GrantObjects::AllTablesInSchema { schemas })) => { assert_eq!(vec![Action::Insert { columns: None }], actions); assert_eq_vec(&["public"], &schemas); @@ -9677,13 +9677,13 @@ fn parse_grant() { let sql3 = "GRANT USAGE, SELECT ON SEQUENCE p TO u"; match verified_stmt(sql3) { - Statement::Grant { + Statement::Grant(Grant { privileges, objects, grantees, granted_by, .. - } => match (privileges, objects, granted_by) { + }) => match (privileges, objects, granted_by) { (Privileges::Actions(actions), Some(GrantObjects::Sequences(objects)), None) => { assert_eq!( vec![Action::Usage, Action::Select { columns: None }], @@ -9699,7 +9699,7 @@ fn parse_grant() { let sql4 = "GRANT ALL PRIVILEGES ON aa, b TO z"; match verified_stmt(sql4) { - Statement::Grant { privileges, .. } => { + Statement::Grant(Grant { privileges, .. }) => { assert_eq!( Privileges::All { with_privileges_keyword: true @@ -9712,11 +9712,11 @@ fn parse_grant() { let sql5 = "GRANT ALL ON SCHEMA aa, b TO z"; match verified_stmt(sql5) { - Statement::Grant { + Statement::Grant(Grant { privileges, objects, .. - } => match (privileges, objects) { + }) => match (privileges, objects) { ( Privileges::All { with_privileges_keyword, @@ -9733,11 +9733,11 @@ fn parse_grant() { let sql6 = "GRANT USAGE ON ALL SEQUENCES IN SCHEMA bus TO a, beta WITH GRANT OPTION"; match verified_stmt(sql6) { - Statement::Grant { + Statement::Grant(Grant { privileges, objects, .. - } => match (privileges, objects) { + }) => match (privileges, objects) { ( Privileges::Actions(actions), Some(GrantObjects::AllSequencesInSchema { schemas }), @@ -9818,13 +9818,13 @@ fn parse_deny() { fn test_revoke() { let sql = "REVOKE ALL PRIVILEGES ON users, auth FROM analyst"; match verified_stmt(sql) { - Statement::Revoke { + Statement::Revoke(Revoke { privileges, objects: Some(GrantObjects::Tables(tables)), grantees, granted_by, cascade, - } => { + }) => { assert_eq!( Privileges::All { with_privileges_keyword: true @@ -9844,13 +9844,13 @@ fn test_revoke() { fn test_revoke_with_cascade() { let sql = "REVOKE ALL PRIVILEGES ON users, auth FROM analyst CASCADE"; match all_dialects_except(|d| d.is::()).verified_stmt(sql) { - Statement::Revoke { + Statement::Revoke(Revoke { privileges, objects: Some(GrantObjects::Tables(tables)), grantees, granted_by, cascade, - } => { + }) => { assert_eq!( Privileges::All { with_privileges_keyword: true @@ -13906,14 +13906,14 @@ fn test_create_policy() { WITH CHECK (1 = 1)"; match all_dialects().verified_stmt(sql) { - Statement::CreatePolicy { + Statement::CreatePolicy(CreatePolicy { name, table_name, to, using, with_check, .. - } => { + }) => { assert_eq!(name.to_string(), "my_policy"); assert_eq!(table_name.to_string(), "my_table"); assert_eq!( @@ -14014,12 +14014,12 @@ fn test_create_policy() { fn test_drop_policy() { let sql = "DROP POLICY IF EXISTS my_policy ON my_table RESTRICT"; match all_dialects().verified_stmt(sql) { - Statement::DropPolicy { + Statement::DropPolicy(DropPolicy { if_exists, name, table_name, drop_behavior, - } => { + }) => { assert_eq!(if_exists, true); assert_eq!(name.to_string(), "my_policy"); assert_eq!(table_name.to_string(), "my_table"); @@ -14054,12 +14054,12 @@ fn test_drop_policy() { #[test] fn test_alter_policy() { match verified_stmt("ALTER POLICY old_policy ON my_table RENAME TO new_policy") { - Statement::AlterPolicy { + Statement::AlterPolicy(AlterPolicy { name, table_name, operation, .. - } => { + }) => { assert_eq!(name.to_string(), "old_policy"); assert_eq!(table_name.to_string(), "my_table"); assert_eq!( @@ -14076,9 +14076,9 @@ fn test_alter_policy() { "ALTER POLICY my_policy ON my_table TO CURRENT_USER ", "USING ((SELECT c0)) WITH CHECK (c0 > 0)" )) { - Statement::AlterPolicy { + Statement::AlterPolicy(AlterPolicy { name, table_name, .. - } => { + }) => { assert_eq!(name.to_string(), "my_policy"); assert_eq!(table_name.to_string(), "my_table"); } diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs index 80aed5bfe..2c942798c 100644 --- a/tests/sqlparser_mysql.rs +++ b/tests/sqlparser_mysql.rs @@ -3805,7 +3805,7 @@ fn parse_bitstring_literal() { fn parse_grant() { let sql = "GRANT ALL ON *.* TO 'jeffrey'@'%'"; let stmt = mysql().verified_stmt(sql); - if let Statement::Grant { + if let Statement::Grant(Grant { privileges, objects, grantees, @@ -3813,7 +3813,7 @@ fn parse_grant() { as_grantor: _, granted_by, current_grants: _, - } = stmt + }) = stmt { assert_eq!( privileges, @@ -3851,13 +3851,13 @@ fn parse_grant() { fn parse_revoke() { let sql = "REVOKE ALL ON db1.* FROM 'jeffrey'@'%'"; let stmt = mysql_and_generic().verified_stmt(sql); - if let Statement::Revoke { + if let Statement::Revoke(Revoke { privileges, objects, grantees, granted_by, cascade, - } = stmt + }) = stmt { assert_eq!( privileges,