Skip to content

Commit ef260ca

Browse files
Moved CreateRole struct out of the Statement enum
1 parent 94f3b1b commit ef260ca

File tree

8 files changed

+167
-212
lines changed

8 files changed

+167
-212
lines changed

src/ast/dcl.rs

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ use serde::{Deserialize, Serialize};
2828
#[cfg(feature = "visitor")]
2929
use sqlparser_derive::{Visit, VisitMut};
3030

31-
use super::{display_comma_separated, Expr, Ident, Password};
31+
use super::{display_comma_separated, Expr, Ident, Password, Spanned};
3232
use crate::ast::{display_separated, ObjectName};
33+
use crate::tokenizer::Span;
3334

3435
/// An option in `ROLE` statement.
3536
///
@@ -252,3 +253,113 @@ impl fmt::Display for SecondaryRoles {
252253
}
253254
}
254255
}
256+
257+
/// CREATE ROLE statement
258+
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createrole.html)
259+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
260+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
261+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
262+
pub struct CreateRole {
263+
pub names: Vec<ObjectName>,
264+
pub if_not_exists: bool,
265+
// Postgres
266+
pub login: Option<bool>,
267+
pub inherit: Option<bool>,
268+
pub bypassrls: Option<bool>,
269+
pub password: Option<Password>,
270+
pub superuser: Option<bool>,
271+
pub create_db: Option<bool>,
272+
pub create_role: Option<bool>,
273+
pub replication: Option<bool>,
274+
pub connection_limit: Option<Expr>,
275+
pub valid_until: Option<Expr>,
276+
pub in_role: Vec<Ident>,
277+
pub in_group: Vec<Ident>,
278+
pub role: Vec<Ident>,
279+
pub user: Vec<Ident>,
280+
pub admin: Vec<Ident>,
281+
// MSSQL
282+
pub authorization_owner: Option<ObjectName>,
283+
}
284+
285+
impl fmt::Display for CreateRole {
286+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
287+
write!(
288+
f,
289+
"CREATE ROLE {if_not_exists}{names}{superuser}{create_db}{create_role}{inherit}{login}{replication}{bypassrls}",
290+
if_not_exists = if self.if_not_exists { "IF NOT EXISTS " } else { "" },
291+
names = display_separated(&self.names, ", "),
292+
superuser = match self.superuser {
293+
Some(true) => " SUPERUSER",
294+
Some(false) => " NOSUPERUSER",
295+
None => ""
296+
},
297+
create_db = match self.create_db {
298+
Some(true) => " CREATEDB",
299+
Some(false) => " NOCREATEDB",
300+
None => ""
301+
},
302+
create_role = match self.create_role {
303+
Some(true) => " CREATEROLE",
304+
Some(false) => " NOCREATEROLE",
305+
None => ""
306+
},
307+
inherit = match self.inherit {
308+
Some(true) => " INHERIT",
309+
Some(false) => " NOINHERIT",
310+
None => ""
311+
},
312+
login = match self.login {
313+
Some(true) => " LOGIN",
314+
Some(false) => " NOLOGIN",
315+
None => ""
316+
},
317+
replication = match self.replication {
318+
Some(true) => " REPLICATION",
319+
Some(false) => " NOREPLICATION",
320+
None => ""
321+
},
322+
bypassrls = match self.bypassrls {
323+
Some(true) => " BYPASSRLS",
324+
Some(false) => " NOBYPASSRLS",
325+
None => ""
326+
}
327+
)?;
328+
if let Some(limit) = &self.connection_limit {
329+
write!(f, " CONNECTION LIMIT {limit}")?;
330+
}
331+
match &self.password {
332+
Some(Password::Password(pass)) => write!(f, " PASSWORD {pass}")?,
333+
Some(Password::NullPassword) => write!(f, " PASSWORD NULL")?,
334+
None => {}
335+
};
336+
if let Some(until) = &self.valid_until {
337+
write!(f, " VALID UNTIL {until}")?;
338+
}
339+
if !self.in_role.is_empty() {
340+
write!(f, " IN ROLE {}", display_comma_separated(&self.in_role))?;
341+
}
342+
if !self.in_group.is_empty() {
343+
write!(f, " IN GROUP {}", display_comma_separated(&self.in_group))?;
344+
}
345+
if !self.role.is_empty() {
346+
write!(f, " ROLE {}", display_comma_separated(&self.role))?;
347+
}
348+
if !self.user.is_empty() {
349+
write!(f, " USER {}", display_comma_separated(&self.user))?;
350+
}
351+
if !self.admin.is_empty() {
352+
write!(f, " ADMIN {}", display_comma_separated(&self.admin))?;
353+
}
354+
if let Some(owner) = &self.authorization_owner {
355+
write!(f, " AUTHORIZATION {owner}")?;
356+
}
357+
Ok(())
358+
}
359+
}
360+
361+
impl Spanned for CreateRole {
362+
fn span(&self) -> Span {
363+
Span::empty()
364+
}
365+
}

src/ast/ddl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
//! (commonly referred to as Data Definition Language, or DDL)
2020
2121
#[cfg(not(feature = "std"))]
22-
use alloc::{boxed::Box, string::String, vec::Vec};
22+
use alloc::{boxed::Box, format, string::String, vec, vec::Vec};
2323
use core::fmt::{self, Display, Write};
2424

2525
#[cfg(feature = "serde")]

src/ast/mod.rs

Lines changed: 9 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub use self::data_type::{
5656
ExactNumberInfo, IntervalFields, StructBracketKind, TimezoneInfo,
5757
};
5858
pub use self::dcl::{
59-
AlterRoleOperation, ResetConfig, RoleOption, SecondaryRoles, SetConfigValue, Use,
59+
AlterRoleOperation, CreateRole, ResetConfig, RoleOption, SecondaryRoles, SetConfigValue, Use,
6060
};
6161
pub use self::ddl::{
6262
AlterColumnOperation, AlterConnectorOwner, AlterIndexOperation, AlterPolicyOperation,
@@ -3273,28 +3273,7 @@ pub enum Statement {
32733273
/// CREATE ROLE
32743274
/// ```
32753275
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createrole.html)
3276-
CreateRole {
3277-
names: Vec<ObjectName>,
3278-
if_not_exists: bool,
3279-
// Postgres
3280-
login: Option<bool>,
3281-
inherit: Option<bool>,
3282-
bypassrls: Option<bool>,
3283-
password: Option<Password>,
3284-
superuser: Option<bool>,
3285-
create_db: Option<bool>,
3286-
create_role: Option<bool>,
3287-
replication: Option<bool>,
3288-
connection_limit: Option<Expr>,
3289-
valid_until: Option<Expr>,
3290-
in_role: Vec<Ident>,
3291-
in_group: Vec<Ident>,
3292-
role: Vec<Ident>,
3293-
user: Vec<Ident>,
3294-
admin: Vec<Ident>,
3295-
// MSSQL
3296-
authorization_owner: Option<ObjectName>,
3297-
},
3276+
CreateRole(CreateRole),
32983277
/// ```sql
32993278
/// CREATE SECRET
33003279
/// ```
@@ -4870,98 +4849,7 @@ impl fmt::Display for Statement {
48704849
}
48714850
Ok(())
48724851
}
4873-
Statement::CreateRole {
4874-
names,
4875-
if_not_exists,
4876-
inherit,
4877-
login,
4878-
bypassrls,
4879-
password,
4880-
create_db,
4881-
create_role,
4882-
superuser,
4883-
replication,
4884-
connection_limit,
4885-
valid_until,
4886-
in_role,
4887-
in_group,
4888-
role,
4889-
user,
4890-
admin,
4891-
authorization_owner,
4892-
} => {
4893-
write!(
4894-
f,
4895-
"CREATE ROLE {if_not_exists}{names}{superuser}{create_db}{create_role}{inherit}{login}{replication}{bypassrls}",
4896-
if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
4897-
names = display_separated(names, ", "),
4898-
superuser = match *superuser {
4899-
Some(true) => " SUPERUSER",
4900-
Some(false) => " NOSUPERUSER",
4901-
None => ""
4902-
},
4903-
create_db = match *create_db {
4904-
Some(true) => " CREATEDB",
4905-
Some(false) => " NOCREATEDB",
4906-
None => ""
4907-
},
4908-
create_role = match *create_role {
4909-
Some(true) => " CREATEROLE",
4910-
Some(false) => " NOCREATEROLE",
4911-
None => ""
4912-
},
4913-
inherit = match *inherit {
4914-
Some(true) => " INHERIT",
4915-
Some(false) => " NOINHERIT",
4916-
None => ""
4917-
},
4918-
login = match *login {
4919-
Some(true) => " LOGIN",
4920-
Some(false) => " NOLOGIN",
4921-
None => ""
4922-
},
4923-
replication = match *replication {
4924-
Some(true) => " REPLICATION",
4925-
Some(false) => " NOREPLICATION",
4926-
None => ""
4927-
},
4928-
bypassrls = match *bypassrls {
4929-
Some(true) => " BYPASSRLS",
4930-
Some(false) => " NOBYPASSRLS",
4931-
None => ""
4932-
}
4933-
)?;
4934-
if let Some(limit) = connection_limit {
4935-
write!(f, " CONNECTION LIMIT {limit}")?;
4936-
}
4937-
match password {
4938-
Some(Password::Password(pass)) => write!(f, " PASSWORD {pass}"),
4939-
Some(Password::NullPassword) => write!(f, " PASSWORD NULL"),
4940-
None => Ok(()),
4941-
}?;
4942-
if let Some(until) = valid_until {
4943-
write!(f, " VALID UNTIL {until}")?;
4944-
}
4945-
if !in_role.is_empty() {
4946-
write!(f, " IN ROLE {}", display_comma_separated(in_role))?;
4947-
}
4948-
if !in_group.is_empty() {
4949-
write!(f, " IN GROUP {}", display_comma_separated(in_group))?;
4950-
}
4951-
if !role.is_empty() {
4952-
write!(f, " ROLE {}", display_comma_separated(role))?;
4953-
}
4954-
if !user.is_empty() {
4955-
write!(f, " USER {}", display_comma_separated(user))?;
4956-
}
4957-
if !admin.is_empty() {
4958-
write!(f, " ADMIN {}", display_comma_separated(admin))?;
4959-
}
4960-
if let Some(owner) = authorization_owner {
4961-
write!(f, " AUTHORIZATION {owner}")?;
4962-
}
4963-
Ok(())
4964-
}
4852+
Statement::CreateRole(create_role) => write!(f, "{create_role}"),
49654853
Statement::CreateSecret {
49664854
or_replace,
49674855
temporary,
@@ -10728,6 +10616,12 @@ impl From<CreateView> for Statement {
1072810616
}
1072910617
}
1073010618

10619+
impl From<CreateRole> for Statement {
10620+
fn from(cr: CreateRole) -> Self {
10621+
Self::CreateRole(cr)
10622+
}
10623+
}
10624+
1073110625
impl From<CaseStatement> for Statement {
1073210626
fn from(c: CaseStatement) -> Self {
1073310627
Self::Case(c)

src/ast/spans.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ impl Spanned for Statement {
361361
.chain(module_args.iter().map(|i| i.span)),
362362
),
363363
Statement::CreateIndex(create_index) => create_index.span(),
364-
Statement::CreateRole { .. } => Span::empty(),
364+
Statement::CreateRole(create_role) => create_role.span(),
365365
Statement::CreateSecret { .. } => Span::empty(),
366366
Statement::CreateServer { .. } => Span::empty(),
367367
Statement::CreateConnector { .. } => Span::empty(),

src/parser/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6210,7 +6210,7 @@ impl<'a> Parser<'a> {
62106210
}?
62116211
}
62126212

6213-
Ok(Statement::CreateRole {
6213+
Ok(CreateRole {
62146214
names,
62156215
if_not_exists,
62166216
login,
@@ -6229,7 +6229,8 @@ impl<'a> Parser<'a> {
62296229
user,
62306230
admin,
62316231
authorization_owner,
6232-
})
6232+
}
6233+
.into())
62336234
}
62346235

62356236
pub fn parse_owner(&mut self) -> Result<Owner, ParserError> {

tests/sqlparser_common.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9406,21 +9406,17 @@ fn parse_drop_index() {
94069406
fn parse_create_role() {
94079407
let sql = "CREATE ROLE consultant";
94089408
match verified_stmt(sql) {
9409-
Statement::CreateRole { names, .. } => {
9410-
assert_eq_vec(&["consultant"], &names);
9409+
Statement::CreateRole(create_role) => {
9410+
assert_eq_vec(&["consultant"], &create_role.names);
94119411
}
94129412
_ => unreachable!(),
94139413
}
94149414

94159415
let sql = "CREATE ROLE IF NOT EXISTS mysql_a, mysql_b";
94169416
match verified_stmt(sql) {
9417-
Statement::CreateRole {
9418-
names,
9419-
if_not_exists,
9420-
..
9421-
} => {
9422-
assert_eq_vec(&["mysql_a", "mysql_b"], &names);
9423-
assert!(if_not_exists);
9417+
Statement::CreateRole(create_role) => {
9418+
assert_eq_vec(&["mysql_a", "mysql_b"], &create_role.names);
9419+
assert!(create_role.if_not_exists);
94249420
}
94259421
_ => unreachable!(),
94269422
}

tests/sqlparser_mssql.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -772,14 +772,10 @@ fn parse_mssql_bin_literal() {
772772
fn parse_mssql_create_role() {
773773
let sql = "CREATE ROLE mssql AUTHORIZATION helena";
774774
match ms().verified_stmt(sql) {
775-
Statement::CreateRole {
776-
names,
777-
authorization_owner,
778-
..
779-
} => {
780-
assert_eq_vec(&["mssql"], &names);
775+
Statement::CreateRole(create_role) => {
776+
assert_eq_vec(&["mssql"], &create_role.names);
781777
assert_eq!(
782-
authorization_owner,
778+
create_role.authorization_owner,
783779
Some(ObjectName::from(vec![Ident {
784780
value: "helena".into(),
785781
quote_style: None,

0 commit comments

Comments
 (0)