nodedb_sql/ddl_ast/alter_ops.rs
1// SPDX-License-Identifier: Apache-2.0
2
3//! Typed sub-operations for `ALTER COLLECTION`, `ALTER USER`, and `ALTER ROLE`.
4
5/// Typed sub-operation for `ALTER COLLECTION <name> ...`.
6///
7/// Each variant corresponds to one ALTER sub-command parsed by
8/// `nodedb-sql/src/ddl_ast/parse/collection.rs`. The handler in
9/// `nodedb/src/control/server/pgwire/ddl/collection/alter/` matches
10/// on this enum instead of rescanning raw SQL.
11#[derive(Debug, Clone, PartialEq)]
12pub enum AlterCollectionOp {
13 /// `ADD [COLUMN] <name> <type> [NOT NULL] [DEFAULT expr]`
14 AddColumn {
15 column_name: String,
16 column_type: String,
17 not_null: bool,
18 default_expr: Option<String>,
19 },
20 /// `DROP COLUMN <name>`
21 DropColumn { column_name: String },
22 /// `RENAME COLUMN <old> TO <new>`
23 RenameColumn { old_name: String, new_name: String },
24 /// `ALTER COLUMN <name> TYPE <type>`
25 AlterColumnType {
26 column_name: String,
27 new_type: String,
28 },
29 /// `OWNER TO <user>`
30 OwnerTo { new_owner: String },
31 /// `SET RETENTION = '<duration>'`
32 SetRetention { value: String },
33 /// `SET APPEND_ONLY`
34 SetAppendOnly,
35 /// `SET LAST_VALUE_CACHE = TRUE|FALSE`
36 SetLastValueCache { enabled: bool },
37 /// `SET LEGAL_HOLD = TRUE|FALSE TAG '<tag>'`
38 SetLegalHold { enabled: bool, tag: String },
39 /// `ADD [COLUMN] <target_column> ... AS MATERIALIZED_SUM SOURCE <source_collection>
40 /// ON <join_column> VALUE <value_expr>` — fully parsed by
41 /// `nodedb-sql`; the handler receives typed fields and never
42 /// rescans raw SQL.
43 AddMaterializedSum {
44 /// Target collection name (lowercased).
45 target_collection: String,
46 /// Target column name to hold the sum (lowercased).
47 target_column: String,
48 /// Source collection name (lowercased).
49 source_collection: String,
50 /// Join column on the source side (lowercased).
51 join_column: String,
52 /// Value expression (column name or qualified `source.column`, lowercased).
53 value_expr: String,
54 },
55 /// `SET ON CONFLICT <policy_keyword> FOR <constraint_kind_keyword>`
56 ///
57 /// Sets the per-collection, per-constraint-kind conflict resolution policy.
58 SetOnConflict {
59 /// Parsed conflict policy keyword.
60 policy: ConflictPolicyKind,
61 /// Which constraint kind this policy applies to.
62 constraint_kind: ConstraintKindKeyword,
63 },
64}
65
66/// Keyword representation of a conflict resolution policy for DDL.
67#[derive(Debug, Clone, PartialEq)]
68pub enum ConflictPolicyKind {
69 LastWriterWins,
70 RenameSuffix,
71 CascadeDefer,
72 EscalateToDlq,
73}
74
75/// Keyword representation of a constraint kind for DDL.
76#[derive(Debug, Clone, PartialEq)]
77pub enum ConstraintKindKeyword {
78 Unique,
79 ForeignKey,
80 NotNull,
81 Check,
82}
83
84/// Typed sub-operation for `ALTER USER <name> ...`.
85///
86/// Five forms are supported:
87/// - `SET PASSWORD '<pw>'` — change password
88/// - `SET ROLE <role>` — change role
89/// - `MUST CHANGE PASSWORD` — require password change on next login
90/// - `PASSWORD NEVER EXPIRES` — clear expiry date
91/// - `PASSWORD EXPIRES '<iso8601>'` or `PASSWORD EXPIRES IN <N> DAYS` — set expiry
92#[derive(Debug, Clone, PartialEq)]
93pub enum AlterUserOp {
94 /// `SET PASSWORD '<password>'`
95 SetPassword { password: String },
96 /// `SET ROLE <role>`
97 SetRole { role: String },
98 /// `MUST CHANGE PASSWORD`
99 MustChangePassword,
100 /// `PASSWORD NEVER EXPIRES`
101 PasswordNeverExpires,
102 /// `PASSWORD EXPIRES '<iso8601_datetime>'`
103 PasswordExpiresAt { iso8601: String },
104 /// `PASSWORD EXPIRES IN <n> DAYS`
105 PasswordExpiresInDays { days: u32 },
106 /// `SET DEFAULT DATABASE <db_name>`
107 SetDefaultDatabase { db_name: String },
108}
109
110/// Typed sub-operation for `ALTER ROLE <name> ...`.
111///
112/// Three forms are supported:
113/// - `GRANT <perm> ON [FUNCTION] <target>` — grant a permission to the role
114/// - `REVOKE <perm> ON [FUNCTION] <target>` — revoke a permission from the role
115/// - `SET INHERIT <parent>` — update role inheritance (original ALTER ROLE form)
116#[derive(Debug, Clone, PartialEq)]
117pub enum AlterRoleOp {
118 /// `GRANT <perm> ON [FUNCTION] <target>`
119 Grant {
120 /// Permission token, e.g. "READ", "WRITE", "ALL".
121 permission: String,
122 /// "COLLECTION" or "FUNCTION".
123 target_type: String,
124 /// Collection or function name.
125 target_name: String,
126 },
127 /// `REVOKE <perm> ON [FUNCTION] <target>`
128 Revoke {
129 /// Permission token, e.g. "READ", "WRITE", "ALL".
130 permission: String,
131 /// "COLLECTION" or "FUNCTION".
132 target_type: String,
133 /// Collection or function name.
134 target_name: String,
135 },
136 /// `SET INHERIT <parent>`
137 SetInherit {
138 /// Parent role name.
139 parent: String,
140 },
141}