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