1use super::{AclRoleSpecification, RoleSpecification};
10use serde::{Deserialize, Serialize};
11
12#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
14pub enum RelationPersistence {
15 #[default]
16 Permanent,
17 Unlogged,
18 Temporary,
19}
20
21impl RelationPersistence {
22 #[must_use]
23 pub const fn catalog_code(self) -> &'static str {
24 match self {
25 Self::Permanent => "p",
26 Self::Unlogged => "u",
27 Self::Temporary => "t",
28 }
29 }
30}
31
32#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
34pub enum OnCommitAction {
35 #[default]
36 PreserveRows,
37 DeleteRows,
38 Drop,
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
42pub enum AlterViewKind {
43 View,
44 MaterializedView,
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
48pub enum AlterViewAction {
49 Set(Vec<(String, String)>),
50 Reset(Vec<String>),
51 OwnerTo(RoleSpecification),
52 RenameTo(String),
53 RenameColumn { from: String, to: String },
54 SetSchema(String),
55}
56
57#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
58pub struct AlterViewStmt {
59 pub name: String,
60 pub kind: AlterViewKind,
61 pub if_exists: bool,
62 pub action: AlterViewAction,
63}
64
65#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
66pub struct DropColumnAction {
67 pub name: String,
68 pub if_exists: bool,
69 pub cascade: bool,
70}
71
72#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
73pub enum AlterForeignTableAction {
74 DropColumns(Vec<DropColumnAction>),
75 OwnerTo(RoleSpecification),
76 RenameTo(String),
77 SetSchema(String),
78}
79
80#[derive(Debug, Clone, PartialEq, Eq)]
81pub struct AlterForeignTableStmt {
82 pub name: String,
83 pub if_exists: bool,
84 pub action: AlterForeignTableAction,
85}
86
87#[derive(Serialize, Deserialize)]
88struct AlterForeignTableStmtSerde {
89 name: String,
90 if_exists: bool,
91 #[serde(default, skip_serializing_if = "Option::is_none")]
92 owner: Option<RoleSpecification>,
93 #[serde(default, skip_serializing_if = "Option::is_none")]
94 rename_to: Option<String>,
95 #[serde(default, skip_serializing_if = "Option::is_none")]
96 set_schema: Option<String>,
97 #[serde(default, skip_serializing_if = "Option::is_none")]
98 drop_columns: Option<Vec<DropColumnAction>>,
99}
100
101impl Serialize for AlterForeignTableStmt {
102 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
103 where
104 S: serde::Serializer,
105 {
106 let (owner, rename_to, set_schema, drop_columns) = match &self.action {
107 AlterForeignTableAction::OwnerTo(owner) => (Some(owner.clone()), None, None, None),
108 AlterForeignTableAction::RenameTo(name) => (None, Some(name.clone()), None, None),
109 AlterForeignTableAction::SetSchema(schema) => (None, None, Some(schema.clone()), None),
110 AlterForeignTableAction::DropColumns(columns) => {
111 (None, None, None, Some(columns.clone()))
112 }
113 };
114 AlterForeignTableStmtSerde {
115 name: self.name.clone(),
116 if_exists: self.if_exists,
117 owner,
118 rename_to,
119 set_schema,
120 drop_columns,
121 }
122 .serialize(serializer)
123 }
124}
125
126impl<'de> Deserialize<'de> for AlterForeignTableStmt {
127 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
128 where
129 D: serde::Deserializer<'de>,
130 {
131 let value = AlterForeignTableStmtSerde::deserialize(deserializer)?;
132 let action = match (
133 value.owner,
134 value.rename_to,
135 value.set_schema,
136 value.drop_columns,
137 ) {
138 (Some(owner), None, None, None) => AlterForeignTableAction::OwnerTo(owner),
139 (None, Some(name), None, None) => AlterForeignTableAction::RenameTo(name),
140 (None, None, Some(schema), None) => AlterForeignTableAction::SetSchema(schema),
141 (None, None, None, Some(columns)) if !columns.is_empty() => {
142 AlterForeignTableAction::DropColumns(columns)
143 }
144 (Some(_), Some(_), None, None) => {
145 return Err(serde::de::Error::custom(
146 "ALTER FOREIGN TABLE cannot contain both owner and rename_to",
147 ));
148 }
149 _ => {
150 return Err(serde::de::Error::custom(
151 "ALTER FOREIGN TABLE requires exactly one of owner, rename_to, set_schema or nonempty drop_columns",
152 ));
153 }
154 };
155 Ok(Self {
156 name: value.name,
157 if_exists: value.if_exists,
158 action,
159 })
160 }
161}
162
163#[derive(Debug, Clone, Serialize, Deserialize)]
164pub struct CreateSequence {
165 pub name: String,
166 pub if_not_exists: bool,
167 pub start: i64,
168 pub increment: i64,
169 #[serde(default)]
170 pub persistence: RelationPersistence,
171 #[serde(default)]
172 pub data_type: SequenceDataType,
173 #[serde(default)]
175 pub min_value: Option<i64>,
176 #[serde(default)]
177 pub max_value: Option<i64>,
178 #[serde(default)]
179 pub cycle: bool,
180 #[serde(default = "default_sequence_cache_size")]
181 pub cache_size: i64,
182 #[serde(default)]
183 pub ownership: SequenceOwnership,
184 #[serde(default)]
186 pub restart: SequenceRestart,
187}
188
189#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
190pub enum SequenceDataType {
191 SmallInt,
192 Integer,
193 #[default]
194 BigInt,
195}
196
197const fn default_sequence_cache_size() -> i64 {
198 1
199}
200
201impl SequenceDataType {
202 #[must_use]
203 pub const fn sql_name(self) -> &'static str {
204 match self {
205 Self::SmallInt => "smallint",
206 Self::Integer => "integer",
207 Self::BigInt => "bigint",
208 }
209 }
210
211 #[must_use]
212 pub const fn bounds(self) -> (i64, i64) {
213 match self {
214 Self::SmallInt => (i16::MIN as i64, i16::MAX as i64),
215 Self::Integer => (i32::MIN as i64, i32::MAX as i64),
216 Self::BigInt => (i64::MIN, i64::MAX),
217 }
218 }
219}
220
221#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
223pub enum SequenceRestart {
224 #[default]
226 Unchanged,
227 FromStart,
229 With(i64),
231}
232
233#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
235pub enum SequenceBound {
236 #[default]
237 Unchanged,
238 Default,
239 Value(i64),
240}
241
242#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
244pub enum SequenceOwnership {
245 #[default]
247 Unchanged,
248 Unowned,
250 Column { table: String, column: String },
252}
253
254#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
256pub enum SequenceLifecycle {
257 #[default]
259 Unchanged,
260 RenameTo {
261 name: String,
262 },
263 SetSchema {
264 schema: String,
265 },
266}
267
268fn deserialize_sequence_restart<'de, D>(deserializer: D) -> Result<SequenceRestart, D::Error>
269where
270 D: serde::Deserializer<'de>,
271{
272 #[derive(Deserialize)]
273 enum Current {
274 Unchanged,
275 FromStart,
276 With(i64),
277 }
278
279 #[derive(Deserialize)]
280 #[serde(untagged)]
281 enum Representation {
282 Current(Current),
283 Legacy(Option<i64>),
286 }
287
288 Ok(match Representation::deserialize(deserializer)? {
289 Representation::Current(Current::Unchanged) | Representation::Legacy(None) => {
290 SequenceRestart::Unchanged
291 }
292 Representation::Current(Current::FromStart) => SequenceRestart::FromStart,
293 Representation::Current(Current::With(value)) | Representation::Legacy(Some(value)) => {
294 SequenceRestart::With(value)
295 }
296 })
297}
298
299#[derive(Debug, Clone, Default, Serialize, Deserialize)]
300pub struct AlterSequence {
301 pub name: String,
302 #[serde(default)]
304 pub if_exists: bool,
305 #[serde(default, deserialize_with = "deserialize_sequence_restart")]
307 pub restart: SequenceRestart,
308 pub increment: Option<i64>,
309 pub start: Option<i64>,
310 #[serde(default)]
311 pub data_type: Option<SequenceDataType>,
312 #[serde(default)]
313 pub min_value: SequenceBound,
314 #[serde(default)]
315 pub max_value: SequenceBound,
316 #[serde(default)]
317 pub cycle: Option<bool>,
318 pub cache_size: Option<i64>,
319 #[serde(default)]
320 pub ownership: SequenceOwnership,
321 #[serde(default)]
323 pub persistence: Option<RelationPersistence>,
324 #[serde(default, skip_serializing_if = "Option::is_none")]
326 pub role_owner: Option<RoleSpecification>,
327 #[serde(default)]
329 pub lifecycle: SequenceLifecycle,
330}
331
332#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
334pub enum SequencePrivilege {
335 Select,
336 Update,
337 Usage,
338 ColumnsUnsupported,
339 Unsupported(String),
340}
341
342#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
344pub struct TablePrivilegeSpec {
345 pub privilege: TablePrivilege,
346 #[serde(default, skip_serializing_if = "Vec::is_empty")]
347 pub columns: Vec<String>,
348}
349
350#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
352pub enum TablePrivilege {
353 Select,
354 Insert,
355 Update,
356 Delete,
357 Truncate,
358 References,
359 Trigger,
360 Maintain,
361 Usage,
362 Unsupported(String),
363}
364
365#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
367pub enum GrantTableTarget {
368 Relations { names: Vec<String> },
369 AllTablesInSchemas { schemas: Vec<String> },
370}
371
372#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
374pub enum TableRevokeBehavior {
375 #[default]
376 Restrict,
377 Cascade,
378}
379
380#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
382pub struct GrantTableStmt {
383 pub is_grant: bool,
384 pub grant_option: bool,
385 pub grant_option_only: bool,
386 pub privileges: Vec<TablePrivilegeSpec>,
387 pub target: GrantTableTarget,
388 pub grantees: Vec<AclRoleSpecification>,
389 #[serde(default, skip_serializing_if = "Option::is_none")]
390 pub grantor: Option<RoleSpecification>,
391 #[serde(default)]
392 pub revoke_behavior: TableRevokeBehavior,
393}
394
395#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
397pub enum GrantSequenceTarget {
398 Sequences { names: Vec<String> },
399 AllSequencesInSchemas { schemas: Vec<String> },
400}
401
402#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
404pub enum SequenceRevokeBehavior {
405 #[default]
406 Restrict,
407 Cascade,
408}
409
410#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
412pub struct GrantSequenceStmt {
413 pub is_grant: bool,
414 pub grant_option: bool,
415 pub grant_option_only: bool,
416 pub privileges: Vec<SequencePrivilege>,
417 pub target: GrantSequenceTarget,
418 pub grantees: Vec<AclRoleSpecification>,
419 #[serde(default, skip_serializing_if = "Option::is_none")]
420 pub grantor: Option<RoleSpecification>,
421 #[serde(default)]
422 pub revoke_behavior: SequenceRevokeBehavior,
423}
424
425#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
427pub enum DatabasePrivilege {
428 Connect,
429 Create,
430 Temporary,
431 Unsupported(String),
432}
433
434#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
436pub enum DatabaseRevokeBehavior {
437 #[default]
438 Restrict,
439 Cascade,
440}
441
442#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
444pub struct GrantDatabaseStmt {
445 pub is_grant: bool,
446 pub grant_option: bool,
447 pub grant_option_only: bool,
448 pub privileges: Vec<DatabasePrivilege>,
449 pub databases: Vec<String>,
450 pub grantees: Vec<AclRoleSpecification>,
451 #[serde(default, skip_serializing_if = "Option::is_none")]
452 pub grantor: Option<RoleSpecification>,
453 #[serde(default)]
454 pub revoke_behavior: DatabaseRevokeBehavior,
455}
456
457#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
459pub enum SchemaPrivilege {
460 Usage,
461 Create,
462 Unsupported(String),
463}
464
465#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
467pub enum SchemaRevokeBehavior {
468 #[default]
469 Restrict,
470 Cascade,
471}
472
473#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
475pub struct GrantSchemaStmt {
476 pub is_grant: bool,
477 pub grant_option: bool,
478 pub grant_option_only: bool,
479 pub privileges: Vec<SchemaPrivilege>,
480 pub schemas: Vec<String>,
481 pub grantees: Vec<AclRoleSpecification>,
482 #[serde(default, skip_serializing_if = "Option::is_none")]
483 pub grantor: Option<RoleSpecification>,
484 #[serde(default)]
485 pub revoke_behavior: SchemaRevokeBehavior,
486}