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)]
200 pub nulls_not_distinct: bool,
201 #[serde(default)]
203 pub without_overlaps: bool,
204}
205
206#[derive(Debug, Clone, Default, Serialize, Deserialize)]
211pub struct TableConstraintSet {
212 #[serde(default, skip_serializing_if = "Option::is_none")]
214 pub columns_declared: Option<bool>,
215 #[serde(default)]
216 pub checks: Vec<TableCheck>,
217 #[serde(default)]
218 pub foreign_keys: Vec<ForeignKey>,
219 #[serde(default)]
220 pub key_constraints: Vec<TableKeyConstraint>,
221 #[serde(default)]
223 pub persistence: RelationPersistence,
224 #[serde(default)]
226 pub on_commit: OnCommitAction,
227 #[serde(default)]
229 pub hierarchy: TableHierarchy,
230}
231
232#[derive(Debug, Clone, Serialize, Deserialize)]
235#[expect(
236 clippy::struct_excessive_bools,
237 reason = "CHECK catalog flags are independent PostgreSQL properties"
238)]
239pub struct TableCheck {
240 pub name: Option<String>,
241 #[serde(default, skip_serializing_if = "Option::is_none")]
243 pub object_id: Option<[u8; 16]>,
244 #[serde(default, skip_serializing_if = "Option::is_none")]
245 pub catalog_oid: Option<i64>,
246 #[serde(default = "default_true", skip_serializing_if = "is_true")]
248 pub is_local: bool,
249 pub expr: Expr,
250 #[serde(default = "default_true")]
251 pub enforced: bool,
252 #[serde(default = "default_true")]
253 pub validated: bool,
254 #[serde(default)]
255 pub no_inherit: bool,
256 #[serde(default, skip_serializing_if = "Option::is_none")]
258 pub partition_constraint: Option<DetachedPartitionConstraint>,
259}
260
261#[derive(Debug, Clone, Serialize, Deserialize)]
262pub struct DetachedPartitionConstraint {
263 pub spec: PartitionSpec,
264 pub bound: PartitionBound,
265}
266
267#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
269#[allow(clippy::struct_excessive_bools)]
270pub struct ForeignKey {
271 #[serde(default, skip_serializing_if = "Option::is_none")]
273 pub referenced_index: Option<[u8; 16]>,
274 #[serde(default, skip_serializing_if = "Option::is_none")]
276 pub referenced_key: Option<String>,
277 pub name: Option<String>,
278 #[serde(default, skip_serializing_if = "Option::is_none")]
280 pub object_id: Option<[u8; 16]>,
281 #[serde(default, skip_serializing_if = "Option::is_none")]
283 pub catalog_identity: Option<ConstraintCatalogIdentity>,
284 pub local_columns: Vec<String>,
285 pub ref_table: String,
286 pub ref_columns: Vec<String>,
287 #[serde(default)]
288 pub on_update: ForeignKeyAction,
289 #[serde(default)]
290 pub on_delete: ForeignKeyAction,
291 #[serde(default)]
295 pub on_delete_set_columns: Vec<String>,
296 #[serde(default)]
297 pub match_type: ForeignKeyMatch,
298 #[serde(default = "default_true")]
299 pub enforced: bool,
300 #[serde(default = "default_true")]
301 pub validated: bool,
302 #[serde(default)]
303 pub deferrable: bool,
304 #[serde(default)]
305 pub initially_deferred: bool,
306 #[serde(default)]
308 pub period: bool,
309}
310
311const fn default_true() -> bool {
312 true
313}
314
315#[expect(
316 clippy::trivially_copy_pass_by_ref,
317 reason = "serde skip_serializing_if requires a borrowed field"
318)]
319const fn is_true(value: &bool) -> bool {
320 *value
321}
322
323#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
324pub enum ForeignKeyAction {
325 #[default]
326 NoAction,
327 Restrict,
328 Cascade,
329 SetNull,
330 SetDefault,
331}
332
333#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
334pub enum ForeignKeyMatch {
335 #[default]
336 Simple,
337 Full,
338}