Skip to main content

uqa_sql/ast/
routine_security.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Routine security, ownership, configuration, privileges, and role statements.
8
9use std::collections::{BTreeMap, BTreeSet};
10
11use serde::{Deserialize, Serialize};
12
13use super::{FunctionVolatility, RoutineColumnTypeReference};
14
15/// `PARALLEL UNSAFE`, `PARALLEL RESTRICTED`, or `PARALLEL SAFE` routine metadata.
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
17pub enum FunctionParallel {
18    #[default]
19    Unsafe,
20    Restricted,
21    Safe,
22}
23
24/// Execution identity and planner leakproofness attached to a routine definition.
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
26pub struct RoutineSecurityAttributes {
27    /// `SECURITY DEFINER` when true, otherwise `SECURITY INVOKER`.
28    #[serde(default)]
29    pub security_definer: bool,
30    /// `LEAKPROOF` planner metadata.
31    #[serde(default)]
32    pub leakproof: bool,
33}
34
35/// One explicit `EXECUTE` ACL entry. `None` on `CreateFunction::execute_acl` retains `PostgreSQL`'s default public execution privilege.
36#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
37pub struct RoutineAclEntry {
38    pub role: String,
39    pub grant_option: bool,
40}
41
42/// Routine namespace selected by `ALTER FUNCTION`, `ALTER PROCEDURE`, or `ALTER ROUTINE`.
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
44pub enum AlterRoutineKind {
45    Function,
46    Procedure,
47    Routine,
48}
49
50/// `ALTER FUNCTION | PROCEDURE | ROUTINE name[(input_types)] ...` with an optional exact declared input identity.
51#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
52pub struct AlterRoutineStmt {
53    pub kind: AlterRoutineKind,
54    pub name: String,
55    #[serde(default, skip_serializing_if = "Option::is_none")]
56    pub arg_types: Option<Vec<String>>,
57    #[serde(default, skip_serializing_if = "Vec::is_empty")]
58    pub arg_type_references: Vec<Option<RoutineColumnTypeReference>>,
59    #[serde(default, skip_serializing_if = "Option::is_none")]
60    pub volatility: Option<FunctionVolatility>,
61    #[serde(default, skip_serializing_if = "Option::is_none")]
62    pub strict: Option<bool>,
63    #[serde(default, skip_serializing_if = "Option::is_none")]
64    pub security_definer: Option<bool>,
65    #[serde(default, skip_serializing_if = "Option::is_none")]
66    pub leakproof: Option<bool>,
67    #[serde(default, skip_serializing_if = "Option::is_none")]
68    pub parallel: Option<FunctionParallel>,
69    #[serde(default, skip_serializing_if = "Option::is_none")]
70    pub support: Option<String>,
71    #[serde(default, skip_serializing_if = "Vec::is_empty")]
72    pub config_actions: Vec<RoutineConfigAction>,
73}
74
75#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
76pub enum RoutineConfigAction {
77    Set { name: String, value: String },
78    FromCurrent { name: String },
79    Reset { name: String },
80    ResetAll,
81}
82
83#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
84pub struct AlterRoutineOwnerStmt {
85    pub kind: AlterRoutineKind,
86    pub name: String,
87    pub arg_types: Option<Vec<String>>,
88    pub arg_type_references: Vec<Option<RoutineColumnTypeReference>>,
89    pub new_owner: String,
90}
91
92#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
93pub struct GrantRoutineItem {
94    pub name: String,
95    pub arg_types: Option<Vec<String>>,
96}
97
98#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
99pub struct GrantRoutineStmt {
100    pub kind: AlterRoutineKind,
101    pub is_grant: bool,
102    pub grant_option: bool,
103    pub grant_option_only: bool,
104    pub items: Vec<GrantRoutineItem>,
105    pub grantees: Vec<String>,
106}
107
108#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
109pub enum RoleAttribute {
110    Superuser,
111    Inherit,
112    CreateRole,
113    CreateDb,
114    Login,
115    Replication,
116    BypassRls,
117}
118
119#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
120pub struct CreateRoleStmt {
121    pub name: String,
122    pub attributes: BTreeSet<RoleAttribute>,
123    pub connection_limit: i32,
124}
125
126#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
127pub struct AlterRoleStmt {
128    pub name: String,
129    pub attributes: BTreeMap<RoleAttribute, bool>,
130    pub connection_limit: Option<i32>,
131}
132
133#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
134pub struct DropRoleStmt {
135    pub names: Vec<String>,
136    pub if_exists: bool,
137}