#[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)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterDefaultPrivilegesObjectType {
Tables,
Sequences,
Functions,
Routines,
Types,
Schemas,
}
impl fmt::Display for AlterDefaultPrivilegesObjectType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match self {
AlterDefaultPrivilegesObjectType::Tables => "TABLES",
AlterDefaultPrivilegesObjectType::Sequences => "SEQUENCES",
AlterDefaultPrivilegesObjectType::Functions => "FUNCTIONS",
AlterDefaultPrivilegesObjectType::Routines => "ROUTINES",
AlterDefaultPrivilegesObjectType::Types => "TYPES",
AlterDefaultPrivilegesObjectType::Schemas => "SCHEMAS",
})
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterDefaultPrivilegesAction {
Grant {
privileges: Privileges,
object_type: AlterDefaultPrivilegesObjectType,
grantees: Vec<Grantee>,
with_grant_option: bool,
},
Revoke {
grant_option_for: bool,
privileges: Privileges,
object_type: AlterDefaultPrivilegesObjectType,
grantees: Vec<Grantee>,
cascade: Option<CascadeOption>,
},
}
impl fmt::Display for AlterDefaultPrivilegesAction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AlterDefaultPrivilegesAction::Grant {
privileges,
object_type,
grantees,
with_grant_option,
} => {
write!(f, "GRANT ")?;
write_privileges_body(f, privileges, object_type, "TO", grantees)?;
if *with_grant_option {
write!(f, " WITH GRANT OPTION")?;
}
Ok(())
}
AlterDefaultPrivilegesAction::Revoke {
grant_option_for,
privileges,
object_type,
grantees,
cascade,
} => {
write!(f, "REVOKE ")?;
if *grant_option_for {
write!(f, "GRANT OPTION FOR ")?;
}
write_privileges_body(f, privileges, object_type, "FROM", grantees)?;
if let Some(cascade) = cascade {
write!(f, " {cascade}")?;
}
Ok(())
}
}
}
}
fn write_privileges_body(
f: &mut fmt::Formatter,
privileges: &Privileges,
object_type: &AlterDefaultPrivilegesObjectType,
connector: &str,
grantees: &[Grantee],
) -> fmt::Result {
write!(
f,
"{privileges} ON {object_type} {connector} {grantees}",
grantees = display_comma_separated(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 AlterDefaultPrivileges {
pub for_roles: Vec<Ident>,
pub in_schemas: Vec<Ident>,
pub action: AlterDefaultPrivilegesAction,
}
impl fmt::Display for AlterDefaultPrivileges {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ALTER DEFAULT PRIVILEGES")?;
if !self.for_roles.is_empty() {
write!(f, " FOR ROLE {}", display_comma_separated(&self.for_roles))?;
}
if !self.in_schemas.is_empty() {
write!(
f,
" IN SCHEMA {}",
display_comma_separated(&self.in_schemas)
)?;
}
write!(f, " {}", self.action)
}
}
impl From<AlterDefaultPrivileges> for crate::ast::Statement {
fn from(v: AlterDefaultPrivileges) -> Self {
crate::ast::Statement::AlterDefaultPrivileges(v)
}
}