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, skip_serializing_if = "Option::is_none")]
40 pub not_null_identity: Option<ConstraintCatalogIdentity>,
41 #[serde(default = "default_true")]
44 pub not_null_validated: bool,
45 #[serde(default)]
48 pub not_null_no_inherit: bool,
49 #[serde(default = "default_true", skip_serializing_if = "is_true")]
51 pub not_null_is_local: bool,
52 #[serde(
54 default,
55 deserialize_with = "deserialize_auto_increment",
56 skip_serializing_if = "Option::is_none"
57 )]
58 pub auto_increment: Option<AutoIncrement>,
59 #[serde(default)]
62 pub unique: bool,
63 #[serde(default, skip_serializing_if = "Option::is_none")]
67 pub default: Option<Expr>,
68 #[serde(default, skip_serializing_if = "Option::is_none")]
72 pub generated: Option<GeneratedColumn>,
73 #[serde(default, skip_serializing_if = "Option::is_none")]
76 pub check: Option<Expr>,
77 #[serde(default, skip_serializing_if = "Option::is_none")]
78 pub check_name: Option<String>,
79 #[serde(default = "default_true")]
80 pub check_enforced: bool,
81 #[serde(default = "default_true")]
82 pub check_validated: bool,
83 #[serde(default)]
84 pub check_no_inherit: bool,
85 #[serde(default = "default_true", skip_serializing_if = "is_true")]
87 pub check_is_local: bool,
88 #[serde(default, skip_serializing_if = "Option::is_none")]
90 pub check_object_id: Option<[u8; 16]>,
91 #[serde(default, skip_serializing_if = "Option::is_none")]
93 pub check_catalog_oid: Option<i64>,
94 #[serde(default, skip_serializing_if = "Option::is_none")]
96 pub references: Option<ForeignKeyRef>,
97}
98
99pub use uqa_core::catalog_identity::CatalogObjectIdentity as ConstraintCatalogIdentity;
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
103#[allow(clippy::struct_excessive_bools)]
104pub struct ForeignKeyRef {
105 #[serde(default, skip_serializing_if = "Option::is_none")]
107 pub referenced_index: Option<[u8; 16]>,
108 #[serde(default, skip_serializing_if = "Option::is_none")]
109 pub referenced_key: Option<String>,
110 #[serde(default, skip_serializing_if = "Option::is_none")]
111 pub name: Option<String>,
112 #[serde(default, skip_serializing_if = "Option::is_none")]
114 pub object_id: Option<[u8; 16]>,
115 #[serde(default, skip_serializing_if = "Option::is_none")]
117 pub catalog_identity: Option<ConstraintCatalogIdentity>,
118 pub table: String,
119 #[serde(default, skip_serializing_if = "Option::is_none")]
120 pub column: Option<String>,
121 #[serde(default)]
122 pub on_update: ForeignKeyAction,
123 #[serde(default)]
124 pub on_delete: ForeignKeyAction,
125 #[serde(default)]
126 pub match_type: ForeignKeyMatch,
127 #[serde(default = "default_true")]
128 pub enforced: bool,
129 #[serde(default = "default_true")]
130 pub validated: bool,
131 #[serde(default)]
132 pub deferrable: bool,
133 #[serde(default)]
134 pub initially_deferred: bool,
135 #[serde(default)]
137 pub period: bool,
138}
139
140#[derive(Debug, Clone, Serialize, Deserialize)]
141pub struct CreateTable {
142 pub name: String,
143 pub qualifier: String,
145 pub columns: Vec<ColumnDef>,
146 pub if_not_exists: bool,
149 #[allow(dead_code)]
152 pub checks: Vec<TableCheck>,
153 pub foreign_keys: Vec<ForeignKey>,
155 #[serde(default)]
160 pub key_constraints: Vec<TableKeyConstraint>,
161 #[serde(default)]
163 pub persistence: RelationPersistence,
164 #[serde(default)]
166 pub on_commit: OnCommitAction,
167 #[serde(default)]
171 pub hierarchy: TableHierarchy,
172}
173
174#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
176pub struct DeferredCreateTable {
177 pub name: String,
178 pub persistence: RelationPersistence,
179 pub definition_sql: String,
180}
181
182#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
183pub enum TableKeyConstraintKind {
184 PrimaryKey,
185 Unique,
186}
187
188#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
190pub struct TableKeyConstraint {
191 #[serde(default, skip_serializing_if = "Option::is_none")]
193 pub catalog_identity: Option<ConstraintCatalogIdentity>,
194 pub name: Option<String>,
195 pub kind: TableKeyConstraintKind,
196 pub columns: Vec<String>,
197 #[serde(default, skip_serializing_if = "Vec::is_empty")]
199 pub included_columns: Vec<String>,
200 #[serde(default)]
203 pub nulls_not_distinct: bool,
204 #[serde(default)]
206 pub without_overlaps: bool,
207}
208
209#[derive(Debug, Clone, Default, Serialize, Deserialize)]
214pub struct TableConstraintSet {
215 #[serde(default, skip_serializing_if = "Option::is_none")]
217 pub columns_declared: Option<bool>,
218 #[serde(default)]
219 pub checks: Vec<TableCheck>,
220 #[serde(default)]
221 pub foreign_keys: Vec<ForeignKey>,
222 #[serde(default)]
223 pub key_constraints: Vec<TableKeyConstraint>,
224 #[serde(default)]
226 pub persistence: RelationPersistence,
227 #[serde(default)]
229 pub on_commit: OnCommitAction,
230 #[serde(default)]
232 pub hierarchy: TableHierarchy,
233}
234
235#[derive(Debug, Clone, Serialize, Deserialize)]
238#[expect(
239 clippy::struct_excessive_bools,
240 reason = "CHECK catalog flags are independent PostgreSQL properties"
241)]
242pub struct TableCheck {
243 pub name: Option<String>,
244 #[serde(default, skip_serializing_if = "Option::is_none")]
246 pub object_id: Option<[u8; 16]>,
247 #[serde(default, skip_serializing_if = "Option::is_none")]
248 pub catalog_oid: Option<i64>,
249 #[serde(default = "default_true", skip_serializing_if = "is_true")]
251 pub is_local: bool,
252 pub expr: Expr,
253 #[serde(default = "default_true")]
254 pub enforced: bool,
255 #[serde(default = "default_true")]
256 pub validated: bool,
257 #[serde(default)]
258 pub no_inherit: bool,
259 #[serde(default, skip_serializing_if = "Option::is_none")]
261 pub partition_constraint: Option<DetachedPartitionConstraint>,
262}
263
264#[derive(Debug, Clone, Serialize, Deserialize)]
265pub struct DetachedPartitionConstraint {
266 pub spec: PartitionSpec,
267 pub bound: PartitionBound,
268}
269
270#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
272#[allow(clippy::struct_excessive_bools)]
273pub struct ForeignKey {
274 #[serde(default, skip_serializing_if = "Option::is_none")]
276 pub referenced_index: Option<[u8; 16]>,
277 #[serde(default, skip_serializing_if = "Option::is_none")]
279 pub referenced_key: Option<String>,
280 pub name: Option<String>,
281 #[serde(default, skip_serializing_if = "Option::is_none")]
283 pub object_id: Option<[u8; 16]>,
284 #[serde(default, skip_serializing_if = "Option::is_none")]
286 pub catalog_identity: Option<ConstraintCatalogIdentity>,
287 pub local_columns: Vec<String>,
288 pub ref_table: String,
289 pub ref_columns: Vec<String>,
290 #[serde(default)]
291 pub on_update: ForeignKeyAction,
292 #[serde(default)]
293 pub on_delete: ForeignKeyAction,
294 #[serde(default)]
298 pub on_delete_set_columns: Vec<String>,
299 #[serde(default)]
300 pub match_type: ForeignKeyMatch,
301 #[serde(default = "default_true")]
302 pub enforced: bool,
303 #[serde(default = "default_true")]
304 pub validated: bool,
305 #[serde(default)]
306 pub deferrable: bool,
307 #[serde(default)]
308 pub initially_deferred: bool,
309 #[serde(default)]
311 pub period: bool,
312}
313
314const fn default_true() -> bool {
315 true
316}
317
318#[expect(
319 clippy::trivially_copy_pass_by_ref,
320 reason = "serde skip_serializing_if requires a borrowed field"
321)]
322const fn is_true(value: &bool) -> bool {
323 *value
324}
325
326#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
327pub enum ForeignKeyAction {
328 #[default]
329 NoAction,
330 Restrict,
331 Cascade,
332 SetNull,
333 SetDefault,
334}
335
336#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
337pub enum ForeignKeyMatch {
338 #[default]
339 Simple,
340 Full,
341}