Skip to main content

uqa_core/
catalog_sequence.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Shared persisted sequence ACL and stable owner identity values.
8
9use serde::{Deserialize, Serialize};
10
11mod security;
12pub use security::{BoundSequenceSecurity, LegacySequenceSecurity};
13
14/// Grantable privileges carried by one sequence ACL path.
15#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
16pub struct SequencePrivileges {
17    #[serde(default)]
18    pub select: bool,
19    #[serde(default)]
20    pub update: bool,
21    #[serde(default)]
22    pub usage: bool,
23}
24
25impl SequencePrivileges {
26    pub const ALL: Self = Self {
27        select: true,
28        update: true,
29        usage: true,
30    };
31
32    #[must_use]
33    pub const fn is_empty(self) -> bool {
34        !self.select && !self.update && !self.usage
35    }
36
37    #[must_use]
38    pub const fn intersects(self, other: Self) -> bool {
39        self.select && other.select || self.update && other.update || self.usage && other.usage
40    }
41
42    pub fn insert(&mut self, other: Self) {
43        self.select |= other.select;
44        self.update |= other.update;
45        self.usage |= other.usage;
46    }
47
48    pub fn remove(&mut self, other: Self) {
49        self.select &= !other.select;
50        self.update &= !other.update;
51        self.usage &= !other.usage;
52    }
53}
54
55/// One explicit sequence ACL path. `None` on `SequenceRow::acl` retains `PostgreSQL`'s default owner-only privileges.
56#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
57pub struct SequenceAclEntry {
58    pub role: crate::catalog_acl::AclGrantee,
59    /// Legacy persisted entries without an explicit grantor originate from the sequence owner.
60    #[serde(default, skip_serializing_if = "Option::is_none")]
61    pub grantor: Option<String>,
62    #[serde(default)]
63    pub privileges: SequencePrivileges,
64    #[serde(default)]
65    pub grant_options: SequencePrivileges,
66}
67
68/// Dependency strength of a sequence owner. Ordinary `OWNED BY` and `SERIAL` use an automatic dependency, while an identity column owns its sequence through an internal dependency that cannot be reassigned or dropped directly.
69#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
70#[serde(rename_all = "snake_case")]
71pub enum SequenceOwnerDependency {
72    #[default]
73    Automatic,
74    Internal,
75}
76
77impl SequenceOwnerDependency {
78    #[must_use]
79    pub const fn catalog_code(self) -> &'static str {
80        match self {
81            Self::Automatic => "a",
82            Self::Internal => "i",
83        }
84    }
85}
86
87/// Stable owner identity for a sequence dependency. Names are deliberately excluded so table and column renames do not require dependency rewrites.
88#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
89pub struct SequenceOwner {
90    pub table_object_id: [u8; 16],
91    pub column_object_id: [u8; 16],
92    #[serde(default)]
93    pub dependency: SequenceOwnerDependency,
94}
95
96#[cfg(test)]
97mod tests;