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 identity_sequence;
24mod indexes;
25mod interval;
26mod locking;
27mod namespaces;
28mod overriding;
29mod ranges;
30mod referenced_partition;
31mod relation_hierarchy;
32mod relation_lifecycle;
33mod role_specification;
34mod routine_security;
35mod routines;
36mod sequence;
37mod sequence_declaration;
38mod types;
39
40pub use acl_role_specification::AclRoleSpecification;
41pub use assignment_target::{AssignmentStep, AssignmentTarget};
42pub use constraints::*;
43pub use cte::*;
44pub use domains::*;
45pub use events::*;
46pub use expressions::*;
47pub use from::*;
48pub use function_binding::*;
49pub use identity_sequence::{DeferredSQLError, IdentitySequenceDeclaration, IdentitySequenceName};
50pub use indexes::*;
51pub use interval::*;
52pub use locking::*;
53pub use namespaces::*;
54pub use overriding::OverridingKind;
55pub use ranges::*;
56pub use referenced_partition::ReferencedPartitionConstraint;
57pub use relation_hierarchy::*;
58pub use relation_lifecycle::*;
59pub use role_specification::RoleSpecification;
60pub use routine_security::*;
61pub use routines::*;
62pub use sequence::*;
63pub use sequence_declaration::{SequenceDeclaration, SequenceOptionValue};
64pub use types::*;
65
66const fn default_include_descendants() -> bool {
67 true
68}
69
70const fn default_true() -> bool {
71 true
72}
73
74#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
75pub enum GeneratedColumnKind {
76 Virtual,
77 Stored,
78}
79
80#[derive(Debug, Clone, Serialize, Deserialize)]
81pub struct GeneratedColumn {
82 pub kind: GeneratedColumnKind,
83 pub expression: Box<Expr>,
84 #[serde(default, skip_serializing_if = "Vec::is_empty")]
85 pub function_dependencies: Vec<GeneratedFunctionDependency>,
86}
87
88#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
89pub struct IndexColumnOrder {
90 pub descending: bool,
91 pub nulls_first: bool,
92}
93
94#[derive(Debug, Clone, Serialize, Deserialize)]
95pub struct CreateIndex {
96 #[serde(default)]
97 pub included_columns: Vec<String>,
98 #[serde(default)]
99 pub column_order: Vec<IndexColumnOrder>,
100 #[serde(default)]
101 pub predicate: Option<Box<Expr>>,
102 pub name: Option<String>,
103 pub table: String,
104 pub access_method: String,
106 pub columns: Vec<IndexKey>,
107 #[serde(default)]
108 pub unique: bool,
109 #[serde(default)]
110 pub nulls_not_distinct: bool,
111 pub if_not_exists: bool,
113 pub options: Vec<(String, String)>,
117 #[serde(default, skip_serializing_if = "Vec::is_empty")]
119 pub option_namespaces: Vec<String>,
120}
121
122#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct DropStmt {
124 pub kind: DropKind,
125 pub names: Vec<String>,
126 pub if_exists: bool,
127 pub cascade: bool,
128}
129
130#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
131pub enum DropKind {
132 Table,
133 ForeignTable,
134 Index,
135 View,
136 MaterializedView,
137 Schema,
138 Sequence,
139 Domain,
140}
141
142#[derive(Debug, Clone, Serialize, Deserialize)]
143pub struct AlterTableStmt {
144 pub table: String,
145 pub qualifier: String,
147 pub if_exists: bool,
148 #[serde(default = "default_true")]
150 pub recurse: bool,
151 pub actions: Vec<AlterTableAction>,
152}
153
154#[derive(Debug, Clone, Serialize, Deserialize)]
155#[expect(
156 clippy::large_enum_variant,
157 reason = "preserves the stable AST serde shape"
158)]
159pub enum AlterTableAction {
160 AddInheritance {
161 parent: String,
162 },
163 DropInheritance {
164 parent: String,
165 },
166 AttachPartition {
167 partition: String,
168 bound: PartitionBound,
169 },
170 DetachPartition {
171 partition: String,
172 concurrently: bool,
173 finalize: bool,
174 },
175 AddColumn {
176 column: ColumnDef,
177 #[serde(default)]
178 checks: Vec<TableCheck>,
179 #[serde(default)]
180 key_constraints: Vec<TableKeyConstraint>,
181 if_not_exists: bool,
182 },
183 AddKeyConstraint {
184 constraint: TableKeyConstraint,
185 },
186 AddCheckConstraint {
187 constraint: TableCheck,
188 },
189 AddForeignKeyConstraint {
190 constraint: ForeignKey,
191 },
192 AddNotNullConstraint {
193 name: Option<String>,
194 column: String,
195 validated: bool,
196 no_inherit: bool,
197 },
198 ValidateConstraint {
199 name: String,
200 },
201 AlterConstraint {
202 name: String,
203 enforceability: Option<bool>,
204 deferrability: Option<(bool, bool)>,
205 no_inherit: Option<bool>,
206 },
207 DropConstraint {
208 name: String,
209 if_exists: bool,
210 cascade: bool,
211 },
212 DropColumn {
213 name: String,
214 if_exists: bool,
215 cascade: bool,
216 },
217 RenameColumn {
218 from: String,
219 to: String,
220 },
221 RenameTable {
222 to: String,
223 },
224 RenameTrigger {
225 from: String,
226 to: String,
227 },
228 RenameConstraint {
229 from: String,
230 to: String,
231 },
232 RenameRule {
233 from: String,
234 to: String,
235 },
236 SetPersistence {
237 persistence: RelationPersistence,
238 },
239 ChangeOwner {
240 owner: RoleSpecification,
241 },
242 SetSchema {
243 schema: String,
244 },
245 SetTriggerEnableMode {
246 name: Option<String>,
247 user_only: bool,
248 mode: EventEnableMode,
249 },
250 SetRuleEnableMode {
251 name: String,
252 mode: EventEnableMode,
253 },
254 SetDefault {
255 name: String,
256 default: Expr,
257 },
258 DropDefault {
259 name: String,
260 },
261 SetExpression {
262 name: String,
263 expression: Expr,
264 },
265 DropExpression {
266 name: String,
267 },
268 SetNotNull {
269 name: String,
270 },
271 DropNotNull {
272 name: String,
273 },
274 AlterColumnType {
275 name: String,
276 ty: ColumnType,
277 #[serde(default, skip_serializing_if = "Option::is_none")]
278 using: Option<Expr>,
279 },
280 AddIdentity {
282 name: String,
283 kind: AutoIncrementKind,
284 #[serde(default, skip_serializing_if = "Option::is_none")]
285 declaration: Option<Box<IdentitySequenceDeclaration>>,
286 },
287 SetIdentity {
289 name: String,
290 kind: Option<AutoIncrementKind>,
292 repeated_kind: bool,
294 #[serde(default)]
296 sequence: SequenceDeclaration,
297 #[serde(default, skip_serializing_if = "Option::is_none")]
299 error: Option<DeferredSQLError>,
300 },
301 DropIdentity {
303 name: String,
304 if_exists: bool,
305 },
306}
307
308#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
309pub struct InsertStmt {
310 pub table: String,
311 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
313 pub target_relation_bound: bool,
314 pub target_qualifier: String,
316 #[serde(default = "default_include_descendants")]
317 pub include_descendants: bool,
318 pub columns: Vec<AssignmentTarget>,
319 #[serde(default, skip_serializing_if = "Option::is_none")]
321 pub overriding: Option<OverridingKind>,
322 pub with: Vec<CTE>,
324 pub rows: Vec<Vec<ValueExpr>>,
326 pub select_source: Option<Box<SelectStmt>>,
330 pub on_conflict: Option<OnConflict>,
333 pub returning: Vec<Projection>,
335 pub returning_aliases: ReturningAliases,
338}
339
340#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
341pub struct ReturningAliases {
342 pub old: String,
343 pub new: String,
344 #[serde(default)]
345 pub old_explicit: bool,
346 #[serde(default)]
347 pub new_explicit: bool,
348}
349
350impl Default for ReturningAliases {
351 fn default() -> Self {
352 Self {
353 old: "old".into(),
354 new: "new".into(),
355 old_explicit: false,
356 new_explicit: false,
357 }
358 }
359}
360
361#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
362pub struct OnConflict {
363 #[serde(default)]
364 pub predicate: Option<Box<Expr>>,
365 #[serde(default)]
366 pub constraint: Option<String>,
367 pub conflict_columns: Vec<String>,
371 #[serde(default)]
372 pub expressions: Vec<Expr>,
373 pub action: OnConflictAction,
374}
375
376#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
377pub enum OnConflictAction {
378 Nothing,
380 Update {
384 assignments: Vec<(AssignmentTarget, Expr)>,
385 r#where: Option<Box<Expr>>,
386 },
387}
388
389#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
390pub struct SelectStmt {
391 pub projections: Vec<Projection>,
392 #[serde(default, skip_serializing_if = "Vec::is_empty")]
396 pub values: Vec<Vec<Expr>>,
397 pub from: Option<FromClause>,
398 pub r#where: Option<Expr>,
399 pub group_by: Vec<Expr>,
400 pub grouping_sets: Vec<Vec<Expr>>,
406 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
408 pub group_distinct: bool,
409 pub having: Option<Expr>,
413 pub order_by: Vec<OrderBy>,
414 pub limit: Option<Expr>,
418 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
420 pub with_ties: bool,
421 pub offset: Option<Expr>,
423 pub with: Vec<CTE>,
425 pub set_op: Option<Box<SetOp>>,
429 pub distinct: bool,
432 pub distinct_on: Vec<Expr>,
435 #[serde(default, skip_serializing_if = "Vec::is_empty")]
437 pub locking: Vec<LockingClause>,
438}
439
440#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
441pub struct SetOp {
442 pub kind: SetOpKind,
443 pub all: bool,
444 #[serde(default, skip_serializing_if = "Option::is_none")]
448 pub left: Option<Box<SelectStmt>>,
449 pub right: SelectStmt,
450 pub combined_order_by: Vec<OrderBy>,
453 pub combined_limit: Option<Expr>,
456 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
458 pub combined_with_ties: bool,
459 pub combined_offset: Option<Expr>,
461}
462
463#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
464pub enum SetOpKind {
465 Union,
466 Intersect,
467 Except,
468}
469
470#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
472pub enum DiscardTarget {
473 All,
474 Plans,
475 Sequences,
476 Temp,
477}
478
479#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
480pub struct UpdateStmt {
481 pub table: String,
482 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
484 pub target_relation_bound: bool,
485 pub target_qualifier: String,
486 #[serde(default = "default_include_descendants")]
487 pub include_descendants: bool,
488 pub assignments: Vec<(AssignmentTarget, Expr)>,
489 pub r#where: Option<Expr>,
490 pub with: Vec<CTE>,
492 pub from: Option<FromClause>,
495 pub returning: Vec<Projection>,
497 pub returning_aliases: ReturningAliases,
498}
499
500#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
501pub struct DeleteStmt {
502 pub table: String,
503 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
505 pub target_relation_bound: bool,
506 pub target_qualifier: String,
507 #[serde(default = "default_include_descendants")]
508 pub include_descendants: bool,
509 pub r#where: Option<Expr>,
510 pub with: Vec<CTE>,
512 pub using: Option<FromClause>,
516 pub returning: Vec<Projection>,
518 pub returning_aliases: ReturningAliases,
519}
520
521#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
522pub struct SetConstraintName {
523 pub catalog: Option<String>,
524 pub schema: Option<String>,
525 pub name: String,
526}
527
528#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
530pub struct VacuumOption {
531 pub name: String,
532 pub value: Option<VacuumOptionValue>,
533}
534
535#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
536pub enum VacuumOptionValue {
537 Boolean(bool),
538 Integer(i32),
539 String(String),
540}
541
542#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
544pub struct VacuumTarget {
545 pub catalog: Option<String>,
546 pub table: String,
547 #[serde(default = "default_include_descendants")]
548 pub include_descendants: bool,
549 #[serde(default, skip_serializing_if = "Vec::is_empty")]
550 pub columns: Vec<String>,
551}
552
553#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
554pub struct VacuumStmt {
555 #[serde(default, skip_serializing_if = "Vec::is_empty")]
556 pub options: Vec<VacuumOption>,
557 #[serde(default, skip_serializing_if = "Vec::is_empty")]
558 pub targets: Vec<VacuumTarget>,
559}
560
561#[derive(Debug, Clone, Serialize, Deserialize)]
562pub enum Statement {
563 CreateDomain(CreateDomain),
564 CreateTable(CreateTable),
565 CreateTableIfNotExists(DeferredCreateTable),
566 CreateIndex(CreateIndex),
567 RenameIndex(RenameIndexStmt),
568 Insert(InsertStmt),
569 Select(Box<SelectStmt>),
573 Update(UpdateStmt),
574 Delete(DeleteStmt),
575 Drop(DropStmt),
576 AlterTable(AlterTableStmt),
577 AlterForeignTable(AlterForeignTableStmt),
578 AlterView(AlterViewStmt),
579 CreateView {
581 name: String,
582 #[serde(default)]
583 column_names: Vec<String>,
584 body: Box<SelectStmt>,
585 or_replace: bool,
586 #[serde(default)]
587 persistence: RelationPersistence,
588 #[serde(default, skip_serializing_if = "Vec::is_empty")]
590 options: Vec<(String, String)>,
591 },
592 CreateMaterializedView {
594 name: String,
595 #[serde(default)]
596 column_names: Vec<String>,
597 #[serde(default)]
598 if_not_exists: bool,
599 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
600 with_no_data: bool,
601 #[serde(default, skip_serializing_if = "Vec::is_empty")]
602 options: Vec<(String, String)>,
603 body: Box<SelectStmt>,
604 },
605 RefreshMaterializedView {
607 name: String,
608 concurrently: bool,
609 with_no_data: bool,
610 },
611 CreateSchema {
613 name: Option<String>,
614 if_not_exists: bool,
615 #[serde(default, skip_serializing_if = "Option::is_none")]
616 authorization: Option<SchemaAuthorization>,
617 },
618 AlterSchemaOwner {
619 name: String,
620 new_owner: RoleSpecification,
621 },
622 Notify {
624 channel: String,
625 payload: String,
626 },
627 Listen {
629 channel: String,
630 },
631 Unlisten {
633 channel: Option<String>,
634 },
635 SetVariable {
639 name: String,
640 value: String,
641 #[serde(default)]
642 local: bool,
643 #[serde(default)]
644 is_default: bool,
645 },
646 ResetVariable {
648 name: String,
649 },
650 ResetAllVariables,
652 SetConstraints {
654 constraints: Vec<SetConstraintName>,
655 deferred: bool,
656 },
657 ShowVariable {
660 name: String,
661 },
662 Discard {
665 target: DiscardTarget,
666 },
667 Load {
672 library: String,
673 },
674 Explain {
677 analyze: bool,
678 verbose: bool,
679 format: Option<String>,
680 body: Box<Statement>,
681 },
682 Analyze {
685 table: Option<String>,
686 },
687 Vacuum(VacuumStmt),
689 LockTable(LockTableStmt),
691 Truncate {
694 tables: Vec<TruncateTarget>,
695 cascade: bool,
696 #[serde(default)]
697 restart_identity: bool,
698 },
699 Transaction(TransactionStmt),
701 DeclareCursor(DeclareCursorStmt),
703 FetchCursor(FetchCursorStmt),
705 CloseCursor {
707 name: Option<String>,
708 },
709 CreateSequence(CreateSequence),
711 AlterSequence(AlterSequence),
714 CreateTableAs {
716 name: String,
717 if_not_exists: bool,
718 #[serde(default, skip_serializing_if = "Vec::is_empty")]
719 column_names: Vec<String>,
720 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
721 with_no_data: bool,
722 #[serde(default)]
723 persistence: RelationPersistence,
724 #[serde(default)]
725 on_commit: OnCommitAction,
726 body: Box<SelectStmt>,
727 },
728 Prepare {
730 name: String,
731 #[serde(default)]
732 parameter_types: Vec<ColumnType>,
733 body: Box<Statement>,
734 },
735 Execute {
737 name: String,
738 params: Vec<Expr>,
739 },
740 Deallocate {
742 name: Option<String>,
743 },
744 Values {
747 rows: Vec<Vec<Expr>>,
748 },
749 CreateForeignServer(CreateForeignServer),
751 CreateForeignTable(CreateForeignTable),
753 CreateForeignTableIfNotExists(DeferredCreateForeignTable),
755 Merge(MergeStmt),
758 CreateFunction(Box<CreateFunction>),
761 DropFunction(DropFunctionStmt),
763 AlterRoutine(AlterRoutineStmt),
765 AlterRoutineOwner(AlterRoutineOwnerStmt),
766 RenameRoutine(RenameRoutineStmt),
767 GrantRoutine(GrantRoutineStmt),
768 GrantTable(GrantTableStmt),
769 GrantSequence(GrantSequenceStmt),
770 GrantDatabase(GrantDatabaseStmt),
771 GrantSchema(GrantSchemaStmt),
772 GrantRole(GrantRoleStmt),
773 CreateRole(CreateRoleStmt),
774 AlterRole(AlterRoleStmt),
775 RenameRole(RenameRoleStmt),
776 DropRole(DropRoleStmt),
777 CreateTrigger(CreateTrigger),
779 DropTrigger(DropTrigger),
781 CreateRule(CreateRule),
783 DropRule(DropRule),
785 DoBlock {
787 language: String,
788 body: String,
789 },
790 Call {
793 name: String,
794 args: Vec<Expr>,
795 },
796}
797
798#[derive(Debug, Clone, Serialize, Deserialize)]
799pub struct TruncateTarget {
800 pub table: String,
801 #[serde(default = "default_include_descendants")]
802 pub include_descendants: bool,
803}
804
805#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
806pub struct MergeTargetColumnBinding {
807 pub object_id: [u8; 16],
808 #[serde(default, skip_serializing_if = "std::collections::BTreeSet::is_empty")]
810 pub domain_dependencies: std::collections::BTreeSet<u32>,
811}
812
813#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
814pub struct MergeStmt {
815 #[serde(default)]
816 pub with: Vec<CTE>,
817 pub target: String,
818 pub target_qualifier: String,
819 pub target_alias: Option<String>,
820 #[serde(default, skip_serializing_if = "std::collections::BTreeMap::is_empty")]
822 pub target_column_bindings: std::collections::BTreeMap<String, MergeTargetColumnBinding>,
823 #[serde(default = "default_include_descendants")]
824 pub include_descendants: bool,
825 pub source: FromClause,
826 pub join_condition: Expr,
827 pub when_clauses: Vec<MergeWhen>,
828 pub returning: Vec<Projection>,
830 pub returning_aliases: ReturningAliases,
831}
832
833#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
834pub enum MergeWhen {
835 UpdateMatched {
837 condition: Option<Expr>,
838 assignments: Vec<(AssignmentTarget, Expr)>,
839 },
840 DeleteMatched { condition: Option<Expr> },
842 UpdateNotMatchedBySource {
844 condition: Option<Expr>,
845 assignments: Vec<(AssignmentTarget, Expr)>,
846 },
847 DeleteNotMatchedBySource { condition: Option<Expr> },
849 InsertNotMatched {
851 condition: Option<Expr>,
852 columns: Vec<AssignmentTarget>,
853 #[serde(default, skip_serializing_if = "Option::is_none")]
854 overriding: Option<OverridingKind>,
855 values: Vec<Expr>,
856 },
857 NothingMatched { condition: Option<Expr> },
859 NothingNotMatched { condition: Option<Expr> },
861 NothingNotMatchedBySource { condition: Option<Expr> },
863}
864
865#[derive(Debug, Clone, Serialize, Deserialize)]
866pub struct CreateForeignServer {
867 pub name: String,
868 pub fdw_type: String,
869 pub options: Vec<(String, String)>,
870 pub if_not_exists: bool,
871}
872
873#[derive(Debug, Clone, Serialize, Deserialize)]
874pub struct CreateForeignTable {
875 pub name: String,
876 pub server_name: String,
877 pub columns: Vec<ColumnDef>,
878 #[serde(default)]
879 pub checks: Vec<TableCheck>,
880 pub options: Vec<(String, String)>,
881 pub if_not_exists: bool,
882}
883
884#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
886pub struct DeferredCreateForeignTable {
887 pub name: String,
888 pub server_name: String,
889 pub definition_sql: String,
890}
891
892#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
893pub enum TransactionIsolationLevel {
894 ReadUncommitted,
895 ReadCommitted,
896 RepeatableRead,
897 Serializable,
898}
899
900impl TransactionIsolationLevel {
901 #[must_use]
902 pub const fn as_str(self) -> &'static str {
903 match self {
904 Self::ReadUncommitted => "read uncommitted",
905 Self::ReadCommitted => "read committed",
906 Self::RepeatableRead => "repeatable read",
907 Self::Serializable => "serializable",
908 }
909 }
910}
911
912#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
913pub struct TransactionCharacteristics {
914 pub isolation: Option<TransactionIsolationLevel>,
915 pub read_only: Option<bool>,
916 pub deferrable: Option<bool>,
917}
918
919#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
920pub enum TransactionStmt {
921 Begin,
922 BeginWithCharacteristics(TransactionCharacteristics),
923 Commit,
924 CommitAndChain,
925 Rollback,
926 RollbackAndChain,
927 SetCharacteristics(TransactionCharacteristics),
928 SetSessionCharacteristics(TransactionCharacteristics),
929 SetSnapshot(String),
930 Savepoint(String),
931 ReleaseSavepoint(String),
932 RollbackToSavepoint(String),
933}
934
935#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
936pub enum CursorDirection {
937 Forward,
938 Backward,
939 Absolute,
940 Relative,
941}
942
943#[derive(Debug, Clone, Serialize, Deserialize)]
944pub struct DeclareCursorStmt {
945 pub name: String,
946 pub binary: bool,
947 pub scroll: Option<bool>,
949 pub hold: bool,
950 pub query: Box<SelectStmt>,
951}
952
953#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
954pub struct FetchCursorStmt {
955 pub name: String,
956 pub direction: CursorDirection,
957 pub count: i64,
959 pub move_only: bool,
960}
961
962#[cfg(test)]
963mod tests;