1use serde::{Deserialize, Serialize};
13
14mod constraints;
15mod cte;
16mod domains;
17mod events;
18mod expressions;
19mod from;
20mod function_binding;
21mod indexes;
22mod interval;
23mod locking;
24mod namespaces;
25mod ranges;
26mod relation_hierarchy;
27mod relation_lifecycle;
28mod routine_security;
29mod routines;
30mod sequence;
31mod types;
32
33pub use constraints::*;
34pub use cte::*;
35pub use domains::*;
36pub use events::*;
37pub use expressions::*;
38pub use from::*;
39pub use function_binding::*;
40pub use indexes::*;
41pub use interval::*;
42pub use locking::*;
43pub use namespaces::*;
44pub use ranges::*;
45pub use relation_hierarchy::*;
46pub use relation_lifecycle::*;
47pub use routine_security::*;
48pub use routines::*;
49pub use sequence::*;
50pub use types::*;
51
52const fn default_include_descendants() -> bool {
53 true
54}
55
56const fn default_true() -> bool {
57 true
58}
59
60#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
61pub enum GeneratedColumnKind {
62 Virtual,
63 Stored,
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize)]
67pub struct GeneratedColumn {
68 pub kind: GeneratedColumnKind,
69 pub expression: Box<Expr>,
70 #[serde(default, skip_serializing_if = "Vec::is_empty")]
71 pub function_dependencies: Vec<GeneratedFunctionDependency>,
72}
73
74#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
75pub struct IndexColumnOrder {
76 pub descending: bool,
77 pub nulls_first: bool,
78}
79
80#[derive(Debug, Clone, Serialize, Deserialize)]
81pub struct CreateIndex {
82 #[serde(default)]
83 pub included_columns: Vec<String>,
84 #[serde(default)]
85 pub column_order: Vec<IndexColumnOrder>,
86 #[serde(default)]
87 pub predicate: Option<Box<Expr>>,
88 pub name: Option<String>,
89 pub table: String,
90 pub access_method: String,
92 pub columns: Vec<IndexKey>,
93 #[serde(default)]
94 pub unique: bool,
95 #[serde(default)]
96 pub nulls_not_distinct: bool,
97 pub if_not_exists: bool,
99 pub options: Vec<(String, String)>,
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct DropStmt {
107 pub kind: DropKind,
108 pub names: Vec<String>,
109 pub if_exists: bool,
110 pub cascade: bool,
111}
112
113#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
114pub enum DropKind {
115 Table,
116 ForeignTable,
117 Index,
118 View,
119 MaterializedView,
120 Schema,
121 Sequence,
122 Domain,
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize)]
126pub struct AlterTableStmt {
127 pub table: String,
128 pub qualifier: String,
130 pub if_exists: bool,
131 #[serde(default = "default_true")]
133 pub recurse: bool,
134 pub actions: Vec<AlterTableAction>,
135}
136
137#[derive(Debug, Clone, Serialize, Deserialize)]
138#[expect(
139 clippy::large_enum_variant,
140 reason = "preserves the stable AST serde shape"
141)]
142pub enum AlterTableAction {
143 AddInheritance {
144 parent: String,
145 },
146 DropInheritance {
147 parent: String,
148 },
149 AttachPartition {
150 partition: String,
151 bound: PartitionBound,
152 },
153 DetachPartition {
154 partition: String,
155 concurrently: bool,
156 finalize: bool,
157 },
158 AddColumn {
159 column: ColumnDef,
160 if_not_exists: bool,
161 },
162 AddKeyConstraint {
163 constraint: TableKeyConstraint,
164 },
165 AddCheckConstraint {
166 constraint: TableCheck,
167 },
168 AddForeignKeyConstraint {
169 constraint: ForeignKey,
170 },
171 AddNotNullConstraint {
172 name: Option<String>,
173 column: String,
174 validated: bool,
175 no_inherit: bool,
176 },
177 ValidateConstraint {
178 name: String,
179 },
180 AlterConstraint {
181 name: String,
182 enforceability: Option<bool>,
183 deferrability: Option<(bool, bool)>,
184 no_inherit: Option<bool>,
185 },
186 DropConstraint {
187 name: String,
188 if_exists: bool,
189 cascade: bool,
190 },
191 DropColumn {
192 name: String,
193 if_exists: bool,
194 cascade: bool,
195 },
196 RenameColumn {
197 from: String,
198 to: String,
199 },
200 RenameTable {
201 to: String,
202 },
203 RenameTrigger {
204 from: String,
205 to: String,
206 },
207 RenameConstraint {
208 from: String,
209 to: String,
210 },
211 RenameRule {
212 from: String,
213 to: String,
214 },
215 SetPersistence {
216 persistence: RelationPersistence,
217 },
218 ChangeOwner {
219 owner: String,
220 },
221 SetSchema {
222 schema: String,
223 },
224 SetTriggerEnableMode {
225 name: Option<String>,
226 user_only: bool,
227 mode: EventEnableMode,
228 },
229 SetRuleEnableMode {
230 name: String,
231 mode: EventEnableMode,
232 },
233 SetDefault {
234 name: String,
235 default: Expr,
236 },
237 DropDefault {
238 name: String,
239 },
240 SetExpression {
241 name: String,
242 expression: Expr,
243 },
244 DropExpression {
245 name: String,
246 },
247 SetNotNull {
248 name: String,
249 },
250 DropNotNull {
251 name: String,
252 },
253 AlterColumnType {
254 name: String,
255 ty: ColumnType,
256 #[serde(default, skip_serializing_if = "Option::is_none")]
257 using: Option<Expr>,
258 },
259}
260
261#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
262pub struct InsertStmt {
263 pub table: String,
264 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
266 pub target_relation_bound: bool,
267 pub target_qualifier: String,
269 #[serde(default = "default_include_descendants")]
270 pub include_descendants: bool,
271 pub columns: Vec<String>,
272 pub with: Vec<CTE>,
274 pub rows: Vec<Vec<ValueExpr>>,
276 pub select_source: Option<Box<SelectStmt>>,
280 pub on_conflict: Option<OnConflict>,
283 pub returning: Vec<Projection>,
285 pub returning_aliases: ReturningAliases,
288}
289
290#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
291pub struct ReturningAliases {
292 pub old: String,
293 pub new: String,
294 #[serde(default)]
295 pub old_explicit: bool,
296 #[serde(default)]
297 pub new_explicit: bool,
298}
299
300impl Default for ReturningAliases {
301 fn default() -> Self {
302 Self {
303 old: "old".into(),
304 new: "new".into(),
305 old_explicit: false,
306 new_explicit: false,
307 }
308 }
309}
310
311#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
312pub struct OnConflict {
313 #[serde(default)]
314 pub predicate: Option<Box<Expr>>,
315 #[serde(default)]
316 pub constraint: Option<String>,
317 pub conflict_columns: Vec<String>,
321 #[serde(default)]
322 pub expressions: Vec<Expr>,
323 pub action: OnConflictAction,
324}
325
326#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
327pub enum OnConflictAction {
328 Nothing,
330 Update {
334 assignments: Vec<(String, Expr)>,
335 r#where: Option<Box<Expr>>,
336 },
337}
338
339#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
340pub struct SelectStmt {
341 pub projections: Vec<Projection>,
342 #[serde(default, skip_serializing_if = "Vec::is_empty")]
346 pub values: Vec<Vec<Expr>>,
347 pub from: Option<FromClause>,
348 pub r#where: Option<Expr>,
349 pub group_by: Vec<Expr>,
350 pub grouping_sets: Vec<Vec<Expr>>,
356 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
358 pub group_distinct: bool,
359 pub having: Option<Expr>,
363 pub order_by: Vec<OrderBy>,
364 pub limit: Option<Expr>,
368 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
370 pub with_ties: bool,
371 pub offset: Option<Expr>,
373 pub with: Vec<CTE>,
375 pub set_op: Option<Box<SetOp>>,
379 pub distinct: bool,
382 pub distinct_on: Vec<Expr>,
385 #[serde(default, skip_serializing_if = "Vec::is_empty")]
387 pub locking: Vec<LockingClause>,
388}
389
390#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
391pub struct SetOp {
392 pub kind: SetOpKind,
393 pub all: bool,
394 #[serde(default, skip_serializing_if = "Option::is_none")]
398 pub left: Option<Box<SelectStmt>>,
399 pub right: SelectStmt,
400 pub combined_order_by: Vec<OrderBy>,
403 pub combined_limit: Option<Expr>,
406 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
408 pub combined_with_ties: bool,
409 pub combined_offset: Option<Expr>,
411}
412
413#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
414pub enum SetOpKind {
415 Union,
416 Intersect,
417 Except,
418}
419
420#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
422pub enum DiscardTarget {
423 All,
424 Plans,
425 Sequences,
426 Temp,
427}
428
429#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
430pub struct UpdateStmt {
431 pub table: String,
432 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
434 pub target_relation_bound: bool,
435 pub target_qualifier: String,
436 #[serde(default = "default_include_descendants")]
437 pub include_descendants: bool,
438 pub assignments: Vec<(String, Expr)>,
439 pub r#where: Option<Expr>,
440 pub with: Vec<CTE>,
442 pub from: Option<FromClause>,
445 pub returning: Vec<Projection>,
447 pub returning_aliases: ReturningAliases,
448}
449
450#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
451pub struct DeleteStmt {
452 pub table: String,
453 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
455 pub target_relation_bound: bool,
456 pub target_qualifier: String,
457 #[serde(default = "default_include_descendants")]
458 pub include_descendants: bool,
459 pub r#where: Option<Expr>,
460 pub with: Vec<CTE>,
462 pub using: Option<FromClause>,
466 pub returning: Vec<Projection>,
468 pub returning_aliases: ReturningAliases,
469}
470
471#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
472pub struct SetConstraintName {
473 pub catalog: Option<String>,
474 pub schema: Option<String>,
475 pub name: String,
476}
477
478#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
480pub struct VacuumOption {
481 pub name: String,
482 pub value: Option<VacuumOptionValue>,
483}
484
485#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
486pub enum VacuumOptionValue {
487 Boolean(bool),
488 Integer(i32),
489 String(String),
490}
491
492#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
494pub struct VacuumTarget {
495 pub catalog: Option<String>,
496 pub table: String,
497 #[serde(default = "default_include_descendants")]
498 pub include_descendants: bool,
499 #[serde(default, skip_serializing_if = "Vec::is_empty")]
500 pub columns: Vec<String>,
501}
502
503#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
504pub struct VacuumStmt {
505 #[serde(default, skip_serializing_if = "Vec::is_empty")]
506 pub options: Vec<VacuumOption>,
507 #[serde(default, skip_serializing_if = "Vec::is_empty")]
508 pub targets: Vec<VacuumTarget>,
509}
510
511#[derive(Debug, Clone, Serialize, Deserialize)]
512pub enum Statement {
513 CreateDomain(CreateDomain),
514 CreateTable(CreateTable),
515 CreateTableIfNotExists(DeferredCreateTable),
516 CreateIndex(CreateIndex),
517 Insert(InsertStmt),
518 Select(Box<SelectStmt>),
522 Update(UpdateStmt),
523 Delete(DeleteStmt),
524 Drop(DropStmt),
525 AlterTable(AlterTableStmt),
526 AlterForeignTable(AlterForeignTableStmt),
527 AlterView(AlterViewStmt),
528 CreateView {
530 name: String,
531 #[serde(default)]
532 column_names: Vec<String>,
533 body: Box<SelectStmt>,
534 or_replace: bool,
535 #[serde(default)]
536 persistence: RelationPersistence,
537 #[serde(default, skip_serializing_if = "Vec::is_empty")]
539 options: Vec<(String, String)>,
540 },
541 CreateMaterializedView {
543 name: String,
544 #[serde(default)]
545 column_names: Vec<String>,
546 #[serde(default)]
547 if_not_exists: bool,
548 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
549 with_no_data: bool,
550 #[serde(default, skip_serializing_if = "Vec::is_empty")]
551 options: Vec<(String, String)>,
552 body: Box<SelectStmt>,
553 },
554 RefreshMaterializedView {
556 name: String,
557 concurrently: bool,
558 with_no_data: bool,
559 },
560 CreateSchema {
562 name: Option<String>,
563 if_not_exists: bool,
564 #[serde(default, skip_serializing_if = "Option::is_none")]
565 authorization: Option<SchemaAuthorization>,
566 },
567 AlterSchemaOwner {
568 name: String,
569 new_owner: String,
570 },
571 Notify {
573 channel: String,
574 payload: String,
575 },
576 Listen {
578 channel: String,
579 },
580 Unlisten {
582 channel: Option<String>,
583 },
584 SetVariable {
588 name: String,
589 value: String,
590 #[serde(default)]
591 local: bool,
592 #[serde(default)]
593 is_default: bool,
594 },
595 ResetVariable {
597 name: String,
598 },
599 ResetAllVariables,
601 SetConstraints {
603 constraints: Vec<SetConstraintName>,
604 deferred: bool,
605 },
606 ShowVariable {
609 name: String,
610 },
611 Discard {
614 target: DiscardTarget,
615 },
616 Load {
621 library: String,
622 },
623 Explain {
626 analyze: bool,
627 verbose: bool,
628 format: Option<String>,
629 body: Box<Statement>,
630 },
631 Analyze {
634 table: Option<String>,
635 },
636 Vacuum(VacuumStmt),
638 Truncate {
641 tables: Vec<TruncateTarget>,
642 cascade: bool,
643 #[serde(default)]
644 restart_identity: bool,
645 },
646 Transaction(TransactionStmt),
648 DeclareCursor(DeclareCursorStmt),
650 FetchCursor(FetchCursorStmt),
652 CloseCursor {
654 name: Option<String>,
655 },
656 CreateSequence(CreateSequence),
658 AlterSequence(AlterSequence),
661 CreateTableAs {
663 name: String,
664 if_not_exists: bool,
665 #[serde(default, skip_serializing_if = "Vec::is_empty")]
666 column_names: Vec<String>,
667 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
668 with_no_data: bool,
669 #[serde(default)]
670 persistence: RelationPersistence,
671 #[serde(default)]
672 on_commit: OnCommitAction,
673 body: Box<SelectStmt>,
674 },
675 Prepare {
677 name: String,
678 #[serde(default)]
679 parameter_types: Vec<ColumnType>,
680 body: Box<Statement>,
681 },
682 Execute {
684 name: String,
685 params: Vec<Expr>,
686 },
687 Deallocate {
689 name: Option<String>,
690 },
691 Values {
694 rows: Vec<Vec<Expr>>,
695 },
696 CreateForeignServer(CreateForeignServer),
698 CreateForeignTable(CreateForeignTable),
700 CreateForeignTableIfNotExists(DeferredCreateForeignTable),
702 Merge(MergeStmt),
705 CreateFunction(Box<CreateFunction>),
708 DropFunction(DropFunctionStmt),
710 AlterRoutine(AlterRoutineStmt),
712 AlterRoutineOwner(AlterRoutineOwnerStmt),
713 RenameRoutine(RenameRoutineStmt),
714 GrantRoutine(GrantRoutineStmt),
715 GrantTable(GrantTableStmt),
716 GrantSequence(GrantSequenceStmt),
717 GrantDatabase(GrantDatabaseStmt),
718 GrantSchema(GrantSchemaStmt),
719 GrantRole(GrantRoleStmt),
720 CreateRole(CreateRoleStmt),
721 AlterRole(AlterRoleStmt),
722 DropRole(DropRoleStmt),
723 CreateTrigger(CreateTrigger),
725 DropTrigger(DropTrigger),
727 CreateRule(CreateRule),
729 DropRule(DropRule),
731 DoBlock {
733 language: String,
734 body: String,
735 },
736 Call {
739 name: String,
740 args: Vec<Expr>,
741 },
742}
743
744#[derive(Debug, Clone, Serialize, Deserialize)]
745pub struct TruncateTarget {
746 pub table: String,
747 #[serde(default = "default_include_descendants")]
748 pub include_descendants: bool,
749}
750
751#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
752pub struct MergeTargetColumnBinding {
753 pub object_id: [u8; 16],
754 #[serde(default, skip_serializing_if = "std::collections::BTreeSet::is_empty")]
756 pub domain_dependencies: std::collections::BTreeSet<u32>,
757}
758
759#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
760pub struct MergeStmt {
761 #[serde(default)]
762 pub with: Vec<CTE>,
763 pub target: String,
764 pub target_qualifier: String,
765 pub target_alias: Option<String>,
766 #[serde(default, skip_serializing_if = "std::collections::BTreeMap::is_empty")]
768 pub target_column_bindings: std::collections::BTreeMap<String, MergeTargetColumnBinding>,
769 #[serde(default = "default_include_descendants")]
770 pub include_descendants: bool,
771 pub source: FromClause,
772 pub join_condition: Expr,
773 pub when_clauses: Vec<MergeWhen>,
774 pub returning: Vec<Projection>,
776 pub returning_aliases: ReturningAliases,
777}
778
779#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
780pub enum MergeWhen {
781 UpdateMatched {
783 condition: Option<Expr>,
784 assignments: Vec<(String, Expr)>,
785 },
786 DeleteMatched { condition: Option<Expr> },
788 UpdateNotMatchedBySource {
790 condition: Option<Expr>,
791 assignments: Vec<(String, Expr)>,
792 },
793 DeleteNotMatchedBySource { condition: Option<Expr> },
795 InsertNotMatched {
797 condition: Option<Expr>,
798 columns: Vec<String>,
799 values: Vec<Expr>,
800 },
801 NothingMatched { condition: Option<Expr> },
803 NothingNotMatched { condition: Option<Expr> },
805 NothingNotMatchedBySource { condition: Option<Expr> },
807}
808
809#[derive(Debug, Clone, Serialize, Deserialize)]
810pub struct CreateForeignServer {
811 pub name: String,
812 pub fdw_type: String,
813 pub options: Vec<(String, String)>,
814 pub if_not_exists: bool,
815}
816
817#[derive(Debug, Clone, Serialize, Deserialize)]
818pub struct CreateForeignTable {
819 pub name: String,
820 pub server_name: String,
821 pub columns: Vec<ColumnDef>,
822 #[serde(default)]
823 pub checks: Vec<TableCheck>,
824 pub options: Vec<(String, String)>,
825 pub if_not_exists: bool,
826}
827
828#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
830pub struct DeferredCreateForeignTable {
831 pub name: String,
832 pub server_name: String,
833 pub definition_sql: String,
834}
835
836#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
837pub enum TransactionIsolationLevel {
838 ReadUncommitted,
839 ReadCommitted,
840 RepeatableRead,
841 Serializable,
842}
843
844impl TransactionIsolationLevel {
845 #[must_use]
846 pub const fn as_str(self) -> &'static str {
847 match self {
848 Self::ReadUncommitted => "read uncommitted",
849 Self::ReadCommitted => "read committed",
850 Self::RepeatableRead => "repeatable read",
851 Self::Serializable => "serializable",
852 }
853 }
854}
855
856#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
857pub struct TransactionCharacteristics {
858 pub isolation: Option<TransactionIsolationLevel>,
859 pub read_only: Option<bool>,
860 pub deferrable: Option<bool>,
861}
862
863#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
864pub enum TransactionStmt {
865 Begin,
866 BeginWithCharacteristics(TransactionCharacteristics),
867 Commit,
868 CommitAndChain,
869 Rollback,
870 RollbackAndChain,
871 SetCharacteristics(TransactionCharacteristics),
872 SetSessionCharacteristics(TransactionCharacteristics),
873 SetSnapshot(String),
874 Savepoint(String),
875 ReleaseSavepoint(String),
876 RollbackToSavepoint(String),
877}
878
879#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
880pub enum CursorDirection {
881 Forward,
882 Backward,
883 Absolute,
884 Relative,
885}
886
887#[derive(Debug, Clone, Serialize, Deserialize)]
888pub struct DeclareCursorStmt {
889 pub name: String,
890 pub binary: bool,
891 pub scroll: Option<bool>,
893 pub hold: bool,
894 pub query: Box<SelectStmt>,
895}
896
897#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
898pub struct FetchCursorStmt {
899 pub name: String,
900 pub direction: CursorDirection,
901 pub count: i64,
903 pub move_only: bool,
904}
905
906#[cfg(test)]
907mod tests;