1use std::fmt::Display;
16use std::fmt::Formatter;
17
18use derive_visitor::Drive;
19use derive_visitor::DriveMut;
20
21use crate::ast::write_comma_separated_list;
22use crate::ast::AuthType;
23use crate::ast::CreateOption;
24use crate::ast::PrincipalIdentity;
25use crate::ast::ShowOptions;
26use crate::ast::UserIdentity;
27use crate::ast::UserPrivilegeType;
28
29#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
30pub struct CreateUserStmt {
31 pub create_option: CreateOption,
32 pub user: UserIdentity,
33 pub auth_option: AuthOption,
34 pub user_options: Vec<UserOptionItem>,
35}
36
37impl Display for CreateUserStmt {
38 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
39 write!(f, "CREATE")?;
40 if let CreateOption::CreateOrReplace = self.create_option {
41 write!(f, " OR REPLACE")?;
42 }
43 write!(f, " USER")?;
44 if let CreateOption::CreateIfNotExists = self.create_option {
45 write!(f, " IF NOT EXISTS")?;
46 }
47 write!(f, " {} IDENTIFIED", self.user)?;
48 write!(f, " {}", self.auth_option)?;
49 if !self.user_options.is_empty() {
50 write!(f, " WITH ")?;
51 write_comma_separated_list(f, &self.user_options)?;
52 }
53
54 Ok(())
55 }
56}
57
58#[derive(Debug, Clone, PartialEq, Eq, Default, Drive, DriveMut)]
59pub struct AuthOption {
60 pub auth_type: Option<AuthType>,
61 pub password: Option<String>,
62}
63
64impl Display for AuthOption {
65 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
66 if let Some(auth_type) = &self.auth_type {
67 write!(f, "WITH {auth_type} ")?;
68 }
69 if let Some(password) = &self.password {
70 write!(f, "BY '{password}'")?;
71 }
72
73 Ok(())
74 }
75}
76
77#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
78pub struct AlterUserStmt {
79 pub user: Option<UserIdentity>,
81 pub auth_option: Option<AuthOption>,
83 pub user_options: Vec<UserOptionItem>,
84}
85
86impl Display for AlterUserStmt {
87 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
88 write!(f, "ALTER USER")?;
89 if let Some(user) = &self.user {
90 write!(f, " {}", user)?;
91 } else {
92 write!(f, " USER()")?;
93 }
94 if let Some(auth_option) = &self.auth_option {
95 write!(f, " IDENTIFIED {}", auth_option)?;
96 }
97 if !self.user_options.is_empty() {
98 write!(f, " WITH ")?;
99 write_comma_separated_list(f, &self.user_options)?;
100 }
101
102 Ok(())
103 }
104}
105
106#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
107pub struct GrantStmt {
108 pub source: AccountMgrSource,
109 pub principal: PrincipalIdentity,
110}
111
112impl Display for GrantStmt {
113 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
114 write!(f, "GRANT")?;
115 write!(f, "{}", self.source)?;
116
117 write!(f, " TO")?;
118 write!(f, "{}", self.principal)
119 }
120}
121
122#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
123pub struct RevokeStmt {
124 pub source: AccountMgrSource,
125 pub principal: PrincipalIdentity,
126}
127
128impl Display for RevokeStmt {
129 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
130 write!(f, "REVOKE")?;
131 write!(f, "{}", self.source)?;
132
133 write!(f, " FROM")?;
134 write!(f, "{}", self.principal)
135 }
136}
137
138#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
139pub struct ShowGranteesOfRoleStmt {
140 pub name: String,
141 pub show_option: Option<ShowOptions>,
142}
143
144impl Display for ShowGranteesOfRoleStmt {
145 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
146 write!(f, "SHOW GRANTS OF ROLE {}", self.name)?;
147
148 if let Some(show_option) = &self.show_option {
149 write!(f, " {show_option}")?;
150 }
151 Ok(())
152 }
153}
154
155#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
156pub struct ShowObjectPrivilegesStmt {
157 pub object: GrantObjectName,
158 pub show_option: Option<ShowOptions>,
159}
160
161#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
162pub enum GrantObjectName {
163 Database(String),
164 Table(Option<String>, String),
165 UDF(String),
166 Stage(String),
167 Warehouse(String),
168 Connection(String),
169 Sequence(String),
170}
171
172impl Display for GrantObjectName {
173 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
174 match self {
175 GrantObjectName::Database(database_name) => {
176 write!(f, "DATABASE {database_name}")
177 }
178 GrantObjectName::Table(database_name, table_name) => {
179 if let Some(database_name) = database_name {
180 write!(f, "TABLE {database_name}.{table_name}")
181 } else {
182 write!(f, "TABLE {table_name}")
183 }
184 }
185 GrantObjectName::UDF(udf) => write!(f, " UDF {udf}"),
186 GrantObjectName::Stage(stage) => write!(f, " STAGE {stage}"),
187 GrantObjectName::Warehouse(w) => write!(f, " WAREHOUSE {w}"),
188 GrantObjectName::Connection(c) => write!(f, " CONNECTION {c}"),
189 GrantObjectName::Sequence(s) => write!(f, " SEQUENCE {s}"),
190 }
191 }
192}
193
194impl Display for ShowObjectPrivilegesStmt {
195 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
196 write!(f, "SHOW GRANTS ON {}", self.object)?;
197
198 if let Some(show_option) = &self.show_option {
199 write!(f, " {show_option}")?;
200 }
201 Ok(())
202 }
203}
204
205#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
206pub enum AccountMgrSource {
207 Role {
208 role: String,
209 },
210 Privs {
211 privileges: Vec<UserPrivilegeType>,
212 level: AccountMgrLevel,
213 },
214 ALL {
215 level: AccountMgrLevel,
216 },
217}
218
219impl Display for AccountMgrSource {
220 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
221 match self {
222 AccountMgrSource::Role { role } => write!(f, " ROLE '{role}'")?,
223 AccountMgrSource::Privs { privileges, level } => {
224 write!(f, " ")?;
225 write_comma_separated_list(f, privileges.iter().map(|p| p.to_string()))?;
226 write!(f, " ON")?;
227 write!(f, " {}", level)?;
228 }
229 AccountMgrSource::ALL { level, .. } => {
230 write!(f, " ALL PRIVILEGES")?;
231 write!(f, " ON")?;
232 write!(f, " {}", level)?;
233 }
234 }
235 Ok(())
236 }
237}
238
239#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
240pub enum AccountMgrLevel {
241 Global,
242 Database(Option<String>),
243 Table(Option<String>, String),
244 UDF(String),
245 Stage(String),
246 Warehouse(String),
247 Connection(String),
248 Sequence(String),
249}
250
251impl Display for AccountMgrLevel {
252 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
253 match self {
254 AccountMgrLevel::Global => write!(f, " *.*"),
255 AccountMgrLevel::Database(database_name) => {
256 if let Some(database_name) = database_name {
257 write!(f, " {database_name}.*")
258 } else {
259 write!(f, " *")
260 }
261 }
262 AccountMgrLevel::Table(database_name, table_name) => {
263 if let Some(database_name) = database_name {
264 write!(f, " {database_name}.{table_name}")
265 } else {
266 write!(f, " {table_name}")
267 }
268 }
269 AccountMgrLevel::UDF(udf) => write!(f, " UDF {udf}"),
270 AccountMgrLevel::Stage(stage) => write!(f, " STAGE {stage}"),
271 AccountMgrLevel::Warehouse(w) => write!(f, " WAREHOUSE {w}"),
272 AccountMgrLevel::Connection(c) => write!(f, " CONNECTION {c}"),
273 AccountMgrLevel::Sequence(s) => write!(f, " SEQUENCE {s}"),
274 }
275 }
276}
277
278#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
279pub enum SecondaryRolesOption {
280 None,
281 All,
282 SpecifyRole(Vec<String>),
283}
284
285#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
286pub enum UserOptionItem {
287 TenantSetting(bool),
288 DefaultRole(String),
289 Disabled(bool),
290 SetNetworkPolicy(String),
291 UnsetNetworkPolicy,
292 SetPasswordPolicy(String),
293 UnsetPasswordPolicy,
294 MustChangePassword(bool),
295 SetWorkloadGroup(String),
296 UnsetWorkloadGroup,
297}
298
299impl Display for UserOptionItem {
300 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
301 match self {
302 UserOptionItem::TenantSetting(true) => write!(f, "TENANTSETTING"),
303 UserOptionItem::TenantSetting(false) => write!(f, "NOTENANTSETTING"),
304 UserOptionItem::DefaultRole(v) => write!(f, "DEFAULT_ROLE = '{}'", v),
305 UserOptionItem::SetNetworkPolicy(v) => write!(f, "SET NETWORK POLICY = '{}'", v),
306 UserOptionItem::UnsetNetworkPolicy => write!(f, "UNSET NETWORK POLICY"),
307 UserOptionItem::SetPasswordPolicy(v) => write!(f, "SET PASSWORD POLICY = '{}'", v),
308 UserOptionItem::SetWorkloadGroup(v) => write!(f, "SET WORKLOAD GROUP = '{}'", v),
309 UserOptionItem::UnsetWorkloadGroup => write!(f, "UNSET WORKLOAD GROUP"),
310 UserOptionItem::UnsetPasswordPolicy => write!(f, "UNSET PASSWORD POLICY"),
311 UserOptionItem::Disabled(v) => write!(f, "DISABLED = {}", v),
312 UserOptionItem::MustChangePassword(v) => write!(f, "MUST_CHANGE_PASSWORD = {}", v),
313 }
314 }
315}