This is an automated email from the ASF dual-hosted git repository.

github-bot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git


The following commit(s) were added to refs/heads/main by this push:
     new ed1c4e2c Moved more structs outside of Statement to facilitate reuse 
(#2188)
ed1c4e2c is described below

commit ed1c4e2cee02cecc26cc0a2f3b860ae0a1526cdb
Author: Luca Cappelletti <[email protected]>
AuthorDate: Mon Feb 2 10:12:50 2026 +0100

    Moved more structs outside of Statement to facilitate reuse (#2188)
---
 src/ast/dcl.rs            | 101 ++++++++++++++++++-
 src/ast/ddl.rs            | 191 ++++++++++++++++++++++++++++++++++++
 src/ast/mod.rs            | 245 ++++------------------------------------------
 src/parser/alter.rs       |   8 +-
 src/parser/mod.rs         |  25 +++--
 tests/sqlparser_common.rs |  46 ++++-----
 tests/sqlparser_mysql.rs  |   8 +-
 7 files changed, 355 insertions(+), 269 deletions(-)

diff --git a/src/ast/dcl.rs b/src/ast/dcl.rs
index 7183bc3f..3c50a81c 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<GrantObjects>,
+    /// List of grantees receiving the privileges.
+    pub grantees: Vec<Grantee>,
+    /// Whether `WITH GRANT OPTION` is present.
+    pub with_grant_option: bool,
+    /// Optional `AS GRANTOR` identifier.
+    pub as_grantor: Option<Ident>,
+    /// Optional `GRANTED BY` identifier.
+    ///
+    /// 
[BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/dcl-statements)
+    pub granted_by: Option<Ident>,
+    /// Optional `CURRENT GRANTS` modifier.
+    ///
+    /// 
[Snowflake](https://docs.snowflake.com/en/sql-reference/sql/grant-privilege)
+    pub current_grants: Option<CurrentGrantsKind>,
+}
+
+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<Grant> 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<GrantObjects>,
+    /// Grantees affected by the revoke.
+    pub grantees: Vec<Grantee>,
+    /// Optional `GRANTED BY` identifier.
+    ///
+    /// 
[BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/dcl-statements)
+    pub granted_by: Option<Ident>,
+    /// Optional `CASCADE`/`RESTRICT` behavior.
+    pub cascade: Option<CascadeOption>,
+}
+
+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<Revoke> 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 1d0059db..0c4f93e6 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<CreatePolicyType>,
+    /// Optional command the policy applies to (e.g., `SELECT`).
+    pub command: Option<CreatePolicyCommand>,
+    /// Optional list of grantee owners.
+    pub to: Option<Vec<Owner>>,
+    /// Optional expression for the `USING` clause.
+    pub using: Option<Expr>,
+    /// Optional expression for the `WITH CHECK` clause.
+    pub with_check: Option<Expr>,
+}
+
+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<DropBehavior>,
+}
+
+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<CreatePolicy> for crate::ast::Statement {
+    fn from(v: CreatePolicy) -> Self {
+        crate::ast::Statement::CreatePolicy(v)
+    }
+}
+
+impl From<DropPolicy> for crate::ast::Statement {
+    fn from(v: DropPolicy) -> Self {
+        crate::ast::Statement::DropPolicy(v)
+    }
+}
+
+/// ALTER POLICY statement.
+///
+/// ```sql
+/// ALTER POLICY <NAME> ON <TABLE NAME> [<OPERATION>]
+/// ```
+/// (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<AlterPolicy> 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 f255e5f3..ce5a67e1 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<CreatePolicyType>,
-        /// Optional command the policy applies to (e.g., `SELECT`).
-        command: Option<CreatePolicyCommand>,
-        /// Optional list of grantee owners.
-        to: Option<Vec<Owner>>,
-        /// Optional expression for the `USING` clause.
-        using: Option<Expr>,
-        /// Optional expression for the `WITH CHECK` clause.
-        with_check: Option<Expr>,
-    },
+    CreatePolicy(CreatePolicy),
     /// ```sql
     /// CREATE CONNECTOR
     /// ```
@@ -3736,15 +3684,7 @@ pub enum Statement {
     /// ALTER POLICY <NAME> ON <TABLE NAME> [<OPERATION>]
     /// ```
     /// (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<DropBehavior>,
-    },
+    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<GrantObjects>,
-        /// List of grantees receiving the privileges.
-        grantees: Vec<Grantee>,
-        /// Whether `WITH GRANT OPTION` is present.
-        with_grant_option: bool,
-        /// Optional `AS GRANTOR` identifier.
-        as_grantor: Option<Ident>,
-        /// Optional `GRANTED BY` identifier.
-        granted_by: Option<Ident>,
-        /// Optional `CURRENT GRANTS` modifier.
-        current_grants: Option<CurrentGrantsKind>,
-    },
+    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<GrantObjects>,
-        /// Grantees affected by the revoke.
-        grantees: Vec<Grantee>,
-        /// Optional `GRANTED BY` identifier.
-        granted_by: Option<Ident>,
-        /// Optional `CASCADE`/`RESTRICT` behavior.
-        cascade: Option<CascadeOption>,
-    },
+    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 8ef712ef..c64c4a40 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<Statement, ParserError> {
+    pub fn parse_alter_policy(&mut self) -> Result<AlterPolicy, ParserError> {
         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 dbdce02d..4dc704ac 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,
@@ -658,12 +657,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(),
@@ -4971,7 +4970,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) {
@@ -6620,7 +6619,7 @@ impl<'a> Parser<'a> {
     /// ```
     ///
     /// [PostgreSQL 
Documentation](https://www.postgresql.org/docs/current/sql-createpolicy.html)
-    pub fn parse_create_policy(&mut self) -> Result<Statement, ParserError> {
+    pub fn parse_create_policy(&mut self) -> Result<CreatePolicy, ParserError> 
{
         let name = self.parse_identifier()?;
         self.expect_keyword_is(Keyword::ON)?;
         let table_name = self.parse_object_name(false)?;
@@ -7052,7 +7051,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) {
@@ -7143,13 +7142,13 @@ impl<'a> Parser<'a> {
     /// ```
     ///
     /// [PostgreSQL 
Documentation](https://www.postgresql.org/docs/current/sql-droppolicy.html)
-    fn parse_drop_policy(&mut self) -> Result<Statement, ParserError> {
+    fn parse_drop_policy(&mut self) -> Result<DropPolicy, ParserError> {
         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,
@@ -10278,7 +10277,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
@@ -16156,7 +16155,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse a GRANT statement.
-    pub fn parse_grant(&mut self) -> Result<Statement, ParserError> {
+    pub fn parse_grant(&mut self) -> Result<Grant, ParserError> {
         let (privileges, objects) = 
self.parse_grant_deny_revoke_privileges_objects()?;
 
         self.expect_keyword_is(Keyword::TO)?;
@@ -16186,7 +16185,7 @@ impl<'a> Parser<'a> {
             None
         };
 
-        Ok(Statement::Grant {
+        Ok(Grant {
             privileges,
             objects,
             grantees,
@@ -16781,7 +16780,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse a REVOKE statement
-    pub fn parse_revoke(&mut self) -> Result<Statement, ParserError> {
+    pub fn parse_revoke(&mut self) -> Result<Revoke, ParserError> {
         let (privileges, objects) = 
self.parse_grant_deny_revoke_privileges_objects()?;
 
         self.expect_keyword_is(Keyword::FROM)?;
@@ -16795,7 +16794,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 69524ff9..5be16f4a 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::<MySqlDialect>()).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 80aed5bf..2c942798 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,


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to