1use serde::{Deserialize, Serialize};
10
11use super::{
12 deserialize_auto_increment, AutoIncrement, ColumnType, Expr, GeneratedColumn, OnCommitAction,
13 PartitionBound, PartitionSpec, RelationPersistence, TableHierarchy,
14};
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17#[allow(clippy::struct_excessive_bools)]
18pub struct ColumnDef {
19 pub name: String,
20 pub ty: ColumnType,
21 #[serde(default, skip_serializing_if = "Option::is_none")]
23 pub object_id: Option<[u8; 16]>,
24 #[serde(default, skip_serializing_if = "Option::is_none")]
26 pub missing_value: Option<uqa_core::Value>,
27 pub primary_key: bool,
28 pub not_null: bool,
29 #[serde(default)]
32 pub not_null_explicit: bool,
33 #[serde(default, skip_serializing_if = "Option::is_none")]
37 pub not_null_name: Option<String>,
38 #[serde(default = "default_true")]
41 pub not_null_validated: bool,
42 #[serde(default)]
45 pub not_null_no_inherit: bool,
46 #[serde(default = "default_true", skip_serializing_if = "is_true")]
48 pub not_null_is_local: bool,
49 #[serde(
51 default,
52 deserialize_with = "deserialize_auto_increment",
53 skip_serializing_if = "Option::is_none"
54 )]
55 pub auto_increment: Option<AutoIncrement>,
56 #[serde(default)]
59 pub unique: bool,
60 #[serde(default, skip_serializing_if = "Option::is_none")]
64 pub default: Option<Expr>,
65 #[serde(default, skip_serializing_if = "Option::is_none")]
69 pub generated: Option<GeneratedColumn>,
70 #[serde(default, skip_serializing_if = "Option::is_none")]
73 pub check: Option<Expr>,
74 #[serde(default, skip_serializing_if = "Option::is_none")]
75 pub check_name: Option<String>,
76 #[serde(default = "default_true")]
77 pub check_enforced: bool,
78 #[serde(default = "default_true")]
79 pub check_validated: bool,
80 #[serde(default)]
81 pub check_no_inherit: bool,
82 #[serde(default = "default_true", skip_serializing_if = "is_true")]
84 pub check_is_local: bool,
85 #[serde(default, skip_serializing_if = "Option::is_none")]
87 pub check_object_id: Option<[u8; 16]>,
88 #[serde(default, skip_serializing_if = "Option::is_none")]
90 pub references: Option<ForeignKeyRef>,
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize)]
95#[allow(clippy::struct_excessive_bools)]
96pub struct ForeignKeyRef {
97 #[serde(default, skip_serializing_if = "Option::is_none")]
98 pub referenced_key: Option<String>,
99 #[serde(default, skip_serializing_if = "Option::is_none")]
100 pub name: Option<String>,
101 #[serde(default, skip_serializing_if = "Option::is_none")]
104 pub object_id: Option<[u8; 16]>,
105 pub table: String,
106 #[serde(default, skip_serializing_if = "Option::is_none")]
107 pub column: Option<String>,
108 #[serde(default)]
109 pub on_update: ForeignKeyAction,
110 #[serde(default)]
111 pub on_delete: ForeignKeyAction,
112 #[serde(default)]
113 pub match_type: ForeignKeyMatch,
114 #[serde(default = "default_true")]
115 pub enforced: bool,
116 #[serde(default = "default_true")]
117 pub validated: bool,
118 #[serde(default)]
119 pub deferrable: bool,
120 #[serde(default)]
121 pub initially_deferred: bool,
122 #[serde(default)]
124 pub period: bool,
125}
126
127#[derive(Debug, Clone, Serialize, Deserialize)]
128pub struct CreateTable {
129 pub name: String,
130 pub qualifier: String,
132 pub columns: Vec<ColumnDef>,
133 pub if_not_exists: bool,
136 #[allow(dead_code)]
139 pub checks: Vec<TableCheck>,
140 pub foreign_keys: Vec<ForeignKey>,
142 #[serde(default)]
147 pub key_constraints: Vec<TableKeyConstraint>,
148 #[serde(default)]
150 pub persistence: RelationPersistence,
151 #[serde(default)]
153 pub on_commit: OnCommitAction,
154 #[serde(default)]
158 pub hierarchy: TableHierarchy,
159}
160
161#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
163pub struct DeferredCreateTable {
164 pub name: String,
165 pub persistence: RelationPersistence,
166 pub definition_sql: String,
167}
168
169#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
170pub enum TableKeyConstraintKind {
171 PrimaryKey,
172 Unique,
173}
174
175#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
177pub struct TableKeyConstraint {
178 pub name: Option<String>,
179 pub kind: TableKeyConstraintKind,
180 pub columns: Vec<String>,
181 #[serde(default)]
184 pub nulls_not_distinct: bool,
185 #[serde(default)]
187 pub without_overlaps: bool,
188}
189
190#[derive(Debug, Clone, Default, Serialize, Deserialize)]
195pub struct TableConstraintSet {
196 #[serde(default)]
197 pub checks: Vec<TableCheck>,
198 #[serde(default)]
199 pub foreign_keys: Vec<ForeignKey>,
200 #[serde(default)]
201 pub key_constraints: Vec<TableKeyConstraint>,
202 #[serde(default)]
204 pub persistence: RelationPersistence,
205 #[serde(default)]
207 pub on_commit: OnCommitAction,
208 #[serde(default)]
210 pub hierarchy: TableHierarchy,
211}
212
213#[derive(Debug, Clone, Serialize, Deserialize)]
216#[expect(
217 clippy::struct_excessive_bools,
218 reason = "CHECK catalog flags are independent PostgreSQL properties"
219)]
220pub struct TableCheck {
221 pub name: Option<String>,
222 #[serde(default, skip_serializing_if = "Option::is_none")]
224 pub object_id: Option<[u8; 16]>,
225 #[serde(default = "default_true", skip_serializing_if = "is_true")]
227 pub is_local: bool,
228 pub expr: Expr,
229 #[serde(default = "default_true")]
230 pub enforced: bool,
231 #[serde(default = "default_true")]
232 pub validated: bool,
233 #[serde(default)]
234 pub no_inherit: bool,
235 #[serde(default, skip_serializing_if = "Option::is_none")]
237 pub partition_constraint: Option<DetachedPartitionConstraint>,
238}
239
240#[derive(Debug, Clone, Serialize, Deserialize)]
241pub struct DetachedPartitionConstraint {
242 pub spec: PartitionSpec,
243 pub bound: PartitionBound,
244}
245
246#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
248#[allow(clippy::struct_excessive_bools)]
249pub struct ForeignKey {
250 #[serde(default, skip_serializing_if = "Option::is_none")]
252 pub referenced_key: Option<String>,
253 pub name: Option<String>,
254 #[serde(default, skip_serializing_if = "Option::is_none")]
257 pub object_id: Option<[u8; 16]>,
258 pub local_columns: Vec<String>,
259 pub ref_table: String,
260 pub ref_columns: Vec<String>,
261 #[serde(default)]
262 pub on_update: ForeignKeyAction,
263 #[serde(default)]
264 pub on_delete: ForeignKeyAction,
265 #[serde(default)]
269 pub on_delete_set_columns: Vec<String>,
270 #[serde(default)]
271 pub match_type: ForeignKeyMatch,
272 #[serde(default = "default_true")]
273 pub enforced: bool,
274 #[serde(default = "default_true")]
275 pub validated: bool,
276 #[serde(default)]
277 pub deferrable: bool,
278 #[serde(default)]
279 pub initially_deferred: bool,
280 #[serde(default)]
282 pub period: bool,
283}
284
285const fn default_true() -> bool {
286 true
287}
288
289#[expect(
290 clippy::trivially_copy_pass_by_ref,
291 reason = "serde skip_serializing_if requires a borrowed field"
292)]
293const fn is_true(value: &bool) -> bool {
294 *value
295}
296
297#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
298pub enum ForeignKeyAction {
299 #[default]
300 NoAction,
301 Restrict,
302 Cascade,
303 SetNull,
304 SetDefault,
305}
306
307#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
308pub enum ForeignKeyMatch {
309 #[default]
310 Simple,
311 Full,
312}