#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::fmt;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "visitor")]
use sqlparser_derive::{Visit, VisitMut};
use super::{display_comma_separated, Expr, Ident, Password, Spanned};
use crate::ast::{
display_separated, CascadeOption, CurrentGrantsKind, GrantObjects, Grantee, ObjectName,
Privileges,
};
use crate::tokenizer::Span;
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum RoleOption {
BypassRLS(bool),
ConnectionLimit(Expr),
CreateDB(bool),
CreateRole(bool),
Inherit(bool),
Login(bool),
Password(Password),
Replication(bool),
SuperUser(bool),
ValidUntil(Expr),
}
impl fmt::Display for RoleOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
RoleOption::BypassRLS(value) => {
write!(f, "{}", if *value { "BYPASSRLS" } else { "NOBYPASSRLS" })
}
RoleOption::ConnectionLimit(expr) => {
write!(f, "CONNECTION LIMIT {expr}")
}
RoleOption::CreateDB(value) => {
write!(f, "{}", if *value { "CREATEDB" } else { "NOCREATEDB" })
}
RoleOption::CreateRole(value) => {
write!(f, "{}", if *value { "CREATEROLE" } else { "NOCREATEROLE" })
}
RoleOption::Inherit(value) => {
write!(f, "{}", if *value { "INHERIT" } else { "NOINHERIT" })
}
RoleOption::Login(value) => {
write!(f, "{}", if *value { "LOGIN" } else { "NOLOGIN" })
}
RoleOption::Password(password) => match password {
Password::Password(expr) => write!(f, "PASSWORD {expr}"),
Password::NullPassword => write!(f, "PASSWORD NULL"),
},
RoleOption::Replication(value) => {
write!(
f,
"{}",
if *value {
"REPLICATION"
} else {
"NOREPLICATION"
}
)
}
RoleOption::SuperUser(value) => {
write!(f, "{}", if *value { "SUPERUSER" } else { "NOSUPERUSER" })
}
RoleOption::ValidUntil(expr) => {
write!(f, "VALID UNTIL {expr}")
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum SetConfigValue {
Default,
FromCurrent,
Value(Expr),
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ResetConfig {
ALL,
ConfigName(ObjectName),
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterRoleOperation {
RenameRole {
role_name: Ident,
},
AddMember {
member_name: Ident,
},
DropMember {
member_name: Ident,
},
WithOptions {
options: Vec<RoleOption>,
},
Set {
config_name: ObjectName,
config_value: SetConfigValue,
in_database: Option<ObjectName>,
},
Reset {
config_name: ResetConfig,
in_database: Option<ObjectName>,
},
}
impl fmt::Display for AlterRoleOperation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AlterRoleOperation::RenameRole { role_name } => {
write!(f, "RENAME TO {role_name}")
}
AlterRoleOperation::AddMember { member_name } => {
write!(f, "ADD MEMBER {member_name}")
}
AlterRoleOperation::DropMember { member_name } => {
write!(f, "DROP MEMBER {member_name}")
}
AlterRoleOperation::WithOptions { options } => {
write!(f, "WITH {}", display_separated(options, " "))
}
AlterRoleOperation::Set {
config_name,
config_value,
in_database,
} => {
if let Some(database_name) = in_database {
write!(f, "IN DATABASE {database_name} ")?;
}
match config_value {
SetConfigValue::Default => write!(f, "SET {config_name} TO DEFAULT"),
SetConfigValue::FromCurrent => write!(f, "SET {config_name} FROM CURRENT"),
SetConfigValue::Value(expr) => write!(f, "SET {config_name} TO {expr}"),
}
}
AlterRoleOperation::Reset {
config_name,
in_database,
} => {
if let Some(database_name) = in_database {
write!(f, "IN DATABASE {database_name} ")?;
}
match config_name {
ResetConfig::ALL => write!(f, "RESET ALL"),
ResetConfig::ConfigName(name) => write!(f, "RESET {name}"),
}
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum Use {
Catalog(ObjectName),
Schema(ObjectName),
Database(ObjectName),
Warehouse(ObjectName),
Role(ObjectName),
SecondaryRoles(SecondaryRoles),
Object(ObjectName),
Default,
}
impl fmt::Display for Use {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("USE ")?;
match self {
Use::Catalog(name) => write!(f, "CATALOG {name}"),
Use::Schema(name) => write!(f, "SCHEMA {name}"),
Use::Database(name) => write!(f, "DATABASE {name}"),
Use::Warehouse(name) => write!(f, "WAREHOUSE {name}"),
Use::Role(name) => write!(f, "ROLE {name}"),
Use::SecondaryRoles(secondary_roles) => {
write!(f, "SECONDARY ROLES {secondary_roles}")
}
Use::Object(name) => write!(f, "{name}"),
Use::Default => write!(f, "DEFAULT"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum SecondaryRoles {
All,
None,
List(Vec<Ident>),
}
impl fmt::Display for SecondaryRoles {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
SecondaryRoles::All => write!(f, "ALL"),
SecondaryRoles::None => write!(f, "NONE"),
SecondaryRoles::List(roles) => write!(f, "{}", display_comma_separated(roles)),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreateRole {
pub names: Vec<ObjectName>,
pub if_not_exists: bool,
pub login: Option<bool>,
pub inherit: Option<bool>,
pub bypassrls: Option<bool>,
pub password: Option<Password>,
pub superuser: Option<bool>,
pub create_db: Option<bool>,
pub create_role: Option<bool>,
pub replication: Option<bool>,
pub connection_limit: Option<Expr>,
pub valid_until: Option<Expr>,
pub in_role: Vec<Ident>,
pub in_group: Vec<Ident>,
pub role: Vec<Ident>,
pub user: Vec<Ident>,
pub admin: Vec<Ident>,
pub authorization_owner: Option<ObjectName>,
}
impl fmt::Display for CreateRole {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"CREATE ROLE {if_not_exists}{names}{superuser}{create_db}{create_role}{inherit}{login}{replication}{bypassrls}",
if_not_exists = if self.if_not_exists { "IF NOT EXISTS " } else { "" },
names = display_separated(&self.names, ", "),
superuser = match self.superuser {
Some(true) => " SUPERUSER",
Some(false) => " NOSUPERUSER",
None => ""
},
create_db = match self.create_db {
Some(true) => " CREATEDB",
Some(false) => " NOCREATEDB",
None => ""
},
create_role = match self.create_role {
Some(true) => " CREATEROLE",
Some(false) => " NOCREATEROLE",
None => ""
},
inherit = match self.inherit {
Some(true) => " INHERIT",
Some(false) => " NOINHERIT",
None => ""
},
login = match self.login {
Some(true) => " LOGIN",
Some(false) => " NOLOGIN",
None => ""
},
replication = match self.replication {
Some(true) => " REPLICATION",
Some(false) => " NOREPLICATION",
None => ""
},
bypassrls = match self.bypassrls {
Some(true) => " BYPASSRLS",
Some(false) => " NOBYPASSRLS",
None => ""
}
)?;
if let Some(limit) = &self.connection_limit {
write!(f, " CONNECTION LIMIT {limit}")?;
}
match &self.password {
Some(Password::Password(pass)) => write!(f, " PASSWORD {pass}")?,
Some(Password::NullPassword) => write!(f, " PASSWORD NULL")?,
None => {}
};
if let Some(until) = &self.valid_until {
write!(f, " VALID UNTIL {until}")?;
}
if !self.in_role.is_empty() {
write!(f, " IN ROLE {}", display_comma_separated(&self.in_role))?;
}
if !self.in_group.is_empty() {
write!(f, " IN GROUP {}", display_comma_separated(&self.in_group))?;
}
if !self.role.is_empty() {
write!(f, " ROLE {}", display_comma_separated(&self.role))?;
}
if !self.user.is_empty() {
write!(f, " USER {}", display_comma_separated(&self.user))?;
}
if !self.admin.is_empty() {
write!(f, " ADMIN {}", display_comma_separated(&self.admin))?;
}
if let Some(owner) = &self.authorization_owner {
write!(f, " AUTHORIZATION {owner}")?;
}
Ok(())
}
}
impl Spanned for CreateRole {
fn span(&self) -> Span {
Span::empty()
}
}
#[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 {
pub privileges: Privileges,
pub objects: Option<GrantObjects>,
pub grantees: Vec<Grantee>,
pub with_grant_option: bool,
pub as_grantor: Option<Ident>,
pub granted_by: Option<Ident>,
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)
}
}
#[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 {
pub privileges: Privileges,
pub objects: Option<GrantObjects>,
pub grantees: Vec<Grantee>,
pub granted_by: Option<Ident>,
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)
}
}