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 #[serde(default, skip_serializing_if = "Vec::is_empty")]
111 pub option_namespaces: Vec<String>,
112}
113
114#[derive(Debug, Clone, Serialize, Deserialize)]
115pub struct DropStmt {
116 pub kind: DropKind,
117 pub names: Vec<String>,
118 pub if_exists: bool,
119 pub cascade: bool,
120}
121
122#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
123pub enum DropKind {
124 Table,
125 ForeignTable,
126 Index,
127 View,
128 MaterializedView,
129 Schema,
130 Sequence,
131 Domain,
132}
133
134#[derive(Debug, Clone, Serialize, Deserialize)]
135pub struct AlterTableStmt {
136 pub table: String,
137 pub qualifier: String,
139 pub if_exists: bool,
140 #[serde(default = "default_true")]
142 pub recurse: bool,
143 pub actions: Vec<AlterTableAction>,
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize)]
147#[expect(
148 clippy::large_enum_variant,
149 reason = "preserves the stable AST serde shape"
150)]
151pub enum AlterTableAction {
152 AddInheritance {
153 parent: String,
154 },
155 DropInheritance {
156 parent: String,
157 },
158 AttachPartition {
159 partition: String,
160 bound: PartitionBound,
161 },
162 DetachPartition {
163 partition: String,
164 concurrently: bool,
165 finalize: bool,
166 },
167 AddColumn {
168 column: ColumnDef,
169 #[serde(default)]
170 checks: Vec<TableCheck>,
171 #[serde(default)]
172 key_constraints: Vec<TableKeyConstraint>,
173 if_not_exists: bool,
174 },
175 AddKeyConstraint {
176 constraint: TableKeyConstraint,
177 },
178 AddCheckConstraint {
179 constraint: TableCheck,
180 },
181 AddForeignKeyConstraint {
182 constraint: ForeignKey,
183 },
184 AddNotNullConstraint {
185 name: Option<String>,
186 column: String,
187 validated: bool,
188 no_inherit: bool,
189 },
190 ValidateConstraint {
191 name: String,
192 },
193 AlterConstraint {
194 name: String,
195 enforceability: Option<bool>,
196 deferrability: Option<(bool, bool)>,
197 no_inherit: Option<bool>,
198 },
199 DropConstraint {
200 name: String,
201 if_exists: bool,
202 cascade: bool,
203 },
204 DropColumn {
205 name: String,
206 if_exists: bool,
207 cascade: bool,
208 },
209 RenameColumn {
210 from: String,
211 to: String,
212 },
213 RenameTable {
214 to: String,
215 },
216 RenameTrigger {
217 from: String,
218 to: String,
219 },
220 RenameConstraint {
221 from: String,
222 to: String,
223 },
224 RenameRule {
225 from: String,
226 to: String,
227 },
228 SetPersistence {
229 persistence: RelationPersistence,
230 },
231 ChangeOwner {
232 owner: RoleSpecification,
233 },
234 SetSchema {
235 schema: String,
236 },
237 SetTriggerEnableMode {
238 name: Option<String>,
239 user_only: bool,
240 mode: EventEnableMode,
241 },
242 SetRuleEnableMode {
243 name: String,
244 mode: EventEnableMode,
245 },
246 SetDefault {
247 name: String,
248 default: Expr,
249 },
250 DropDefault {
251 name: String,
252 },
253 SetExpression {
254 name: String,
255 expression: Expr,
256 },
257 DropExpression {
258 name: String,
259 },
260 SetNotNull {
261 name: String,
262 },
263 DropNotNull {
264 name: String,
265 },
266 AlterColumnType {
267 name: String,
268 ty: ColumnType,
269 #[serde(default, skip_serializing_if = "Option::is_none")]
270 using: Option<Expr>,
271 },
272}
273
274#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
275pub struct InsertStmt {
276 pub table: String,
277 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
279 pub target_relation_bound: bool,
280 pub target_qualifier: String,
282 #[serde(default = "default_include_descendants")]
283 pub include_descendants: bool,
284 pub columns: Vec<AssignmentTarget>,
285 pub with: Vec<CTE>,
287 pub rows: Vec<Vec<ValueExpr>>,
289 pub select_source: Option<Box<SelectStmt>>,
293 pub on_conflict: Option<OnConflict>,
296 pub returning: Vec<Projection>,
298 pub returning_aliases: ReturningAliases,
301}
302
303#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
304pub struct ReturningAliases {
305 pub old: String,
306 pub new: String,
307 #[serde(default)]
308 pub old_explicit: bool,
309 #[serde(default)]
310 pub new_explicit: bool,
311}
312
313impl Default for ReturningAliases {
314 fn default() -> Self {
315 Self {
316 old: "old".into(),
317 new: "new".into(),
318 old_explicit: false,
319 new_explicit: false,
320 }
321 }
322}
323
324#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
325pub struct OnConflict {
326 #[serde(default)]
327 pub predicate: Option<Box<Expr>>,
328 #[serde(default)]
329 pub constraint: Option<String>,
330 pub conflict_columns: Vec<String>,
334 #[serde(default)]
335 pub expressions: Vec<Expr>,
336 pub action: OnConflictAction,
337}
338
339#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
340pub enum OnConflictAction {
341 Nothing,
343 Update {
347 assignments: Vec<(AssignmentTarget, Expr)>,
348 r#where: Option<Box<Expr>>,
349 },
350}
351
352#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
353pub struct SelectStmt {
354 pub projections: Vec<Projection>,
355 #[serde(default, skip_serializing_if = "Vec::is_empty")]
359 pub values: Vec<Vec<Expr>>,
360 pub from: Option<FromClause>,
361 pub r#where: Option<Expr>,
362 pub group_by: Vec<Expr>,
363 pub grouping_sets: Vec<Vec<Expr>>,
369 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
371 pub group_distinct: bool,
372 pub having: Option<Expr>,
376 pub order_by: Vec<OrderBy>,
377 pub limit: Option<Expr>,
381 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
383 pub with_ties: bool,
384 pub offset: Option<Expr>,
386 pub with: Vec<CTE>,
388 pub set_op: Option<Box<SetOp>>,
392 pub distinct: bool,
395 pub distinct_on: Vec<Expr>,
398 #[serde(default, skip_serializing_if = "Vec::is_empty")]
400 pub locking: Vec<LockingClause>,
401}
402
403#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
404pub struct SetOp {
405 pub kind: SetOpKind,
406 pub all: bool,
407 #[serde(default, skip_serializing_if = "Option::is_none")]
411 pub left: Option<Box<SelectStmt>>,
412 pub right: SelectStmt,
413 pub combined_order_by: Vec<OrderBy>,
416 pub combined_limit: Option<Expr>,
419 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
421 pub combined_with_ties: bool,
422 pub combined_offset: Option<Expr>,
424}
425
426#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
427pub enum SetOpKind {
428 Union,
429 Intersect,
430 Except,
431}
432
433#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
435pub enum DiscardTarget {
436 All,
437 Plans,
438 Sequences,
439 Temp,
440}
441
442#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
443pub struct UpdateStmt {
444 pub table: String,
445 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
447 pub target_relation_bound: bool,
448 pub target_qualifier: String,
449 #[serde(default = "default_include_descendants")]
450 pub include_descendants: bool,
451 pub assignments: Vec<(AssignmentTarget, Expr)>,
452 pub r#where: Option<Expr>,
453 pub with: Vec<CTE>,
455 pub from: Option<FromClause>,
458 pub returning: Vec<Projection>,
460 pub returning_aliases: ReturningAliases,
461}
462
463#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
464pub struct DeleteStmt {
465 pub table: String,
466 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
468 pub target_relation_bound: bool,
469 pub target_qualifier: String,
470 #[serde(default = "default_include_descendants")]
471 pub include_descendants: bool,
472 pub r#where: Option<Expr>,
473 pub with: Vec<CTE>,
475 pub using: Option<FromClause>,
479 pub returning: Vec<Projection>,
481 pub returning_aliases: ReturningAliases,
482}
483
484#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
485pub struct SetConstraintName {
486 pub catalog: Option<String>,
487 pub schema: Option<String>,
488 pub name: String,
489}
490
491#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
493pub struct VacuumOption {
494 pub name: String,
495 pub value: Option<VacuumOptionValue>,
496}
497
498#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
499pub enum VacuumOptionValue {
500 Boolean(bool),
501 Integer(i32),
502 String(String),
503}
504
505#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
507pub struct VacuumTarget {
508 pub catalog: Option<String>,
509 pub table: String,
510 #[serde(default = "default_include_descendants")]
511 pub include_descendants: bool,
512 #[serde(default, skip_serializing_if = "Vec::is_empty")]
513 pub columns: Vec<String>,
514}
515
516#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
517pub struct VacuumStmt {
518 #[serde(default, skip_serializing_if = "Vec::is_empty")]
519 pub options: Vec<VacuumOption>,
520 #[serde(default, skip_serializing_if = "Vec::is_empty")]
521 pub targets: Vec<VacuumTarget>,
522}
523
524#[derive(Debug, Clone, Serialize, Deserialize)]
525pub enum Statement {
526 CreateDomain(CreateDomain),
527 CreateTable(CreateTable),
528 CreateTableIfNotExists(DeferredCreateTable),
529 CreateIndex(CreateIndex),
530 RenameIndex(RenameIndexStmt),
531 Insert(InsertStmt),
532 Select(Box<SelectStmt>),
536 Update(UpdateStmt),
537 Delete(DeleteStmt),
538 Drop(DropStmt),
539 AlterTable(AlterTableStmt),
540 AlterForeignTable(AlterForeignTableStmt),
541 AlterView(AlterViewStmt),
542 CreateView {
544 name: String,
545 #[serde(default)]
546 column_names: Vec<String>,
547 body: Box<SelectStmt>,
548 or_replace: bool,
549 #[serde(default)]
550 persistence: RelationPersistence,
551 #[serde(default, skip_serializing_if = "Vec::is_empty")]
553 options: Vec<(String, String)>,
554 },
555 CreateMaterializedView {
557 name: String,
558 #[serde(default)]
559 column_names: Vec<String>,
560 #[serde(default)]
561 if_not_exists: bool,
562 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
563 with_no_data: bool,
564 #[serde(default, skip_serializing_if = "Vec::is_empty")]
565 options: Vec<(String, String)>,
566 body: Box<SelectStmt>,
567 },
568 RefreshMaterializedView {
570 name: String,
571 concurrently: bool,
572 with_no_data: bool,
573 },
574 CreateSchema {
576 name: Option<String>,
577 if_not_exists: bool,
578 #[serde(default, skip_serializing_if = "Option::is_none")]
579 authorization: Option<SchemaAuthorization>,
580 },
581 AlterSchemaOwner {
582 name: String,
583 new_owner: RoleSpecification,
584 },
585 Notify {
587 channel: String,
588 payload: String,
589 },
590 Listen {
592 channel: String,
593 },
594 Unlisten {
596 channel: Option<String>,
597 },
598 SetVariable {
602 name: String,
603 value: String,
604 #[serde(default)]
605 local: bool,
606 #[serde(default)]
607 is_default: bool,
608 },
609 ResetVariable {
611 name: String,
612 },
613 ResetAllVariables,
615 SetConstraints {
617 constraints: Vec<SetConstraintName>,
618 deferred: bool,
619 },
620 ShowVariable {
623 name: String,
624 },
625 Discard {
628 target: DiscardTarget,
629 },
630 Load {
635 library: String,
636 },
637 Explain {
640 analyze: bool,
641 verbose: bool,
642 format: Option<String>,
643 body: Box<Statement>,
644 },
645 Analyze {
648 table: Option<String>,
649 },
650 Vacuum(VacuumStmt),
652 LockTable(LockTableStmt),
654 Truncate {
657 tables: Vec<TruncateTarget>,
658 cascade: bool,
659 #[serde(default)]
660 restart_identity: bool,
661 },
662 Transaction(TransactionStmt),
664 DeclareCursor(DeclareCursorStmt),
666 FetchCursor(FetchCursorStmt),
668 CloseCursor {
670 name: Option<String>,
671 },
672 CreateSequence(CreateSequence),
674 AlterSequence(AlterSequence),
677 CreateTableAs {
679 name: String,
680 if_not_exists: bool,
681 #[serde(default, skip_serializing_if = "Vec::is_empty")]
682 column_names: Vec<String>,
683 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
684 with_no_data: bool,
685 #[serde(default)]
686 persistence: RelationPersistence,
687 #[serde(default)]
688 on_commit: OnCommitAction,
689 body: Box<SelectStmt>,
690 },
691 Prepare {
693 name: String,
694 #[serde(default)]
695 parameter_types: Vec<ColumnType>,
696 body: Box<Statement>,
697 },
698 Execute {
700 name: String,
701 params: Vec<Expr>,
702 },
703 Deallocate {
705 name: Option<String>,
706 },
707 Values {
710 rows: Vec<Vec<Expr>>,
711 },
712 CreateForeignServer(CreateForeignServer),
714 CreateForeignTable(CreateForeignTable),
716 CreateForeignTableIfNotExists(DeferredCreateForeignTable),
718 Merge(MergeStmt),
721 CreateFunction(Box<CreateFunction>),
724 DropFunction(DropFunctionStmt),
726 AlterRoutine(AlterRoutineStmt),
728 AlterRoutineOwner(AlterRoutineOwnerStmt),
729 RenameRoutine(RenameRoutineStmt),
730 GrantRoutine(GrantRoutineStmt),
731 GrantTable(GrantTableStmt),
732 GrantSequence(GrantSequenceStmt),
733 GrantDatabase(GrantDatabaseStmt),
734 GrantSchema(GrantSchemaStmt),
735 GrantRole(GrantRoleStmt),
736 CreateRole(CreateRoleStmt),
737 AlterRole(AlterRoleStmt),
738 RenameRole(RenameRoleStmt),
739 DropRole(DropRoleStmt),
740 CreateTrigger(CreateTrigger),
742 DropTrigger(DropTrigger),
744 CreateRule(CreateRule),
746 DropRule(DropRule),
748 DoBlock {
750 language: String,
751 body: String,
752 },
753 Call {
756 name: String,
757 args: Vec<Expr>,
758 },
759}
760
761#[derive(Debug, Clone, Serialize, Deserialize)]
762pub struct TruncateTarget {
763 pub table: String,
764 #[serde(default = "default_include_descendants")]
765 pub include_descendants: bool,
766}
767
768#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
769pub struct MergeTargetColumnBinding {
770 pub object_id: [u8; 16],
771 #[serde(default, skip_serializing_if = "std::collections::BTreeSet::is_empty")]
773 pub domain_dependencies: std::collections::BTreeSet<u32>,
774}
775
776#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
777pub struct MergeStmt {
778 #[serde(default)]
779 pub with: Vec<CTE>,
780 pub target: String,
781 pub target_qualifier: String,
782 pub target_alias: Option<String>,
783 #[serde(default, skip_serializing_if = "std::collections::BTreeMap::is_empty")]
785 pub target_column_bindings: std::collections::BTreeMap<String, MergeTargetColumnBinding>,
786 #[serde(default = "default_include_descendants")]
787 pub include_descendants: bool,
788 pub source: FromClause,
789 pub join_condition: Expr,
790 pub when_clauses: Vec<MergeWhen>,
791 pub returning: Vec<Projection>,
793 pub returning_aliases: ReturningAliases,
794}
795
796#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
797pub enum MergeWhen {
798 UpdateMatched {
800 condition: Option<Expr>,
801 assignments: Vec<(AssignmentTarget, Expr)>,
802 },
803 DeleteMatched { condition: Option<Expr> },
805 UpdateNotMatchedBySource {
807 condition: Option<Expr>,
808 assignments: Vec<(AssignmentTarget, Expr)>,
809 },
810 DeleteNotMatchedBySource { condition: Option<Expr> },
812 InsertNotMatched {
814 condition: Option<Expr>,
815 columns: Vec<AssignmentTarget>,
816 values: Vec<Expr>,
817 },
818 NothingMatched { condition: Option<Expr> },
820 NothingNotMatched { condition: Option<Expr> },
822 NothingNotMatchedBySource { condition: Option<Expr> },
824}
825
826#[derive(Debug, Clone, Serialize, Deserialize)]
827pub struct CreateForeignServer {
828 pub name: String,
829 pub fdw_type: String,
830 pub options: Vec<(String, String)>,
831 pub if_not_exists: bool,
832}
833
834#[derive(Debug, Clone, Serialize, Deserialize)]
835pub struct CreateForeignTable {
836 pub name: String,
837 pub server_name: String,
838 pub columns: Vec<ColumnDef>,
839 #[serde(default)]
840 pub checks: Vec<TableCheck>,
841 pub options: Vec<(String, String)>,
842 pub if_not_exists: bool,
843}
844
845#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
847pub struct DeferredCreateForeignTable {
848 pub name: String,
849 pub server_name: String,
850 pub definition_sql: String,
851}
852
853#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
854pub enum TransactionIsolationLevel {
855 ReadUncommitted,
856 ReadCommitted,
857 RepeatableRead,
858 Serializable,
859}
860
861impl TransactionIsolationLevel {
862 #[must_use]
863 pub const fn as_str(self) -> &'static str {
864 match self {
865 Self::ReadUncommitted => "read uncommitted",
866 Self::ReadCommitted => "read committed",
867 Self::RepeatableRead => "repeatable read",
868 Self::Serializable => "serializable",
869 }
870 }
871}
872
873#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
874pub struct TransactionCharacteristics {
875 pub isolation: Option<TransactionIsolationLevel>,
876 pub read_only: Option<bool>,
877 pub deferrable: Option<bool>,
878}
879
880#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
881pub enum TransactionStmt {
882 Begin,
883 BeginWithCharacteristics(TransactionCharacteristics),
884 Commit,
885 CommitAndChain,
886 Rollback,
887 RollbackAndChain,
888 SetCharacteristics(TransactionCharacteristics),
889 SetSessionCharacteristics(TransactionCharacteristics),
890 SetSnapshot(String),
891 Savepoint(String),
892 ReleaseSavepoint(String),
893 RollbackToSavepoint(String),
894}
895
896#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
897pub enum CursorDirection {
898 Forward,
899 Backward,
900 Absolute,
901 Relative,
902}
903
904#[derive(Debug, Clone, Serialize, Deserialize)]
905pub struct DeclareCursorStmt {
906 pub name: String,
907 pub binary: bool,
908 pub scroll: Option<bool>,
910 pub hold: bool,
911 pub query: Box<SelectStmt>,
912}
913
914#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
915pub struct FetchCursorStmt {
916 pub name: String,
917 pub direction: CursorDirection,
918 pub count: i64,
920 pub move_only: bool,
921}
922
923#[cfg(test)]
924mod tests;