1use serde::{Deserialize, Serialize};
13
14mod constraints;
15mod cte;
16mod events;
17mod expressions;
18mod from;
19mod function_binding;
20mod indexes;
21mod locking;
22mod ranges;
23mod relation_hierarchy;
24mod relation_lifecycle;
25mod routine_security;
26mod routines;
27mod sequence;
28mod types;
29
30pub use constraints::*;
31pub use cte::*;
32pub use events::*;
33pub use expressions::*;
34pub use from::*;
35pub use function_binding::*;
36pub use indexes::*;
37pub use locking::*;
38pub use ranges::*;
39pub use relation_hierarchy::*;
40pub use relation_lifecycle::*;
41pub use routine_security::*;
42pub use routines::*;
43pub use sequence::*;
44pub use types::*;
45
46const fn default_include_descendants() -> bool {
47 true
48}
49
50const fn default_true() -> bool {
51 true
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
55pub enum GeneratedColumnKind {
56 Virtual,
57 Stored,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize)]
61pub struct GeneratedColumn {
62 pub kind: GeneratedColumnKind,
63 pub expression: Box<Expr>,
64 #[serde(default, skip_serializing_if = "Vec::is_empty")]
65 pub function_dependencies: Vec<GeneratedFunctionDependency>,
66}
67
68#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
69pub struct IndexColumnOrder {
70 pub descending: bool,
71 pub nulls_first: bool,
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct CreateIndex {
76 #[serde(default)]
77 pub included_columns: Vec<String>,
78 #[serde(default)]
79 pub column_order: Vec<IndexColumnOrder>,
80 #[serde(default)]
81 pub predicate: Option<Box<Expr>>,
82 pub name: Option<String>,
83 pub table: String,
84 pub access_method: String,
86 pub columns: Vec<IndexKey>,
87 #[serde(default)]
88 pub unique: bool,
89 #[serde(default)]
90 pub nulls_not_distinct: bool,
91 pub if_not_exists: bool,
93 pub options: Vec<(String, String)>,
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize)]
100pub struct DropStmt {
101 pub kind: DropKind,
102 pub names: Vec<String>,
103 pub if_exists: bool,
104 pub cascade: bool,
105}
106
107#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
108pub enum DropKind {
109 Table,
110 ForeignTable,
111 Index,
112 View,
113 MaterializedView,
114 Schema,
115 Sequence,
116}
117
118#[derive(Debug, Clone, Serialize, Deserialize)]
119pub struct AlterTableStmt {
120 pub table: String,
121 pub qualifier: String,
123 pub if_exists: bool,
124 #[serde(default = "default_true")]
126 pub recurse: bool,
127 pub actions: Vec<AlterTableAction>,
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize)]
131#[expect(
132 clippy::large_enum_variant,
133 reason = "preserves the stable AST serde shape"
134)]
135pub enum AlterTableAction {
136 AddInheritance {
137 parent: String,
138 },
139 DropInheritance {
140 parent: String,
141 },
142 AttachPartition {
143 partition: String,
144 bound: PartitionBound,
145 },
146 DetachPartition {
147 partition: String,
148 concurrently: bool,
149 finalize: bool,
150 },
151 AddColumn {
152 column: ColumnDef,
153 if_not_exists: bool,
154 },
155 AddKeyConstraint {
156 constraint: TableKeyConstraint,
157 },
158 AddCheckConstraint {
159 constraint: TableCheck,
160 },
161 AddForeignKeyConstraint {
162 constraint: ForeignKey,
163 },
164 AddNotNullConstraint {
165 name: Option<String>,
166 column: String,
167 validated: bool,
168 no_inherit: bool,
169 },
170 ValidateConstraint {
171 name: String,
172 },
173 AlterConstraint {
174 name: String,
175 enforceability: Option<bool>,
176 deferrability: Option<(bool, bool)>,
177 no_inherit: Option<bool>,
178 },
179 DropConstraint {
180 name: String,
181 if_exists: bool,
182 cascade: bool,
183 },
184 DropColumn {
185 name: String,
186 if_exists: bool,
187 cascade: bool,
188 },
189 RenameColumn {
190 from: String,
191 to: String,
192 },
193 RenameTable {
194 to: String,
195 },
196 RenameTrigger {
197 from: String,
198 to: String,
199 },
200 RenameConstraint {
201 from: String,
202 to: String,
203 },
204 RenameRule {
205 from: String,
206 to: String,
207 },
208 SetPersistence {
209 persistence: RelationPersistence,
210 },
211 ChangeOwner {
212 owner: String,
213 },
214 SetSchema {
215 schema: String,
216 },
217 SetTriggerEnableMode {
218 name: Option<String>,
219 user_only: bool,
220 mode: EventEnableMode,
221 },
222 SetRuleEnableMode {
223 name: String,
224 mode: EventEnableMode,
225 },
226 SetDefault {
227 name: String,
228 default: Expr,
229 },
230 DropDefault {
231 name: String,
232 },
233 SetExpression {
234 name: String,
235 expression: Expr,
236 },
237 DropExpression {
238 name: String,
239 },
240 SetNotNull {
241 name: String,
242 },
243 DropNotNull {
244 name: String,
245 },
246 AlterColumnType {
247 name: String,
248 ty: ColumnType,
249 #[serde(default, skip_serializing_if = "Option::is_none")]
250 using: Option<Expr>,
251 },
252}
253
254#[derive(Debug, Clone, Serialize, Deserialize)]
255pub struct InsertStmt {
256 pub table: String,
257 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
259 pub target_relation_bound: bool,
260 pub target_qualifier: String,
262 #[serde(default = "default_include_descendants")]
263 pub include_descendants: bool,
264 pub columns: Vec<String>,
265 pub with: Vec<CTE>,
267 pub rows: Vec<Vec<ValueExpr>>,
269 pub select_source: Option<Box<SelectStmt>>,
273 pub on_conflict: Option<OnConflict>,
276 pub returning: Vec<Projection>,
278 pub returning_aliases: ReturningAliases,
281}
282
283#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
284pub struct ReturningAliases {
285 pub old: String,
286 pub new: String,
287 #[serde(default)]
288 pub old_explicit: bool,
289 #[serde(default)]
290 pub new_explicit: bool,
291}
292
293impl Default for ReturningAliases {
294 fn default() -> Self {
295 Self {
296 old: "old".into(),
297 new: "new".into(),
298 old_explicit: false,
299 new_explicit: false,
300 }
301 }
302}
303
304#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
305pub struct OnConflict {
306 #[serde(default)]
307 pub predicate: Option<Box<Expr>>,
308 #[serde(default)]
309 pub constraint: Option<String>,
310 pub conflict_columns: Vec<String>,
314 #[serde(default)]
315 pub expressions: Vec<Expr>,
316 pub action: OnConflictAction,
317}
318
319#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
320pub enum OnConflictAction {
321 Nothing,
323 Update {
327 assignments: Vec<(String, Expr)>,
328 r#where: Option<Box<Expr>>,
329 },
330}
331
332#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
333pub struct SelectStmt {
334 pub projections: Vec<Projection>,
335 #[serde(default, skip_serializing_if = "Vec::is_empty")]
339 pub values: Vec<Vec<Expr>>,
340 pub from: Option<FromClause>,
341 pub r#where: Option<Expr>,
342 pub group_by: Vec<Expr>,
343 pub grouping_sets: Vec<Vec<Expr>>,
349 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
351 pub group_distinct: bool,
352 pub having: Option<Expr>,
356 pub order_by: Vec<OrderBy>,
357 pub limit: Option<Expr>,
361 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
363 pub with_ties: bool,
364 pub offset: Option<Expr>,
366 pub with: Vec<CTE>,
368 pub set_op: Option<Box<SetOp>>,
372 pub distinct: bool,
375 pub distinct_on: Vec<Expr>,
378 #[serde(default, skip_serializing_if = "Vec::is_empty")]
380 pub locking: Vec<LockingClause>,
381}
382
383#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
384pub struct SetOp {
385 pub kind: SetOpKind,
386 pub all: bool,
387 #[serde(default, skip_serializing_if = "Option::is_none")]
391 pub left: Option<Box<SelectStmt>>,
392 pub right: SelectStmt,
393 pub combined_order_by: Vec<OrderBy>,
396 pub combined_limit: Option<Expr>,
399 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
401 pub combined_with_ties: bool,
402 pub combined_offset: Option<Expr>,
404}
405
406#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
407pub enum SetOpKind {
408 Union,
409 Intersect,
410 Except,
411}
412
413#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
415pub enum DiscardTarget {
416 All,
417 Plans,
418 Sequences,
419 Temp,
420}
421
422#[derive(Debug, Clone, Serialize, Deserialize)]
423pub struct UpdateStmt {
424 pub table: String,
425 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
427 pub target_relation_bound: bool,
428 pub target_qualifier: String,
429 #[serde(default = "default_include_descendants")]
430 pub include_descendants: bool,
431 pub assignments: Vec<(String, Expr)>,
432 pub r#where: Option<Expr>,
433 pub with: Vec<CTE>,
435 pub from: Option<FromClause>,
438 pub returning: Vec<Projection>,
440 pub returning_aliases: ReturningAliases,
441}
442
443#[derive(Debug, Clone, Serialize, Deserialize)]
444pub struct DeleteStmt {
445 pub table: String,
446 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
448 pub target_relation_bound: bool,
449 pub target_qualifier: String,
450 #[serde(default = "default_include_descendants")]
451 pub include_descendants: bool,
452 pub r#where: Option<Expr>,
453 pub with: Vec<CTE>,
455 pub using: Option<FromClause>,
459 pub returning: Vec<Projection>,
461 pub returning_aliases: ReturningAliases,
462}
463
464#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
465pub struct SetConstraintName {
466 pub catalog: Option<String>,
467 pub schema: Option<String>,
468 pub name: String,
469}
470
471#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
473pub struct VacuumOption {
474 pub name: String,
475 pub value: Option<VacuumOptionValue>,
476}
477
478#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
479pub enum VacuumOptionValue {
480 Boolean(bool),
481 Integer(i32),
482 String(String),
483}
484
485#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
487pub struct VacuumTarget {
488 pub catalog: Option<String>,
489 pub table: String,
490 #[serde(default = "default_include_descendants")]
491 pub include_descendants: bool,
492 #[serde(default, skip_serializing_if = "Vec::is_empty")]
493 pub columns: Vec<String>,
494}
495
496#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
497pub struct VacuumStmt {
498 #[serde(default, skip_serializing_if = "Vec::is_empty")]
499 pub options: Vec<VacuumOption>,
500 #[serde(default, skip_serializing_if = "Vec::is_empty")]
501 pub targets: Vec<VacuumTarget>,
502}
503
504#[derive(Debug, Clone, Serialize, Deserialize)]
505pub enum Statement {
506 CreateTable(CreateTable),
507 CreateTableIfNotExists(DeferredCreateTable),
508 CreateIndex(CreateIndex),
509 Insert(InsertStmt),
510 Select(Box<SelectStmt>),
514 Update(UpdateStmt),
515 Delete(DeleteStmt),
516 Drop(DropStmt),
517 AlterTable(AlterTableStmt),
518 AlterForeignTable(AlterForeignTableStmt),
519 AlterView(AlterViewStmt),
520 CreateView {
522 name: String,
523 #[serde(default)]
524 column_names: Vec<String>,
525 body: Box<SelectStmt>,
526 or_replace: bool,
527 #[serde(default)]
528 persistence: RelationPersistence,
529 #[serde(default, skip_serializing_if = "Vec::is_empty")]
531 options: Vec<(String, String)>,
532 },
533 CreateMaterializedView {
535 name: String,
536 #[serde(default)]
537 column_names: Vec<String>,
538 #[serde(default)]
539 if_not_exists: bool,
540 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
541 with_no_data: bool,
542 #[serde(default, skip_serializing_if = "Vec::is_empty")]
543 options: Vec<(String, String)>,
544 body: Box<SelectStmt>,
545 },
546 RefreshMaterializedView {
548 name: String,
549 concurrently: bool,
550 with_no_data: bool,
551 },
552 CreateSchema {
556 name: String,
557 if_not_exists: bool,
558 },
559 Notify {
561 channel: String,
562 payload: String,
563 },
564 Listen {
566 channel: String,
567 },
568 Unlisten {
570 channel: Option<String>,
571 },
572 SetVariable {
576 name: String,
577 value: String,
578 },
579 ResetVariable {
581 name: String,
582 },
583 ResetAllVariables,
585 SetConstraints {
587 constraints: Vec<SetConstraintName>,
588 deferred: bool,
589 },
590 ShowVariable {
593 name: String,
594 },
595 Discard {
598 target: DiscardTarget,
599 },
600 Load {
605 library: String,
606 },
607 Explain {
610 analyze: bool,
611 verbose: bool,
612 format: Option<String>,
613 body: Box<Statement>,
614 },
615 Analyze {
618 table: Option<String>,
619 },
620 Vacuum(VacuumStmt),
622 Truncate {
625 tables: Vec<TruncateTarget>,
626 cascade: bool,
627 #[serde(default)]
628 restart_identity: bool,
629 },
630 Transaction(TransactionStmt),
632 DeclareCursor(DeclareCursorStmt),
634 FetchCursor(FetchCursorStmt),
636 CloseCursor {
638 name: Option<String>,
639 },
640 CreateSequence(CreateSequence),
642 AlterSequence(AlterSequence),
645 CreateTableAs {
647 name: String,
648 if_not_exists: bool,
649 #[serde(default, skip_serializing_if = "Vec::is_empty")]
650 column_names: Vec<String>,
651 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
652 with_no_data: bool,
653 #[serde(default)]
654 persistence: RelationPersistence,
655 #[serde(default)]
656 on_commit: OnCommitAction,
657 body: Box<SelectStmt>,
658 },
659 Prepare {
661 name: String,
662 body: Box<Statement>,
663 },
664 Execute {
666 name: String,
667 params: Vec<Expr>,
668 },
669 Deallocate {
671 name: Option<String>,
672 },
673 Values {
676 rows: Vec<Vec<Expr>>,
677 },
678 CreateForeignServer(CreateForeignServer),
680 CreateForeignTable(CreateForeignTable),
682 CreateForeignTableIfNotExists(DeferredCreateForeignTable),
684 Merge(MergeStmt),
687 CreateFunction(Box<CreateFunction>),
690 DropFunction(DropFunctionStmt),
692 AlterRoutine(AlterRoutineStmt),
694 AlterRoutineOwner(AlterRoutineOwnerStmt),
695 RenameRoutine(RenameRoutineStmt),
696 GrantRoutine(GrantRoutineStmt),
697 GrantTable(GrantTableStmt),
698 GrantSequence(GrantSequenceStmt),
699 GrantDatabase(GrantDatabaseStmt),
700 GrantSchema(GrantSchemaStmt),
701 GrantRole(GrantRoleStmt),
702 CreateRole(CreateRoleStmt),
703 AlterRole(AlterRoleStmt),
704 DropRole(DropRoleStmt),
705 CreateTrigger(CreateTrigger),
707 DropTrigger(DropTrigger),
709 CreateRule(CreateRule),
711 DropRule(DropRule),
713 DoBlock {
715 language: String,
716 body: String,
717 },
718 Call {
721 name: String,
722 args: Vec<Expr>,
723 },
724}
725
726#[derive(Debug, Clone, Serialize, Deserialize)]
727pub struct TruncateTarget {
728 pub table: String,
729 #[serde(default = "default_include_descendants")]
730 pub include_descendants: bool,
731}
732
733#[derive(Debug, Clone, Serialize, Deserialize)]
734pub struct MergeStmt {
735 pub target: String,
736 pub target_qualifier: String,
737 pub target_alias: Option<String>,
738 #[serde(default = "default_include_descendants")]
739 pub include_descendants: bool,
740 pub source: FromClause,
741 pub join_condition: Expr,
742 pub when_clauses: Vec<MergeWhen>,
743 pub returning: Vec<Projection>,
745 pub returning_aliases: ReturningAliases,
746}
747
748#[derive(Debug, Clone, Serialize, Deserialize)]
749pub enum MergeWhen {
750 UpdateMatched {
752 condition: Option<Expr>,
753 assignments: Vec<(String, Expr)>,
754 },
755 DeleteMatched { condition: Option<Expr> },
757 UpdateNotMatchedBySource {
759 condition: Option<Expr>,
760 assignments: Vec<(String, Expr)>,
761 },
762 DeleteNotMatchedBySource { condition: Option<Expr> },
764 InsertNotMatched {
766 condition: Option<Expr>,
767 columns: Vec<String>,
768 values: Vec<Expr>,
769 },
770 NothingMatched { condition: Option<Expr> },
772 NothingNotMatched { condition: Option<Expr> },
774 NothingNotMatchedBySource { condition: Option<Expr> },
776}
777
778#[derive(Debug, Clone, Serialize, Deserialize)]
779pub struct CreateForeignServer {
780 pub name: String,
781 pub fdw_type: String,
782 pub options: Vec<(String, String)>,
783 pub if_not_exists: bool,
784}
785
786#[derive(Debug, Clone, Serialize, Deserialize)]
787pub struct CreateForeignTable {
788 pub name: String,
789 pub server_name: String,
790 pub columns: Vec<ColumnDef>,
791 #[serde(default)]
792 pub checks: Vec<TableCheck>,
793 pub options: Vec<(String, String)>,
794 pub if_not_exists: bool,
795}
796
797#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
799pub struct DeferredCreateForeignTable {
800 pub name: String,
801 pub server_name: String,
802 pub definition_sql: String,
803}
804
805#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
806pub enum TransactionIsolationLevel {
807 ReadUncommitted,
808 ReadCommitted,
809 RepeatableRead,
810 Serializable,
811}
812
813impl TransactionIsolationLevel {
814 #[must_use]
815 pub const fn as_str(self) -> &'static str {
816 match self {
817 Self::ReadUncommitted => "read uncommitted",
818 Self::ReadCommitted => "read committed",
819 Self::RepeatableRead => "repeatable read",
820 Self::Serializable => "serializable",
821 }
822 }
823}
824
825#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
826pub struct TransactionCharacteristics {
827 pub isolation: Option<TransactionIsolationLevel>,
828 pub read_only: Option<bool>,
829 pub deferrable: Option<bool>,
830}
831
832#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
833pub enum TransactionStmt {
834 Begin,
835 BeginWithCharacteristics(TransactionCharacteristics),
836 Commit,
837 CommitAndChain,
838 Rollback,
839 RollbackAndChain,
840 SetCharacteristics(TransactionCharacteristics),
841 SetSessionCharacteristics(TransactionCharacteristics),
842 SetSnapshot(String),
843 Savepoint(String),
844 ReleaseSavepoint(String),
845 RollbackToSavepoint(String),
846}
847
848#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
849pub enum CursorDirection {
850 Forward,
851 Backward,
852 Absolute,
853 Relative,
854}
855
856#[derive(Debug, Clone, Serialize, Deserialize)]
857pub struct DeclareCursorStmt {
858 pub name: String,
859 pub binary: bool,
860 pub scroll: Option<bool>,
862 pub hold: bool,
863 pub query: Box<SelectStmt>,
864}
865
866#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
867pub struct FetchCursorStmt {
868 pub name: String,
869 pub direction: CursorDirection,
870 pub count: i64,
872 pub move_only: bool,
873}
874
875#[cfg(test)]
876mod tests;