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
11/// Grantable privileges carried by one sequence ACL path.
12#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
13pub struct SequencePrivileges {
14    #[serde(default)]
15    pub select: bool,
16    #[serde(default)]
17    pub update: bool,
18    #[serde(default)]
19    pub usage: bool,
20}
21
22impl SequencePrivileges {
23    pub const ALL: Self = Self {
24        select: true,
25        update: true,
26        usage: true,
27    };
28
29    #[must_use]
30    pub const fn is_empty(self) -> bool {
31        !self.select && !self.update && !self.usage
32    }
33
34    #[must_use]
35    pub const fn intersects(self, other: Self) -> bool {
36        self.select && other.select || self.update && other.update || self.usage && other.usage
37    }
38
39    pub fn insert(&mut self, other: Self) {
40        self.select |= other.select;
41        self.update |= other.update;
42        self.usage |= other.usage;
43    }
44
45    pub fn remove(&mut self, other: Self) {
46        self.select &= !other.select;
47        self.update &= !other.update;
48        self.usage &= !other.usage;
49    }
50}
51
52/// One explicit sequence ACL path. `None` on `SequenceRow::acl` retains `PostgreSQL`'s default owner-only privileges.
53#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
54pub struct SequenceAclEntry {
55    pub role: String,
56    /// Legacy persisted entries without an explicit grantor originate from the sequence owner.
57    #[serde(default, skip_serializing_if = "Option::is_none")]
58    pub grantor: Option<String>,
59    #[serde(default)]
60    pub privileges: SequencePrivileges,
61    #[serde(default)]
62    pub grant_options: SequencePrivileges,
63}
64
65/// 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.
66#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
67#[serde(rename_all = "snake_case")]
68pub enum SequenceOwnerDependency {
69    #[default]
70    Automatic,
71    Internal,
72}
73
74impl SequenceOwnerDependency {
75    #[must_use]
76    pub const fn catalog_code(self) -> &'static str {
77        match self {
78            Self::Automatic => "a",
79            Self::Internal => "i",
80        }
81    }
82}
83
84/// Stable owner identity for a sequence dependency. Names are deliberately excluded so table and column renames do not require dependency rewrites.
85#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
86pub struct SequenceOwner {
87    pub table_object_id: [u8; 16],
88    pub column_object_id: [u8; 16],
89    #[serde(default)]
90    pub dependency: SequenceOwnerDependency,
91}
92
93#[cfg(test)]
94mod tests;