use std::collections::{BTreeMap, BTreeSet};
use serde::{Deserialize, Serialize};
use super::{
AclRoleSpecification, FunctionVolatility, RoleSpecification, RoutineColumnTypeReference,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
pub enum FunctionParallel {
#[default]
Unsafe,
Restricted,
Safe,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct RoutineSecurityAttributes {
#[serde(default)]
pub security_definer: bool,
#[serde(default)]
pub leakproof: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RoutineAclEntry {
#[serde(deserialize_with = "Deserialize::deserialize")]
pub role: Option<uqa_core::catalog_role::RoleIdentity>,
pub grantor: uqa_core::catalog_role::RoleIdentity,
pub grant_option: bool,
}
pub(super) fn deserialize_routine_owner<'de, D: serde::Deserializer<'de>>(
deserializer: D,
) -> Result<Option<uqa_core::catalog_role::RoleIdentity>, D::Error> {
#[derive(Deserialize)]
#[serde(untagged)]
enum Owner {
Bound(Option<uqa_core::catalog_role::RoleIdentity>),
Unbound(String),
}
match Owner::deserialize(deserializer)? {
Owner::Bound(identity) => Ok(identity),
Owner::Unbound(name) if name.is_empty() => Ok(None),
Owner::Unbound(_) => Err(serde::de::Error::custom(
"routine owner requires a role identity",
)),
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum AlterRoutineKind {
Function,
Procedure,
Routine,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AlterRoutineStmt {
pub kind: AlterRoutineKind,
pub name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub arg_types: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub arg_type_references: Vec<Option<RoutineColumnTypeReference>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub volatility: Option<FunctionVolatility>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub strict: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub security_definer: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub leakproof: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub parallel: Option<FunctionParallel>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub support: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub config_actions: Vec<RoutineConfigAction>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum RoutineConfigAction {
Set { name: String, value: String },
FromCurrent { name: String },
Reset { name: String },
ResetAll,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AlterRoutineOwnerStmt {
pub kind: AlterRoutineKind,
pub name: String,
pub arg_types: Option<Vec<String>>,
pub arg_type_references: Vec<Option<RoutineColumnTypeReference>>,
pub new_owner: RoleSpecification,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RenameRoutineStmt {
pub kind: AlterRoutineKind,
pub name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub arg_types: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub arg_type_references: Vec<Option<RoutineColumnTypeReference>>,
pub new_name: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct GrantRoutineItem {
pub name: String,
pub arg_types: Option<Vec<String>>,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum RoutineRevokeBehavior {
#[default]
Restrict,
Cascade,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct GrantRoutineStmt {
pub kind: AlterRoutineKind,
pub is_grant: bool,
pub grant_option: bool,
pub grant_option_only: bool,
pub items: Vec<GrantRoutineItem>,
pub grantees: Vec<AclRoleSpecification>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub grantor: Option<RoleSpecification>,
#[serde(default)]
pub revoke_behavior: RoutineRevokeBehavior,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct RoleMembershipOptions {
pub admin: Option<bool>,
pub inherit: Option<bool>,
pub set: Option<bool>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct GrantRoleStmt {
pub granted_roles: Vec<String>,
pub grantee_roles: Vec<RoleSpecification>,
pub is_grant: bool,
pub options: RoleMembershipOptions,
pub grantor: Option<RoleSpecification>,
pub cascade: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum RoleAttribute {
Superuser,
Inherit,
CreateRole,
CreateDb,
Login,
Replication,
BypassRls,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CreateRoleStmt {
pub name: String,
pub attributes: BTreeSet<RoleAttribute>,
pub connection_limit: i32,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub in_roles: Vec<RoleSpecification>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub role_members: Vec<RoleSpecification>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub admin_members: Vec<RoleSpecification>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum RoleMembershipAction {
Add,
Drop,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AlterRoleStmt {
pub name: RoleSpecification,
pub attributes: BTreeMap<RoleAttribute, bool>,
pub connection_limit: Option<i32>,
pub membership_action: Option<RoleMembershipAction>,
pub members: Vec<RoleSpecification>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RenameRoleStmt {
pub name: String,
pub new_name: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DropRoleStmt {
pub names: Vec<RoleSpecification>,
pub if_exists: bool,
}