sqlparser/ast/
dcl.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5// http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12
13//! AST types specific to GRANT/REVOKE/ROLE variants of [`Statement`](crate::ast::Statement)
14//! (commonly referred to as Data Control Language, or DCL)
15
16#[cfg(not(feature = "std"))]
17use alloc::vec::Vec;
18use core::fmt;
19
20#[cfg(feature = "serde")]
21use serde::{Deserialize, Serialize};
22
23#[cfg(feature = "visitor")]
24use sqlparser_derive::{Visit, VisitMut};
25
26use super::{Expr, Ident, Password};
27use crate::ast::{display_separated, ObjectName};
28
29/// An option in `ROLE` statement.
30///
31/// <https://www.postgresql.org/docs/current/sql-createrole.html>
32#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
33#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
34#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
35pub enum RoleOption {
36    BypassRLS(bool),
37    ConnectionLimit(Expr),
38    CreateDB(bool),
39    CreateRole(bool),
40    Inherit(bool),
41    Login(bool),
42    Password(Password),
43    Replication(bool),
44    SuperUser(bool),
45    ValidUntil(Expr),
46}
47
48impl fmt::Display for RoleOption {
49    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
50        match self {
51            RoleOption::BypassRLS(value) => {
52                write!(f, "{}", if *value { "BYPASSRLS" } else { "NOBYPASSRLS" })
53            }
54            RoleOption::ConnectionLimit(expr) => {
55                write!(f, "CONNECTION LIMIT {expr}")
56            }
57            RoleOption::CreateDB(value) => {
58                write!(f, "{}", if *value { "CREATEDB" } else { "NOCREATEDB" })
59            }
60            RoleOption::CreateRole(value) => {
61                write!(f, "{}", if *value { "CREATEROLE" } else { "NOCREATEROLE" })
62            }
63            RoleOption::Inherit(value) => {
64                write!(f, "{}", if *value { "INHERIT" } else { "NOINHERIT" })
65            }
66            RoleOption::Login(value) => {
67                write!(f, "{}", if *value { "LOGIN" } else { "NOLOGIN" })
68            }
69            RoleOption::Password(password) => match password {
70                Password::Password(expr) => write!(f, "PASSWORD {expr}"),
71                Password::NullPassword => write!(f, "PASSWORD NULL"),
72            },
73            RoleOption::Replication(value) => {
74                write!(
75                    f,
76                    "{}",
77                    if *value {
78                        "REPLICATION"
79                    } else {
80                        "NOREPLICATION"
81                    }
82                )
83            }
84            RoleOption::SuperUser(value) => {
85                write!(f, "{}", if *value { "SUPERUSER" } else { "NOSUPERUSER" })
86            }
87            RoleOption::ValidUntil(expr) => {
88                write!(f, "VALID UNTIL {expr}")
89            }
90        }
91    }
92}
93
94/// SET config value option:
95/// * SET `configuration_parameter` { TO | = } { `value` | DEFAULT }
96/// * SET `configuration_parameter` FROM CURRENT
97#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
98#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
99#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
100pub enum SetConfigValue {
101    Default,
102    FromCurrent,
103    Value(Expr),
104}
105
106/// RESET config option:
107/// * RESET `configuration_parameter`
108/// * RESET ALL
109#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
110#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
111#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
112pub enum ResetConfig {
113    ALL,
114    ConfigName(ObjectName),
115}
116
117/// An `ALTER ROLE` (`Statement::AlterRole`) operation
118#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
119#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
120#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
121pub enum AlterRoleOperation {
122    /// Generic
123    RenameRole {
124        role_name: Ident,
125    },
126    /// MS SQL Server
127    /// <https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-role-transact-sql>
128    AddMember {
129        member_name: Ident,
130    },
131    DropMember {
132        member_name: Ident,
133    },
134    /// PostgreSQL
135    /// <https://www.postgresql.org/docs/current/sql-alterrole.html>
136    WithOptions {
137        options: Vec<RoleOption>,
138    },
139    Set {
140        config_name: ObjectName,
141        config_value: SetConfigValue,
142        in_database: Option<ObjectName>,
143    },
144    Reset {
145        config_name: ResetConfig,
146        in_database: Option<ObjectName>,
147    },
148}
149
150impl fmt::Display for AlterRoleOperation {
151    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
152        match self {
153            AlterRoleOperation::RenameRole { role_name } => {
154                write!(f, "RENAME TO {role_name}")
155            }
156            AlterRoleOperation::AddMember { member_name } => {
157                write!(f, "ADD MEMBER {member_name}")
158            }
159            AlterRoleOperation::DropMember { member_name } => {
160                write!(f, "DROP MEMBER {member_name}")
161            }
162            AlterRoleOperation::WithOptions { options } => {
163                write!(f, "WITH {}", display_separated(options, " "))
164            }
165            AlterRoleOperation::Set {
166                config_name,
167                config_value,
168                in_database,
169            } => {
170                if let Some(database_name) = in_database {
171                    write!(f, "IN DATABASE {} ", database_name)?;
172                }
173
174                match config_value {
175                    SetConfigValue::Default => write!(f, "SET {config_name} TO DEFAULT"),
176                    SetConfigValue::FromCurrent => write!(f, "SET {config_name} FROM CURRENT"),
177                    SetConfigValue::Value(expr) => write!(f, "SET {config_name} TO {expr}"),
178                }
179            }
180            AlterRoleOperation::Reset {
181                config_name,
182                in_database,
183            } => {
184                if let Some(database_name) = in_database {
185                    write!(f, "IN DATABASE {} ", database_name)?;
186                }
187
188                match config_name {
189                    ResetConfig::ALL => write!(f, "RESET ALL"),
190                    ResetConfig::ConfigName(name) => write!(f, "RESET {name}"),
191                }
192            }
193        }
194    }
195}