1#[cfg(not(feature = "std"))]
15use alloc::{
16 boxed::Box,
17 string::{String, ToString},
18 vec::Vec,
19};
20use core::fmt::{self, Display};
21
22#[cfg(feature = "serde")]
23use serde::{Deserialize, Serialize};
24
25#[cfg(feature = "visitor")]
26use sqlparser_derive::{Visit, VisitMut};
27
28pub use self::data_type::{
29 ArrayElemTypeDef, CharLengthUnits, CharacterLength, DataType, ExactNumberInfo, TimezoneInfo,
30};
31pub use self::dcl::{AlterRoleOperation, ResetConfig, RoleOption, SetConfigValue};
32pub use self::ddl::{
33 AlterColumnOperation, AlterIndexOperation, AlterTableOperation, ColumnDef, ColumnOption,
34 ColumnOptionDef, GeneratedAs, IndexType, KeyOrIndexDisplay, Partition, ProcedureParam,
35 ReferentialAction, TableConstraint, UserDefinedTypeCompositeAttributeDef,
36 UserDefinedTypeRepresentation,
37};
38pub use self::operator::{BinaryOperator, UnaryOperator};
39pub use self::query::{
40 Cte, Distinct, ExceptSelectItem, ExcludeSelectItem, Fetch, GroupByExpr, IdentWithAlias, Join,
41 JoinConstraint, JoinOperator, LateralView, LockClause, LockType, NamedWindowDefinition,
42 NonBlock, Offset, OffsetRows, OrderByExpr, Query, RenameSelectItem, ReplaceSelectElement,
43 ReplaceSelectItem, Select, SelectInto, SelectItem, SetExpr, SetOperator, SetQuantifier, Table,
44 TableAlias, TableFactor, TableVersion, TableWithJoins, Top, Values, WildcardAdditionalOptions,
45 With,
46};
47pub use self::value::{
48 escape_quoted_string, DateTimeField, DollarQuotedString, TrimWhereField, Value,
49};
50
51use crate::ast::helpers::stmt_data_loading::{
52 DataLoadingOptions, StageLoadSelectItem, StageParamsObject,
53};
54#[cfg(feature = "visitor")]
55pub use visitor::*;
56
57mod data_type;
58mod dcl;
59mod ddl;
60pub mod helpers;
61mod operator;
62mod query;
63mod value;
64
65#[cfg(feature = "visitor")]
66mod visitor;
67
68struct DisplaySeparated<'a, T>
69where
70 T: fmt::Display,
71{
72 slice: &'a [T],
73 sep: &'static str,
74}
75
76impl<'a, T> fmt::Display for DisplaySeparated<'a, T>
77where
78 T: fmt::Display,
79{
80 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
81 let mut delim = "";
82 for t in self.slice {
83 write!(f, "{delim}")?;
84 delim = self.sep;
85 write!(f, "{t}")?;
86 }
87 Ok(())
88 }
89}
90
91fn display_separated<'a, T>(slice: &'a [T], sep: &'static str) -> DisplaySeparated<'a, T>
92where
93 T: fmt::Display,
94{
95 DisplaySeparated { slice, sep }
96}
97
98fn display_comma_separated<T>(slice: &[T]) -> DisplaySeparated<'_, T>
99where
100 T: fmt::Display,
101{
102 DisplaySeparated { slice, sep: ", " }
103}
104
105#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
107#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
108#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
109pub struct Ident {
110 pub value: String,
112 pub quote_style: Option<char>,
115}
116
117impl Ident {
118 pub fn new<S>(value: S) -> Self
120 where
121 S: Into<String>,
122 {
123 Ident {
124 value: value.into(),
125 quote_style: None,
126 }
127 }
128
129 pub fn with_quote<S>(quote: char, value: S) -> Self
132 where
133 S: Into<String>,
134 {
135 assert!(quote == '\'' || quote == '"' || quote == '`' || quote == '[');
136 Ident {
137 value: value.into(),
138 quote_style: Some(quote),
139 }
140 }
141}
142
143impl From<&str> for Ident {
144 fn from(value: &str) -> Self {
145 Ident {
146 value: value.to_string(),
147 quote_style: None,
148 }
149 }
150}
151
152impl fmt::Display for Ident {
153 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
154 match self.quote_style {
155 Some(q) if q == '"' || q == '\'' || q == '`' => {
156 let escaped = value::escape_quoted_string(&self.value, q);
157 write!(f, "{q}{escaped}{q}")
158 }
159 Some('[') => write!(f, "[{}]", self.value),
160 None => f.write_str(&self.value),
161 _ => panic!("unexpected quote style"),
162 }
163 }
164}
165
166#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
168#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
169#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
170pub struct ObjectName(pub Vec<Ident>);
171
172impl fmt::Display for ObjectName {
173 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
174 write!(f, "{}", display_separated(&self.0, "."))
175 }
176}
177
178#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
181#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
182#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
183pub struct Array {
184 pub elem: Vec<Expr>,
186
187 pub named: bool,
189}
190
191impl fmt::Display for Array {
192 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
193 write!(
194 f,
195 "{}[{}]",
196 if self.named { "ARRAY" } else { "" },
197 display_comma_separated(&self.elem)
198 )
199 }
200}
201
202#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
211#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
212#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
213pub struct Interval {
214 pub value: Box<Expr>,
215 pub leading_field: Option<DateTimeField>,
216 pub leading_precision: Option<u64>,
217 pub last_field: Option<DateTimeField>,
218 pub fractional_seconds_precision: Option<u64>,
223}
224
225impl fmt::Display for Interval {
226 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
227 let value = self.value.as_ref();
228 match (
229 self.leading_field,
230 self.leading_precision,
231 self.fractional_seconds_precision,
232 ) {
233 (
234 Some(DateTimeField::Second),
235 Some(leading_precision),
236 Some(fractional_seconds_precision),
237 ) => {
238 assert!(self.last_field.is_none());
241 write!(
242 f,
243 "INTERVAL {value} SECOND ({leading_precision}, {fractional_seconds_precision})"
244 )
245 }
246 _ => {
247 write!(f, "INTERVAL {value}")?;
248 if let Some(leading_field) = self.leading_field {
249 write!(f, " {leading_field}")?;
250 }
251 if let Some(leading_precision) = self.leading_precision {
252 write!(f, " ({leading_precision})")?;
253 }
254 if let Some(last_field) = self.last_field {
255 write!(f, " TO {last_field}")?;
256 }
257 if let Some(fractional_seconds_precision) = self.fractional_seconds_precision {
258 write!(f, " ({fractional_seconds_precision})")?;
259 }
260 Ok(())
261 }
262 }
263 }
264}
265
266#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
268#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
269#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
270pub enum JsonOperator {
271 Arrow,
273 LongArrow,
275 HashArrow,
277 HashLongArrow,
279 Colon,
281 AtArrow,
283 ArrowAt,
285 HashMinus,
288 AtQuestion,
291 AtAt,
295}
296
297impl fmt::Display for JsonOperator {
298 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
299 match self {
300 JsonOperator::Arrow => {
301 write!(f, "->")
302 }
303 JsonOperator::LongArrow => {
304 write!(f, "->>")
305 }
306 JsonOperator::HashArrow => {
307 write!(f, "#>")
308 }
309 JsonOperator::HashLongArrow => {
310 write!(f, "#>>")
311 }
312 JsonOperator::Colon => {
313 write!(f, ":")
314 }
315 JsonOperator::AtArrow => {
316 write!(f, "@>")
317 }
318 JsonOperator::ArrowAt => write!(f, "<@"),
319 JsonOperator::HashMinus => write!(f, "#-"),
320 JsonOperator::AtQuestion => write!(f, "@?"),
321 JsonOperator::AtAt => write!(f, "@@"),
322 }
323 }
324}
325
326#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
330#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
331#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
332pub struct StructField {
333 pub field_name: Option<Ident>,
334 pub field_type: DataType,
335}
336
337impl fmt::Display for StructField {
338 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
339 if let Some(name) = &self.field_name {
340 write!(f, "{name} {}", self.field_type)
341 } else {
342 write!(f, "{}", self.field_type)
343 }
344 }
345}
346
347#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
350#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
351#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
352pub enum CastFormat {
353 Value(Value),
354 ValueAtTimeZone(Value, Value),
355}
356
357#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
363#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
364#[cfg_attr(
365 feature = "visitor",
366 derive(Visit, VisitMut),
367 visit(with = "visit_expr")
368)]
369pub enum Expr {
370 Identifier(Ident),
372 CompoundIdentifier(Vec<Ident>),
374 JsonAccess {
376 left: Box<Expr>,
377 operator: JsonOperator,
378 right: Box<Expr>,
379 },
380 CompositeAccess { expr: Box<Expr>, key: Ident },
382 IsFalse(Box<Expr>),
384 IsNotFalse(Box<Expr>),
386 IsTrue(Box<Expr>),
388 IsNotTrue(Box<Expr>),
390 IsNull(Box<Expr>),
392 IsNotNull(Box<Expr>),
394 IsUnknown(Box<Expr>),
396 IsNotUnknown(Box<Expr>),
398 IsDistinctFrom(Box<Expr>, Box<Expr>),
400 IsNotDistinctFrom(Box<Expr>, Box<Expr>),
402 InList {
404 expr: Box<Expr>,
405 list: Vec<Expr>,
406 negated: bool,
407 },
408 InSubquery {
410 expr: Box<Expr>,
411 subquery: Box<Query>,
412 negated: bool,
413 },
414 InUnnest {
416 expr: Box<Expr>,
417 array_expr: Box<Expr>,
418 negated: bool,
419 },
420 Between {
422 expr: Box<Expr>,
423 negated: bool,
424 low: Box<Expr>,
425 high: Box<Expr>,
426 },
427 BinaryOp {
429 left: Box<Expr>,
430 op: BinaryOperator,
431 right: Box<Expr>,
432 },
433 Like {
435 negated: bool,
436 expr: Box<Expr>,
437 pattern: Box<Expr>,
438 escape_char: Option<char>,
439 },
440 ILike {
442 negated: bool,
443 expr: Box<Expr>,
444 pattern: Box<Expr>,
445 escape_char: Option<char>,
446 },
447 SimilarTo {
449 negated: bool,
450 expr: Box<Expr>,
451 pattern: Box<Expr>,
452 escape_char: Option<char>,
453 },
454 RLike {
456 negated: bool,
457 expr: Box<Expr>,
458 pattern: Box<Expr>,
459 regexp: bool,
461 },
462 AnyOp {
464 left: Box<Expr>,
465 compare_op: BinaryOperator,
466 right: Box<Expr>,
467 },
468 AllOp {
470 left: Box<Expr>,
471 compare_op: BinaryOperator,
472 right: Box<Expr>,
473 },
474 UnaryOp { op: UnaryOperator, expr: Box<Expr> },
476 Cast {
478 expr: Box<Expr>,
479 data_type: DataType,
480 format: Option<CastFormat>,
483 },
484 TryCast {
487 expr: Box<Expr>,
488 data_type: DataType,
489 format: Option<CastFormat>,
492 },
493 SafeCast {
497 expr: Box<Expr>,
498 data_type: DataType,
499 format: Option<CastFormat>,
502 },
503 AtTimeZone {
505 timestamp: Box<Expr>,
506 time_zone: String,
507 },
508 Extract {
512 field: DateTimeField,
513 expr: Box<Expr>,
514 },
515 Ceil {
519 expr: Box<Expr>,
520 field: DateTimeField,
521 },
522 Floor {
526 expr: Box<Expr>,
527 field: DateTimeField,
528 },
529 Position { expr: Box<Expr>, r#in: Box<Expr> },
533 Substring {
537 expr: Box<Expr>,
538 substring_from: Option<Box<Expr>>,
539 substring_for: Option<Box<Expr>>,
540
541 special: bool,
544 },
545 Trim {
551 expr: Box<Expr>,
552 trim_where: Option<TrimWhereField>,
554 trim_what: Option<Box<Expr>>,
555 trim_characters: Option<Vec<Expr>>,
556 },
557 Overlay {
561 expr: Box<Expr>,
562 overlay_what: Box<Expr>,
563 overlay_from: Box<Expr>,
564 overlay_for: Option<Box<Expr>>,
565 },
566 Collate {
568 expr: Box<Expr>,
569 collation: ObjectName,
570 },
571 Nested(Box<Expr>),
573 Value(Value),
575 IntroducedString { introducer: String, value: Value },
577 TypedString { data_type: DataType, value: String },
581 MapAccess { column: Box<Expr>, keys: Vec<Expr> },
586 Function(Function),
588 AggregateExpressionWithFilter { expr: Box<Expr>, filter: Box<Expr> },
590 Case {
596 operand: Option<Box<Expr>>,
597 conditions: Vec<Expr>,
598 results: Vec<Expr>,
599 else_result: Option<Box<Expr>>,
600 },
601 Exists { subquery: Box<Query>, negated: bool },
604 Subquery(Box<Query>),
607 ArraySubquery(Box<Query>),
609 ListAgg(ListAgg),
611 ArrayAgg(ArrayAgg),
613 GroupingSets(Vec<Vec<Expr>>),
615 Cube(Vec<Vec<Expr>>),
617 Rollup(Vec<Vec<Expr>>),
619 Tuple(Vec<Expr>),
621 Struct {
628 values: Vec<Expr>,
630 fields: Vec<StructField>,
632 },
633 Named { expr: Box<Expr>, name: Ident },
641 ArrayIndex { obj: Box<Expr>, indexes: Vec<Expr> },
643 Array(Array),
645 Interval(Interval),
647 MatchAgainst {
660 columns: Vec<Ident>,
662 match_value: Value,
664 opt_search_modifier: Option<SearchModifier>,
666 },
667}
668
669impl fmt::Display for CastFormat {
670 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
671 match self {
672 CastFormat::Value(v) => write!(f, "{v}"),
673 CastFormat::ValueAtTimeZone(v, tz) => write!(f, "{v} AT TIME ZONE {tz}"),
674 }
675 }
676}
677
678impl fmt::Display for Expr {
679 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
680 match self {
681 Expr::Identifier(s) => write!(f, "{s}"),
682 Expr::MapAccess { column, keys } => {
683 write!(f, "{column}")?;
684 for k in keys {
685 match k {
686 k @ Expr::Value(Value::Number(_, _)) => write!(f, "[{k}]")?,
687 Expr::Value(Value::SingleQuotedString(s)) => write!(f, "[\"{s}\"]")?,
688 _ => write!(f, "[{k}]")?,
689 }
690 }
691 Ok(())
692 }
693 Expr::CompoundIdentifier(s) => write!(f, "{}", display_separated(s, ".")),
694 Expr::IsTrue(ast) => write!(f, "{ast} IS TRUE"),
695 Expr::IsNotTrue(ast) => write!(f, "{ast} IS NOT TRUE"),
696 Expr::IsFalse(ast) => write!(f, "{ast} IS FALSE"),
697 Expr::IsNotFalse(ast) => write!(f, "{ast} IS NOT FALSE"),
698 Expr::IsNull(ast) => write!(f, "{ast} IS NULL"),
699 Expr::IsNotNull(ast) => write!(f, "{ast} IS NOT NULL"),
700 Expr::IsUnknown(ast) => write!(f, "{ast} IS UNKNOWN"),
701 Expr::IsNotUnknown(ast) => write!(f, "{ast} IS NOT UNKNOWN"),
702 Expr::InList {
703 expr,
704 list,
705 negated,
706 } => write!(
707 f,
708 "{} {}IN ({})",
709 expr,
710 if *negated { "NOT " } else { "" },
711 display_comma_separated(list)
712 ),
713 Expr::InSubquery {
714 expr,
715 subquery,
716 negated,
717 } => write!(
718 f,
719 "{} {}IN ({})",
720 expr,
721 if *negated { "NOT " } else { "" },
722 subquery
723 ),
724 Expr::InUnnest {
725 expr,
726 array_expr,
727 negated,
728 } => write!(
729 f,
730 "{} {}IN UNNEST({})",
731 expr,
732 if *negated { "NOT " } else { "" },
733 array_expr
734 ),
735 Expr::Between {
736 expr,
737 negated,
738 low,
739 high,
740 } => write!(
741 f,
742 "{} {}BETWEEN {} AND {}",
743 expr,
744 if *negated { "NOT " } else { "" },
745 low,
746 high
747 ),
748 Expr::BinaryOp { left, op, right } => write!(f, "{left} {op} {right}"),
749 Expr::Like {
750 negated,
751 expr,
752 pattern,
753 escape_char,
754 } => match escape_char {
755 Some(ch) => write!(
756 f,
757 "{} {}LIKE {} ESCAPE '{}'",
758 expr,
759 if *negated { "NOT " } else { "" },
760 pattern,
761 ch
762 ),
763 _ => write!(
764 f,
765 "{} {}LIKE {}",
766 expr,
767 if *negated { "NOT " } else { "" },
768 pattern
769 ),
770 },
771 Expr::ILike {
772 negated,
773 expr,
774 pattern,
775 escape_char,
776 } => match escape_char {
777 Some(ch) => write!(
778 f,
779 "{} {}ILIKE {} ESCAPE '{}'",
780 expr,
781 if *negated { "NOT " } else { "" },
782 pattern,
783 ch
784 ),
785 _ => write!(
786 f,
787 "{} {}ILIKE {}",
788 expr,
789 if *negated { "NOT " } else { "" },
790 pattern
791 ),
792 },
793 Expr::RLike {
794 negated,
795 expr,
796 pattern,
797 regexp,
798 } => write!(
799 f,
800 "{} {}{} {}",
801 expr,
802 if *negated { "NOT " } else { "" },
803 if *regexp { "REGEXP" } else { "RLIKE" },
804 pattern
805 ),
806 Expr::SimilarTo {
807 negated,
808 expr,
809 pattern,
810 escape_char,
811 } => match escape_char {
812 Some(ch) => write!(
813 f,
814 "{} {}SIMILAR TO {} ESCAPE '{}'",
815 expr,
816 if *negated { "NOT " } else { "" },
817 pattern,
818 ch
819 ),
820 _ => write!(
821 f,
822 "{} {}SIMILAR TO {}",
823 expr,
824 if *negated { "NOT " } else { "" },
825 pattern
826 ),
827 },
828 Expr::AnyOp {
829 left,
830 compare_op,
831 right,
832 } => write!(f, "{left} {compare_op} ANY({right})"),
833 Expr::AllOp {
834 left,
835 compare_op,
836 right,
837 } => write!(f, "{left} {compare_op} ALL({right})"),
838 Expr::UnaryOp { op, expr } => {
839 if op == &UnaryOperator::PGPostfixFactorial {
840 write!(f, "{expr}{op}")
841 } else if op == &UnaryOperator::Not {
842 write!(f, "{op} {expr}")
843 } else {
844 write!(f, "{op}{expr}")
845 }
846 }
847 Expr::Cast {
848 expr,
849 data_type,
850 format,
851 } => {
852 if let Some(format) = format {
853 write!(f, "CAST({expr} AS {data_type} FORMAT {format})")
854 } else {
855 write!(f, "CAST({expr} AS {data_type})")
856 }
857 }
858 Expr::TryCast {
859 expr,
860 data_type,
861 format,
862 } => {
863 if let Some(format) = format {
864 write!(f, "TRY_CAST({expr} AS {data_type} FORMAT {format})")
865 } else {
866 write!(f, "TRY_CAST({expr} AS {data_type})")
867 }
868 }
869 Expr::SafeCast {
870 expr,
871 data_type,
872 format,
873 } => {
874 if let Some(format) = format {
875 write!(f, "SAFE_CAST({expr} AS {data_type} FORMAT {format})")
876 } else {
877 write!(f, "SAFE_CAST({expr} AS {data_type})")
878 }
879 }
880 Expr::Extract { field, expr } => write!(f, "EXTRACT({field} FROM {expr})"),
881 Expr::Ceil { expr, field } => {
882 if field == &DateTimeField::NoDateTime {
883 write!(f, "CEIL({expr})")
884 } else {
885 write!(f, "CEIL({expr} TO {field})")
886 }
887 }
888 Expr::Floor { expr, field } => {
889 if field == &DateTimeField::NoDateTime {
890 write!(f, "FLOOR({expr})")
891 } else {
892 write!(f, "FLOOR({expr} TO {field})")
893 }
894 }
895 Expr::Position { expr, r#in } => write!(f, "POSITION({expr} IN {in})"),
896 Expr::Collate { expr, collation } => write!(f, "{expr} COLLATE {collation}"),
897 Expr::Nested(ast) => write!(f, "({ast})"),
898 Expr::Value(v) => write!(f, "{v}"),
899 Expr::IntroducedString { introducer, value } => write!(f, "{introducer} {value}"),
900 Expr::TypedString { data_type, value } => {
901 write!(f, "{data_type}")?;
902 write!(f, " '{}'", &value::escape_single_quote_string(value))
903 }
904 Expr::Function(fun) => write!(f, "{fun}"),
905 Expr::AggregateExpressionWithFilter { expr, filter } => {
906 write!(f, "{expr} FILTER (WHERE {filter})")
907 }
908 Expr::Case {
909 operand,
910 conditions,
911 results,
912 else_result,
913 } => {
914 write!(f, "CASE")?;
915 if let Some(operand) = operand {
916 write!(f, " {operand}")?;
917 }
918 for (c, r) in conditions.iter().zip(results) {
919 write!(f, " WHEN {c} THEN {r}")?;
920 }
921
922 if let Some(else_result) = else_result {
923 write!(f, " ELSE {else_result}")?;
924 }
925 write!(f, " END")
926 }
927 Expr::Exists { subquery, negated } => write!(
928 f,
929 "{}EXISTS ({})",
930 if *negated { "NOT " } else { "" },
931 subquery
932 ),
933 Expr::Subquery(s) => write!(f, "({s})"),
934 Expr::ArraySubquery(s) => write!(f, "ARRAY({s})"),
935 Expr::ListAgg(listagg) => write!(f, "{listagg}"),
936 Expr::ArrayAgg(arrayagg) => write!(f, "{arrayagg}"),
937 Expr::GroupingSets(sets) => {
938 write!(f, "GROUPING SETS (")?;
939 let mut sep = "";
940 for set in sets {
941 write!(f, "{sep}")?;
942 sep = ", ";
943 write!(f, "({})", display_comma_separated(set))?;
944 }
945 write!(f, ")")
946 }
947 Expr::Cube(sets) => {
948 write!(f, "CUBE (")?;
949 let mut sep = "";
950 for set in sets {
951 write!(f, "{sep}")?;
952 sep = ", ";
953 if set.len() == 1 {
954 write!(f, "{}", set[0])?;
955 } else {
956 write!(f, "({})", display_comma_separated(set))?;
957 }
958 }
959 write!(f, ")")
960 }
961 Expr::Rollup(sets) => {
962 write!(f, "ROLLUP (")?;
963 let mut sep = "";
964 for set in sets {
965 write!(f, "{sep}")?;
966 sep = ", ";
967 if set.len() == 1 {
968 write!(f, "{}", set[0])?;
969 } else {
970 write!(f, "({})", display_comma_separated(set))?;
971 }
972 }
973 write!(f, ")")
974 }
975 Expr::Substring {
976 expr,
977 substring_from,
978 substring_for,
979 special,
980 } => {
981 write!(f, "SUBSTRING({expr}")?;
982 if let Some(from_part) = substring_from {
983 if *special {
984 write!(f, ", {from_part}")?;
985 } else {
986 write!(f, " FROM {from_part}")?;
987 }
988 }
989 if let Some(for_part) = substring_for {
990 if *special {
991 write!(f, ", {for_part}")?;
992 } else {
993 write!(f, " FOR {for_part}")?;
994 }
995 }
996
997 write!(f, ")")
998 }
999 Expr::Overlay {
1000 expr,
1001 overlay_what,
1002 overlay_from,
1003 overlay_for,
1004 } => {
1005 write!(
1006 f,
1007 "OVERLAY({expr} PLACING {overlay_what} FROM {overlay_from}"
1008 )?;
1009 if let Some(for_part) = overlay_for {
1010 write!(f, " FOR {for_part}")?;
1011 }
1012
1013 write!(f, ")")
1014 }
1015 Expr::IsDistinctFrom(a, b) => write!(f, "{a} IS DISTINCT FROM {b}"),
1016 Expr::IsNotDistinctFrom(a, b) => write!(f, "{a} IS NOT DISTINCT FROM {b}"),
1017 Expr::Trim {
1018 expr,
1019 trim_where,
1020 trim_what,
1021 trim_characters,
1022 } => {
1023 write!(f, "TRIM(")?;
1024 if let Some(ident) = trim_where {
1025 write!(f, "{ident} ")?;
1026 }
1027 if let Some(trim_char) = trim_what {
1028 write!(f, "{trim_char} FROM {expr}")?;
1029 } else {
1030 write!(f, "{expr}")?;
1031 }
1032 if let Some(characters) = trim_characters {
1033 write!(f, ", {}", display_comma_separated(characters))?;
1034 }
1035
1036 write!(f, ")")
1037 }
1038 Expr::Tuple(exprs) => {
1039 write!(f, "({})", display_comma_separated(exprs))
1040 }
1041 Expr::Struct { values, fields } => {
1042 if !fields.is_empty() {
1043 write!(
1044 f,
1045 "STRUCT<{}>({})",
1046 display_comma_separated(fields),
1047 display_comma_separated(values)
1048 )
1049 } else {
1050 write!(f, "STRUCT({})", display_comma_separated(values))
1051 }
1052 }
1053 Expr::Named { expr, name } => {
1054 write!(f, "{} AS {}", expr, name)
1055 }
1056 Expr::ArrayIndex { obj, indexes } => {
1057 write!(f, "{obj}")?;
1058 for i in indexes {
1059 write!(f, "[{i}]")?;
1060 }
1061 Ok(())
1062 }
1063 Expr::Array(set) => {
1064 write!(f, "{set}")
1065 }
1066 Expr::JsonAccess {
1067 left,
1068 operator,
1069 right,
1070 } => {
1071 if operator == &JsonOperator::Colon {
1072 write!(f, "{left}{operator}{right}")
1073 } else {
1074 write!(f, "{left} {operator} {right}")
1075 }
1076 }
1077 Expr::CompositeAccess { expr, key } => {
1078 write!(f, "{expr}.{key}")
1079 }
1080 Expr::AtTimeZone {
1081 timestamp,
1082 time_zone,
1083 } => {
1084 write!(f, "{timestamp} AT TIME ZONE '{time_zone}'")
1085 }
1086 Expr::Interval(interval) => {
1087 write!(f, "{interval}")
1088 }
1089 Expr::MatchAgainst {
1090 columns,
1091 match_value: match_expr,
1092 opt_search_modifier,
1093 } => {
1094 write!(f, "MATCH ({}) AGAINST ", display_comma_separated(columns),)?;
1095
1096 if let Some(search_modifier) = opt_search_modifier {
1097 write!(f, "({match_expr} {search_modifier})")?;
1098 } else {
1099 write!(f, "({match_expr})")?;
1100 }
1101
1102 Ok(())
1103 }
1104 }
1105 }
1106}
1107
1108#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1109#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1110#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1111pub enum WindowType {
1112 WindowSpec(WindowSpec),
1113 NamedWindow(Ident),
1114}
1115
1116impl Display for WindowType {
1117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1118 match self {
1119 WindowType::WindowSpec(spec) => write!(f, "({})", spec),
1120 WindowType::NamedWindow(name) => write!(f, "{}", name),
1121 }
1122 }
1123}
1124
1125#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1127#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1128#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1129pub struct WindowSpec {
1130 pub partition_by: Vec<Expr>,
1132 pub order_by: Vec<OrderByExpr>,
1134 pub window_frame: Option<WindowFrame>,
1136}
1137
1138impl fmt::Display for WindowSpec {
1139 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1140 let mut delim = "";
1141 if !self.partition_by.is_empty() {
1142 delim = " ";
1143 write!(
1144 f,
1145 "PARTITION BY {}",
1146 display_comma_separated(&self.partition_by)
1147 )?;
1148 }
1149 if !self.order_by.is_empty() {
1150 f.write_str(delim)?;
1151 delim = " ";
1152 write!(f, "ORDER BY {}", display_comma_separated(&self.order_by))?;
1153 }
1154 if let Some(window_frame) = &self.window_frame {
1155 f.write_str(delim)?;
1156 if let Some(end_bound) = &window_frame.end_bound {
1157 write!(
1158 f,
1159 "{} BETWEEN {} AND {}",
1160 window_frame.units, window_frame.start_bound, end_bound
1161 )?;
1162 } else {
1163 write!(f, "{} {}", window_frame.units, window_frame.start_bound)?;
1164 }
1165 }
1166 Ok(())
1167 }
1168}
1169
1170#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1176#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1177#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1178pub struct WindowFrame {
1179 pub units: WindowFrameUnits,
1180 pub start_bound: WindowFrameBound,
1181 pub end_bound: Option<WindowFrameBound>,
1185 }
1187
1188impl Default for WindowFrame {
1189 fn default() -> Self {
1193 Self {
1194 units: WindowFrameUnits::Range,
1195 start_bound: WindowFrameBound::Preceding(None),
1196 end_bound: None,
1197 }
1198 }
1199}
1200
1201#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1202#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1203#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1204pub enum WindowFrameUnits {
1205 Rows,
1206 Range,
1207 Groups,
1208}
1209
1210impl fmt::Display for WindowFrameUnits {
1211 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1212 f.write_str(match self {
1213 WindowFrameUnits::Rows => "ROWS",
1214 WindowFrameUnits::Range => "RANGE",
1215 WindowFrameUnits::Groups => "GROUPS",
1216 })
1217 }
1218}
1219
1220#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1224#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1225#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1226pub enum NullTreatment {
1227 IgnoreNulls,
1228 RespectNulls,
1229}
1230
1231impl fmt::Display for NullTreatment {
1232 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1233 f.write_str(match self {
1234 NullTreatment::IgnoreNulls => "IGNORE NULLS",
1235 NullTreatment::RespectNulls => "RESPECT NULLS",
1236 })
1237 }
1238}
1239
1240#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1242#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1243#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1244pub enum WindowFrameBound {
1245 CurrentRow,
1247 Preceding(Option<Box<Expr>>),
1249 Following(Option<Box<Expr>>),
1251}
1252
1253impl fmt::Display for WindowFrameBound {
1254 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1255 match self {
1256 WindowFrameBound::CurrentRow => f.write_str("CURRENT ROW"),
1257 WindowFrameBound::Preceding(None) => f.write_str("UNBOUNDED PRECEDING"),
1258 WindowFrameBound::Following(None) => f.write_str("UNBOUNDED FOLLOWING"),
1259 WindowFrameBound::Preceding(Some(n)) => write!(f, "{n} PRECEDING"),
1260 WindowFrameBound::Following(Some(n)) => write!(f, "{n} FOLLOWING"),
1261 }
1262 }
1263}
1264
1265#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1266#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1267#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1268pub enum AddDropSync {
1269 ADD,
1270 DROP,
1271 SYNC,
1272}
1273
1274impl fmt::Display for AddDropSync {
1275 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1276 match self {
1277 AddDropSync::SYNC => f.write_str("SYNC PARTITIONS"),
1278 AddDropSync::DROP => f.write_str("DROP PARTITIONS"),
1279 AddDropSync::ADD => f.write_str("ADD PARTITIONS"),
1280 }
1281 }
1282}
1283
1284#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1285#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1286#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1287pub enum ShowCreateObject {
1288 Event,
1289 Function,
1290 Procedure,
1291 Table,
1292 Trigger,
1293 View,
1294}
1295
1296impl fmt::Display for ShowCreateObject {
1297 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1298 match self {
1299 ShowCreateObject::Event => f.write_str("EVENT"),
1300 ShowCreateObject::Function => f.write_str("FUNCTION"),
1301 ShowCreateObject::Procedure => f.write_str("PROCEDURE"),
1302 ShowCreateObject::Table => f.write_str("TABLE"),
1303 ShowCreateObject::Trigger => f.write_str("TRIGGER"),
1304 ShowCreateObject::View => f.write_str("VIEW"),
1305 }
1306 }
1307}
1308
1309#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1310#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1311#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1312pub enum CommentObject {
1313 Column,
1314 Table,
1315}
1316
1317impl fmt::Display for CommentObject {
1318 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1319 match self {
1320 CommentObject::Column => f.write_str("COLUMN"),
1321 CommentObject::Table => f.write_str("TABLE"),
1322 }
1323 }
1324}
1325
1326#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1327#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1328#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1329pub enum Password {
1330 Password(Expr),
1331 NullPassword,
1332}
1333
1334#[allow(clippy::large_enum_variant)]
1336#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1337#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1338#[cfg_attr(
1339 feature = "visitor",
1340 derive(Visit, VisitMut),
1341 visit(with = "visit_statement")
1342)]
1343pub enum Statement {
1344 Analyze {
1346 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1347 table_name: ObjectName,
1348 partitions: Option<Vec<Expr>>,
1349 for_columns: bool,
1350 columns: Vec<Ident>,
1351 cache_metadata: bool,
1352 noscan: bool,
1353 compute_statistics: bool,
1354 },
1355 Truncate {
1357 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1358 table_name: ObjectName,
1359 partitions: Option<Vec<Expr>>,
1360 table: bool,
1362 },
1363 Msck {
1365 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1366 table_name: ObjectName,
1367 repair: bool,
1368 partition_action: Option<AddDropSync>,
1369 },
1370 Query(Box<Query>),
1372 Insert {
1374 or: Option<SqliteOnConflict>,
1376 ignore: bool,
1378 into: bool,
1380 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1382 table_name: ObjectName,
1383 columns: Vec<Ident>,
1385 overwrite: bool,
1387 source: Box<Query>,
1389 partitioned: Option<Vec<Expr>>,
1391 after_columns: Vec<Ident>,
1393 table: bool,
1395 on: Option<OnInsert>,
1396 returning: Option<Vec<SelectItem>>,
1398 },
1399 Directory {
1401 overwrite: bool,
1402 local: bool,
1403 path: String,
1404 file_format: Option<FileFormat>,
1405 source: Box<Query>,
1406 },
1407 Copy {
1408 source: CopySource,
1410 to: bool,
1412 target: CopyTarget,
1414 options: Vec<CopyOption>,
1416 legacy_options: Vec<CopyLegacyOption>,
1418 values: Vec<Option<String>>,
1420 },
1421 CopyIntoSnowflake {
1430 into: ObjectName,
1431 from_stage: ObjectName,
1432 from_stage_alias: Option<Ident>,
1433 stage_params: StageParamsObject,
1434 from_transformations: Option<Vec<StageLoadSelectItem>>,
1435 files: Option<Vec<String>>,
1436 pattern: Option<String>,
1437 file_format: DataLoadingOptions,
1438 copy_options: DataLoadingOptions,
1439 validation_mode: Option<String>,
1440 },
1441 Close {
1443 cursor: CloseCursor,
1445 },
1446 Update {
1448 table: TableWithJoins,
1450 assignments: Vec<Assignment>,
1452 from: Option<TableWithJoins>,
1454 selection: Option<Expr>,
1456 returning: Option<Vec<SelectItem>>,
1458 },
1459 Delete {
1461 tables: Vec<ObjectName>,
1463 from: Vec<TableWithJoins>,
1465 using: Option<Vec<TableWithJoins>>,
1467 selection: Option<Expr>,
1469 returning: Option<Vec<SelectItem>>,
1471 order_by: Vec<OrderByExpr>,
1473 limit: Option<Expr>,
1475 },
1476 CreateView {
1478 or_replace: bool,
1479 materialized: bool,
1480 name: ObjectName,
1482 columns: Vec<Ident>,
1483 query: Box<Query>,
1484 with_options: Vec<SqlOption>,
1485 cluster_by: Vec<Ident>,
1486 with_no_schema_binding: bool,
1488 if_not_exists: bool,
1490 temporary: bool,
1492 },
1493 CreateTable {
1495 or_replace: bool,
1496 temporary: bool,
1497 external: bool,
1498 global: Option<bool>,
1499 if_not_exists: bool,
1500 transient: bool,
1501 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1503 name: ObjectName,
1504 columns: Vec<ColumnDef>,
1506 constraints: Vec<TableConstraint>,
1507 hive_distribution: HiveDistributionStyle,
1508 hive_formats: Option<HiveFormat>,
1509 table_properties: Vec<SqlOption>,
1510 with_options: Vec<SqlOption>,
1511 file_format: Option<FileFormat>,
1512 location: Option<String>,
1513 query: Option<Box<Query>>,
1514 without_rowid: bool,
1515 like: Option<ObjectName>,
1516 clone: Option<ObjectName>,
1517 engine: Option<String>,
1518 comment: Option<String>,
1519 auto_increment_offset: Option<u32>,
1520 default_charset: Option<String>,
1521 collation: Option<String>,
1522 on_commit: Option<OnCommit>,
1523 on_cluster: Option<String>,
1526 order_by: Option<Vec<Ident>>,
1530 strict: bool,
1534 },
1535 CreateVirtualTable {
1537 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1538 name: ObjectName,
1539 if_not_exists: bool,
1540 module_name: Ident,
1541 module_args: Vec<Ident>,
1542 },
1543 CreateIndex {
1545 name: Option<ObjectName>,
1547 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1548 table_name: ObjectName,
1549 using: Option<Ident>,
1550 columns: Vec<OrderByExpr>,
1551 unique: bool,
1552 concurrently: bool,
1553 if_not_exists: bool,
1554 include: Vec<Ident>,
1555 nulls_distinct: Option<bool>,
1556 predicate: Option<Expr>,
1557 },
1558 CreateRole {
1561 names: Vec<ObjectName>,
1562 if_not_exists: bool,
1563 login: Option<bool>,
1565 inherit: Option<bool>,
1566 bypassrls: Option<bool>,
1567 password: Option<Password>,
1568 superuser: Option<bool>,
1569 create_db: Option<bool>,
1570 create_role: Option<bool>,
1571 replication: Option<bool>,
1572 connection_limit: Option<Expr>,
1573 valid_until: Option<Expr>,
1574 in_role: Vec<Ident>,
1575 in_group: Vec<Ident>,
1576 role: Vec<Ident>,
1577 user: Vec<Ident>,
1578 admin: Vec<Ident>,
1579 authorization_owner: Option<ObjectName>,
1581 },
1582 AlterTable {
1584 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1586 name: ObjectName,
1587 if_exists: bool,
1588 only: bool,
1589 operations: Vec<AlterTableOperation>,
1590 },
1591 AlterIndex {
1592 name: ObjectName,
1593 operation: AlterIndexOperation,
1594 },
1595 AlterView {
1597 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1599 name: ObjectName,
1600 columns: Vec<Ident>,
1601 query: Box<Query>,
1602 with_options: Vec<SqlOption>,
1603 },
1604 AlterRole {
1606 name: Ident,
1607 operation: AlterRoleOperation,
1608 },
1609 AttachDatabase {
1612 schema_name: Ident,
1614 database_file_name: Expr,
1616 database: bool,
1618 },
1619 Drop {
1621 object_type: ObjectType,
1623 if_exists: bool,
1625 names: Vec<ObjectName>,
1627 cascade: bool,
1630 restrict: bool,
1633 purge: bool,
1636 temporary: bool,
1638 },
1639 DropFunction {
1641 if_exists: bool,
1642 func_desc: Vec<DropFunctionDesc>,
1644 option: Option<ReferentialAction>,
1646 },
1647 Declare {
1652 name: Ident,
1654 binary: bool,
1656 sensitive: Option<bool>,
1660 scroll: Option<bool>,
1664 hold: Option<bool>,
1668 query: Box<Query>,
1669 },
1670 Fetch {
1675 name: Ident,
1677 direction: FetchDirection,
1678 into: Option<ObjectName>,
1680 },
1681 Discard { object_type: DiscardObject },
1686 SetRole {
1693 context_modifier: ContextModifier,
1695 role_name: Option<Ident>,
1697 },
1698 SetVariable {
1706 local: bool,
1707 hivevar: bool,
1708 variable: ObjectName,
1709 value: Vec<Expr>,
1710 },
1711 SetTimeZone { local: bool, value: Expr },
1718 SetNames {
1722 charset_name: String,
1723 collation_name: Option<String>,
1724 },
1725 SetNamesDefault {},
1729 ShowFunctions { filter: Option<ShowStatementFilter> },
1733 ShowVariable { variable: Vec<Ident> },
1739 ShowVariables { filter: Option<ShowStatementFilter> },
1743 ShowCreate {
1747 obj_type: ShowCreateObject,
1748 obj_name: ObjectName,
1749 },
1750 ShowColumns {
1754 extended: bool,
1755 full: bool,
1756 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1757 table_name: ObjectName,
1758 filter: Option<ShowStatementFilter>,
1759 },
1760 ShowTables {
1764 extended: bool,
1765 full: bool,
1766 db_name: Option<Ident>,
1767 filter: Option<ShowStatementFilter>,
1768 },
1769 ShowCollation { filter: Option<ShowStatementFilter> },
1773 Use { db_name: Ident },
1777 StartTransaction {
1783 modes: Vec<TransactionMode>,
1784 begin: bool,
1785 },
1786 SetTransaction {
1788 modes: Vec<TransactionMode>,
1789 snapshot: Option<Value>,
1790 session: bool,
1791 },
1792 Comment {
1796 object_type: CommentObject,
1797 object_name: ObjectName,
1798 comment: Option<String>,
1799 if_exists: bool,
1802 },
1803 Commit { chain: bool },
1805 Rollback { chain: bool },
1807 CreateSchema {
1809 schema_name: SchemaName,
1811 if_not_exists: bool,
1812 },
1813 CreateDatabase {
1815 db_name: ObjectName,
1816 if_not_exists: bool,
1817 location: Option<String>,
1818 managed_location: Option<String>,
1819 },
1820 CreateFunction {
1828 or_replace: bool,
1829 temporary: bool,
1830 name: ObjectName,
1831 args: Option<Vec<OperateFunctionArg>>,
1832 return_type: Option<DataType>,
1833 params: CreateFunctionBody,
1835 },
1836 CreateProcedure {
1840 or_alter: bool,
1841 name: ObjectName,
1842 params: Option<Vec<ProcedureParam>>,
1843 body: Vec<Statement>,
1844 },
1845 CreateMacro {
1852 or_replace: bool,
1853 temporary: bool,
1854 name: ObjectName,
1855 args: Option<Vec<MacroArg>>,
1856 definition: MacroDefinition,
1857 },
1858 CreateStage {
1863 or_replace: bool,
1864 temporary: bool,
1865 if_not_exists: bool,
1866 name: ObjectName,
1867 stage_params: StageParamsObject,
1868 directory_table_params: DataLoadingOptions,
1869 file_format: DataLoadingOptions,
1870 copy_options: DataLoadingOptions,
1871 comment: Option<String>,
1872 },
1873 Assert {
1875 condition: Expr,
1876 message: Option<Expr>,
1877 },
1878 Grant {
1880 privileges: Privileges,
1881 objects: GrantObjects,
1882 grantees: Vec<Ident>,
1883 with_grant_option: bool,
1884 granted_by: Option<Ident>,
1885 },
1886 Revoke {
1888 privileges: Privileges,
1889 objects: GrantObjects,
1890 grantees: Vec<Ident>,
1891 granted_by: Option<Ident>,
1892 cascade: bool,
1893 },
1894 Deallocate { name: Ident, prepare: bool },
1898 Execute { name: Ident, parameters: Vec<Expr> },
1902 Prepare {
1906 name: Ident,
1907 data_types: Vec<DataType>,
1908 statement: Box<Statement>,
1909 },
1910 Kill {
1915 modifier: Option<KillType>,
1916 id: u64,
1918 },
1919 ExplainTable {
1922 describe_alias: bool,
1924 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1926 table_name: ObjectName,
1927 },
1928 Explain {
1930 describe_alias: bool,
1932 analyze: bool,
1934 verbose: bool,
1936 statement: Box<Statement>,
1938 format: Option<AnalyzeFormat>,
1940 },
1941 Savepoint { name: Ident },
1943 Merge {
1945 into: bool,
1947 table: TableFactor,
1949 source: TableFactor,
1951 on: Box<Expr>,
1953 clauses: Vec<MergeClause>,
1955 },
1956 Cache {
1962 table_flag: Option<ObjectName>,
1964 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1967 table_name: ObjectName,
1968 has_as: bool,
1969 options: Vec<SqlOption>,
1971 query: Option<Query>,
1973 },
1974 UNCache {
1976 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1978 table_name: ObjectName,
1979 if_exists: bool,
1980 },
1981 CreateSequence {
1984 temporary: bool,
1985 if_not_exists: bool,
1986 name: ObjectName,
1987 data_type: Option<DataType>,
1988 sequence_options: Vec<SequenceOptions>,
1989 owned_by: Option<ObjectName>,
1990 },
1991 CreateType {
1993 name: ObjectName,
1994 representation: UserDefinedTypeRepresentation,
1995 },
1996 Pragma {
1998 name: ObjectName,
1999 value: Option<Value>,
2000 is_eq: bool,
2001 },
2002}
2003
2004impl fmt::Display for Statement {
2005 #[allow(clippy::cognitive_complexity)]
2008 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2009 match self {
2010 Statement::Kill { modifier, id } => {
2011 write!(f, "KILL ")?;
2012
2013 if let Some(m) = modifier {
2014 write!(f, "{m} ")?;
2015 }
2016
2017 write!(f, "{id}")
2018 }
2019 Statement::ExplainTable {
2020 describe_alias,
2021 table_name,
2022 } => {
2023 if *describe_alias {
2024 write!(f, "DESCRIBE ")?;
2025 } else {
2026 write!(f, "EXPLAIN ")?;
2027 }
2028
2029 write!(f, "{table_name}")
2030 }
2031 Statement::Explain {
2032 describe_alias,
2033 verbose,
2034 analyze,
2035 statement,
2036 format,
2037 } => {
2038 if *describe_alias {
2039 write!(f, "DESCRIBE ")?;
2040 } else {
2041 write!(f, "EXPLAIN ")?;
2042 }
2043
2044 if *analyze {
2045 write!(f, "ANALYZE ")?;
2046 }
2047
2048 if *verbose {
2049 write!(f, "VERBOSE ")?;
2050 }
2051
2052 if let Some(format) = format {
2053 write!(f, "FORMAT {format} ")?;
2054 }
2055
2056 write!(f, "{statement}")
2057 }
2058 Statement::Query(s) => write!(f, "{s}"),
2059 Statement::Declare {
2060 name,
2061 binary,
2062 sensitive,
2063 scroll,
2064 hold,
2065 query,
2066 } => {
2067 write!(f, "DECLARE {name} ")?;
2068
2069 if *binary {
2070 write!(f, "BINARY ")?;
2071 }
2072
2073 if let Some(sensitive) = sensitive {
2074 if *sensitive {
2075 write!(f, "INSENSITIVE ")?;
2076 } else {
2077 write!(f, "ASENSITIVE ")?;
2078 }
2079 }
2080
2081 if let Some(scroll) = scroll {
2082 if *scroll {
2083 write!(f, "SCROLL ")?;
2084 } else {
2085 write!(f, "NO SCROLL ")?;
2086 }
2087 }
2088
2089 write!(f, "CURSOR ")?;
2090
2091 if let Some(hold) = hold {
2092 if *hold {
2093 write!(f, "WITH HOLD ")?;
2094 } else {
2095 write!(f, "WITHOUT HOLD ")?;
2096 }
2097 }
2098
2099 write!(f, "FOR {query}")
2100 }
2101 Statement::Fetch {
2102 name,
2103 direction,
2104 into,
2105 } => {
2106 write!(f, "FETCH {direction} ")?;
2107
2108 write!(f, "IN {name}")?;
2109
2110 if let Some(into) = into {
2111 write!(f, " INTO {into}")?;
2112 }
2113
2114 Ok(())
2115 }
2116 Statement::Directory {
2117 overwrite,
2118 local,
2119 path,
2120 file_format,
2121 source,
2122 } => {
2123 write!(
2124 f,
2125 "INSERT{overwrite}{local} DIRECTORY '{path}'",
2126 overwrite = if *overwrite { " OVERWRITE" } else { "" },
2127 local = if *local { " LOCAL" } else { "" },
2128 path = path
2129 )?;
2130 if let Some(ref ff) = file_format {
2131 write!(f, " STORED AS {ff}")?
2132 }
2133 write!(f, " {source}")
2134 }
2135 Statement::Msck {
2136 table_name,
2137 repair,
2138 partition_action,
2139 } => {
2140 write!(
2141 f,
2142 "MSCK {repair}TABLE {table}",
2143 repair = if *repair { "REPAIR " } else { "" },
2144 table = table_name
2145 )?;
2146 if let Some(pa) = partition_action {
2147 write!(f, " {pa}")?;
2148 }
2149 Ok(())
2150 }
2151 Statement::Truncate {
2152 table_name,
2153 partitions,
2154 table,
2155 } => {
2156 let table = if *table { "TABLE " } else { "" };
2157 write!(f, "TRUNCATE {table}{table_name}")?;
2158 if let Some(ref parts) = partitions {
2159 if !parts.is_empty() {
2160 write!(f, " PARTITION ({})", display_comma_separated(parts))?;
2161 }
2162 }
2163 Ok(())
2164 }
2165 Statement::AttachDatabase {
2166 schema_name,
2167 database_file_name,
2168 database,
2169 } => {
2170 let keyword = if *database { "DATABASE " } else { "" };
2171 write!(f, "ATTACH {keyword}{database_file_name} AS {schema_name}")
2172 }
2173 Statement::Analyze {
2174 table_name,
2175 partitions,
2176 for_columns,
2177 columns,
2178 cache_metadata,
2179 noscan,
2180 compute_statistics,
2181 } => {
2182 write!(f, "ANALYZE TABLE {table_name}")?;
2183 if let Some(ref parts) = partitions {
2184 if !parts.is_empty() {
2185 write!(f, " PARTITION ({})", display_comma_separated(parts))?;
2186 }
2187 }
2188
2189 if *compute_statistics {
2190 write!(f, " COMPUTE STATISTICS")?;
2191 }
2192 if *noscan {
2193 write!(f, " NOSCAN")?;
2194 }
2195 if *cache_metadata {
2196 write!(f, " CACHE METADATA")?;
2197 }
2198 if *for_columns {
2199 write!(f, " FOR COLUMNS")?;
2200 if !columns.is_empty() {
2201 write!(f, " {}", display_comma_separated(columns))?;
2202 }
2203 }
2204 Ok(())
2205 }
2206 Statement::Insert {
2207 or,
2208 ignore,
2209 into,
2210 table_name,
2211 overwrite,
2212 partitioned,
2213 columns,
2214 after_columns,
2215 source,
2216 table,
2217 on,
2218 returning,
2219 } => {
2220 if let Some(action) = or {
2221 write!(f, "INSERT OR {action} INTO {table_name} ")?;
2222 } else {
2223 write!(
2224 f,
2225 "INSERT{ignore}{over}{int}{tbl} {table_name} ",
2226 table_name = table_name,
2227 ignore = if *ignore { " IGNORE" } else { "" },
2228 over = if *overwrite { " OVERWRITE" } else { "" },
2229 int = if *into { " INTO" } else { "" },
2230 tbl = if *table { " TABLE" } else { "" }
2231 )?;
2232 }
2233 if !columns.is_empty() {
2234 write!(f, "({}) ", display_comma_separated(columns))?;
2235 }
2236 if let Some(ref parts) = partitioned {
2237 if !parts.is_empty() {
2238 write!(f, "PARTITION ({}) ", display_comma_separated(parts))?;
2239 }
2240 }
2241 if !after_columns.is_empty() {
2242 write!(f, "({}) ", display_comma_separated(after_columns))?;
2243 }
2244 write!(f, "{source}")?;
2245
2246 if let Some(on) = on {
2247 write!(f, "{on}")?;
2248 }
2249
2250 if let Some(returning) = returning {
2251 write!(f, " RETURNING {}", display_comma_separated(returning))?;
2252 }
2253
2254 Ok(())
2255 }
2256
2257 Statement::Copy {
2258 source,
2259 to,
2260 target,
2261 options,
2262 legacy_options,
2263 values,
2264 } => {
2265 write!(f, "COPY")?;
2266 match source {
2267 CopySource::Query(query) => write!(f, " ({query})")?,
2268 CopySource::Table {
2269 table_name,
2270 columns,
2271 } => {
2272 write!(f, " {table_name}")?;
2273 if !columns.is_empty() {
2274 write!(f, " ({})", display_comma_separated(columns))?;
2275 }
2276 }
2277 }
2278 write!(f, " {} {}", if *to { "TO" } else { "FROM" }, target)?;
2279 if !options.is_empty() {
2280 write!(f, " ({})", display_comma_separated(options))?;
2281 }
2282 if !legacy_options.is_empty() {
2283 write!(f, " {}", display_separated(legacy_options, " "))?;
2284 }
2285 if !values.is_empty() {
2286 writeln!(f, ";")?;
2287 let mut delim = "";
2288 for v in values {
2289 write!(f, "{delim}")?;
2290 delim = "\t";
2291 if let Some(v) = v {
2292 write!(f, "{v}")?;
2293 } else {
2294 write!(f, "\\N")?;
2295 }
2296 }
2297 write!(f, "\n\\.")?;
2298 }
2299 Ok(())
2300 }
2301 Statement::Update {
2302 table,
2303 assignments,
2304 from,
2305 selection,
2306 returning,
2307 } => {
2308 write!(f, "UPDATE {table}")?;
2309 if !assignments.is_empty() {
2310 write!(f, " SET {}", display_comma_separated(assignments))?;
2311 }
2312 if let Some(from) = from {
2313 write!(f, " FROM {from}")?;
2314 }
2315 if let Some(selection) = selection {
2316 write!(f, " WHERE {selection}")?;
2317 }
2318 if let Some(returning) = returning {
2319 write!(f, " RETURNING {}", display_comma_separated(returning))?;
2320 }
2321 Ok(())
2322 }
2323 Statement::Delete {
2324 tables,
2325 from,
2326 using,
2327 selection,
2328 returning,
2329 order_by,
2330 limit,
2331 } => {
2332 write!(f, "DELETE ")?;
2333 if !tables.is_empty() {
2334 write!(f, "{} ", display_comma_separated(tables))?;
2335 }
2336 write!(f, "FROM {}", display_comma_separated(from))?;
2337 if let Some(using) = using {
2338 write!(f, " USING {}", display_comma_separated(using))?;
2339 }
2340 if let Some(selection) = selection {
2341 write!(f, " WHERE {selection}")?;
2342 }
2343 if let Some(returning) = returning {
2344 write!(f, " RETURNING {}", display_comma_separated(returning))?;
2345 }
2346 if !order_by.is_empty() {
2347 write!(f, " ORDER BY {}", display_comma_separated(order_by))?;
2348 }
2349 if let Some(limit) = limit {
2350 write!(f, " LIMIT {limit}")?;
2351 }
2352 Ok(())
2353 }
2354 Statement::Close { cursor } => {
2355 write!(f, "CLOSE {cursor}")?;
2356
2357 Ok(())
2358 }
2359 Statement::CreateDatabase {
2360 db_name,
2361 if_not_exists,
2362 location,
2363 managed_location,
2364 } => {
2365 write!(f, "CREATE DATABASE")?;
2366 if *if_not_exists {
2367 write!(f, " IF NOT EXISTS")?;
2368 }
2369 write!(f, " {db_name}")?;
2370 if let Some(l) = location {
2371 write!(f, " LOCATION '{l}'")?;
2372 }
2373 if let Some(ml) = managed_location {
2374 write!(f, " MANAGEDLOCATION '{ml}'")?;
2375 }
2376 Ok(())
2377 }
2378 Statement::CreateFunction {
2379 or_replace,
2380 temporary,
2381 name,
2382 args,
2383 return_type,
2384 params,
2385 } => {
2386 write!(
2387 f,
2388 "CREATE {or_replace}{temp}FUNCTION {name}",
2389 temp = if *temporary { "TEMPORARY " } else { "" },
2390 or_replace = if *or_replace { "OR REPLACE " } else { "" },
2391 )?;
2392 if let Some(args) = args {
2393 write!(f, "({})", display_comma_separated(args))?;
2394 }
2395 if let Some(return_type) = return_type {
2396 write!(f, " RETURNS {return_type}")?;
2397 }
2398 write!(f, "{params}")?;
2399 Ok(())
2400 }
2401 Statement::CreateProcedure {
2402 name,
2403 or_alter,
2404 params,
2405 body,
2406 } => {
2407 write!(
2408 f,
2409 "CREATE {or_alter}PROCEDURE {name}",
2410 or_alter = if *or_alter { "OR ALTER " } else { "" },
2411 name = name
2412 )?;
2413
2414 if let Some(p) = params {
2415 if !p.is_empty() {
2416 write!(f, " ({})", display_comma_separated(p))?;
2417 }
2418 }
2419 write!(
2420 f,
2421 " AS BEGIN {body} END",
2422 body = display_separated(body, "; ")
2423 )
2424 }
2425 Statement::CreateMacro {
2426 or_replace,
2427 temporary,
2428 name,
2429 args,
2430 definition,
2431 } => {
2432 write!(
2433 f,
2434 "CREATE {or_replace}{temp}MACRO {name}",
2435 temp = if *temporary { "TEMPORARY " } else { "" },
2436 or_replace = if *or_replace { "OR REPLACE " } else { "" },
2437 )?;
2438 if let Some(args) = args {
2439 write!(f, "({})", display_comma_separated(args))?;
2440 }
2441 match definition {
2442 MacroDefinition::Expr(expr) => write!(f, " AS {expr}")?,
2443 MacroDefinition::Table(query) => write!(f, " AS TABLE {query}")?,
2444 }
2445 Ok(())
2446 }
2447 Statement::CreateView {
2448 name,
2449 or_replace,
2450 columns,
2451 query,
2452 materialized,
2453 with_options,
2454 cluster_by,
2455 with_no_schema_binding,
2456 if_not_exists,
2457 temporary,
2458 } => {
2459 write!(
2460 f,
2461 "CREATE {or_replace}{materialized}{temporary}VIEW {if_not_exists}{name}",
2462 or_replace = if *or_replace { "OR REPLACE " } else { "" },
2463 materialized = if *materialized { "MATERIALIZED " } else { "" },
2464 name = name,
2465 temporary = if *temporary { "TEMPORARY " } else { "" },
2466 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" }
2467 )?;
2468 if !with_options.is_empty() {
2469 write!(f, " WITH ({})", display_comma_separated(with_options))?;
2470 }
2471 if !columns.is_empty() {
2472 write!(f, " ({})", display_comma_separated(columns))?;
2473 }
2474 if !cluster_by.is_empty() {
2475 write!(f, " CLUSTER BY ({})", display_comma_separated(cluster_by))?;
2476 }
2477 write!(f, " AS {query}")?;
2478 if *with_no_schema_binding {
2479 write!(f, " WITH NO SCHEMA BINDING")?;
2480 }
2481 Ok(())
2482 }
2483 Statement::CreateTable {
2484 name,
2485 columns,
2486 constraints,
2487 table_properties,
2488 with_options,
2489 or_replace,
2490 if_not_exists,
2491 transient,
2492 hive_distribution,
2493 hive_formats,
2494 external,
2495 global,
2496 temporary,
2497 file_format,
2498 location,
2499 query,
2500 without_rowid,
2501 like,
2502 clone,
2503 default_charset,
2504 engine,
2505 comment,
2506 auto_increment_offset,
2507 collation,
2508 on_commit,
2509 on_cluster,
2510 order_by,
2511 strict,
2512 } => {
2513 write!(
2521 f,
2522 "CREATE {or_replace}{external}{global}{temporary}{transient}TABLE {if_not_exists}{name}",
2523 or_replace = if *or_replace { "OR REPLACE " } else { "" },
2524 external = if *external { "EXTERNAL " } else { "" },
2525 global = global
2526 .map(|global| {
2527 if global {
2528 "GLOBAL "
2529 } else {
2530 "LOCAL "
2531 }
2532 })
2533 .unwrap_or(""),
2534 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
2535 temporary = if *temporary { "TEMPORARY " } else { "" },
2536 transient = if *transient { "TRANSIENT " } else { "" },
2537 name = name,
2538 )?;
2539 if let Some(on_cluster) = on_cluster {
2540 write!(
2541 f,
2542 " ON CLUSTER {}",
2543 on_cluster.replace('{', "'{").replace('}', "}'")
2544 )?;
2545 }
2546 if !columns.is_empty() || !constraints.is_empty() {
2547 write!(f, " ({}", display_comma_separated(columns))?;
2548 if !columns.is_empty() && !constraints.is_empty() {
2549 write!(f, ", ")?;
2550 }
2551 write!(f, "{})", display_comma_separated(constraints))?;
2552 } else if query.is_none() && like.is_none() && clone.is_none() {
2553 write!(f, " ()")?;
2555 }
2556 if *without_rowid {
2558 write!(f, " WITHOUT ROWID")?;
2559 }
2560
2561 if let Some(l) = like {
2563 write!(f, " LIKE {l}")?;
2564 }
2565
2566 if let Some(c) = clone {
2567 write!(f, " CLONE {c}")?;
2568 }
2569
2570 match hive_distribution {
2571 HiveDistributionStyle::PARTITIONED { columns } => {
2572 write!(f, " PARTITIONED BY ({})", display_comma_separated(columns))?;
2573 }
2574 HiveDistributionStyle::CLUSTERED {
2575 columns,
2576 sorted_by,
2577 num_buckets,
2578 } => {
2579 write!(f, " CLUSTERED BY ({})", display_comma_separated(columns))?;
2580 if !sorted_by.is_empty() {
2581 write!(f, " SORTED BY ({})", display_comma_separated(sorted_by))?;
2582 }
2583 if *num_buckets > 0 {
2584 write!(f, " INTO {num_buckets} BUCKETS")?;
2585 }
2586 }
2587 HiveDistributionStyle::SKEWED {
2588 columns,
2589 on,
2590 stored_as_directories,
2591 } => {
2592 write!(
2593 f,
2594 " SKEWED BY ({})) ON ({})",
2595 display_comma_separated(columns),
2596 display_comma_separated(on)
2597 )?;
2598 if *stored_as_directories {
2599 write!(f, " STORED AS DIRECTORIES")?;
2600 }
2601 }
2602 _ => (),
2603 }
2604
2605 if let Some(HiveFormat {
2606 row_format,
2607 storage,
2608 location,
2609 }) = hive_formats
2610 {
2611 match row_format {
2612 Some(HiveRowFormat::SERDE { class }) => {
2613 write!(f, " ROW FORMAT SERDE '{class}'")?
2614 }
2615 Some(HiveRowFormat::DELIMITED) => write!(f, " ROW FORMAT DELIMITED")?,
2616 None => (),
2617 }
2618 match storage {
2619 Some(HiveIOFormat::IOF {
2620 input_format,
2621 output_format,
2622 }) => write!(
2623 f,
2624 " STORED AS INPUTFORMAT {input_format} OUTPUTFORMAT {output_format}"
2625 )?,
2626 Some(HiveIOFormat::FileFormat { format }) if !*external => {
2627 write!(f, " STORED AS {format}")?
2628 }
2629 _ => (),
2630 }
2631 if !*external {
2632 if let Some(loc) = location {
2633 write!(f, " LOCATION '{loc}'")?;
2634 }
2635 }
2636 }
2637 if *external {
2638 write!(
2639 f,
2640 " STORED AS {} LOCATION '{}'",
2641 file_format.as_ref().unwrap(),
2642 location.as_ref().unwrap()
2643 )?;
2644 }
2645 if !table_properties.is_empty() {
2646 write!(
2647 f,
2648 " TBLPROPERTIES ({})",
2649 display_comma_separated(table_properties)
2650 )?;
2651 }
2652 if !with_options.is_empty() {
2653 write!(f, " WITH ({})", display_comma_separated(with_options))?;
2654 }
2655 if let Some(engine) = engine {
2656 write!(f, " ENGINE={engine}")?;
2657 }
2658 if let Some(comment) = comment {
2659 write!(f, " COMMENT '{comment}'")?;
2660 }
2661 if let Some(auto_increment_offset) = auto_increment_offset {
2662 write!(f, " AUTO_INCREMENT {auto_increment_offset}")?;
2663 }
2664 if let Some(order_by) = order_by {
2665 write!(f, " ORDER BY ({})", display_comma_separated(order_by))?;
2666 }
2667 if let Some(query) = query {
2668 write!(f, " AS {query}")?;
2669 }
2670 if let Some(default_charset) = default_charset {
2671 write!(f, " DEFAULT CHARSET={default_charset}")?;
2672 }
2673 if let Some(collation) = collation {
2674 write!(f, " COLLATE={collation}")?;
2675 }
2676
2677 if on_commit.is_some() {
2678 let on_commit = match on_commit {
2679 Some(OnCommit::DeleteRows) => "ON COMMIT DELETE ROWS",
2680 Some(OnCommit::PreserveRows) => "ON COMMIT PRESERVE ROWS",
2681 Some(OnCommit::Drop) => "ON COMMIT DROP",
2682 None => "",
2683 };
2684 write!(f, " {on_commit}")?;
2685 }
2686 if *strict {
2687 write!(f, " STRICT")?;
2688 }
2689 Ok(())
2690 }
2691 Statement::CreateVirtualTable {
2692 name,
2693 if_not_exists,
2694 module_name,
2695 module_args,
2696 } => {
2697 write!(
2698 f,
2699 "CREATE VIRTUAL TABLE {if_not_exists}{name} USING {module_name}",
2700 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
2701 name = name,
2702 module_name = module_name
2703 )?;
2704 if !module_args.is_empty() {
2705 write!(f, " ({})", display_comma_separated(module_args))?;
2706 }
2707 Ok(())
2708 }
2709 Statement::CreateIndex {
2710 name,
2711 table_name,
2712 using,
2713 columns,
2714 unique,
2715 concurrently,
2716 if_not_exists,
2717 include,
2718 nulls_distinct,
2719 predicate,
2720 } => {
2721 write!(
2722 f,
2723 "CREATE {unique}INDEX {concurrently}{if_not_exists}",
2724 unique = if *unique { "UNIQUE " } else { "" },
2725 concurrently = if *concurrently { "CONCURRENTLY " } else { "" },
2726 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
2727 )?;
2728 if let Some(value) = name {
2729 write!(f, "{value} ")?;
2730 }
2731 write!(f, "ON {table_name}")?;
2732 if let Some(value) = using {
2733 write!(f, " USING {value} ")?;
2734 }
2735 write!(f, "({})", display_separated(columns, ","))?;
2736 if !include.is_empty() {
2737 write!(f, " INCLUDE ({})", display_separated(include, ","))?;
2738 }
2739 if let Some(value) = nulls_distinct {
2740 if *value {
2741 write!(f, " NULLS DISTINCT")?;
2742 } else {
2743 write!(f, " NULLS NOT DISTINCT")?;
2744 }
2745 }
2746 if let Some(predicate) = predicate {
2747 write!(f, " WHERE {predicate}")?;
2748 }
2749 Ok(())
2750 }
2751 Statement::CreateRole {
2752 names,
2753 if_not_exists,
2754 inherit,
2755 login,
2756 bypassrls,
2757 password,
2758 create_db,
2759 create_role,
2760 superuser,
2761 replication,
2762 connection_limit,
2763 valid_until,
2764 in_role,
2765 in_group,
2766 role,
2767 user,
2768 admin,
2769 authorization_owner,
2770 } => {
2771 write!(
2772 f,
2773 "CREATE ROLE {if_not_exists}{names}{superuser}{create_db}{create_role}{inherit}{login}{replication}{bypassrls}",
2774 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
2775 names = display_separated(names, ", "),
2776 superuser = match *superuser {
2777 Some(true) => " SUPERUSER",
2778 Some(false) => " NOSUPERUSER",
2779 None => ""
2780 },
2781 create_db = match *create_db {
2782 Some(true) => " CREATEDB",
2783 Some(false) => " NOCREATEDB",
2784 None => ""
2785 },
2786 create_role = match *create_role {
2787 Some(true) => " CREATEROLE",
2788 Some(false) => " NOCREATEROLE",
2789 None => ""
2790 },
2791 inherit = match *inherit {
2792 Some(true) => " INHERIT",
2793 Some(false) => " NOINHERIT",
2794 None => ""
2795 },
2796 login = match *login {
2797 Some(true) => " LOGIN",
2798 Some(false) => " NOLOGIN",
2799 None => ""
2800 },
2801 replication = match *replication {
2802 Some(true) => " REPLICATION",
2803 Some(false) => " NOREPLICATION",
2804 None => ""
2805 },
2806 bypassrls = match *bypassrls {
2807 Some(true) => " BYPASSRLS",
2808 Some(false) => " NOBYPASSRLS",
2809 None => ""
2810 }
2811 )?;
2812 if let Some(limit) = connection_limit {
2813 write!(f, " CONNECTION LIMIT {limit}")?;
2814 }
2815 match password {
2816 Some(Password::Password(pass)) => write!(f, " PASSWORD {pass}"),
2817 Some(Password::NullPassword) => write!(f, " PASSWORD NULL"),
2818 None => Ok(()),
2819 }?;
2820 if let Some(until) = valid_until {
2821 write!(f, " VALID UNTIL {until}")?;
2822 }
2823 if !in_role.is_empty() {
2824 write!(f, " IN ROLE {}", display_comma_separated(in_role))?;
2825 }
2826 if !in_group.is_empty() {
2827 write!(f, " IN GROUP {}", display_comma_separated(in_group))?;
2828 }
2829 if !role.is_empty() {
2830 write!(f, " ROLE {}", display_comma_separated(role))?;
2831 }
2832 if !user.is_empty() {
2833 write!(f, " USER {}", display_comma_separated(user))?;
2834 }
2835 if !admin.is_empty() {
2836 write!(f, " ADMIN {}", display_comma_separated(admin))?;
2837 }
2838 if let Some(owner) = authorization_owner {
2839 write!(f, " AUTHORIZATION {owner}")?;
2840 }
2841 Ok(())
2842 }
2843 Statement::AlterTable {
2844 name,
2845 if_exists,
2846 only,
2847 operations,
2848 } => {
2849 write!(f, "ALTER TABLE ")?;
2850 if *if_exists {
2851 write!(f, "IF EXISTS ")?;
2852 }
2853 if *only {
2854 write!(f, "ONLY ")?;
2855 }
2856 write!(
2857 f,
2858 "{name} {operations}",
2859 operations = display_comma_separated(operations)
2860 )
2861 }
2862 Statement::AlterIndex { name, operation } => {
2863 write!(f, "ALTER INDEX {name} {operation}")
2864 }
2865 Statement::AlterView {
2866 name,
2867 columns,
2868 query,
2869 with_options,
2870 } => {
2871 write!(f, "ALTER VIEW {name}")?;
2872 if !with_options.is_empty() {
2873 write!(f, " WITH ({})", display_comma_separated(with_options))?;
2874 }
2875 if !columns.is_empty() {
2876 write!(f, " ({})", display_comma_separated(columns))?;
2877 }
2878 write!(f, " AS {query}")
2879 }
2880 Statement::AlterRole { name, operation } => {
2881 write!(f, "ALTER ROLE {name} {operation}")
2882 }
2883 Statement::Drop {
2884 object_type,
2885 if_exists,
2886 names,
2887 cascade,
2888 restrict,
2889 purge,
2890 temporary,
2891 } => write!(
2892 f,
2893 "DROP {}{}{} {}{}{}{}",
2894 if *temporary { "TEMPORARY " } else { "" },
2895 object_type,
2896 if *if_exists { " IF EXISTS" } else { "" },
2897 display_comma_separated(names),
2898 if *cascade { " CASCADE" } else { "" },
2899 if *restrict { " RESTRICT" } else { "" },
2900 if *purge { " PURGE" } else { "" }
2901 ),
2902 Statement::DropFunction {
2903 if_exists,
2904 func_desc,
2905 option,
2906 } => {
2907 write!(
2908 f,
2909 "DROP FUNCTION{} {}",
2910 if *if_exists { " IF EXISTS" } else { "" },
2911 display_comma_separated(func_desc),
2912 )?;
2913 if let Some(op) = option {
2914 write!(f, " {op}")?;
2915 }
2916 Ok(())
2917 }
2918 Statement::Discard { object_type } => {
2919 write!(f, "DISCARD {object_type}")?;
2920 Ok(())
2921 }
2922 Self::SetRole {
2923 context_modifier,
2924 role_name,
2925 } => {
2926 let role_name = role_name.clone().unwrap_or_else(|| Ident::new("NONE"));
2927 write!(f, "SET{context_modifier} ROLE {role_name}")
2928 }
2929 Statement::SetVariable {
2930 local,
2931 variable,
2932 hivevar,
2933 value,
2934 } => {
2935 f.write_str("SET ")?;
2936 if *local {
2937 f.write_str("LOCAL ")?;
2938 }
2939 write!(
2940 f,
2941 "{hivevar}{name} = {value}",
2942 hivevar = if *hivevar { "HIVEVAR:" } else { "" },
2943 name = variable,
2944 value = display_comma_separated(value)
2945 )
2946 }
2947 Statement::SetTimeZone { local, value } => {
2948 f.write_str("SET ")?;
2949 if *local {
2950 f.write_str("LOCAL ")?;
2951 }
2952 write!(f, "TIME ZONE {value}")
2953 }
2954 Statement::SetNames {
2955 charset_name,
2956 collation_name,
2957 } => {
2958 f.write_str("SET NAMES ")?;
2959 f.write_str(charset_name)?;
2960
2961 if let Some(collation) = collation_name {
2962 f.write_str(" COLLATE ")?;
2963 f.write_str(collation)?;
2964 };
2965
2966 Ok(())
2967 }
2968 Statement::SetNamesDefault {} => {
2969 f.write_str("SET NAMES DEFAULT")?;
2970
2971 Ok(())
2972 }
2973 Statement::ShowVariable { variable } => {
2974 write!(f, "SHOW")?;
2975 if !variable.is_empty() {
2976 write!(f, " {}", display_separated(variable, " "))?;
2977 }
2978 Ok(())
2979 }
2980 Statement::ShowVariables { filter } => {
2981 write!(f, "SHOW VARIABLES")?;
2982 if filter.is_some() {
2983 write!(f, " {}", filter.as_ref().unwrap())?;
2984 }
2985 Ok(())
2986 }
2987 Statement::ShowCreate { obj_type, obj_name } => {
2988 write!(f, "SHOW CREATE {obj_type} {obj_name}",)?;
2989 Ok(())
2990 }
2991 Statement::ShowColumns {
2992 extended,
2993 full,
2994 table_name,
2995 filter,
2996 } => {
2997 write!(
2998 f,
2999 "SHOW {extended}{full}COLUMNS FROM {table_name}",
3000 extended = if *extended { "EXTENDED " } else { "" },
3001 full = if *full { "FULL " } else { "" },
3002 table_name = table_name,
3003 )?;
3004 if let Some(filter) = filter {
3005 write!(f, " {filter}")?;
3006 }
3007 Ok(())
3008 }
3009 Statement::ShowTables {
3010 extended,
3011 full,
3012 db_name,
3013 filter,
3014 } => {
3015 write!(
3016 f,
3017 "SHOW {extended}{full}TABLES",
3018 extended = if *extended { "EXTENDED " } else { "" },
3019 full = if *full { "FULL " } else { "" },
3020 )?;
3021 if let Some(db_name) = db_name {
3022 write!(f, " FROM {db_name}")?;
3023 }
3024 if let Some(filter) = filter {
3025 write!(f, " {filter}")?;
3026 }
3027 Ok(())
3028 }
3029 Statement::ShowFunctions { filter } => {
3030 write!(f, "SHOW FUNCTIONS")?;
3031 if let Some(filter) = filter {
3032 write!(f, " {filter}")?;
3033 }
3034 Ok(())
3035 }
3036 Statement::Use { db_name } => {
3037 write!(f, "USE {db_name}")?;
3038 Ok(())
3039 }
3040 Statement::ShowCollation { filter } => {
3041 write!(f, "SHOW COLLATION")?;
3042 if let Some(filter) = filter {
3043 write!(f, " {filter}")?;
3044 }
3045 Ok(())
3046 }
3047 Statement::StartTransaction {
3048 modes,
3049 begin: syntax_begin,
3050 } => {
3051 if *syntax_begin {
3052 write!(f, "BEGIN TRANSACTION")?;
3053 } else {
3054 write!(f, "START TRANSACTION")?;
3055 }
3056 if !modes.is_empty() {
3057 write!(f, " {}", display_comma_separated(modes))?;
3058 }
3059 Ok(())
3060 }
3061 Statement::SetTransaction {
3062 modes,
3063 snapshot,
3064 session,
3065 } => {
3066 if *session {
3067 write!(f, "SET SESSION CHARACTERISTICS AS TRANSACTION")?;
3068 } else {
3069 write!(f, "SET TRANSACTION")?;
3070 }
3071 if !modes.is_empty() {
3072 write!(f, " {}", display_comma_separated(modes))?;
3073 }
3074 if let Some(snapshot_id) = snapshot {
3075 write!(f, " SNAPSHOT {snapshot_id}")?;
3076 }
3077 Ok(())
3078 }
3079 Statement::Commit { chain } => {
3080 write!(f, "COMMIT{}", if *chain { " AND CHAIN" } else { "" },)
3081 }
3082 Statement::Rollback { chain } => {
3083 write!(f, "ROLLBACK{}", if *chain { " AND CHAIN" } else { "" },)
3084 }
3085 Statement::CreateSchema {
3086 schema_name,
3087 if_not_exists,
3088 } => write!(
3089 f,
3090 "CREATE SCHEMA {if_not_exists}{name}",
3091 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
3092 name = schema_name
3093 ),
3094 Statement::Assert { condition, message } => {
3095 write!(f, "ASSERT {condition}")?;
3096 if let Some(m) = message {
3097 write!(f, " AS {m}")?;
3098 }
3099 Ok(())
3100 }
3101 Statement::Grant {
3102 privileges,
3103 objects,
3104 grantees,
3105 with_grant_option,
3106 granted_by,
3107 } => {
3108 write!(f, "GRANT {privileges} ")?;
3109 write!(f, "ON {objects} ")?;
3110 write!(f, "TO {}", display_comma_separated(grantees))?;
3111 if *with_grant_option {
3112 write!(f, " WITH GRANT OPTION")?;
3113 }
3114 if let Some(grantor) = granted_by {
3115 write!(f, " GRANTED BY {grantor}")?;
3116 }
3117 Ok(())
3118 }
3119 Statement::Revoke {
3120 privileges,
3121 objects,
3122 grantees,
3123 granted_by,
3124 cascade,
3125 } => {
3126 write!(f, "REVOKE {privileges} ")?;
3127 write!(f, "ON {objects} ")?;
3128 write!(f, "FROM {}", display_comma_separated(grantees))?;
3129 if let Some(grantor) = granted_by {
3130 write!(f, " GRANTED BY {grantor}")?;
3131 }
3132 write!(f, " {}", if *cascade { "CASCADE" } else { "RESTRICT" })?;
3133 Ok(())
3134 }
3135 Statement::Deallocate { name, prepare } => write!(
3136 f,
3137 "DEALLOCATE {prepare}{name}",
3138 prepare = if *prepare { "PREPARE " } else { "" },
3139 name = name,
3140 ),
3141 Statement::Execute { name, parameters } => {
3142 write!(f, "EXECUTE {name}")?;
3143 if !parameters.is_empty() {
3144 write!(f, "({})", display_comma_separated(parameters))?;
3145 }
3146 Ok(())
3147 }
3148 Statement::Prepare {
3149 name,
3150 data_types,
3151 statement,
3152 } => {
3153 write!(f, "PREPARE {name} ")?;
3154 if !data_types.is_empty() {
3155 write!(f, "({}) ", display_comma_separated(data_types))?;
3156 }
3157 write!(f, "AS {statement}")
3158 }
3159 Statement::Comment {
3160 object_type,
3161 object_name,
3162 comment,
3163 if_exists,
3164 } => {
3165 write!(f, "COMMENT ")?;
3166 if *if_exists {
3167 write!(f, "IF EXISTS ")?
3168 };
3169 write!(f, "ON {object_type} {object_name} IS ")?;
3170 if let Some(c) = comment {
3171 write!(f, "'{c}'")
3172 } else {
3173 write!(f, "NULL")
3174 }
3175 }
3176 Statement::Savepoint { name } => {
3177 write!(f, "SAVEPOINT ")?;
3178 write!(f, "{name}")
3179 }
3180 Statement::Merge {
3181 into,
3182 table,
3183 source,
3184 on,
3185 clauses,
3186 } => {
3187 write!(
3188 f,
3189 "MERGE{int} {table} USING {source} ",
3190 int = if *into { " INTO" } else { "" }
3191 )?;
3192 write!(f, "ON {on} ")?;
3193 write!(f, "{}", display_separated(clauses, " "))
3194 }
3195 Statement::Cache {
3196 table_name,
3197 table_flag,
3198 has_as,
3199 options,
3200 query,
3201 } => {
3202 if table_flag.is_some() {
3203 write!(
3204 f,
3205 "CACHE {table_flag} TABLE {table_name}",
3206 table_flag = table_flag.clone().unwrap(),
3207 table_name = table_name,
3208 )?;
3209 } else {
3210 write!(f, "CACHE TABLE {table_name}",)?;
3211 }
3212
3213 if !options.is_empty() {
3214 write!(f, " OPTIONS({})", display_comma_separated(options))?;
3215 }
3216
3217 let has_query = query.is_some();
3218 if *has_as && has_query {
3219 write!(f, " AS {query}", query = query.clone().unwrap())
3220 } else if !has_as && has_query {
3221 write!(f, " {query}", query = query.clone().unwrap())
3222 } else if *has_as && !has_query {
3223 write!(f, " AS")
3224 } else {
3225 Ok(())
3226 }
3227 }
3228 Statement::UNCache {
3229 table_name,
3230 if_exists,
3231 } => {
3232 if *if_exists {
3233 write!(f, "UNCACHE TABLE IF EXISTS {table_name}")
3234 } else {
3235 write!(f, "UNCACHE TABLE {table_name}")
3236 }
3237 }
3238 Statement::CreateSequence {
3239 temporary,
3240 if_not_exists,
3241 name,
3242 data_type,
3243 sequence_options,
3244 owned_by,
3245 } => {
3246 let as_type: String = if let Some(dt) = data_type.as_ref() {
3247 [" AS ", &dt.to_string()].concat()
3250 } else {
3251 "".to_string()
3252 };
3253 write!(
3254 f,
3255 "CREATE {temporary}SEQUENCE {if_not_exists}{name}{as_type}",
3256 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
3257 temporary = if *temporary { "TEMPORARY " } else { "" },
3258 name = name,
3259 as_type = as_type
3260 )?;
3261 for sequence_option in sequence_options {
3262 write!(f, "{sequence_option}")?;
3263 }
3264 if let Some(ob) = owned_by.as_ref() {
3265 write!(f, " OWNED BY {ob}")?;
3266 }
3267 write!(f, "")
3268 }
3269 Statement::CreateStage {
3270 or_replace,
3271 temporary,
3272 if_not_exists,
3273 name,
3274 stage_params,
3275 directory_table_params,
3276 file_format,
3277 copy_options,
3278 comment,
3279 ..
3280 } => {
3281 write!(
3282 f,
3283 "CREATE {or_replace}{temp}STAGE {if_not_exists}{name}{stage_params}",
3284 temp = if *temporary { "TEMPORARY " } else { "" },
3285 or_replace = if *or_replace { "OR REPLACE " } else { "" },
3286 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
3287 )?;
3288 if !directory_table_params.options.is_empty() {
3289 write!(f, " DIRECTORY=({})", directory_table_params)?;
3290 }
3291 if !file_format.options.is_empty() {
3292 write!(f, " FILE_FORMAT=({})", file_format)?;
3293 }
3294 if !copy_options.options.is_empty() {
3295 write!(f, " COPY_OPTIONS=({})", copy_options)?;
3296 }
3297 if comment.is_some() {
3298 write!(f, " COMMENT='{}'", comment.as_ref().unwrap())?;
3299 }
3300 Ok(())
3301 }
3302 Statement::CopyIntoSnowflake {
3303 into,
3304 from_stage,
3305 from_stage_alias,
3306 stage_params,
3307 from_transformations,
3308 files,
3309 pattern,
3310 file_format,
3311 copy_options,
3312 validation_mode,
3313 } => {
3314 write!(f, "COPY INTO {}", into)?;
3315 if from_transformations.is_none() {
3316 write!(f, " FROM {}{}", from_stage, stage_params)?;
3318 if from_stage_alias.as_ref().is_some() {
3319 write!(f, " AS {}", from_stage_alias.as_ref().unwrap())?;
3320 }
3321 } else {
3322 write!(
3324 f,
3325 " FROM (SELECT {} FROM {}{}",
3326 display_separated(from_transformations.as_ref().unwrap(), ", "),
3327 from_stage,
3328 stage_params,
3329 )?;
3330 if from_stage_alias.as_ref().is_some() {
3331 write!(f, " AS {}", from_stage_alias.as_ref().unwrap())?;
3332 }
3333 write!(f, ")")?;
3334 }
3335 if files.is_some() {
3336 write!(
3337 f,
3338 " FILES = ('{}')",
3339 display_separated(files.as_ref().unwrap(), "', '")
3340 )?;
3341 }
3342 if pattern.is_some() {
3343 write!(f, " PATTERN = '{}'", pattern.as_ref().unwrap())?;
3344 }
3345 if !file_format.options.is_empty() {
3346 write!(f, " FILE_FORMAT=({})", file_format)?;
3347 }
3348 if !copy_options.options.is_empty() {
3349 write!(f, " COPY_OPTIONS=({})", copy_options)?;
3350 }
3351 if validation_mode.is_some() {
3352 write!(
3353 f,
3354 " VALIDATION_MODE = {}",
3355 validation_mode.as_ref().unwrap()
3356 )?;
3357 }
3358 Ok(())
3359 }
3360 Statement::CreateType {
3361 name,
3362 representation,
3363 } => {
3364 write!(f, "CREATE TYPE {name} AS {representation}")
3365 }
3366 Statement::Pragma { name, value, is_eq } => {
3367 write!(f, "PRAGMA {name}")?;
3368 if value.is_some() {
3369 let val = value.as_ref().unwrap();
3370 if *is_eq {
3371 write!(f, " = {val}")?;
3372 } else {
3373 write!(f, "({val})")?;
3374 }
3375 }
3376 Ok(())
3377 }
3378 }
3379 }
3380}
3381
3382#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3389#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3390#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3391pub enum SequenceOptions {
3392 IncrementBy(Expr, bool),
3393 MinValue(MinMaxValue),
3394 MaxValue(MinMaxValue),
3395 StartWith(Expr, bool),
3396 Cache(Expr),
3397 Cycle(bool),
3398}
3399
3400impl fmt::Display for SequenceOptions {
3401 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3402 match self {
3403 SequenceOptions::IncrementBy(increment, by) => {
3404 write!(
3405 f,
3406 " INCREMENT{by} {increment}",
3407 by = if *by { " BY" } else { "" },
3408 increment = increment
3409 )
3410 }
3411 SequenceOptions::MinValue(value) => match value {
3412 MinMaxValue::Empty => {
3413 write!(f, "")
3414 }
3415 MinMaxValue::None => {
3416 write!(f, " NO MINVALUE")
3417 }
3418 MinMaxValue::Some(minvalue) => {
3419 write!(f, " MINVALUE {minvalue}")
3420 }
3421 },
3422 SequenceOptions::MaxValue(value) => match value {
3423 MinMaxValue::Empty => {
3424 write!(f, "")
3425 }
3426 MinMaxValue::None => {
3427 write!(f, " NO MAXVALUE")
3428 }
3429 MinMaxValue::Some(maxvalue) => {
3430 write!(f, " MAXVALUE {maxvalue}")
3431 }
3432 },
3433 SequenceOptions::StartWith(start, with) => {
3434 write!(
3435 f,
3436 " START{with} {start}",
3437 with = if *with { " WITH" } else { "" },
3438 start = start
3439 )
3440 }
3441 SequenceOptions::Cache(cache) => {
3442 write!(f, " CACHE {}", *cache)
3443 }
3444 SequenceOptions::Cycle(no) => {
3445 write!(f, " {}CYCLE", if *no { "NO " } else { "" })
3446 }
3447 }
3448 }
3449}
3450
3451#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3454#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3455#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3456pub enum MinMaxValue {
3457 Empty,
3459 None,
3461 Some(Expr),
3463}
3464
3465#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3466#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3467#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3468#[non_exhaustive]
3469pub enum OnInsert {
3470 DuplicateKeyUpdate(Vec<Assignment>),
3472 OnConflict(OnConflict),
3474}
3475
3476#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3477#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3478#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3479pub struct OnConflict {
3480 pub conflict_target: Option<ConflictTarget>,
3481 pub action: OnConflictAction,
3482}
3483#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3484#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3485#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3486pub enum ConflictTarget {
3487 Columns(Vec<Ident>),
3488 OnConstraint(ObjectName),
3489}
3490#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3491#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3492#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3493pub enum OnConflictAction {
3494 DoNothing,
3495 DoUpdate(DoUpdate),
3496}
3497
3498#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3499#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3500#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3501pub struct DoUpdate {
3502 pub assignments: Vec<Assignment>,
3504 pub selection: Option<Expr>,
3506}
3507
3508impl fmt::Display for OnInsert {
3509 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3510 match self {
3511 Self::DuplicateKeyUpdate(expr) => write!(
3512 f,
3513 " ON DUPLICATE KEY UPDATE {}",
3514 display_comma_separated(expr)
3515 ),
3516 Self::OnConflict(o) => write!(f, " {o}"),
3517 }
3518 }
3519}
3520impl fmt::Display for OnConflict {
3521 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3522 write!(f, " ON CONFLICT")?;
3523 if let Some(target) = &self.conflict_target {
3524 write!(f, "{target}")?;
3525 }
3526 write!(f, " {}", self.action)
3527 }
3528}
3529impl fmt::Display for ConflictTarget {
3530 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3531 match self {
3532 ConflictTarget::Columns(cols) => write!(f, "({})", display_comma_separated(cols)),
3533 ConflictTarget::OnConstraint(name) => write!(f, " ON CONSTRAINT {name}"),
3534 }
3535 }
3536}
3537impl fmt::Display for OnConflictAction {
3538 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3539 match self {
3540 Self::DoNothing => write!(f, "DO NOTHING"),
3541 Self::DoUpdate(do_update) => {
3542 write!(f, "DO UPDATE")?;
3543 if !do_update.assignments.is_empty() {
3544 write!(
3545 f,
3546 " SET {}",
3547 display_comma_separated(&do_update.assignments)
3548 )?;
3549 }
3550 if let Some(selection) = &do_update.selection {
3551 write!(f, " WHERE {selection}")?;
3552 }
3553 Ok(())
3554 }
3555 }
3556 }
3557}
3558
3559#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3561#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3562#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3563pub enum Privileges {
3564 All {
3566 with_privileges_keyword: bool,
3568 },
3569 Actions(Vec<Action>),
3571}
3572
3573impl fmt::Display for Privileges {
3574 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3575 match self {
3576 Privileges::All {
3577 with_privileges_keyword,
3578 } => {
3579 write!(
3580 f,
3581 "ALL{}",
3582 if *with_privileges_keyword {
3583 " PRIVILEGES"
3584 } else {
3585 ""
3586 }
3587 )
3588 }
3589 Privileges::Actions(actions) => {
3590 write!(f, "{}", display_comma_separated(actions))
3591 }
3592 }
3593 }
3594}
3595
3596#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3598#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3599#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3600pub enum FetchDirection {
3601 Count { limit: Value },
3602 Next,
3603 Prior,
3604 First,
3605 Last,
3606 Absolute { limit: Value },
3607 Relative { limit: Value },
3608 All,
3609 Forward { limit: Option<Value> },
3612 ForwardAll,
3613 Backward { limit: Option<Value> },
3616 BackwardAll,
3617}
3618
3619impl fmt::Display for FetchDirection {
3620 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3621 match self {
3622 FetchDirection::Count { limit } => f.write_str(&limit.to_string())?,
3623 FetchDirection::Next => f.write_str("NEXT")?,
3624 FetchDirection::Prior => f.write_str("PRIOR")?,
3625 FetchDirection::First => f.write_str("FIRST")?,
3626 FetchDirection::Last => f.write_str("LAST")?,
3627 FetchDirection::Absolute { limit } => {
3628 f.write_str("ABSOLUTE ")?;
3629 f.write_str(&limit.to_string())?;
3630 }
3631 FetchDirection::Relative { limit } => {
3632 f.write_str("RELATIVE ")?;
3633 f.write_str(&limit.to_string())?;
3634 }
3635 FetchDirection::All => f.write_str("ALL")?,
3636 FetchDirection::Forward { limit } => {
3637 f.write_str("FORWARD")?;
3638
3639 if let Some(l) = limit {
3640 f.write_str(" ")?;
3641 f.write_str(&l.to_string())?;
3642 }
3643 }
3644 FetchDirection::ForwardAll => f.write_str("FORWARD ALL")?,
3645 FetchDirection::Backward { limit } => {
3646 f.write_str("BACKWARD")?;
3647
3648 if let Some(l) = limit {
3649 f.write_str(" ")?;
3650 f.write_str(&l.to_string())?;
3651 }
3652 }
3653 FetchDirection::BackwardAll => f.write_str("BACKWARD ALL")?,
3654 };
3655
3656 Ok(())
3657 }
3658}
3659
3660#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3662#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3663#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3664pub enum Action {
3665 Connect,
3666 Create,
3667 Delete,
3668 Execute,
3669 Insert { columns: Option<Vec<Ident>> },
3670 References { columns: Option<Vec<Ident>> },
3671 Select { columns: Option<Vec<Ident>> },
3672 Temporary,
3673 Trigger,
3674 Truncate,
3675 Update { columns: Option<Vec<Ident>> },
3676 Usage,
3677}
3678
3679impl fmt::Display for Action {
3680 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3681 match self {
3682 Action::Connect => f.write_str("CONNECT")?,
3683 Action::Create => f.write_str("CREATE")?,
3684 Action::Delete => f.write_str("DELETE")?,
3685 Action::Execute => f.write_str("EXECUTE")?,
3686 Action::Insert { .. } => f.write_str("INSERT")?,
3687 Action::References { .. } => f.write_str("REFERENCES")?,
3688 Action::Select { .. } => f.write_str("SELECT")?,
3689 Action::Temporary => f.write_str("TEMPORARY")?,
3690 Action::Trigger => f.write_str("TRIGGER")?,
3691 Action::Truncate => f.write_str("TRUNCATE")?,
3692 Action::Update { .. } => f.write_str("UPDATE")?,
3693 Action::Usage => f.write_str("USAGE")?,
3694 };
3695 match self {
3696 Action::Insert { columns }
3697 | Action::References { columns }
3698 | Action::Select { columns }
3699 | Action::Update { columns } => {
3700 if let Some(columns) = columns {
3701 write!(f, " ({})", display_comma_separated(columns))?;
3702 }
3703 }
3704 _ => (),
3705 };
3706 Ok(())
3707 }
3708}
3709
3710#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3712#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3713#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3714pub enum GrantObjects {
3715 AllSequencesInSchema { schemas: Vec<ObjectName> },
3717 AllTablesInSchema { schemas: Vec<ObjectName> },
3719 Schemas(Vec<ObjectName>),
3721 Sequences(Vec<ObjectName>),
3723 Tables(Vec<ObjectName>),
3725}
3726
3727impl fmt::Display for GrantObjects {
3728 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3729 match self {
3730 GrantObjects::Sequences(sequences) => {
3731 write!(f, "SEQUENCE {}", display_comma_separated(sequences))
3732 }
3733 GrantObjects::Schemas(schemas) => {
3734 write!(f, "SCHEMA {}", display_comma_separated(schemas))
3735 }
3736 GrantObjects::Tables(tables) => {
3737 write!(f, "{}", display_comma_separated(tables))
3738 }
3739 GrantObjects::AllSequencesInSchema { schemas } => {
3740 write!(
3741 f,
3742 "ALL SEQUENCES IN SCHEMA {}",
3743 display_comma_separated(schemas)
3744 )
3745 }
3746 GrantObjects::AllTablesInSchema { schemas } => {
3747 write!(
3748 f,
3749 "ALL TABLES IN SCHEMA {}",
3750 display_comma_separated(schemas)
3751 )
3752 }
3753 }
3754 }
3755}
3756
3757#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3759#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3760#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3761pub struct Assignment {
3762 pub id: Vec<Ident>,
3763 pub value: Expr,
3764}
3765
3766impl fmt::Display for Assignment {
3767 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3768 write!(f, "{} = {}", display_separated(&self.id, "."), self.value)
3769 }
3770}
3771
3772#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3773#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3774#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3775pub enum FunctionArgExpr {
3776 Expr(Expr),
3777 QualifiedWildcard(ObjectName),
3779 Wildcard,
3781}
3782
3783impl fmt::Display for FunctionArgExpr {
3784 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3785 match self {
3786 FunctionArgExpr::Expr(expr) => write!(f, "{expr}"),
3787 FunctionArgExpr::QualifiedWildcard(prefix) => write!(f, "{prefix}.*"),
3788 FunctionArgExpr::Wildcard => f.write_str("*"),
3789 }
3790 }
3791}
3792
3793#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3794#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3795#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3796pub enum FunctionArg {
3797 Named { name: Ident, arg: FunctionArgExpr },
3798 Unnamed(FunctionArgExpr),
3799}
3800
3801impl fmt::Display for FunctionArg {
3802 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3803 match self {
3804 FunctionArg::Named { name, arg } => write!(f, "{name} => {arg}"),
3805 FunctionArg::Unnamed(unnamed_arg) => write!(f, "{unnamed_arg}"),
3806 }
3807 }
3808}
3809
3810#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3811#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3812#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3813pub enum CloseCursor {
3814 All,
3815 Specific { name: Ident },
3816}
3817
3818impl fmt::Display for CloseCursor {
3819 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3820 match self {
3821 CloseCursor::All => write!(f, "ALL"),
3822 CloseCursor::Specific { name } => write!(f, "{name}"),
3823 }
3824 }
3825}
3826
3827#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3829#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3830#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3831pub struct Function {
3832 pub name: ObjectName,
3833 pub args: Vec<FunctionArg>,
3834 pub filter: Option<Box<Expr>>,
3836 pub null_treatment: Option<NullTreatment>,
3838 pub over: Option<WindowType>,
3839 pub distinct: bool,
3841 pub special: bool,
3844 pub order_by: Vec<OrderByExpr>,
3846}
3847
3848#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3849#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3850#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3851pub enum AnalyzeFormat {
3852 TEXT,
3853 GRAPHVIZ,
3854 JSON,
3855}
3856
3857impl fmt::Display for AnalyzeFormat {
3858 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3859 f.write_str(match self {
3860 AnalyzeFormat::TEXT => "TEXT",
3861 AnalyzeFormat::GRAPHVIZ => "GRAPHVIZ",
3862 AnalyzeFormat::JSON => "JSON",
3863 })
3864 }
3865}
3866
3867impl fmt::Display for Function {
3868 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3869 if self.special {
3870 write!(f, "{}", self.name)?;
3871 } else {
3872 let order_by = if !self.order_by.is_empty() {
3873 " ORDER BY "
3874 } else {
3875 ""
3876 };
3877 write!(
3878 f,
3879 "{}({}{}{order_by}{})",
3880 self.name,
3881 if self.distinct { "DISTINCT " } else { "" },
3882 display_comma_separated(&self.args),
3883 display_comma_separated(&self.order_by),
3884 )?;
3885
3886 if let Some(filter_cond) = &self.filter {
3887 write!(f, " FILTER (WHERE {filter_cond})")?;
3888 }
3889
3890 if let Some(o) = &self.null_treatment {
3891 write!(f, " {o}")?;
3892 }
3893
3894 if let Some(o) = &self.over {
3895 write!(f, " OVER {o}")?;
3896 }
3897 }
3898
3899 Ok(())
3900 }
3901}
3902
3903#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3905#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3906#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3907pub enum FileFormat {
3908 TEXTFILE,
3909 SEQUENCEFILE,
3910 ORC,
3911 PARQUET,
3912 AVRO,
3913 RCFILE,
3914 JSONFILE,
3915}
3916
3917impl fmt::Display for FileFormat {
3918 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3919 use self::FileFormat::*;
3920 f.write_str(match self {
3921 TEXTFILE => "TEXTFILE",
3922 SEQUENCEFILE => "SEQUENCEFILE",
3923 ORC => "ORC",
3924 PARQUET => "PARQUET",
3925 AVRO => "AVRO",
3926 RCFILE => "RCFILE",
3927 JSONFILE => "JSONFILE",
3928 })
3929 }
3930}
3931
3932#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3935#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3936#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3937pub struct ListAgg {
3938 pub distinct: bool,
3939 pub expr: Box<Expr>,
3940 pub separator: Option<Box<Expr>>,
3941 pub on_overflow: Option<ListAggOnOverflow>,
3942 pub within_group: Vec<OrderByExpr>,
3943}
3944
3945impl fmt::Display for ListAgg {
3946 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3947 write!(
3948 f,
3949 "LISTAGG({}{}",
3950 if self.distinct { "DISTINCT " } else { "" },
3951 self.expr
3952 )?;
3953 if let Some(separator) = &self.separator {
3954 write!(f, ", {separator}")?;
3955 }
3956 if let Some(on_overflow) = &self.on_overflow {
3957 write!(f, "{on_overflow}")?;
3958 }
3959 write!(f, ")")?;
3960 if !self.within_group.is_empty() {
3961 write!(
3962 f,
3963 " WITHIN GROUP (ORDER BY {})",
3964 display_comma_separated(&self.within_group)
3965 )?;
3966 }
3967 Ok(())
3968 }
3969}
3970
3971#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3973#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3974#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3975pub enum ListAggOnOverflow {
3976 Error,
3978
3979 Truncate {
3981 filler: Option<Box<Expr>>,
3982 with_count: bool,
3983 },
3984}
3985
3986impl fmt::Display for ListAggOnOverflow {
3987 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3988 write!(f, " ON OVERFLOW")?;
3989 match self {
3990 ListAggOnOverflow::Error => write!(f, " ERROR"),
3991 ListAggOnOverflow::Truncate { filler, with_count } => {
3992 write!(f, " TRUNCATE")?;
3993 if let Some(filler) = filler {
3994 write!(f, " {filler}")?;
3995 }
3996 if *with_count {
3997 write!(f, " WITH")?;
3998 } else {
3999 write!(f, " WITHOUT")?;
4000 }
4001 write!(f, " COUNT")
4002 }
4003 }
4004 }
4005}
4006
4007#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4011#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4012#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4013pub struct ArrayAgg {
4014 pub distinct: bool,
4015 pub expr: Box<Expr>,
4016 pub order_by: Option<Vec<OrderByExpr>>,
4017 pub limit: Option<Box<Expr>>,
4018 pub within_group: bool, }
4020
4021impl fmt::Display for ArrayAgg {
4022 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4023 write!(
4024 f,
4025 "ARRAY_AGG({}{}",
4026 if self.distinct { "DISTINCT " } else { "" },
4027 self.expr
4028 )?;
4029 if !self.within_group {
4030 if let Some(order_by) = &self.order_by {
4031 write!(f, " ORDER BY {}", display_comma_separated(order_by))?;
4032 }
4033 if let Some(limit) = &self.limit {
4034 write!(f, " LIMIT {limit}")?;
4035 }
4036 }
4037 write!(f, ")")?;
4038 if self.within_group {
4039 if let Some(order_by) = &self.order_by {
4040 write!(
4041 f,
4042 " WITHIN GROUP (ORDER BY {})",
4043 display_comma_separated(order_by)
4044 )?;
4045 }
4046 }
4047 Ok(())
4048 }
4049}
4050
4051#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4052#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4053#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4054pub enum ObjectType {
4055 Table,
4056 View,
4057 Index,
4058 Schema,
4059 Role,
4060 Sequence,
4061 Stage,
4062}
4063
4064impl fmt::Display for ObjectType {
4065 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4066 f.write_str(match self {
4067 ObjectType::Table => "TABLE",
4068 ObjectType::View => "VIEW",
4069 ObjectType::Index => "INDEX",
4070 ObjectType::Schema => "SCHEMA",
4071 ObjectType::Role => "ROLE",
4072 ObjectType::Sequence => "SEQUENCE",
4073 ObjectType::Stage => "STAGE",
4074 })
4075 }
4076}
4077
4078#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4079#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4080#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4081pub enum KillType {
4082 Connection,
4083 Query,
4084 Mutation,
4085}
4086
4087impl fmt::Display for KillType {
4088 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4089 f.write_str(match self {
4090 KillType::Connection => "CONNECTION",
4092 KillType::Query => "QUERY",
4093 KillType::Mutation => "MUTATION",
4095 })
4096 }
4097}
4098
4099#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4100#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4101#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4102pub enum HiveDistributionStyle {
4103 PARTITIONED {
4104 columns: Vec<ColumnDef>,
4105 },
4106 CLUSTERED {
4107 columns: Vec<Ident>,
4108 sorted_by: Vec<ColumnDef>,
4109 num_buckets: i32,
4110 },
4111 SKEWED {
4112 columns: Vec<ColumnDef>,
4113 on: Vec<ColumnDef>,
4114 stored_as_directories: bool,
4115 },
4116 NONE,
4117}
4118
4119#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4120#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4121#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4122pub enum HiveRowFormat {
4123 SERDE { class: String },
4124 DELIMITED,
4125}
4126
4127#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4128#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4129#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4130#[allow(clippy::large_enum_variant)]
4131pub enum HiveIOFormat {
4132 IOF {
4133 input_format: Expr,
4134 output_format: Expr,
4135 },
4136 FileFormat {
4137 format: FileFormat,
4138 },
4139}
4140
4141#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
4142#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4143#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4144pub struct HiveFormat {
4145 pub row_format: Option<HiveRowFormat>,
4146 pub storage: Option<HiveIOFormat>,
4147 pub location: Option<String>,
4148}
4149
4150#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4151#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4152#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4153pub struct SqlOption {
4154 pub name: Ident,
4155 pub value: Value,
4156}
4157
4158impl fmt::Display for SqlOption {
4159 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4160 write!(f, "{} = {}", self.name, self.value)
4161 }
4162}
4163
4164#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4165#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4166#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4167pub enum TransactionMode {
4168 AccessMode(TransactionAccessMode),
4169 IsolationLevel(TransactionIsolationLevel),
4170}
4171
4172impl fmt::Display for TransactionMode {
4173 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4174 use TransactionMode::*;
4175 match self {
4176 AccessMode(access_mode) => write!(f, "{access_mode}"),
4177 IsolationLevel(iso_level) => write!(f, "ISOLATION LEVEL {iso_level}"),
4178 }
4179 }
4180}
4181
4182#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4183#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4184#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4185pub enum TransactionAccessMode {
4186 ReadOnly,
4187 ReadWrite,
4188}
4189
4190impl fmt::Display for TransactionAccessMode {
4191 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4192 use TransactionAccessMode::*;
4193 f.write_str(match self {
4194 ReadOnly => "READ ONLY",
4195 ReadWrite => "READ WRITE",
4196 })
4197 }
4198}
4199
4200#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4201#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4202#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4203pub enum TransactionIsolationLevel {
4204 ReadUncommitted,
4205 ReadCommitted,
4206 RepeatableRead,
4207 Serializable,
4208}
4209
4210impl fmt::Display for TransactionIsolationLevel {
4211 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4212 use TransactionIsolationLevel::*;
4213 f.write_str(match self {
4214 ReadUncommitted => "READ UNCOMMITTED",
4215 ReadCommitted => "READ COMMITTED",
4216 RepeatableRead => "REPEATABLE READ",
4217 Serializable => "SERIALIZABLE",
4218 })
4219 }
4220}
4221
4222#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4223#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4224#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4225pub enum ShowStatementFilter {
4226 Like(String),
4227 ILike(String),
4228 Where(Expr),
4229}
4230
4231impl fmt::Display for ShowStatementFilter {
4232 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4233 use ShowStatementFilter::*;
4234 match self {
4235 Like(pattern) => write!(f, "LIKE '{}'", value::escape_single_quote_string(pattern)),
4236 ILike(pattern) => write!(f, "ILIKE {}", value::escape_single_quote_string(pattern)),
4237 Where(expr) => write!(f, "WHERE {expr}"),
4238 }
4239 }
4240}
4241
4242#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4247#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4248#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4249pub enum SqliteOnConflict {
4250 Rollback,
4251 Abort,
4252 Fail,
4253 Ignore,
4254 Replace,
4255}
4256
4257impl fmt::Display for SqliteOnConflict {
4258 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4259 use SqliteOnConflict::*;
4260 match self {
4261 Rollback => write!(f, "ROLLBACK"),
4262 Abort => write!(f, "ABORT"),
4263 Fail => write!(f, "FAIL"),
4264 Ignore => write!(f, "IGNORE"),
4265 Replace => write!(f, "REPLACE"),
4266 }
4267 }
4268}
4269
4270#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4271#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4272#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4273pub enum CopySource {
4274 Table {
4275 table_name: ObjectName,
4277 columns: Vec<Ident>,
4280 },
4281 Query(Box<Query>),
4282}
4283
4284#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4285#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4286#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4287pub enum CopyTarget {
4288 Stdin,
4289 Stdout,
4290 File {
4291 filename: String,
4293 },
4294 Program {
4295 command: String,
4297 },
4298}
4299
4300impl fmt::Display for CopyTarget {
4301 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4302 use CopyTarget::*;
4303 match self {
4304 Stdin { .. } => write!(f, "STDIN"),
4305 Stdout => write!(f, "STDOUT"),
4306 File { filename } => write!(f, "'{}'", value::escape_single_quote_string(filename)),
4307 Program { command } => write!(
4308 f,
4309 "PROGRAM '{}'",
4310 value::escape_single_quote_string(command)
4311 ),
4312 }
4313 }
4314}
4315
4316#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4317#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4318#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4319pub enum OnCommit {
4320 DeleteRows,
4321 PreserveRows,
4322 Drop,
4323}
4324
4325#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4329#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4330#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4331pub enum CopyOption {
4332 Format(Ident),
4334 Freeze(bool),
4336 Delimiter(char),
4338 Null(String),
4340 Header(bool),
4342 Quote(char),
4344 Escape(char),
4346 ForceQuote(Vec<Ident>),
4348 ForceNotNull(Vec<Ident>),
4350 ForceNull(Vec<Ident>),
4352 Encoding(String),
4354}
4355
4356impl fmt::Display for CopyOption {
4357 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4358 use CopyOption::*;
4359 match self {
4360 Format(name) => write!(f, "FORMAT {name}"),
4361 Freeze(true) => write!(f, "FREEZE"),
4362 Freeze(false) => write!(f, "FREEZE FALSE"),
4363 Delimiter(char) => write!(f, "DELIMITER '{char}'"),
4364 Null(string) => write!(f, "NULL '{}'", value::escape_single_quote_string(string)),
4365 Header(true) => write!(f, "HEADER"),
4366 Header(false) => write!(f, "HEADER FALSE"),
4367 Quote(char) => write!(f, "QUOTE '{char}'"),
4368 Escape(char) => write!(f, "ESCAPE '{char}'"),
4369 ForceQuote(columns) => write!(f, "FORCE_QUOTE ({})", display_comma_separated(columns)),
4370 ForceNotNull(columns) => {
4371 write!(f, "FORCE_NOT_NULL ({})", display_comma_separated(columns))
4372 }
4373 ForceNull(columns) => write!(f, "FORCE_NULL ({})", display_comma_separated(columns)),
4374 Encoding(name) => write!(f, "ENCODING '{}'", value::escape_single_quote_string(name)),
4375 }
4376 }
4377}
4378
4379#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4383#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4384#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4385pub enum CopyLegacyOption {
4386 Binary,
4388 Delimiter(char),
4390 Null(String),
4392 Csv(Vec<CopyLegacyCsvOption>),
4394}
4395
4396impl fmt::Display for CopyLegacyOption {
4397 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4398 use CopyLegacyOption::*;
4399 match self {
4400 Binary => write!(f, "BINARY"),
4401 Delimiter(char) => write!(f, "DELIMITER '{char}'"),
4402 Null(string) => write!(f, "NULL '{}'", value::escape_single_quote_string(string)),
4403 Csv(opts) => write!(f, "CSV {}", display_separated(opts, " ")),
4404 }
4405 }
4406}
4407
4408#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4412#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4413#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4414pub enum CopyLegacyCsvOption {
4415 Header,
4417 Quote(char),
4419 Escape(char),
4421 ForceQuote(Vec<Ident>),
4423 ForceNotNull(Vec<Ident>),
4425}
4426
4427impl fmt::Display for CopyLegacyCsvOption {
4428 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4429 use CopyLegacyCsvOption::*;
4430 match self {
4431 Header => write!(f, "HEADER"),
4432 Quote(char) => write!(f, "QUOTE '{char}'"),
4433 Escape(char) => write!(f, "ESCAPE '{char}'"),
4434 ForceQuote(columns) => write!(f, "FORCE QUOTE {}", display_comma_separated(columns)),
4435 ForceNotNull(columns) => {
4436 write!(f, "FORCE NOT NULL {}", display_comma_separated(columns))
4437 }
4438 }
4439 }
4440}
4441
4442#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4444#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4445#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4446pub enum MergeClause {
4447 MatchedUpdate {
4448 predicate: Option<Expr>,
4449 assignments: Vec<Assignment>,
4450 },
4451 MatchedDelete(Option<Expr>),
4452 NotMatched {
4453 predicate: Option<Expr>,
4454 columns: Vec<Ident>,
4455 values: Values,
4456 },
4457}
4458
4459impl fmt::Display for MergeClause {
4460 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4461 use MergeClause::*;
4462 write!(f, "WHEN")?;
4463 match self {
4464 MatchedUpdate {
4465 predicate,
4466 assignments,
4467 } => {
4468 write!(f, " MATCHED")?;
4469 if let Some(pred) = predicate {
4470 write!(f, " AND {pred}")?;
4471 }
4472 write!(
4473 f,
4474 " THEN UPDATE SET {}",
4475 display_comma_separated(assignments)
4476 )
4477 }
4478 MatchedDelete(predicate) => {
4479 write!(f, " MATCHED")?;
4480 if let Some(pred) = predicate {
4481 write!(f, " AND {pred}")?;
4482 }
4483 write!(f, " THEN DELETE")
4484 }
4485 NotMatched {
4486 predicate,
4487 columns,
4488 values,
4489 } => {
4490 write!(f, " NOT MATCHED")?;
4491 if let Some(pred) = predicate {
4492 write!(f, " AND {pred}")?;
4493 }
4494 write!(
4495 f,
4496 " THEN INSERT ({}) {}",
4497 display_comma_separated(columns),
4498 values
4499 )
4500 }
4501 }
4502 }
4503}
4504
4505#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4506#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4507#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4508pub enum DiscardObject {
4509 ALL,
4510 PLANS,
4511 SEQUENCES,
4512 TEMP,
4513}
4514
4515impl fmt::Display for DiscardObject {
4516 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4517 match self {
4518 DiscardObject::ALL => f.write_str("ALL"),
4519 DiscardObject::PLANS => f.write_str("PLANS"),
4520 DiscardObject::SEQUENCES => f.write_str("SEQUENCES"),
4521 DiscardObject::TEMP => f.write_str("TEMP"),
4522 }
4523 }
4524}
4525
4526#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4528#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4529#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4530pub enum ContextModifier {
4531 None,
4533 Local,
4535 Session,
4537}
4538
4539impl fmt::Display for ContextModifier {
4540 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4541 match self {
4542 Self::None => {
4543 write!(f, "")
4544 }
4545 Self::Local => {
4546 write!(f, " LOCAL")
4547 }
4548 Self::Session => {
4549 write!(f, " SESSION")
4550 }
4551 }
4552 }
4553}
4554
4555#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4557#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4558pub enum DropFunctionOption {
4559 Restrict,
4560 Cascade,
4561}
4562
4563impl fmt::Display for DropFunctionOption {
4564 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4565 match self {
4566 DropFunctionOption::Restrict => write!(f, "RESTRICT "),
4567 DropFunctionOption::Cascade => write!(f, "CASCADE "),
4568 }
4569 }
4570}
4571
4572#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4574#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4575#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4576pub struct DropFunctionDesc {
4577 pub name: ObjectName,
4578 pub args: Option<Vec<OperateFunctionArg>>,
4579}
4580
4581impl fmt::Display for DropFunctionDesc {
4582 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4583 write!(f, "{}", self.name)?;
4584 if let Some(args) = &self.args {
4585 write!(f, "({})", display_comma_separated(args))?;
4586 }
4587 Ok(())
4588 }
4589}
4590
4591#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4593#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4594#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4595pub struct OperateFunctionArg {
4596 pub mode: Option<ArgMode>,
4597 pub name: Option<Ident>,
4598 pub data_type: DataType,
4599 pub default_expr: Option<Expr>,
4600}
4601
4602impl OperateFunctionArg {
4603 pub fn unnamed(data_type: DataType) -> Self {
4605 Self {
4606 mode: None,
4607 name: None,
4608 data_type,
4609 default_expr: None,
4610 }
4611 }
4612
4613 pub fn with_name(name: &str, data_type: DataType) -> Self {
4615 Self {
4616 mode: None,
4617 name: Some(name.into()),
4618 data_type,
4619 default_expr: None,
4620 }
4621 }
4622}
4623
4624impl fmt::Display for OperateFunctionArg {
4625 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4626 if let Some(mode) = &self.mode {
4627 write!(f, "{mode} ")?;
4628 }
4629 if let Some(name) = &self.name {
4630 write!(f, "{name} ")?;
4631 }
4632 write!(f, "{}", self.data_type)?;
4633 if let Some(default_expr) = &self.default_expr {
4634 write!(f, " = {default_expr}")?;
4635 }
4636 Ok(())
4637 }
4638}
4639
4640#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4642#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4643#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4644pub enum ArgMode {
4645 In,
4646 Out,
4647 InOut,
4648}
4649
4650impl fmt::Display for ArgMode {
4651 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4652 match self {
4653 ArgMode::In => write!(f, "IN"),
4654 ArgMode::Out => write!(f, "OUT"),
4655 ArgMode::InOut => write!(f, "INOUT"),
4656 }
4657 }
4658}
4659
4660#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4662#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4663#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4664pub enum FunctionBehavior {
4665 Immutable,
4666 Stable,
4667 Volatile,
4668}
4669
4670impl fmt::Display for FunctionBehavior {
4671 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4672 match self {
4673 FunctionBehavior::Immutable => write!(f, "IMMUTABLE"),
4674 FunctionBehavior::Stable => write!(f, "STABLE"),
4675 FunctionBehavior::Volatile => write!(f, "VOLATILE"),
4676 }
4677 }
4678}
4679
4680#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4681#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4682#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4683pub enum FunctionDefinition {
4684 SingleQuotedDef(String),
4685 DoubleDollarDef(String),
4686}
4687
4688impl fmt::Display for FunctionDefinition {
4689 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4690 match self {
4691 FunctionDefinition::SingleQuotedDef(s) => write!(f, "'{s}'")?,
4692 FunctionDefinition::DoubleDollarDef(s) => write!(f, "$${s}$$")?,
4693 }
4694 Ok(())
4695 }
4696}
4697
4698#[derive(Debug, Default, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4703#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4704#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4705pub struct CreateFunctionBody {
4706 pub language: Option<Ident>,
4708 pub behavior: Option<FunctionBehavior>,
4710 pub as_: Option<FunctionDefinition>,
4714 pub return_: Option<Expr>,
4716 pub using: Option<CreateFunctionUsing>,
4718}
4719
4720impl fmt::Display for CreateFunctionBody {
4721 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4722 if let Some(language) = &self.language {
4723 write!(f, " LANGUAGE {language}")?;
4724 }
4725 if let Some(behavior) = &self.behavior {
4726 write!(f, " {behavior}")?;
4727 }
4728 if let Some(definition) = &self.as_ {
4729 write!(f, " AS {definition}")?;
4730 }
4731 if let Some(expr) = &self.return_ {
4732 write!(f, " RETURN {expr}")?;
4733 }
4734 if let Some(using) = &self.using {
4735 write!(f, " {using}")?;
4736 }
4737 Ok(())
4738 }
4739}
4740
4741#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4742#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4743#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4744pub enum CreateFunctionUsing {
4745 Jar(String),
4746 File(String),
4747 Archive(String),
4748}
4749
4750impl fmt::Display for CreateFunctionUsing {
4751 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4752 write!(f, "USING ")?;
4753 match self {
4754 CreateFunctionUsing::Jar(uri) => write!(f, "JAR '{uri}'"),
4755 CreateFunctionUsing::File(uri) => write!(f, "FILE '{uri}'"),
4756 CreateFunctionUsing::Archive(uri) => write!(f, "ARCHIVE '{uri}'"),
4757 }
4758 }
4759}
4760
4761#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4766#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4767#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4768pub struct MacroArg {
4769 pub name: Ident,
4770 pub default_expr: Option<Expr>,
4771}
4772
4773impl MacroArg {
4774 pub fn new(name: &str) -> Self {
4776 Self {
4777 name: name.into(),
4778 default_expr: None,
4779 }
4780 }
4781}
4782
4783impl fmt::Display for MacroArg {
4784 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4785 write!(f, "{}", self.name)?;
4786 if let Some(default_expr) = &self.default_expr {
4787 write!(f, " := {default_expr}")?;
4788 }
4789 Ok(())
4790 }
4791}
4792
4793#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4794#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4795#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4796pub enum MacroDefinition {
4797 Expr(Expr),
4798 Table(Query),
4799}
4800
4801impl fmt::Display for MacroDefinition {
4802 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4803 match self {
4804 MacroDefinition::Expr(expr) => write!(f, "{expr}")?,
4805 MacroDefinition::Table(query) => write!(f, "{query}")?,
4806 }
4807 Ok(())
4808 }
4809}
4810
4811#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4815#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4816#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4817pub enum SchemaName {
4818 Simple(ObjectName),
4820 UnnamedAuthorization(Ident),
4822 NamedAuthorization(ObjectName, Ident),
4824}
4825
4826impl fmt::Display for SchemaName {
4827 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4828 match self {
4829 SchemaName::Simple(name) => {
4830 write!(f, "{name}")
4831 }
4832 SchemaName::UnnamedAuthorization(authorization) => {
4833 write!(f, "AUTHORIZATION {authorization}")
4834 }
4835 SchemaName::NamedAuthorization(name, authorization) => {
4836 write!(f, "{name} AUTHORIZATION {authorization}")
4837 }
4838 }
4839 }
4840}
4841
4842#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4846#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4847#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4848pub enum SearchModifier {
4849 InNaturalLanguageMode,
4851 InNaturalLanguageModeWithQueryExpansion,
4853 InBooleanMode,
4855 WithQueryExpansion,
4857}
4858
4859impl fmt::Display for SearchModifier {
4860 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4861 match self {
4862 Self::InNaturalLanguageMode => {
4863 write!(f, "IN NATURAL LANGUAGE MODE")?;
4864 }
4865 Self::InNaturalLanguageModeWithQueryExpansion => {
4866 write!(f, "IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION")?;
4867 }
4868 Self::InBooleanMode => {
4869 write!(f, "IN BOOLEAN MODE")?;
4870 }
4871 Self::WithQueryExpansion => {
4872 write!(f, "WITH QUERY EXPANSION")?;
4873 }
4874 }
4875
4876 Ok(())
4877 }
4878}
4879
4880#[cfg(test)]
4881mod tests {
4882 use super::*;
4883
4884 #[test]
4885 fn test_window_frame_default() {
4886 let window_frame = WindowFrame::default();
4887 assert_eq!(WindowFrameBound::Preceding(None), window_frame.start_bound);
4888 }
4889
4890 #[test]
4891 fn test_grouping_sets_display() {
4892 let grouping_sets = Expr::GroupingSets(vec![
4894 vec![Expr::Identifier(Ident::new("a"))],
4895 vec![Expr::Identifier(Ident::new("b"))],
4896 ]);
4897 assert_eq!("GROUPING SETS ((a), (b))", format!("{grouping_sets}"));
4898
4899 let grouping_sets = Expr::GroupingSets(vec![vec![
4901 Expr::Identifier(Ident::new("a")),
4902 Expr::Identifier(Ident::new("b")),
4903 ]]);
4904 assert_eq!("GROUPING SETS ((a, b))", format!("{grouping_sets}"));
4905
4906 let grouping_sets = Expr::GroupingSets(vec![
4908 vec![
4909 Expr::Identifier(Ident::new("a")),
4910 Expr::Identifier(Ident::new("b")),
4911 ],
4912 vec![
4913 Expr::Identifier(Ident::new("c")),
4914 Expr::Identifier(Ident::new("d")),
4915 ],
4916 ]);
4917 assert_eq!("GROUPING SETS ((a, b), (c, d))", format!("{grouping_sets}"));
4918 }
4919
4920 #[test]
4921 fn test_rollup_display() {
4922 let rollup = Expr::Rollup(vec![vec![Expr::Identifier(Ident::new("a"))]]);
4923 assert_eq!("ROLLUP (a)", format!("{rollup}"));
4924
4925 let rollup = Expr::Rollup(vec![vec![
4926 Expr::Identifier(Ident::new("a")),
4927 Expr::Identifier(Ident::new("b")),
4928 ]]);
4929 assert_eq!("ROLLUP ((a, b))", format!("{rollup}"));
4930
4931 let rollup = Expr::Rollup(vec![
4932 vec![Expr::Identifier(Ident::new("a"))],
4933 vec![Expr::Identifier(Ident::new("b"))],
4934 ]);
4935 assert_eq!("ROLLUP (a, b)", format!("{rollup}"));
4936
4937 let rollup = Expr::Rollup(vec![
4938 vec![Expr::Identifier(Ident::new("a"))],
4939 vec![
4940 Expr::Identifier(Ident::new("b")),
4941 Expr::Identifier(Ident::new("c")),
4942 ],
4943 vec![Expr::Identifier(Ident::new("d"))],
4944 ]);
4945 assert_eq!("ROLLUP (a, (b, c), d)", format!("{rollup}"));
4946 }
4947
4948 #[test]
4949 fn test_cube_display() {
4950 let cube = Expr::Cube(vec![vec![Expr::Identifier(Ident::new("a"))]]);
4951 assert_eq!("CUBE (a)", format!("{cube}"));
4952
4953 let cube = Expr::Cube(vec![vec![
4954 Expr::Identifier(Ident::new("a")),
4955 Expr::Identifier(Ident::new("b")),
4956 ]]);
4957 assert_eq!("CUBE ((a, b))", format!("{cube}"));
4958
4959 let cube = Expr::Cube(vec![
4960 vec![Expr::Identifier(Ident::new("a"))],
4961 vec![Expr::Identifier(Ident::new("b"))],
4962 ]);
4963 assert_eq!("CUBE (a, b)", format!("{cube}"));
4964
4965 let cube = Expr::Cube(vec![
4966 vec![Expr::Identifier(Ident::new("a"))],
4967 vec![
4968 Expr::Identifier(Ident::new("b")),
4969 Expr::Identifier(Ident::new("c")),
4970 ],
4971 vec![Expr::Identifier(Ident::new("d"))],
4972 ]);
4973 assert_eq!("CUBE (a, (b, c), d)", format!("{cube}"));
4974 }
4975
4976 #[test]
4977 fn test_interval_display() {
4978 let interval = Expr::Interval(Interval {
4979 value: Box::new(Expr::Value(Value::SingleQuotedString(String::from(
4980 "123:45.67",
4981 )))),
4982 leading_field: Some(DateTimeField::Minute),
4983 leading_precision: Some(10),
4984 last_field: Some(DateTimeField::Second),
4985 fractional_seconds_precision: Some(9),
4986 });
4987 assert_eq!(
4988 "INTERVAL '123:45.67' MINUTE (10) TO SECOND (9)",
4989 format!("{interval}"),
4990 );
4991
4992 let interval = Expr::Interval(Interval {
4993 value: Box::new(Expr::Value(Value::SingleQuotedString(String::from("5")))),
4994 leading_field: Some(DateTimeField::Second),
4995 leading_precision: Some(1),
4996 last_field: None,
4997 fractional_seconds_precision: Some(3),
4998 });
4999 assert_eq!("INTERVAL '5' SECOND (1, 3)", format!("{interval}"));
5000 }
5001}