1#[cfg(not(feature = "std"))]
15use alloc::{
16 boxed::Box,
17 format,
18 string::{String, ToString},
19 vec::Vec,
20};
21use core::fmt::{self, Display};
22
23#[cfg(feature = "serde")]
24use serde::{Deserialize, Serialize};
25
26#[cfg(feature = "visitor")]
27use sqlparser_derive::{Visit, VisitMut};
28
29pub use self::data_type::{
30 ArrayElemTypeDef, CharLengthUnits, CharacterLength, DataType, ExactNumberInfo, TimezoneInfo,
31};
32pub use self::dcl::{AlterRoleOperation, ResetConfig, RoleOption, SetConfigValue};
33pub use self::ddl::{
34 AlterColumnOperation, AlterIndexOperation, AlterTableOperation, ColumnDef, ColumnOption,
35 ColumnOptionDef, ConstraintCharacteristics, DeferrableInitial, GeneratedAs,
36 GeneratedExpressionMode, IndexType, KeyOrIndexDisplay, Partition, ProcedureParam,
37 ReferentialAction, TableConstraint, UserDefinedTypeCompositeAttributeDef,
38 UserDefinedTypeRepresentation, ViewColumnDef,
39};
40pub use self::operator::{BinaryOperator, UnaryOperator};
41pub use self::query::{
42 Cte, Distinct, ExceptSelectItem, ExcludeSelectItem, Fetch, ForClause, ForJson, ForXml,
43 GroupByExpr, IdentWithAlias, Join, JoinConstraint, JoinOperator, JsonTableColumn,
44 JsonTableColumnErrorHandling, LateralView, LockClause, LockType, NamedWindowDefinition,
45 NonBlock, Offset, OffsetRows, OrderByExpr, Query, RenameSelectItem, ReplaceSelectElement,
46 ReplaceSelectItem, Select, SelectInto, SelectItem, SetExpr, SetOperator, SetQuantifier, Table,
47 TableAlias, TableFactor, TableVersion, TableWithJoins, Top, TopQuantity, Values,
48 WildcardAdditionalOptions, With,
49};
50pub use self::value::{
51 escape_quoted_string, DateTimeField, DollarQuotedString, TrimWhereField, Value,
52};
53
54use crate::ast::helpers::stmt_data_loading::{
55 DataLoadingOptions, StageLoadSelectItem, StageParamsObject,
56};
57#[cfg(feature = "visitor")]
58pub use visitor::*;
59
60mod data_type;
61mod dcl;
62mod ddl;
63pub mod helpers;
64mod operator;
65mod query;
66mod value;
67
68#[cfg(feature = "visitor")]
69mod visitor;
70
71struct DisplaySeparated<'a, T>
72where
73 T: fmt::Display,
74{
75 slice: &'a [T],
76 sep: &'static str,
77}
78
79impl<'a, T> fmt::Display for DisplaySeparated<'a, T>
80where
81 T: fmt::Display,
82{
83 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84 let mut delim = "";
85 for t in self.slice {
86 write!(f, "{delim}")?;
87 delim = self.sep;
88 write!(f, "{t}")?;
89 }
90 Ok(())
91 }
92}
93
94fn display_separated<'a, T>(slice: &'a [T], sep: &'static str) -> DisplaySeparated<'a, T>
95where
96 T: fmt::Display,
97{
98 DisplaySeparated { slice, sep }
99}
100
101fn display_comma_separated<T>(slice: &[T]) -> DisplaySeparated<'_, T>
102where
103 T: fmt::Display,
104{
105 DisplaySeparated { slice, sep: ", " }
106}
107
108#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
110#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
111#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
112pub struct Ident {
113 pub value: String,
115 pub quote_style: Option<char>,
118}
119
120impl Ident {
121 pub fn new<S>(value: S) -> Self
123 where
124 S: Into<String>,
125 {
126 Ident {
127 value: value.into(),
128 quote_style: None,
129 }
130 }
131
132 pub fn with_quote<S>(quote: char, value: S) -> Self
135 where
136 S: Into<String>,
137 {
138 assert!(quote == '\'' || quote == '"' || quote == '`' || quote == '[');
139 Ident {
140 value: value.into(),
141 quote_style: Some(quote),
142 }
143 }
144}
145
146impl From<&str> for Ident {
147 fn from(value: &str) -> Self {
148 Ident {
149 value: value.to_string(),
150 quote_style: None,
151 }
152 }
153}
154
155impl fmt::Display for Ident {
156 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
157 match self.quote_style {
158 Some(q) if q == '"' || q == '\'' || q == '`' => {
159 let escaped = value::escape_quoted_string(&self.value, q);
160 write!(f, "{q}{escaped}{q}")
161 }
162 Some('[') => write!(f, "[{}]", self.value),
163 None => f.write_str(&self.value),
164 _ => panic!("unexpected quote style"),
165 }
166 }
167}
168
169#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
171#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
172#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
173pub struct ObjectName(pub Vec<Ident>);
174
175impl fmt::Display for ObjectName {
176 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
177 write!(f, "{}", display_separated(&self.0, "."))
178 }
179}
180
181#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
184#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
185#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
186pub struct Array {
187 pub elem: Vec<Expr>,
189
190 pub named: bool,
192}
193
194impl fmt::Display for Array {
195 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
196 write!(
197 f,
198 "{}[{}]",
199 if self.named { "ARRAY" } else { "" },
200 display_comma_separated(&self.elem)
201 )
202 }
203}
204
205#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
214#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
215#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
216pub struct Interval {
217 pub value: Box<Expr>,
218 pub leading_field: Option<DateTimeField>,
219 pub leading_precision: Option<u64>,
220 pub last_field: Option<DateTimeField>,
221 pub fractional_seconds_precision: Option<u64>,
226}
227
228impl fmt::Display for Interval {
229 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
230 let value = self.value.as_ref();
231 match (
232 self.leading_field,
233 self.leading_precision,
234 self.fractional_seconds_precision,
235 ) {
236 (
237 Some(DateTimeField::Second),
238 Some(leading_precision),
239 Some(fractional_seconds_precision),
240 ) => {
241 assert!(self.last_field.is_none());
244 write!(
245 f,
246 "INTERVAL {value} SECOND ({leading_precision}, {fractional_seconds_precision})"
247 )
248 }
249 _ => {
250 write!(f, "INTERVAL {value}")?;
251 if let Some(leading_field) = self.leading_field {
252 write!(f, " {leading_field}")?;
253 }
254 if let Some(leading_precision) = self.leading_precision {
255 write!(f, " ({leading_precision})")?;
256 }
257 if let Some(last_field) = self.last_field {
258 write!(f, " TO {last_field}")?;
259 }
260 if let Some(fractional_seconds_precision) = self.fractional_seconds_precision {
261 write!(f, " ({fractional_seconds_precision})")?;
262 }
263 Ok(())
264 }
265 }
266 }
267}
268
269#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
271#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
272#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
273pub enum JsonOperator {
274 Arrow,
276 LongArrow,
278 HashArrow,
280 HashLongArrow,
282 Colon,
284 AtArrow,
286 ArrowAt,
288 HashMinus,
291 AtQuestion,
294 AtAt,
298}
299
300impl fmt::Display for JsonOperator {
301 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
302 match self {
303 JsonOperator::Arrow => {
304 write!(f, "->")
305 }
306 JsonOperator::LongArrow => {
307 write!(f, "->>")
308 }
309 JsonOperator::HashArrow => {
310 write!(f, "#>")
311 }
312 JsonOperator::HashLongArrow => {
313 write!(f, "#>>")
314 }
315 JsonOperator::Colon => {
316 write!(f, ":")
317 }
318 JsonOperator::AtArrow => {
319 write!(f, "@>")
320 }
321 JsonOperator::ArrowAt => write!(f, "<@"),
322 JsonOperator::HashMinus => write!(f, "#-"),
323 JsonOperator::AtQuestion => write!(f, "@?"),
324 JsonOperator::AtAt => write!(f, "@@"),
325 }
326 }
327}
328
329#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
333#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
334#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
335pub struct StructField {
336 pub field_name: Option<Ident>,
337 pub field_type: DataType,
338}
339
340impl fmt::Display for StructField {
341 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
342 if let Some(name) = &self.field_name {
343 write!(f, "{name} {}", self.field_type)
344 } else {
345 write!(f, "{}", self.field_type)
346 }
347 }
348}
349
350#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
353#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
354#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
355pub enum CastFormat {
356 Value(Value),
357 ValueAtTimeZone(Value, Value),
358}
359
360#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
366#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
367#[cfg_attr(
368 feature = "visitor",
369 derive(Visit, VisitMut),
370 visit(with = "visit_expr")
371)]
372pub enum Expr {
373 Identifier(Ident),
375 CompoundIdentifier(Vec<Ident>),
377 JsonAccess {
379 left: Box<Expr>,
380 operator: JsonOperator,
381 right: Box<Expr>,
382 },
383 CompositeAccess {
385 expr: Box<Expr>,
386 key: Ident,
387 },
388 IsFalse(Box<Expr>),
390 IsNotFalse(Box<Expr>),
392 IsTrue(Box<Expr>),
394 IsNotTrue(Box<Expr>),
396 IsNull(Box<Expr>),
398 IsNotNull(Box<Expr>),
400 IsUnknown(Box<Expr>),
402 IsNotUnknown(Box<Expr>),
404 IsDistinctFrom(Box<Expr>, Box<Expr>),
406 IsNotDistinctFrom(Box<Expr>, Box<Expr>),
408 InList {
410 expr: Box<Expr>,
411 list: Vec<Expr>,
412 negated: bool,
413 },
414 InSubquery {
416 expr: Box<Expr>,
417 subquery: Box<Query>,
418 negated: bool,
419 },
420 InUnnest {
422 expr: Box<Expr>,
423 array_expr: Box<Expr>,
424 negated: bool,
425 },
426 Between {
428 expr: Box<Expr>,
429 negated: bool,
430 low: Box<Expr>,
431 high: Box<Expr>,
432 },
433 BinaryOp {
435 left: Box<Expr>,
436 op: BinaryOperator,
437 right: Box<Expr>,
438 },
439 Like {
441 negated: bool,
442 expr: Box<Expr>,
443 pattern: Box<Expr>,
444 escape_char: Option<char>,
445 },
446 ILike {
448 negated: bool,
449 expr: Box<Expr>,
450 pattern: Box<Expr>,
451 escape_char: Option<char>,
452 },
453 SimilarTo {
455 negated: bool,
456 expr: Box<Expr>,
457 pattern: Box<Expr>,
458 escape_char: Option<char>,
459 },
460 RLike {
462 negated: bool,
463 expr: Box<Expr>,
464 pattern: Box<Expr>,
465 regexp: bool,
467 },
468 AnyOp {
470 left: Box<Expr>,
471 compare_op: BinaryOperator,
472 right: Box<Expr>,
473 },
474 AllOp {
476 left: Box<Expr>,
477 compare_op: BinaryOperator,
478 right: Box<Expr>,
479 },
480 UnaryOp {
482 op: UnaryOperator,
483 expr: Box<Expr>,
484 },
485 Convert {
487 expr: Box<Expr>,
489 data_type: Option<DataType>,
491 charset: Option<ObjectName>,
493 target_before_value: bool,
495 },
496 Cast {
498 expr: Box<Expr>,
499 data_type: DataType,
500 format: Option<CastFormat>,
503 },
504 TryCast {
507 expr: Box<Expr>,
508 data_type: DataType,
509 format: Option<CastFormat>,
512 },
513 SafeCast {
517 expr: Box<Expr>,
518 data_type: DataType,
519 format: Option<CastFormat>,
522 },
523 AtTimeZone {
525 timestamp: Box<Expr>,
526 time_zone: String,
527 },
528 Extract {
535 field: DateTimeField,
536 expr: Box<Expr>,
537 },
538 Ceil {
542 expr: Box<Expr>,
543 field: DateTimeField,
544 },
545 Floor {
549 expr: Box<Expr>,
550 field: DateTimeField,
551 },
552 Position {
556 expr: Box<Expr>,
557 r#in: Box<Expr>,
558 },
559 Substring {
563 expr: Box<Expr>,
564 substring_from: Option<Box<Expr>>,
565 substring_for: Option<Box<Expr>>,
566
567 special: bool,
570 },
571 Trim {
577 expr: Box<Expr>,
578 trim_where: Option<TrimWhereField>,
580 trim_what: Option<Box<Expr>>,
581 trim_characters: Option<Vec<Expr>>,
582 },
583 Overlay {
587 expr: Box<Expr>,
588 overlay_what: Box<Expr>,
589 overlay_from: Box<Expr>,
590 overlay_for: Option<Box<Expr>>,
591 },
592 Collate {
594 expr: Box<Expr>,
595 collation: ObjectName,
596 },
597 Nested(Box<Expr>),
599 Value(Value),
601 IntroducedString {
603 introducer: String,
604 value: Value,
605 },
606 TypedString {
610 data_type: DataType,
611 value: String,
612 },
613 MapAccess {
618 column: Box<Expr>,
619 keys: Vec<Expr>,
620 },
621 Function(Function),
623 AggregateExpressionWithFilter {
625 expr: Box<Expr>,
626 filter: Box<Expr>,
627 },
628 Case {
634 operand: Option<Box<Expr>>,
635 conditions: Vec<Expr>,
636 results: Vec<Expr>,
637 else_result: Option<Box<Expr>>,
638 },
639 Exists {
642 subquery: Box<Query>,
643 negated: bool,
644 },
645 Subquery(Box<Query>),
648 ArraySubquery(Box<Query>),
650 ListAgg(ListAgg),
652 ArrayAgg(ArrayAgg),
654 GroupingSets(Vec<Vec<Expr>>),
656 Cube(Vec<Vec<Expr>>),
658 Rollup(Vec<Vec<Expr>>),
660 Tuple(Vec<Expr>),
662 Struct {
669 values: Vec<Expr>,
671 fields: Vec<StructField>,
673 },
674 Named {
682 expr: Box<Expr>,
683 name: Ident,
684 },
685 ArrayIndex {
687 obj: Box<Expr>,
688 indexes: Vec<Expr>,
689 },
690 Array(Array),
692 Interval(Interval),
694 MatchAgainst {
705 columns: Vec<Ident>,
707 match_value: Value,
709 opt_search_modifier: Option<SearchModifier>,
711 },
712 Wildcard,
713 QualifiedWildcard(ObjectName),
716}
717
718impl fmt::Display for CastFormat {
719 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
720 match self {
721 CastFormat::Value(v) => write!(f, "{v}"),
722 CastFormat::ValueAtTimeZone(v, tz) => write!(f, "{v} AT TIME ZONE {tz}"),
723 }
724 }
725}
726
727impl fmt::Display for Expr {
728 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
729 match self {
730 Expr::Identifier(s) => write!(f, "{s}"),
731 Expr::MapAccess { column, keys } => {
732 write!(f, "{column}")?;
733 for k in keys {
734 match k {
735 k @ Expr::Value(Value::Number(_, _)) => write!(f, "[{k}]")?,
736 Expr::Value(Value::SingleQuotedString(s)) => write!(f, "[\"{s}\"]")?,
737 _ => write!(f, "[{k}]")?,
738 }
739 }
740 Ok(())
741 }
742 Expr::Wildcard => f.write_str("*"),
743 Expr::QualifiedWildcard(prefix) => write!(f, "{}.*", prefix),
744 Expr::CompoundIdentifier(s) => write!(f, "{}", display_separated(s, ".")),
745 Expr::IsTrue(ast) => write!(f, "{ast} IS TRUE"),
746 Expr::IsNotTrue(ast) => write!(f, "{ast} IS NOT TRUE"),
747 Expr::IsFalse(ast) => write!(f, "{ast} IS FALSE"),
748 Expr::IsNotFalse(ast) => write!(f, "{ast} IS NOT FALSE"),
749 Expr::IsNull(ast) => write!(f, "{ast} IS NULL"),
750 Expr::IsNotNull(ast) => write!(f, "{ast} IS NOT NULL"),
751 Expr::IsUnknown(ast) => write!(f, "{ast} IS UNKNOWN"),
752 Expr::IsNotUnknown(ast) => write!(f, "{ast} IS NOT UNKNOWN"),
753 Expr::InList {
754 expr,
755 list,
756 negated,
757 } => write!(
758 f,
759 "{} {}IN ({})",
760 expr,
761 if *negated { "NOT " } else { "" },
762 display_comma_separated(list)
763 ),
764 Expr::InSubquery {
765 expr,
766 subquery,
767 negated,
768 } => write!(
769 f,
770 "{} {}IN ({})",
771 expr,
772 if *negated { "NOT " } else { "" },
773 subquery
774 ),
775 Expr::InUnnest {
776 expr,
777 array_expr,
778 negated,
779 } => write!(
780 f,
781 "{} {}IN UNNEST({})",
782 expr,
783 if *negated { "NOT " } else { "" },
784 array_expr
785 ),
786 Expr::Between {
787 expr,
788 negated,
789 low,
790 high,
791 } => write!(
792 f,
793 "{} {}BETWEEN {} AND {}",
794 expr,
795 if *negated { "NOT " } else { "" },
796 low,
797 high
798 ),
799 Expr::BinaryOp { left, op, right } => write!(f, "{left} {op} {right}"),
800 Expr::Like {
801 negated,
802 expr,
803 pattern,
804 escape_char,
805 } => match escape_char {
806 Some(ch) => write!(
807 f,
808 "{} {}LIKE {} ESCAPE '{}'",
809 expr,
810 if *negated { "NOT " } else { "" },
811 pattern,
812 ch
813 ),
814 _ => write!(
815 f,
816 "{} {}LIKE {}",
817 expr,
818 if *negated { "NOT " } else { "" },
819 pattern
820 ),
821 },
822 Expr::ILike {
823 negated,
824 expr,
825 pattern,
826 escape_char,
827 } => match escape_char {
828 Some(ch) => write!(
829 f,
830 "{} {}ILIKE {} ESCAPE '{}'",
831 expr,
832 if *negated { "NOT " } else { "" },
833 pattern,
834 ch
835 ),
836 _ => write!(
837 f,
838 "{} {}ILIKE {}",
839 expr,
840 if *negated { "NOT " } else { "" },
841 pattern
842 ),
843 },
844 Expr::RLike {
845 negated,
846 expr,
847 pattern,
848 regexp,
849 } => write!(
850 f,
851 "{} {}{} {}",
852 expr,
853 if *negated { "NOT " } else { "" },
854 if *regexp { "REGEXP" } else { "RLIKE" },
855 pattern
856 ),
857 Expr::SimilarTo {
858 negated,
859 expr,
860 pattern,
861 escape_char,
862 } => match escape_char {
863 Some(ch) => write!(
864 f,
865 "{} {}SIMILAR TO {} ESCAPE '{}'",
866 expr,
867 if *negated { "NOT " } else { "" },
868 pattern,
869 ch
870 ),
871 _ => write!(
872 f,
873 "{} {}SIMILAR TO {}",
874 expr,
875 if *negated { "NOT " } else { "" },
876 pattern
877 ),
878 },
879 Expr::AnyOp {
880 left,
881 compare_op,
882 right,
883 } => write!(f, "{left} {compare_op} ANY({right})"),
884 Expr::AllOp {
885 left,
886 compare_op,
887 right,
888 } => write!(f, "{left} {compare_op} ALL({right})"),
889 Expr::UnaryOp { op, expr } => {
890 if op == &UnaryOperator::PGPostfixFactorial {
891 write!(f, "{expr}{op}")
892 } else if op == &UnaryOperator::Not {
893 write!(f, "{op} {expr}")
894 } else {
895 write!(f, "{op}{expr}")
896 }
897 }
898 Expr::Convert {
899 expr,
900 target_before_value,
901 data_type,
902 charset,
903 } => {
904 write!(f, "CONVERT(")?;
905 if let Some(data_type) = data_type {
906 if let Some(charset) = charset {
907 write!(f, "{expr}, {data_type} CHARACTER SET {charset}")
908 } else if *target_before_value {
909 write!(f, "{data_type}, {expr}")
910 } else {
911 write!(f, "{expr}, {data_type}")
912 }
913 } else if let Some(charset) = charset {
914 write!(f, "{expr} USING {charset}")
915 } else {
916 write!(f, "{expr}") }?;
918 write!(f, ")")
919 }
920 Expr::Cast {
921 expr,
922 data_type,
923 format,
924 } => {
925 if let Some(format) = format {
926 write!(f, "CAST({expr} AS {data_type} FORMAT {format})")
927 } else {
928 write!(f, "CAST({expr} AS {data_type})")
929 }
930 }
931 Expr::TryCast {
932 expr,
933 data_type,
934 format,
935 } => {
936 if let Some(format) = format {
937 write!(f, "TRY_CAST({expr} AS {data_type} FORMAT {format})")
938 } else {
939 write!(f, "TRY_CAST({expr} AS {data_type})")
940 }
941 }
942 Expr::SafeCast {
943 expr,
944 data_type,
945 format,
946 } => {
947 if let Some(format) = format {
948 write!(f, "SAFE_CAST({expr} AS {data_type} FORMAT {format})")
949 } else {
950 write!(f, "SAFE_CAST({expr} AS {data_type})")
951 }
952 }
953 Expr::Extract { field, expr } => write!(f, "EXTRACT({field} FROM {expr})"),
954 Expr::Ceil { expr, field } => {
955 if field == &DateTimeField::NoDateTime {
956 write!(f, "CEIL({expr})")
957 } else {
958 write!(f, "CEIL({expr} TO {field})")
959 }
960 }
961 Expr::Floor { expr, field } => {
962 if field == &DateTimeField::NoDateTime {
963 write!(f, "FLOOR({expr})")
964 } else {
965 write!(f, "FLOOR({expr} TO {field})")
966 }
967 }
968 Expr::Position { expr, r#in } => write!(f, "POSITION({expr} IN {in})"),
969 Expr::Collate { expr, collation } => write!(f, "{expr} COLLATE {collation}"),
970 Expr::Nested(ast) => write!(f, "({ast})"),
971 Expr::Value(v) => write!(f, "{v}"),
972 Expr::IntroducedString { introducer, value } => write!(f, "{introducer} {value}"),
973 Expr::TypedString { data_type, value } => {
974 write!(f, "{data_type}")?;
975 write!(f, " '{}'", &value::escape_single_quote_string(value))
976 }
977 Expr::Function(fun) => write!(f, "{fun}"),
978 Expr::AggregateExpressionWithFilter { expr, filter } => {
979 write!(f, "{expr} FILTER (WHERE {filter})")
980 }
981 Expr::Case {
982 operand,
983 conditions,
984 results,
985 else_result,
986 } => {
987 write!(f, "CASE")?;
988 if let Some(operand) = operand {
989 write!(f, " {operand}")?;
990 }
991 for (c, r) in conditions.iter().zip(results) {
992 write!(f, " WHEN {c} THEN {r}")?;
993 }
994
995 if let Some(else_result) = else_result {
996 write!(f, " ELSE {else_result}")?;
997 }
998 write!(f, " END")
999 }
1000 Expr::Exists { subquery, negated } => write!(
1001 f,
1002 "{}EXISTS ({})",
1003 if *negated { "NOT " } else { "" },
1004 subquery
1005 ),
1006 Expr::Subquery(s) => write!(f, "({s})"),
1007 Expr::ArraySubquery(s) => write!(f, "ARRAY({s})"),
1008 Expr::ListAgg(listagg) => write!(f, "{listagg}"),
1009 Expr::ArrayAgg(arrayagg) => write!(f, "{arrayagg}"),
1010 Expr::GroupingSets(sets) => {
1011 write!(f, "GROUPING SETS (")?;
1012 let mut sep = "";
1013 for set in sets {
1014 write!(f, "{sep}")?;
1015 sep = ", ";
1016 write!(f, "({})", display_comma_separated(set))?;
1017 }
1018 write!(f, ")")
1019 }
1020 Expr::Cube(sets) => {
1021 write!(f, "CUBE (")?;
1022 let mut sep = "";
1023 for set in sets {
1024 write!(f, "{sep}")?;
1025 sep = ", ";
1026 if set.len() == 1 {
1027 write!(f, "{}", set[0])?;
1028 } else {
1029 write!(f, "({})", display_comma_separated(set))?;
1030 }
1031 }
1032 write!(f, ")")
1033 }
1034 Expr::Rollup(sets) => {
1035 write!(f, "ROLLUP (")?;
1036 let mut sep = "";
1037 for set in sets {
1038 write!(f, "{sep}")?;
1039 sep = ", ";
1040 if set.len() == 1 {
1041 write!(f, "{}", set[0])?;
1042 } else {
1043 write!(f, "({})", display_comma_separated(set))?;
1044 }
1045 }
1046 write!(f, ")")
1047 }
1048 Expr::Substring {
1049 expr,
1050 substring_from,
1051 substring_for,
1052 special,
1053 } => {
1054 write!(f, "SUBSTRING({expr}")?;
1055 if let Some(from_part) = substring_from {
1056 if *special {
1057 write!(f, ", {from_part}")?;
1058 } else {
1059 write!(f, " FROM {from_part}")?;
1060 }
1061 }
1062 if let Some(for_part) = substring_for {
1063 if *special {
1064 write!(f, ", {for_part}")?;
1065 } else {
1066 write!(f, " FOR {for_part}")?;
1067 }
1068 }
1069
1070 write!(f, ")")
1071 }
1072 Expr::Overlay {
1073 expr,
1074 overlay_what,
1075 overlay_from,
1076 overlay_for,
1077 } => {
1078 write!(
1079 f,
1080 "OVERLAY({expr} PLACING {overlay_what} FROM {overlay_from}"
1081 )?;
1082 if let Some(for_part) = overlay_for {
1083 write!(f, " FOR {for_part}")?;
1084 }
1085
1086 write!(f, ")")
1087 }
1088 Expr::IsDistinctFrom(a, b) => write!(f, "{a} IS DISTINCT FROM {b}"),
1089 Expr::IsNotDistinctFrom(a, b) => write!(f, "{a} IS NOT DISTINCT FROM {b}"),
1090 Expr::Trim {
1091 expr,
1092 trim_where,
1093 trim_what,
1094 trim_characters,
1095 } => {
1096 write!(f, "TRIM(")?;
1097 if let Some(ident) = trim_where {
1098 write!(f, "{ident} ")?;
1099 }
1100 if let Some(trim_char) = trim_what {
1101 write!(f, "{trim_char} FROM {expr}")?;
1102 } else {
1103 write!(f, "{expr}")?;
1104 }
1105 if let Some(characters) = trim_characters {
1106 write!(f, ", {}", display_comma_separated(characters))?;
1107 }
1108
1109 write!(f, ")")
1110 }
1111 Expr::Tuple(exprs) => {
1112 write!(f, "({})", display_comma_separated(exprs))
1113 }
1114 Expr::Struct { values, fields } => {
1115 if !fields.is_empty() {
1116 write!(
1117 f,
1118 "STRUCT<{}>({})",
1119 display_comma_separated(fields),
1120 display_comma_separated(values)
1121 )
1122 } else {
1123 write!(f, "STRUCT({})", display_comma_separated(values))
1124 }
1125 }
1126 Expr::Named { expr, name } => {
1127 write!(f, "{} AS {}", expr, name)
1128 }
1129 Expr::ArrayIndex { obj, indexes } => {
1130 write!(f, "{obj}")?;
1131 for i in indexes {
1132 write!(f, "[{i}]")?;
1133 }
1134 Ok(())
1135 }
1136 Expr::Array(set) => {
1137 write!(f, "{set}")
1138 }
1139 Expr::JsonAccess {
1140 left,
1141 operator,
1142 right,
1143 } => {
1144 if operator == &JsonOperator::Colon {
1145 write!(f, "{left}{operator}{right}")
1146 } else {
1147 write!(f, "{left} {operator} {right}")
1148 }
1149 }
1150 Expr::CompositeAccess { expr, key } => {
1151 write!(f, "{expr}.{key}")
1152 }
1153 Expr::AtTimeZone {
1154 timestamp,
1155 time_zone,
1156 } => {
1157 write!(f, "{timestamp} AT TIME ZONE '{time_zone}'")
1158 }
1159 Expr::Interval(interval) => {
1160 write!(f, "{interval}")
1161 }
1162 Expr::MatchAgainst {
1163 columns,
1164 match_value: match_expr,
1165 opt_search_modifier,
1166 } => {
1167 write!(f, "MATCH ({}) AGAINST ", display_comma_separated(columns),)?;
1168
1169 if let Some(search_modifier) = opt_search_modifier {
1170 write!(f, "({match_expr} {search_modifier})")?;
1171 } else {
1172 write!(f, "({match_expr})")?;
1173 }
1174
1175 Ok(())
1176 }
1177 }
1178 }
1179}
1180
1181#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1182#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1183#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1184pub enum WindowType {
1185 WindowSpec(WindowSpec),
1186 NamedWindow(Ident),
1187}
1188
1189impl Display for WindowType {
1190 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1191 match self {
1192 WindowType::WindowSpec(spec) => write!(f, "({})", spec),
1193 WindowType::NamedWindow(name) => write!(f, "{}", name),
1194 }
1195 }
1196}
1197
1198#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1200#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1201#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1202pub struct WindowSpec {
1203 pub partition_by: Vec<Expr>,
1205 pub order_by: Vec<OrderByExpr>,
1207 pub window_frame: Option<WindowFrame>,
1209}
1210
1211impl fmt::Display for WindowSpec {
1212 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1213 let mut delim = "";
1214 if !self.partition_by.is_empty() {
1215 delim = " ";
1216 write!(
1217 f,
1218 "PARTITION BY {}",
1219 display_comma_separated(&self.partition_by)
1220 )?;
1221 }
1222 if !self.order_by.is_empty() {
1223 f.write_str(delim)?;
1224 delim = " ";
1225 write!(f, "ORDER BY {}", display_comma_separated(&self.order_by))?;
1226 }
1227 if let Some(window_frame) = &self.window_frame {
1228 f.write_str(delim)?;
1229 if let Some(end_bound) = &window_frame.end_bound {
1230 write!(
1231 f,
1232 "{} BETWEEN {} AND {}",
1233 window_frame.units, window_frame.start_bound, end_bound
1234 )?;
1235 } else {
1236 write!(f, "{} {}", window_frame.units, window_frame.start_bound)?;
1237 }
1238 }
1239 Ok(())
1240 }
1241}
1242
1243#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1249#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1250#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1251pub struct WindowFrame {
1252 pub units: WindowFrameUnits,
1253 pub start_bound: WindowFrameBound,
1254 pub end_bound: Option<WindowFrameBound>,
1258 }
1260
1261impl Default for WindowFrame {
1262 fn default() -> Self {
1266 Self {
1267 units: WindowFrameUnits::Range,
1268 start_bound: WindowFrameBound::Preceding(None),
1269 end_bound: None,
1270 }
1271 }
1272}
1273
1274#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1275#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1276#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1277pub enum WindowFrameUnits {
1278 Rows,
1279 Range,
1280 Groups,
1281}
1282
1283impl fmt::Display for WindowFrameUnits {
1284 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1285 f.write_str(match self {
1286 WindowFrameUnits::Rows => "ROWS",
1287 WindowFrameUnits::Range => "RANGE",
1288 WindowFrameUnits::Groups => "GROUPS",
1289 })
1290 }
1291}
1292
1293#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1297#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1298#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1299pub enum NullTreatment {
1300 IgnoreNulls,
1301 RespectNulls,
1302}
1303
1304impl fmt::Display for NullTreatment {
1305 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1306 f.write_str(match self {
1307 NullTreatment::IgnoreNulls => "IGNORE NULLS",
1308 NullTreatment::RespectNulls => "RESPECT NULLS",
1309 })
1310 }
1311}
1312
1313#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1315#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1316#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1317pub enum WindowFrameBound {
1318 CurrentRow,
1320 Preceding(Option<Box<Expr>>),
1322 Following(Option<Box<Expr>>),
1324}
1325
1326impl fmt::Display for WindowFrameBound {
1327 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1328 match self {
1329 WindowFrameBound::CurrentRow => f.write_str("CURRENT ROW"),
1330 WindowFrameBound::Preceding(None) => f.write_str("UNBOUNDED PRECEDING"),
1331 WindowFrameBound::Following(None) => f.write_str("UNBOUNDED FOLLOWING"),
1332 WindowFrameBound::Preceding(Some(n)) => write!(f, "{n} PRECEDING"),
1333 WindowFrameBound::Following(Some(n)) => write!(f, "{n} FOLLOWING"),
1334 }
1335 }
1336}
1337
1338#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1339#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1340#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1341pub enum AddDropSync {
1342 ADD,
1343 DROP,
1344 SYNC,
1345}
1346
1347impl fmt::Display for AddDropSync {
1348 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1349 match self {
1350 AddDropSync::SYNC => f.write_str("SYNC PARTITIONS"),
1351 AddDropSync::DROP => f.write_str("DROP PARTITIONS"),
1352 AddDropSync::ADD => f.write_str("ADD PARTITIONS"),
1353 }
1354 }
1355}
1356
1357#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1358#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1359#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1360pub enum ShowCreateObject {
1361 Event,
1362 Function,
1363 Procedure,
1364 Table,
1365 Trigger,
1366 View,
1367}
1368
1369impl fmt::Display for ShowCreateObject {
1370 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1371 match self {
1372 ShowCreateObject::Event => f.write_str("EVENT"),
1373 ShowCreateObject::Function => f.write_str("FUNCTION"),
1374 ShowCreateObject::Procedure => f.write_str("PROCEDURE"),
1375 ShowCreateObject::Table => f.write_str("TABLE"),
1376 ShowCreateObject::Trigger => f.write_str("TRIGGER"),
1377 ShowCreateObject::View => f.write_str("VIEW"),
1378 }
1379 }
1380}
1381
1382#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1383#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1384#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1385pub enum CommentObject {
1386 Column,
1387 Table,
1388}
1389
1390impl fmt::Display for CommentObject {
1391 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1392 match self {
1393 CommentObject::Column => f.write_str("COLUMN"),
1394 CommentObject::Table => f.write_str("TABLE"),
1395 }
1396 }
1397}
1398
1399#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1400#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1401#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1402pub enum Password {
1403 Password(Expr),
1404 NullPassword,
1405}
1406
1407#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1409#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1410#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1411pub enum CreateTableOptions {
1412 None,
1413 With(Vec<SqlOption>),
1418 Options(Vec<SqlOption>),
1423}
1424
1425impl fmt::Display for CreateTableOptions {
1426 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1427 match self {
1428 CreateTableOptions::With(with_options) => {
1429 write!(f, "WITH ({})", display_comma_separated(with_options))
1430 }
1431 CreateTableOptions::Options(options) => {
1432 write!(f, "OPTIONS({})", display_comma_separated(options))
1433 }
1434 CreateTableOptions::None => Ok(()),
1435 }
1436 }
1437}
1438
1439#[allow(clippy::large_enum_variant)]
1441#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1442#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1443#[cfg_attr(
1444 feature = "visitor",
1445 derive(Visit, VisitMut),
1446 visit(with = "visit_statement")
1447)]
1448pub enum Statement {
1449 Analyze {
1454 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1455 table_name: ObjectName,
1456 partitions: Option<Vec<Expr>>,
1457 for_columns: bool,
1458 columns: Vec<Ident>,
1459 cache_metadata: bool,
1460 noscan: bool,
1461 compute_statistics: bool,
1462 },
1463 Truncate {
1468 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1469 table_name: ObjectName,
1470 partitions: Option<Vec<Expr>>,
1471 table: bool,
1473 },
1474 Msck {
1479 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1480 table_name: ObjectName,
1481 repair: bool,
1482 partition_action: Option<AddDropSync>,
1483 },
1484 Query(Box<Query>),
1488 Insert {
1492 or: Option<SqliteOnConflict>,
1494 ignore: bool,
1496 into: bool,
1498 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1500 table_name: ObjectName,
1501 table_alias: Option<Ident>,
1503 columns: Vec<Ident>,
1505 overwrite: bool,
1507 source: Option<Box<Query>>,
1509 partitioned: Option<Vec<Expr>>,
1511 after_columns: Vec<Ident>,
1513 table: bool,
1515 as_table: Option<ObjectName>,
1517 as_table_after_columns: Vec<Ident>,
1519 on: Option<OnInsert>,
1520 returning: Option<Vec<SelectItem>>,
1522 replace_into: bool,
1524 priority: Option<MysqlInsertPriority>,
1526 },
1527 Directory {
1529 overwrite: bool,
1530 local: bool,
1531 path: String,
1532 file_format: Option<FileFormat>,
1533 source: Box<Query>,
1534 },
1535 Call(Function),
1539 Copy {
1543 source: CopySource,
1545 to: bool,
1547 target: CopyTarget,
1549 options: Vec<CopyOption>,
1551 legacy_options: Vec<CopyLegacyOption>,
1553 values: Vec<Option<String>>,
1555 },
1556 CopyIntoSnowflake {
1565 into: ObjectName,
1566 from_stage: ObjectName,
1567 from_stage_alias: Option<Ident>,
1568 stage_params: StageParamsObject,
1569 from_transformations: Option<Vec<StageLoadSelectItem>>,
1570 files: Option<Vec<String>>,
1571 pattern: Option<String>,
1572 file_format: DataLoadingOptions,
1573 copy_options: DataLoadingOptions,
1574 validation_mode: Option<String>,
1575 },
1576 Close {
1581 cursor: CloseCursor,
1583 },
1584 Update {
1588 table: TableWithJoins,
1590 assignments: Vec<Assignment>,
1592 from: Option<TableWithJoins>,
1594 selection: Option<Expr>,
1596 returning: Option<Vec<SelectItem>>,
1598 },
1599 Delete {
1603 tables: Vec<ObjectName>,
1605 from: Vec<TableWithJoins>,
1607 using: Option<Vec<TableWithJoins>>,
1609 selection: Option<Expr>,
1611 returning: Option<Vec<SelectItem>>,
1613 order_by: Vec<OrderByExpr>,
1615 limit: Option<Expr>,
1617 },
1618 CreateView {
1622 or_replace: bool,
1623 materialized: bool,
1624 name: ObjectName,
1626 columns: Vec<ViewColumnDef>,
1627 query: Box<Query>,
1628 options: CreateTableOptions,
1629 cluster_by: Vec<Ident>,
1630 with_no_schema_binding: bool,
1632 if_not_exists: bool,
1634 temporary: bool,
1636 },
1637 CreateTable {
1641 or_replace: bool,
1642 temporary: bool,
1643 external: bool,
1644 global: Option<bool>,
1645 if_not_exists: bool,
1646 transient: bool,
1647 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1649 name: ObjectName,
1650 columns: Vec<ColumnDef>,
1652 constraints: Vec<TableConstraint>,
1653 hive_distribution: HiveDistributionStyle,
1654 hive_formats: Option<HiveFormat>,
1655 table_properties: Vec<SqlOption>,
1656 with_options: Vec<SqlOption>,
1657 file_format: Option<FileFormat>,
1658 location: Option<String>,
1659 query: Option<Box<Query>>,
1660 without_rowid: bool,
1661 like: Option<ObjectName>,
1662 clone: Option<ObjectName>,
1663 engine: Option<String>,
1664 comment: Option<String>,
1665 auto_increment_offset: Option<u32>,
1666 default_charset: Option<String>,
1667 collation: Option<String>,
1668 on_commit: Option<OnCommit>,
1669 on_cluster: Option<String>,
1672 order_by: Option<Vec<Ident>>,
1676 partition_by: Option<Box<Expr>>,
1679 cluster_by: Option<Vec<Ident>>,
1682 options: Option<Vec<SqlOption>>,
1685 strict: bool,
1689 },
1690 CreateVirtualTable {
1695 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1696 name: ObjectName,
1697 if_not_exists: bool,
1698 module_name: Ident,
1699 module_args: Vec<Ident>,
1700 },
1701 CreateIndex {
1705 name: Option<ObjectName>,
1707 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1708 table_name: ObjectName,
1709 using: Option<Ident>,
1710 columns: Vec<OrderByExpr>,
1711 unique: bool,
1712 concurrently: bool,
1713 if_not_exists: bool,
1714 include: Vec<Ident>,
1715 nulls_distinct: Option<bool>,
1716 predicate: Option<Expr>,
1717 },
1718 CreateRole {
1723 names: Vec<ObjectName>,
1724 if_not_exists: bool,
1725 login: Option<bool>,
1727 inherit: Option<bool>,
1728 bypassrls: Option<bool>,
1729 password: Option<Password>,
1730 superuser: Option<bool>,
1731 create_db: Option<bool>,
1732 create_role: Option<bool>,
1733 replication: Option<bool>,
1734 connection_limit: Option<Expr>,
1735 valid_until: Option<Expr>,
1736 in_role: Vec<Ident>,
1737 in_group: Vec<Ident>,
1738 role: Vec<Ident>,
1739 user: Vec<Ident>,
1740 admin: Vec<Ident>,
1741 authorization_owner: Option<ObjectName>,
1743 },
1744 AlterTable {
1748 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1750 name: ObjectName,
1751 if_exists: bool,
1752 only: bool,
1753 operations: Vec<AlterTableOperation>,
1754 },
1755 AlterIndex {
1759 name: ObjectName,
1760 operation: AlterIndexOperation,
1761 },
1762 AlterView {
1766 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1768 name: ObjectName,
1769 columns: Vec<Ident>,
1770 query: Box<Query>,
1771 with_options: Vec<SqlOption>,
1772 },
1773 AlterRole {
1777 name: Ident,
1778 operation: AlterRoleOperation,
1779 },
1780 AttachDatabase {
1785 schema_name: Ident,
1787 database_file_name: Expr,
1789 database: bool,
1791 },
1792 Drop {
1796 object_type: ObjectType,
1798 if_exists: bool,
1800 names: Vec<ObjectName>,
1802 cascade: bool,
1805 restrict: bool,
1808 purge: bool,
1811 temporary: bool,
1813 },
1814 DropFunction {
1818 if_exists: bool,
1819 func_desc: Vec<DropFunctionDesc>,
1821 option: Option<ReferentialAction>,
1823 },
1824 Declare {
1832 name: Ident,
1834 binary: bool,
1836 sensitive: Option<bool>,
1840 scroll: Option<bool>,
1844 hold: Option<bool>,
1848 query: Box<Query>,
1849 },
1850 CreateExtension {
1859 name: Ident,
1860 if_not_exists: bool,
1861 cascade: bool,
1862 schema: Option<Ident>,
1863 version: Option<Ident>,
1864 },
1865 Fetch {
1873 name: Ident,
1875 direction: FetchDirection,
1876 into: Option<ObjectName>,
1878 },
1879 Flush {
1886 object_type: FlushType,
1887 location: Option<FlushLocation>,
1888 channel: Option<String>,
1889 read_lock: bool,
1890 export: bool,
1891 tables: Vec<ObjectName>,
1892 },
1893 Discard { object_type: DiscardObject },
1900 SetRole {
1911 context_modifier: ContextModifier,
1913 role_name: Option<Ident>,
1915 },
1916 SetVariable {
1924 local: bool,
1925 hivevar: bool,
1926 variable: ObjectName,
1927 value: Vec<Expr>,
1928 },
1929 SetTimeZone { local: bool, value: Expr },
1936 SetNames {
1942 charset_name: String,
1943 collation_name: Option<String>,
1944 },
1945 SetNamesDefault {},
1951 ShowFunctions { filter: Option<ShowStatementFilter> },
1955 ShowVariable { variable: Vec<Ident> },
1961 ShowVariables {
1967 filter: Option<ShowStatementFilter>,
1968 global: bool,
1969 session: bool,
1970 },
1971 ShowCreate {
1977 obj_type: ShowCreateObject,
1978 obj_name: ObjectName,
1979 },
1980 ShowColumns {
1986 extended: bool,
1987 full: bool,
1988 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1989 table_name: ObjectName,
1990 filter: Option<ShowStatementFilter>,
1991 },
1992 ShowTables {
1997 extended: bool,
1998 full: bool,
1999 db_name: Option<Ident>,
2000 filter: Option<ShowStatementFilter>,
2001 },
2002 ShowCollation { filter: Option<ShowStatementFilter> },
2008 Use { db_name: Ident },
2014 StartTransaction {
2024 modes: Vec<TransactionMode>,
2025 begin: bool,
2026 modifier: Option<TransactionModifier>,
2028 },
2029 SetTransaction {
2033 modes: Vec<TransactionMode>,
2034 snapshot: Option<Value>,
2035 session: bool,
2036 },
2037 Comment {
2043 object_type: CommentObject,
2044 object_name: ObjectName,
2045 comment: Option<String>,
2046 if_exists: bool,
2049 },
2050 Commit { chain: bool },
2054 Rollback {
2058 chain: bool,
2059 savepoint: Option<Ident>,
2060 },
2061 CreateSchema {
2065 schema_name: SchemaName,
2067 if_not_exists: bool,
2068 },
2069 CreateDatabase {
2073 db_name: ObjectName,
2074 if_not_exists: bool,
2075 location: Option<String>,
2076 managed_location: Option<String>,
2077 },
2078 CreateFunction {
2086 or_replace: bool,
2087 temporary: bool,
2088 name: ObjectName,
2089 args: Option<Vec<OperateFunctionArg>>,
2090 return_type: Option<DataType>,
2091 params: CreateFunctionBody,
2093 },
2094 CreateProcedure {
2098 or_alter: bool,
2099 name: ObjectName,
2100 params: Option<Vec<ProcedureParam>>,
2101 body: Vec<Statement>,
2102 },
2103 CreateMacro {
2110 or_replace: bool,
2111 temporary: bool,
2112 name: ObjectName,
2113 args: Option<Vec<MacroArg>>,
2114 definition: MacroDefinition,
2115 },
2116 CreateStage {
2121 or_replace: bool,
2122 temporary: bool,
2123 if_not_exists: bool,
2124 name: ObjectName,
2125 stage_params: StageParamsObject,
2126 directory_table_params: DataLoadingOptions,
2127 file_format: DataLoadingOptions,
2128 copy_options: DataLoadingOptions,
2129 comment: Option<String>,
2130 },
2131 Assert {
2135 condition: Expr,
2136 message: Option<Expr>,
2137 },
2138 Grant {
2142 privileges: Privileges,
2143 objects: GrantObjects,
2144 grantees: Vec<Ident>,
2145 with_grant_option: bool,
2146 granted_by: Option<Ident>,
2147 },
2148 Revoke {
2152 privileges: Privileges,
2153 objects: GrantObjects,
2154 grantees: Vec<Ident>,
2155 granted_by: Option<Ident>,
2156 cascade: bool,
2157 },
2158 Deallocate { name: Ident, prepare: bool },
2164 Execute { name: Ident, parameters: Vec<Expr> },
2170 Prepare {
2176 name: Ident,
2177 data_types: Vec<DataType>,
2178 statement: Box<Statement>,
2179 },
2180 Kill {
2187 modifier: Option<KillType>,
2188 id: u64,
2190 },
2191 ExplainTable {
2196 describe_alias: bool,
2198 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
2200 table_name: ObjectName,
2201 },
2202 Explain {
2206 describe_alias: bool,
2208 analyze: bool,
2210 verbose: bool,
2212 statement: Box<Statement>,
2214 format: Option<AnalyzeFormat>,
2216 },
2217 Savepoint { name: Ident },
2222 ReleaseSavepoint { name: Ident },
2226 Merge {
2231 into: bool,
2233 table: TableFactor,
2235 source: TableFactor,
2237 on: Box<Expr>,
2239 clauses: Vec<MergeClause>,
2241 },
2242 Cache {
2250 table_flag: Option<ObjectName>,
2252 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
2255 table_name: ObjectName,
2256 has_as: bool,
2257 options: Vec<SqlOption>,
2259 query: Option<Query>,
2261 },
2262 UNCache {
2266 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
2268 table_name: ObjectName,
2269 if_exists: bool,
2270 },
2271 CreateSequence {
2276 temporary: bool,
2277 if_not_exists: bool,
2278 name: ObjectName,
2279 data_type: Option<DataType>,
2280 sequence_options: Vec<SequenceOptions>,
2281 owned_by: Option<ObjectName>,
2282 },
2283 CreateType {
2287 name: ObjectName,
2288 representation: UserDefinedTypeRepresentation,
2289 },
2290 Pragma {
2294 name: ObjectName,
2295 value: Option<Value>,
2296 is_eq: bool,
2297 },
2298 LockTables { tables: Vec<LockTable> },
2303 UnlockTables,
2308}
2309
2310impl fmt::Display for Statement {
2311 #[allow(clippy::cognitive_complexity)]
2314 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2315 match self {
2316 Statement::Flush {
2317 object_type,
2318 location,
2319 channel,
2320 read_lock,
2321 export,
2322 tables,
2323 } => {
2324 write!(f, "FLUSH")?;
2325 if let Some(location) = location {
2326 write!(f, " {location}")?;
2327 }
2328 write!(f, " {object_type}")?;
2329
2330 if let Some(channel) = channel {
2331 write!(f, " FOR CHANNEL {channel}")?;
2332 }
2333
2334 write!(
2335 f,
2336 "{tables}{read}{export}",
2337 tables = if !tables.is_empty() {
2338 " ".to_string() + &display_comma_separated(tables).to_string()
2339 } else {
2340 "".to_string()
2341 },
2342 export = if *export { " FOR EXPORT" } else { "" },
2343 read = if *read_lock { " WITH READ LOCK" } else { "" }
2344 )
2345 }
2346 Statement::Kill { modifier, id } => {
2347 write!(f, "KILL ")?;
2348
2349 if let Some(m) = modifier {
2350 write!(f, "{m} ")?;
2351 }
2352
2353 write!(f, "{id}")
2354 }
2355 Statement::ExplainTable {
2356 describe_alias,
2357 table_name,
2358 } => {
2359 if *describe_alias {
2360 write!(f, "DESCRIBE ")?;
2361 } else {
2362 write!(f, "EXPLAIN ")?;
2363 }
2364
2365 write!(f, "{table_name}")
2366 }
2367 Statement::Explain {
2368 describe_alias,
2369 verbose,
2370 analyze,
2371 statement,
2372 format,
2373 } => {
2374 if *describe_alias {
2375 write!(f, "DESCRIBE ")?;
2376 } else {
2377 write!(f, "EXPLAIN ")?;
2378 }
2379
2380 if *analyze {
2381 write!(f, "ANALYZE ")?;
2382 }
2383
2384 if *verbose {
2385 write!(f, "VERBOSE ")?;
2386 }
2387
2388 if let Some(format) = format {
2389 write!(f, "FORMAT {format} ")?;
2390 }
2391
2392 write!(f, "{statement}")
2393 }
2394 Statement::Query(s) => write!(f, "{s}"),
2395 Statement::Declare {
2396 name,
2397 binary,
2398 sensitive,
2399 scroll,
2400 hold,
2401 query,
2402 } => {
2403 write!(f, "DECLARE {name} ")?;
2404
2405 if *binary {
2406 write!(f, "BINARY ")?;
2407 }
2408
2409 if let Some(sensitive) = sensitive {
2410 if *sensitive {
2411 write!(f, "INSENSITIVE ")?;
2412 } else {
2413 write!(f, "ASENSITIVE ")?;
2414 }
2415 }
2416
2417 if let Some(scroll) = scroll {
2418 if *scroll {
2419 write!(f, "SCROLL ")?;
2420 } else {
2421 write!(f, "NO SCROLL ")?;
2422 }
2423 }
2424
2425 write!(f, "CURSOR ")?;
2426
2427 if let Some(hold) = hold {
2428 if *hold {
2429 write!(f, "WITH HOLD ")?;
2430 } else {
2431 write!(f, "WITHOUT HOLD ")?;
2432 }
2433 }
2434
2435 write!(f, "FOR {query}")
2436 }
2437 Statement::Fetch {
2438 name,
2439 direction,
2440 into,
2441 } => {
2442 write!(f, "FETCH {direction} ")?;
2443
2444 write!(f, "IN {name}")?;
2445
2446 if let Some(into) = into {
2447 write!(f, " INTO {into}")?;
2448 }
2449
2450 Ok(())
2451 }
2452 Statement::Directory {
2453 overwrite,
2454 local,
2455 path,
2456 file_format,
2457 source,
2458 } => {
2459 write!(
2460 f,
2461 "INSERT{overwrite}{local} DIRECTORY '{path}'",
2462 overwrite = if *overwrite { " OVERWRITE" } else { "" },
2463 local = if *local { " LOCAL" } else { "" },
2464 path = path
2465 )?;
2466 if let Some(ref ff) = file_format {
2467 write!(f, " STORED AS {ff}")?
2468 }
2469 write!(f, " {source}")
2470 }
2471 Statement::Msck {
2472 table_name,
2473 repair,
2474 partition_action,
2475 } => {
2476 write!(
2477 f,
2478 "MSCK {repair}TABLE {table}",
2479 repair = if *repair { "REPAIR " } else { "" },
2480 table = table_name
2481 )?;
2482 if let Some(pa) = partition_action {
2483 write!(f, " {pa}")?;
2484 }
2485 Ok(())
2486 }
2487 Statement::Truncate {
2488 table_name,
2489 partitions,
2490 table,
2491 } => {
2492 let table = if *table { "TABLE " } else { "" };
2493 write!(f, "TRUNCATE {table}{table_name}")?;
2494 if let Some(ref parts) = partitions {
2495 if !parts.is_empty() {
2496 write!(f, " PARTITION ({})", display_comma_separated(parts))?;
2497 }
2498 }
2499 Ok(())
2500 }
2501 Statement::AttachDatabase {
2502 schema_name,
2503 database_file_name,
2504 database,
2505 } => {
2506 let keyword = if *database { "DATABASE " } else { "" };
2507 write!(f, "ATTACH {keyword}{database_file_name} AS {schema_name}")
2508 }
2509 Statement::Analyze {
2510 table_name,
2511 partitions,
2512 for_columns,
2513 columns,
2514 cache_metadata,
2515 noscan,
2516 compute_statistics,
2517 } => {
2518 write!(f, "ANALYZE TABLE {table_name}")?;
2519 if let Some(ref parts) = partitions {
2520 if !parts.is_empty() {
2521 write!(f, " PARTITION ({})", display_comma_separated(parts))?;
2522 }
2523 }
2524
2525 if *compute_statistics {
2526 write!(f, " COMPUTE STATISTICS")?;
2527 }
2528 if *noscan {
2529 write!(f, " NOSCAN")?;
2530 }
2531 if *cache_metadata {
2532 write!(f, " CACHE METADATA")?;
2533 }
2534 if *for_columns {
2535 write!(f, " FOR COLUMNS")?;
2536 if !columns.is_empty() {
2537 write!(f, " {}", display_comma_separated(columns))?;
2538 }
2539 }
2540 Ok(())
2541 }
2542 Statement::Insert {
2543 or,
2544 ignore,
2545 into,
2546 table_name,
2547 table_alias,
2548 overwrite,
2549 partitioned,
2550 columns,
2551 after_columns,
2552 source,
2553 table,
2554 as_table,
2555 as_table_after_columns,
2556 on,
2557 returning,
2558 replace_into,
2559 priority,
2560 } => {
2561 let table_name = if let Some(alias) = table_alias {
2562 format!("{table_name} AS {alias}")
2563 } else {
2564 table_name.to_string()
2565 };
2566
2567 if let Some(action) = or {
2568 write!(f, "INSERT OR {action} INTO {table_name} ")?;
2569 } else {
2570 write!(
2571 f,
2572 "{start}",
2573 start = if *replace_into { "REPLACE" } else { "INSERT" },
2574 )?;
2575 if let Some(priority) = priority {
2576 write!(f, " {priority}",)?;
2577 }
2578
2579 write!(
2580 f,
2581 "{ignore}{over}{int}{tbl} {table_name} ",
2582 table_name = table_name,
2583 ignore = if *ignore { " IGNORE" } else { "" },
2584 over = if *overwrite { " OVERWRITE" } else { "" },
2585 int = if *into { " INTO" } else { "" },
2586 tbl = if *table { " TABLE" } else { "" },
2587 )?;
2588 }
2589 if !columns.is_empty() {
2590 write!(f, "({}) ", display_comma_separated(columns))?;
2591 }
2592 if let Some(ref parts) = partitioned {
2593 if !parts.is_empty() {
2594 write!(f, "PARTITION ({}) ", display_comma_separated(parts))?;
2595 }
2596 }
2597 if !after_columns.is_empty() {
2598 write!(f, "({}) ", display_comma_separated(after_columns))?;
2599 }
2600
2601 if let Some(source) = source {
2602 write!(f, "{source}")?;
2603 }
2604
2605 if source.is_none() && columns.is_empty() {
2606 write!(f, "DEFAULT VALUES")?;
2607 }
2608
2609 if let Some(as_table) = as_table {
2610 write!(f, " AS {as_table}")?;
2611
2612 if !as_table_after_columns.is_empty() {
2613 write!(f, " ({}) ", display_comma_separated(as_table_after_columns))?;
2614 }
2615 }
2616
2617 if let Some(on) = on {
2618 write!(f, "{on}")?;
2619 }
2620
2621 if let Some(returning) = returning {
2622 write!(f, " RETURNING {}", display_comma_separated(returning))?;
2623 }
2624
2625 Ok(())
2626 }
2627
2628 Statement::Call(function) => write!(f, "CALL {function}"),
2629
2630 Statement::Copy {
2631 source,
2632 to,
2633 target,
2634 options,
2635 legacy_options,
2636 values,
2637 } => {
2638 write!(f, "COPY")?;
2639 match source {
2640 CopySource::Query(query) => write!(f, " ({query})")?,
2641 CopySource::Table {
2642 table_name,
2643 columns,
2644 } => {
2645 write!(f, " {table_name}")?;
2646 if !columns.is_empty() {
2647 write!(f, " ({})", display_comma_separated(columns))?;
2648 }
2649 }
2650 }
2651 write!(f, " {} {}", if *to { "TO" } else { "FROM" }, target)?;
2652 if !options.is_empty() {
2653 write!(f, " ({})", display_comma_separated(options))?;
2654 }
2655 if !legacy_options.is_empty() {
2656 write!(f, " {}", display_separated(legacy_options, " "))?;
2657 }
2658 if !values.is_empty() {
2659 writeln!(f, ";")?;
2660 let mut delim = "";
2661 for v in values {
2662 write!(f, "{delim}")?;
2663 delim = "\t";
2664 if let Some(v) = v {
2665 write!(f, "{v}")?;
2666 } else {
2667 write!(f, "\\N")?;
2668 }
2669 }
2670 write!(f, "\n\\.")?;
2671 }
2672 Ok(())
2673 }
2674 Statement::Update {
2675 table,
2676 assignments,
2677 from,
2678 selection,
2679 returning,
2680 } => {
2681 write!(f, "UPDATE {table}")?;
2682 if !assignments.is_empty() {
2683 write!(f, " SET {}", display_comma_separated(assignments))?;
2684 }
2685 if let Some(from) = from {
2686 write!(f, " FROM {from}")?;
2687 }
2688 if let Some(selection) = selection {
2689 write!(f, " WHERE {selection}")?;
2690 }
2691 if let Some(returning) = returning {
2692 write!(f, " RETURNING {}", display_comma_separated(returning))?;
2693 }
2694 Ok(())
2695 }
2696 Statement::Delete {
2697 tables,
2698 from,
2699 using,
2700 selection,
2701 returning,
2702 order_by,
2703 limit,
2704 } => {
2705 write!(f, "DELETE ")?;
2706 if !tables.is_empty() {
2707 write!(f, "{} ", display_comma_separated(tables))?;
2708 }
2709 write!(f, "FROM {}", display_comma_separated(from))?;
2710 if let Some(using) = using {
2711 write!(f, " USING {}", display_comma_separated(using))?;
2712 }
2713 if let Some(selection) = selection {
2714 write!(f, " WHERE {selection}")?;
2715 }
2716 if let Some(returning) = returning {
2717 write!(f, " RETURNING {}", display_comma_separated(returning))?;
2718 }
2719 if !order_by.is_empty() {
2720 write!(f, " ORDER BY {}", display_comma_separated(order_by))?;
2721 }
2722 if let Some(limit) = limit {
2723 write!(f, " LIMIT {limit}")?;
2724 }
2725 Ok(())
2726 }
2727 Statement::Close { cursor } => {
2728 write!(f, "CLOSE {cursor}")?;
2729
2730 Ok(())
2731 }
2732 Statement::CreateDatabase {
2733 db_name,
2734 if_not_exists,
2735 location,
2736 managed_location,
2737 } => {
2738 write!(f, "CREATE DATABASE")?;
2739 if *if_not_exists {
2740 write!(f, " IF NOT EXISTS")?;
2741 }
2742 write!(f, " {db_name}")?;
2743 if let Some(l) = location {
2744 write!(f, " LOCATION '{l}'")?;
2745 }
2746 if let Some(ml) = managed_location {
2747 write!(f, " MANAGEDLOCATION '{ml}'")?;
2748 }
2749 Ok(())
2750 }
2751 Statement::CreateFunction {
2752 or_replace,
2753 temporary,
2754 name,
2755 args,
2756 return_type,
2757 params,
2758 } => {
2759 write!(
2760 f,
2761 "CREATE {or_replace}{temp}FUNCTION {name}",
2762 temp = if *temporary { "TEMPORARY " } else { "" },
2763 or_replace = if *or_replace { "OR REPLACE " } else { "" },
2764 )?;
2765 if let Some(args) = args {
2766 write!(f, "({})", display_comma_separated(args))?;
2767 }
2768 if let Some(return_type) = return_type {
2769 write!(f, " RETURNS {return_type}")?;
2770 }
2771 write!(f, "{params}")?;
2772 Ok(())
2773 }
2774 Statement::CreateProcedure {
2775 name,
2776 or_alter,
2777 params,
2778 body,
2779 } => {
2780 write!(
2781 f,
2782 "CREATE {or_alter}PROCEDURE {name}",
2783 or_alter = if *or_alter { "OR ALTER " } else { "" },
2784 name = name
2785 )?;
2786
2787 if let Some(p) = params {
2788 if !p.is_empty() {
2789 write!(f, " ({})", display_comma_separated(p))?;
2790 }
2791 }
2792 write!(
2793 f,
2794 " AS BEGIN {body} END",
2795 body = display_separated(body, "; ")
2796 )
2797 }
2798 Statement::CreateMacro {
2799 or_replace,
2800 temporary,
2801 name,
2802 args,
2803 definition,
2804 } => {
2805 write!(
2806 f,
2807 "CREATE {or_replace}{temp}MACRO {name}",
2808 temp = if *temporary { "TEMPORARY " } else { "" },
2809 or_replace = if *or_replace { "OR REPLACE " } else { "" },
2810 )?;
2811 if let Some(args) = args {
2812 write!(f, "({})", display_comma_separated(args))?;
2813 }
2814 match definition {
2815 MacroDefinition::Expr(expr) => write!(f, " AS {expr}")?,
2816 MacroDefinition::Table(query) => write!(f, " AS TABLE {query}")?,
2817 }
2818 Ok(())
2819 }
2820 Statement::CreateView {
2821 name,
2822 or_replace,
2823 columns,
2824 query,
2825 materialized,
2826 options,
2827 cluster_by,
2828 with_no_schema_binding,
2829 if_not_exists,
2830 temporary,
2831 } => {
2832 write!(
2833 f,
2834 "CREATE {or_replace}{materialized}{temporary}VIEW {if_not_exists}{name}",
2835 or_replace = if *or_replace { "OR REPLACE " } else { "" },
2836 materialized = if *materialized { "MATERIALIZED " } else { "" },
2837 name = name,
2838 temporary = if *temporary { "TEMPORARY " } else { "" },
2839 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" }
2840 )?;
2841 if matches!(options, CreateTableOptions::With(_)) {
2842 write!(f, " {options}")?;
2843 }
2844 if !columns.is_empty() {
2845 write!(f, " ({})", display_comma_separated(columns))?;
2846 }
2847 if !cluster_by.is_empty() {
2848 write!(f, " CLUSTER BY ({})", display_comma_separated(cluster_by))?;
2849 }
2850 if matches!(options, CreateTableOptions::Options(_)) {
2851 write!(f, " {options}")?;
2852 }
2853 write!(f, " AS {query}")?;
2854 if *with_no_schema_binding {
2855 write!(f, " WITH NO SCHEMA BINDING")?;
2856 }
2857 Ok(())
2858 }
2859 Statement::CreateTable {
2860 name,
2861 columns,
2862 constraints,
2863 table_properties,
2864 with_options,
2865 or_replace,
2866 if_not_exists,
2867 transient,
2868 hive_distribution,
2869 hive_formats,
2870 external,
2871 global,
2872 temporary,
2873 file_format,
2874 location,
2875 query,
2876 without_rowid,
2877 like,
2878 clone,
2879 default_charset,
2880 engine,
2881 comment,
2882 auto_increment_offset,
2883 collation,
2884 on_commit,
2885 on_cluster,
2886 order_by,
2887 partition_by,
2888 cluster_by,
2889 options,
2890 strict,
2891 } => {
2892 write!(
2900 f,
2901 "CREATE {or_replace}{external}{global}{temporary}{transient}TABLE {if_not_exists}{name}",
2902 or_replace = if *or_replace { "OR REPLACE " } else { "" },
2903 external = if *external { "EXTERNAL " } else { "" },
2904 global = global
2905 .map(|global| {
2906 if global {
2907 "GLOBAL "
2908 } else {
2909 "LOCAL "
2910 }
2911 })
2912 .unwrap_or(""),
2913 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
2914 temporary = if *temporary { "TEMPORARY " } else { "" },
2915 transient = if *transient { "TRANSIENT " } else { "" },
2916 name = name,
2917 )?;
2918 if let Some(on_cluster) = on_cluster {
2919 write!(
2920 f,
2921 " ON CLUSTER {}",
2922 on_cluster.replace('{', "'{").replace('}', "}'")
2923 )?;
2924 }
2925 if !columns.is_empty() || !constraints.is_empty() {
2926 write!(f, " ({}", display_comma_separated(columns))?;
2927 if !columns.is_empty() && !constraints.is_empty() {
2928 write!(f, ", ")?;
2929 }
2930 write!(f, "{})", display_comma_separated(constraints))?;
2931 } else if query.is_none() && like.is_none() && clone.is_none() {
2932 write!(f, " ()")?;
2934 }
2935 if *without_rowid {
2937 write!(f, " WITHOUT ROWID")?;
2938 }
2939
2940 if let Some(l) = like {
2942 write!(f, " LIKE {l}")?;
2943 }
2944
2945 if let Some(c) = clone {
2946 write!(f, " CLONE {c}")?;
2947 }
2948
2949 match hive_distribution {
2950 HiveDistributionStyle::PARTITIONED { columns } => {
2951 write!(f, " PARTITIONED BY ({})", display_comma_separated(columns))?;
2952 }
2953 HiveDistributionStyle::CLUSTERED {
2954 columns,
2955 sorted_by,
2956 num_buckets,
2957 } => {
2958 write!(f, " CLUSTERED BY ({})", display_comma_separated(columns))?;
2959 if !sorted_by.is_empty() {
2960 write!(f, " SORTED BY ({})", display_comma_separated(sorted_by))?;
2961 }
2962 if *num_buckets > 0 {
2963 write!(f, " INTO {num_buckets} BUCKETS")?;
2964 }
2965 }
2966 HiveDistributionStyle::SKEWED {
2967 columns,
2968 on,
2969 stored_as_directories,
2970 } => {
2971 write!(
2972 f,
2973 " SKEWED BY ({})) ON ({})",
2974 display_comma_separated(columns),
2975 display_comma_separated(on)
2976 )?;
2977 if *stored_as_directories {
2978 write!(f, " STORED AS DIRECTORIES")?;
2979 }
2980 }
2981 _ => (),
2982 }
2983
2984 if let Some(HiveFormat {
2985 row_format,
2986 storage,
2987 location,
2988 }) = hive_formats
2989 {
2990 match row_format {
2991 Some(HiveRowFormat::SERDE { class }) => {
2992 write!(f, " ROW FORMAT SERDE '{class}'")?
2993 }
2994 Some(HiveRowFormat::DELIMITED) => write!(f, " ROW FORMAT DELIMITED")?,
2995 None => (),
2996 }
2997 match storage {
2998 Some(HiveIOFormat::IOF {
2999 input_format,
3000 output_format,
3001 }) => write!(
3002 f,
3003 " STORED AS INPUTFORMAT {input_format} OUTPUTFORMAT {output_format}"
3004 )?,
3005 Some(HiveIOFormat::FileFormat { format }) if !*external => {
3006 write!(f, " STORED AS {format}")?
3007 }
3008 _ => (),
3009 }
3010 if !*external {
3011 if let Some(loc) = location {
3012 write!(f, " LOCATION '{loc}'")?;
3013 }
3014 }
3015 }
3016 if *external {
3017 write!(
3018 f,
3019 " STORED AS {} LOCATION '{}'",
3020 file_format.as_ref().unwrap(),
3021 location.as_ref().unwrap()
3022 )?;
3023 }
3024 if !table_properties.is_empty() {
3025 write!(
3026 f,
3027 " TBLPROPERTIES ({})",
3028 display_comma_separated(table_properties)
3029 )?;
3030 }
3031 if !with_options.is_empty() {
3032 write!(f, " WITH ({})", display_comma_separated(with_options))?;
3033 }
3034 if let Some(engine) = engine {
3035 write!(f, " ENGINE={engine}")?;
3036 }
3037 if let Some(comment) = comment {
3038 write!(f, " COMMENT '{comment}'")?;
3039 }
3040 if let Some(auto_increment_offset) = auto_increment_offset {
3041 write!(f, " AUTO_INCREMENT {auto_increment_offset}")?;
3042 }
3043 if let Some(order_by) = order_by {
3044 write!(f, " ORDER BY ({})", display_comma_separated(order_by))?;
3045 }
3046 if let Some(partition_by) = partition_by.as_ref() {
3047 write!(f, " PARTITION BY {partition_by}")?;
3048 }
3049 if let Some(cluster_by) = cluster_by.as_ref() {
3050 write!(
3051 f,
3052 " CLUSTER BY {}",
3053 display_comma_separated(cluster_by.as_slice())
3054 )?;
3055 }
3056 if let Some(options) = options.as_ref() {
3057 write!(
3058 f,
3059 " OPTIONS({})",
3060 display_comma_separated(options.as_slice())
3061 )?;
3062 }
3063 if let Some(query) = query {
3064 write!(f, " AS {query}")?;
3065 }
3066 if let Some(default_charset) = default_charset {
3067 write!(f, " DEFAULT CHARSET={default_charset}")?;
3068 }
3069 if let Some(collation) = collation {
3070 write!(f, " COLLATE={collation}")?;
3071 }
3072
3073 if on_commit.is_some() {
3074 let on_commit = match on_commit {
3075 Some(OnCommit::DeleteRows) => "ON COMMIT DELETE ROWS",
3076 Some(OnCommit::PreserveRows) => "ON COMMIT PRESERVE ROWS",
3077 Some(OnCommit::Drop) => "ON COMMIT DROP",
3078 None => "",
3079 };
3080 write!(f, " {on_commit}")?;
3081 }
3082 if *strict {
3083 write!(f, " STRICT")?;
3084 }
3085 Ok(())
3086 }
3087 Statement::CreateVirtualTable {
3088 name,
3089 if_not_exists,
3090 module_name,
3091 module_args,
3092 } => {
3093 write!(
3094 f,
3095 "CREATE VIRTUAL TABLE {if_not_exists}{name} USING {module_name}",
3096 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
3097 name = name,
3098 module_name = module_name
3099 )?;
3100 if !module_args.is_empty() {
3101 write!(f, " ({})", display_comma_separated(module_args))?;
3102 }
3103 Ok(())
3104 }
3105 Statement::CreateIndex {
3106 name,
3107 table_name,
3108 using,
3109 columns,
3110 unique,
3111 concurrently,
3112 if_not_exists,
3113 include,
3114 nulls_distinct,
3115 predicate,
3116 } => {
3117 write!(
3118 f,
3119 "CREATE {unique}INDEX {concurrently}{if_not_exists}",
3120 unique = if *unique { "UNIQUE " } else { "" },
3121 concurrently = if *concurrently { "CONCURRENTLY " } else { "" },
3122 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
3123 )?;
3124 if let Some(value) = name {
3125 write!(f, "{value} ")?;
3126 }
3127 write!(f, "ON {table_name}")?;
3128 if let Some(value) = using {
3129 write!(f, " USING {value} ")?;
3130 }
3131 write!(f, "({})", display_separated(columns, ","))?;
3132 if !include.is_empty() {
3133 write!(f, " INCLUDE ({})", display_separated(include, ","))?;
3134 }
3135 if let Some(value) = nulls_distinct {
3136 if *value {
3137 write!(f, " NULLS DISTINCT")?;
3138 } else {
3139 write!(f, " NULLS NOT DISTINCT")?;
3140 }
3141 }
3142 if let Some(predicate) = predicate {
3143 write!(f, " WHERE {predicate}")?;
3144 }
3145 Ok(())
3146 }
3147 Statement::CreateExtension {
3148 name,
3149 if_not_exists,
3150 cascade,
3151 schema,
3152 version,
3153 } => {
3154 write!(
3155 f,
3156 "CREATE EXTENSION {if_not_exists}{name}",
3157 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" }
3158 )?;
3159 if *cascade || schema.is_some() || version.is_some() {
3160 write!(f, " WITH")?;
3161
3162 if let Some(name) = schema {
3163 write!(f, " SCHEMA {name}")?;
3164 }
3165 if let Some(version) = version {
3166 write!(f, " VERSION {version}")?;
3167 }
3168 if *cascade {
3169 write!(f, " CASCADE")?;
3170 }
3171 }
3172
3173 Ok(())
3174 }
3175 Statement::CreateRole {
3176 names,
3177 if_not_exists,
3178 inherit,
3179 login,
3180 bypassrls,
3181 password,
3182 create_db,
3183 create_role,
3184 superuser,
3185 replication,
3186 connection_limit,
3187 valid_until,
3188 in_role,
3189 in_group,
3190 role,
3191 user,
3192 admin,
3193 authorization_owner,
3194 } => {
3195 write!(
3196 f,
3197 "CREATE ROLE {if_not_exists}{names}{superuser}{create_db}{create_role}{inherit}{login}{replication}{bypassrls}",
3198 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
3199 names = display_separated(names, ", "),
3200 superuser = match *superuser {
3201 Some(true) => " SUPERUSER",
3202 Some(false) => " NOSUPERUSER",
3203 None => ""
3204 },
3205 create_db = match *create_db {
3206 Some(true) => " CREATEDB",
3207 Some(false) => " NOCREATEDB",
3208 None => ""
3209 },
3210 create_role = match *create_role {
3211 Some(true) => " CREATEROLE",
3212 Some(false) => " NOCREATEROLE",
3213 None => ""
3214 },
3215 inherit = match *inherit {
3216 Some(true) => " INHERIT",
3217 Some(false) => " NOINHERIT",
3218 None => ""
3219 },
3220 login = match *login {
3221 Some(true) => " LOGIN",
3222 Some(false) => " NOLOGIN",
3223 None => ""
3224 },
3225 replication = match *replication {
3226 Some(true) => " REPLICATION",
3227 Some(false) => " NOREPLICATION",
3228 None => ""
3229 },
3230 bypassrls = match *bypassrls {
3231 Some(true) => " BYPASSRLS",
3232 Some(false) => " NOBYPASSRLS",
3233 None => ""
3234 }
3235 )?;
3236 if let Some(limit) = connection_limit {
3237 write!(f, " CONNECTION LIMIT {limit}")?;
3238 }
3239 match password {
3240 Some(Password::Password(pass)) => write!(f, " PASSWORD {pass}"),
3241 Some(Password::NullPassword) => write!(f, " PASSWORD NULL"),
3242 None => Ok(()),
3243 }?;
3244 if let Some(until) = valid_until {
3245 write!(f, " VALID UNTIL {until}")?;
3246 }
3247 if !in_role.is_empty() {
3248 write!(f, " IN ROLE {}", display_comma_separated(in_role))?;
3249 }
3250 if !in_group.is_empty() {
3251 write!(f, " IN GROUP {}", display_comma_separated(in_group))?;
3252 }
3253 if !role.is_empty() {
3254 write!(f, " ROLE {}", display_comma_separated(role))?;
3255 }
3256 if !user.is_empty() {
3257 write!(f, " USER {}", display_comma_separated(user))?;
3258 }
3259 if !admin.is_empty() {
3260 write!(f, " ADMIN {}", display_comma_separated(admin))?;
3261 }
3262 if let Some(owner) = authorization_owner {
3263 write!(f, " AUTHORIZATION {owner}")?;
3264 }
3265 Ok(())
3266 }
3267 Statement::AlterTable {
3268 name,
3269 if_exists,
3270 only,
3271 operations,
3272 } => {
3273 write!(f, "ALTER TABLE ")?;
3274 if *if_exists {
3275 write!(f, "IF EXISTS ")?;
3276 }
3277 if *only {
3278 write!(f, "ONLY ")?;
3279 }
3280 write!(
3281 f,
3282 "{name} {operations}",
3283 operations = display_comma_separated(operations)
3284 )
3285 }
3286 Statement::AlterIndex { name, operation } => {
3287 write!(f, "ALTER INDEX {name} {operation}")
3288 }
3289 Statement::AlterView {
3290 name,
3291 columns,
3292 query,
3293 with_options,
3294 } => {
3295 write!(f, "ALTER VIEW {name}")?;
3296 if !with_options.is_empty() {
3297 write!(f, " WITH ({})", display_comma_separated(with_options))?;
3298 }
3299 if !columns.is_empty() {
3300 write!(f, " ({})", display_comma_separated(columns))?;
3301 }
3302 write!(f, " AS {query}")
3303 }
3304 Statement::AlterRole { name, operation } => {
3305 write!(f, "ALTER ROLE {name} {operation}")
3306 }
3307 Statement::Drop {
3308 object_type,
3309 if_exists,
3310 names,
3311 cascade,
3312 restrict,
3313 purge,
3314 temporary,
3315 } => write!(
3316 f,
3317 "DROP {}{}{} {}{}{}{}",
3318 if *temporary { "TEMPORARY " } else { "" },
3319 object_type,
3320 if *if_exists { " IF EXISTS" } else { "" },
3321 display_comma_separated(names),
3322 if *cascade { " CASCADE" } else { "" },
3323 if *restrict { " RESTRICT" } else { "" },
3324 if *purge { " PURGE" } else { "" }
3325 ),
3326 Statement::DropFunction {
3327 if_exists,
3328 func_desc,
3329 option,
3330 } => {
3331 write!(
3332 f,
3333 "DROP FUNCTION{} {}",
3334 if *if_exists { " IF EXISTS" } else { "" },
3335 display_comma_separated(func_desc),
3336 )?;
3337 if let Some(op) = option {
3338 write!(f, " {op}")?;
3339 }
3340 Ok(())
3341 }
3342 Statement::Discard { object_type } => {
3343 write!(f, "DISCARD {object_type}")?;
3344 Ok(())
3345 }
3346 Self::SetRole {
3347 context_modifier,
3348 role_name,
3349 } => {
3350 let role_name = role_name.clone().unwrap_or_else(|| Ident::new("NONE"));
3351 write!(f, "SET{context_modifier} ROLE {role_name}")
3352 }
3353 Statement::SetVariable {
3354 local,
3355 variable,
3356 hivevar,
3357 value,
3358 } => {
3359 f.write_str("SET ")?;
3360 if *local {
3361 f.write_str("LOCAL ")?;
3362 }
3363 write!(
3364 f,
3365 "{hivevar}{name} = {value}",
3366 hivevar = if *hivevar { "HIVEVAR:" } else { "" },
3367 name = variable,
3368 value = display_comma_separated(value)
3369 )
3370 }
3371 Statement::SetTimeZone { local, value } => {
3372 f.write_str("SET ")?;
3373 if *local {
3374 f.write_str("LOCAL ")?;
3375 }
3376 write!(f, "TIME ZONE {value}")
3377 }
3378 Statement::SetNames {
3379 charset_name,
3380 collation_name,
3381 } => {
3382 f.write_str("SET NAMES ")?;
3383 f.write_str(charset_name)?;
3384
3385 if let Some(collation) = collation_name {
3386 f.write_str(" COLLATE ")?;
3387 f.write_str(collation)?;
3388 };
3389
3390 Ok(())
3391 }
3392 Statement::SetNamesDefault {} => {
3393 f.write_str("SET NAMES DEFAULT")?;
3394
3395 Ok(())
3396 }
3397 Statement::ShowVariable { variable } => {
3398 write!(f, "SHOW")?;
3399 if !variable.is_empty() {
3400 write!(f, " {}", display_separated(variable, " "))?;
3401 }
3402 Ok(())
3403 }
3404 Statement::ShowVariables {
3405 filter,
3406 global,
3407 session,
3408 } => {
3409 write!(f, "SHOW")?;
3410 if *global {
3411 write!(f, " GLOBAL")?;
3412 }
3413 if *session {
3414 write!(f, " SESSION")?;
3415 }
3416 write!(f, " VARIABLES")?;
3417 if filter.is_some() {
3418 write!(f, " {}", filter.as_ref().unwrap())?;
3419 }
3420 Ok(())
3421 }
3422 Statement::ShowCreate { obj_type, obj_name } => {
3423 write!(f, "SHOW CREATE {obj_type} {obj_name}",)?;
3424 Ok(())
3425 }
3426 Statement::ShowColumns {
3427 extended,
3428 full,
3429 table_name,
3430 filter,
3431 } => {
3432 write!(
3433 f,
3434 "SHOW {extended}{full}COLUMNS FROM {table_name}",
3435 extended = if *extended { "EXTENDED " } else { "" },
3436 full = if *full { "FULL " } else { "" },
3437 table_name = table_name,
3438 )?;
3439 if let Some(filter) = filter {
3440 write!(f, " {filter}")?;
3441 }
3442 Ok(())
3443 }
3444 Statement::ShowTables {
3445 extended,
3446 full,
3447 db_name,
3448 filter,
3449 } => {
3450 write!(
3451 f,
3452 "SHOW {extended}{full}TABLES",
3453 extended = if *extended { "EXTENDED " } else { "" },
3454 full = if *full { "FULL " } else { "" },
3455 )?;
3456 if let Some(db_name) = db_name {
3457 write!(f, " FROM {db_name}")?;
3458 }
3459 if let Some(filter) = filter {
3460 write!(f, " {filter}")?;
3461 }
3462 Ok(())
3463 }
3464 Statement::ShowFunctions { filter } => {
3465 write!(f, "SHOW FUNCTIONS")?;
3466 if let Some(filter) = filter {
3467 write!(f, " {filter}")?;
3468 }
3469 Ok(())
3470 }
3471 Statement::Use { db_name } => {
3472 write!(f, "USE {db_name}")?;
3473 Ok(())
3474 }
3475 Statement::ShowCollation { filter } => {
3476 write!(f, "SHOW COLLATION")?;
3477 if let Some(filter) = filter {
3478 write!(f, " {filter}")?;
3479 }
3480 Ok(())
3481 }
3482 Statement::StartTransaction {
3483 modes,
3484 begin: syntax_begin,
3485 modifier,
3486 } => {
3487 if *syntax_begin {
3488 if let Some(modifier) = *modifier {
3489 write!(f, "BEGIN {} TRANSACTION", modifier)?;
3490 } else {
3491 write!(f, "BEGIN TRANSACTION")?;
3492 }
3493 } else {
3494 write!(f, "START TRANSACTION")?;
3495 }
3496 if !modes.is_empty() {
3497 write!(f, " {}", display_comma_separated(modes))?;
3498 }
3499 Ok(())
3500 }
3501 Statement::SetTransaction {
3502 modes,
3503 snapshot,
3504 session,
3505 } => {
3506 if *session {
3507 write!(f, "SET SESSION CHARACTERISTICS AS TRANSACTION")?;
3508 } else {
3509 write!(f, "SET TRANSACTION")?;
3510 }
3511 if !modes.is_empty() {
3512 write!(f, " {}", display_comma_separated(modes))?;
3513 }
3514 if let Some(snapshot_id) = snapshot {
3515 write!(f, " SNAPSHOT {snapshot_id}")?;
3516 }
3517 Ok(())
3518 }
3519 Statement::Commit { chain } => {
3520 write!(f, "COMMIT{}", if *chain { " AND CHAIN" } else { "" },)
3521 }
3522 Statement::Rollback { chain, savepoint } => {
3523 write!(f, "ROLLBACK")?;
3524
3525 if *chain {
3526 write!(f, " AND CHAIN")?;
3527 }
3528
3529 if let Some(savepoint) = savepoint {
3530 write!(f, " TO SAVEPOINT {savepoint}")?;
3531 }
3532
3533 Ok(())
3534 }
3535 Statement::CreateSchema {
3536 schema_name,
3537 if_not_exists,
3538 } => write!(
3539 f,
3540 "CREATE SCHEMA {if_not_exists}{name}",
3541 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
3542 name = schema_name
3543 ),
3544 Statement::Assert { condition, message } => {
3545 write!(f, "ASSERT {condition}")?;
3546 if let Some(m) = message {
3547 write!(f, " AS {m}")?;
3548 }
3549 Ok(())
3550 }
3551 Statement::Grant {
3552 privileges,
3553 objects,
3554 grantees,
3555 with_grant_option,
3556 granted_by,
3557 } => {
3558 write!(f, "GRANT {privileges} ")?;
3559 write!(f, "ON {objects} ")?;
3560 write!(f, "TO {}", display_comma_separated(grantees))?;
3561 if *with_grant_option {
3562 write!(f, " WITH GRANT OPTION")?;
3563 }
3564 if let Some(grantor) = granted_by {
3565 write!(f, " GRANTED BY {grantor}")?;
3566 }
3567 Ok(())
3568 }
3569 Statement::Revoke {
3570 privileges,
3571 objects,
3572 grantees,
3573 granted_by,
3574 cascade,
3575 } => {
3576 write!(f, "REVOKE {privileges} ")?;
3577 write!(f, "ON {objects} ")?;
3578 write!(f, "FROM {}", display_comma_separated(grantees))?;
3579 if let Some(grantor) = granted_by {
3580 write!(f, " GRANTED BY {grantor}")?;
3581 }
3582 write!(f, " {}", if *cascade { "CASCADE" } else { "RESTRICT" })?;
3583 Ok(())
3584 }
3585 Statement::Deallocate { name, prepare } => write!(
3586 f,
3587 "DEALLOCATE {prepare}{name}",
3588 prepare = if *prepare { "PREPARE " } else { "" },
3589 name = name,
3590 ),
3591 Statement::Execute { name, parameters } => {
3592 write!(f, "EXECUTE {name}")?;
3593 if !parameters.is_empty() {
3594 write!(f, "({})", display_comma_separated(parameters))?;
3595 }
3596 Ok(())
3597 }
3598 Statement::Prepare {
3599 name,
3600 data_types,
3601 statement,
3602 } => {
3603 write!(f, "PREPARE {name} ")?;
3604 if !data_types.is_empty() {
3605 write!(f, "({}) ", display_comma_separated(data_types))?;
3606 }
3607 write!(f, "AS {statement}")
3608 }
3609 Statement::Comment {
3610 object_type,
3611 object_name,
3612 comment,
3613 if_exists,
3614 } => {
3615 write!(f, "COMMENT ")?;
3616 if *if_exists {
3617 write!(f, "IF EXISTS ")?
3618 };
3619 write!(f, "ON {object_type} {object_name} IS ")?;
3620 if let Some(c) = comment {
3621 write!(f, "'{c}'")
3622 } else {
3623 write!(f, "NULL")
3624 }
3625 }
3626 Statement::Savepoint { name } => {
3627 write!(f, "SAVEPOINT ")?;
3628 write!(f, "{name}")
3629 }
3630 Statement::ReleaseSavepoint { name } => {
3631 write!(f, "RELEASE SAVEPOINT {name}")
3632 }
3633 Statement::Merge {
3634 into,
3635 table,
3636 source,
3637 on,
3638 clauses,
3639 } => {
3640 write!(
3641 f,
3642 "MERGE{int} {table} USING {source} ",
3643 int = if *into { " INTO" } else { "" }
3644 )?;
3645 write!(f, "ON {on} ")?;
3646 write!(f, "{}", display_separated(clauses, " "))
3647 }
3648 Statement::Cache {
3649 table_name,
3650 table_flag,
3651 has_as,
3652 options,
3653 query,
3654 } => {
3655 if table_flag.is_some() {
3656 write!(
3657 f,
3658 "CACHE {table_flag} TABLE {table_name}",
3659 table_flag = table_flag.clone().unwrap(),
3660 table_name = table_name,
3661 )?;
3662 } else {
3663 write!(f, "CACHE TABLE {table_name}",)?;
3664 }
3665
3666 if !options.is_empty() {
3667 write!(f, " OPTIONS({})", display_comma_separated(options))?;
3668 }
3669
3670 let has_query = query.is_some();
3671 if *has_as && has_query {
3672 write!(f, " AS {query}", query = query.clone().unwrap())
3673 } else if !has_as && has_query {
3674 write!(f, " {query}", query = query.clone().unwrap())
3675 } else if *has_as && !has_query {
3676 write!(f, " AS")
3677 } else {
3678 Ok(())
3679 }
3680 }
3681 Statement::UNCache {
3682 table_name,
3683 if_exists,
3684 } => {
3685 if *if_exists {
3686 write!(f, "UNCACHE TABLE IF EXISTS {table_name}")
3687 } else {
3688 write!(f, "UNCACHE TABLE {table_name}")
3689 }
3690 }
3691 Statement::CreateSequence {
3692 temporary,
3693 if_not_exists,
3694 name,
3695 data_type,
3696 sequence_options,
3697 owned_by,
3698 } => {
3699 let as_type: String = if let Some(dt) = data_type.as_ref() {
3700 [" AS ", &dt.to_string()].concat()
3703 } else {
3704 "".to_string()
3705 };
3706 write!(
3707 f,
3708 "CREATE {temporary}SEQUENCE {if_not_exists}{name}{as_type}",
3709 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
3710 temporary = if *temporary { "TEMPORARY " } else { "" },
3711 name = name,
3712 as_type = as_type
3713 )?;
3714 for sequence_option in sequence_options {
3715 write!(f, "{sequence_option}")?;
3716 }
3717 if let Some(ob) = owned_by.as_ref() {
3718 write!(f, " OWNED BY {ob}")?;
3719 }
3720 write!(f, "")
3721 }
3722 Statement::CreateStage {
3723 or_replace,
3724 temporary,
3725 if_not_exists,
3726 name,
3727 stage_params,
3728 directory_table_params,
3729 file_format,
3730 copy_options,
3731 comment,
3732 ..
3733 } => {
3734 write!(
3735 f,
3736 "CREATE {or_replace}{temp}STAGE {if_not_exists}{name}{stage_params}",
3737 temp = if *temporary { "TEMPORARY " } else { "" },
3738 or_replace = if *or_replace { "OR REPLACE " } else { "" },
3739 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
3740 )?;
3741 if !directory_table_params.options.is_empty() {
3742 write!(f, " DIRECTORY=({})", directory_table_params)?;
3743 }
3744 if !file_format.options.is_empty() {
3745 write!(f, " FILE_FORMAT=({})", file_format)?;
3746 }
3747 if !copy_options.options.is_empty() {
3748 write!(f, " COPY_OPTIONS=({})", copy_options)?;
3749 }
3750 if comment.is_some() {
3751 write!(f, " COMMENT='{}'", comment.as_ref().unwrap())?;
3752 }
3753 Ok(())
3754 }
3755 Statement::CopyIntoSnowflake {
3756 into,
3757 from_stage,
3758 from_stage_alias,
3759 stage_params,
3760 from_transformations,
3761 files,
3762 pattern,
3763 file_format,
3764 copy_options,
3765 validation_mode,
3766 } => {
3767 write!(f, "COPY INTO {}", into)?;
3768 if from_transformations.is_none() {
3769 write!(f, " FROM {}{}", from_stage, stage_params)?;
3771 if from_stage_alias.as_ref().is_some() {
3772 write!(f, " AS {}", from_stage_alias.as_ref().unwrap())?;
3773 }
3774 } else {
3775 write!(
3777 f,
3778 " FROM (SELECT {} FROM {}{}",
3779 display_separated(from_transformations.as_ref().unwrap(), ", "),
3780 from_stage,
3781 stage_params,
3782 )?;
3783 if from_stage_alias.as_ref().is_some() {
3784 write!(f, " AS {}", from_stage_alias.as_ref().unwrap())?;
3785 }
3786 write!(f, ")")?;
3787 }
3788 if files.is_some() {
3789 write!(
3790 f,
3791 " FILES = ('{}')",
3792 display_separated(files.as_ref().unwrap(), "', '")
3793 )?;
3794 }
3795 if pattern.is_some() {
3796 write!(f, " PATTERN = '{}'", pattern.as_ref().unwrap())?;
3797 }
3798 if !file_format.options.is_empty() {
3799 write!(f, " FILE_FORMAT=({})", file_format)?;
3800 }
3801 if !copy_options.options.is_empty() {
3802 write!(f, " COPY_OPTIONS=({})", copy_options)?;
3803 }
3804 if validation_mode.is_some() {
3805 write!(
3806 f,
3807 " VALIDATION_MODE = {}",
3808 validation_mode.as_ref().unwrap()
3809 )?;
3810 }
3811 Ok(())
3812 }
3813 Statement::CreateType {
3814 name,
3815 representation,
3816 } => {
3817 write!(f, "CREATE TYPE {name} AS {representation}")
3818 }
3819 Statement::Pragma { name, value, is_eq } => {
3820 write!(f, "PRAGMA {name}")?;
3821 if value.is_some() {
3822 let val = value.as_ref().unwrap();
3823 if *is_eq {
3824 write!(f, " = {val}")?;
3825 } else {
3826 write!(f, "({val})")?;
3827 }
3828 }
3829 Ok(())
3830 }
3831 Statement::LockTables { tables } => {
3832 write!(f, "LOCK TABLES {}", display_comma_separated(tables))
3833 }
3834 Statement::UnlockTables => {
3835 write!(f, "UNLOCK TABLES")
3836 }
3837 }
3838 }
3839}
3840
3841#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3848#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3849#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3850pub enum SequenceOptions {
3851 IncrementBy(Expr, bool),
3852 MinValue(Option<Expr>),
3853 MaxValue(Option<Expr>),
3854 StartWith(Expr, bool),
3855 Cache(Expr),
3856 Cycle(bool),
3857}
3858
3859impl fmt::Display for SequenceOptions {
3860 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3861 match self {
3862 SequenceOptions::IncrementBy(increment, by) => {
3863 write!(
3864 f,
3865 " INCREMENT{by} {increment}",
3866 by = if *by { " BY" } else { "" },
3867 increment = increment
3868 )
3869 }
3870 SequenceOptions::MinValue(Some(expr)) => {
3871 write!(f, " MINVALUE {expr}")
3872 }
3873 SequenceOptions::MinValue(None) => {
3874 write!(f, " NO MINVALUE")
3875 }
3876 SequenceOptions::MaxValue(Some(expr)) => {
3877 write!(f, " MAXVALUE {expr}")
3878 }
3879 SequenceOptions::MaxValue(None) => {
3880 write!(f, " NO MAXVALUE")
3881 }
3882 SequenceOptions::StartWith(start, with) => {
3883 write!(
3884 f,
3885 " START{with} {start}",
3886 with = if *with { " WITH" } else { "" },
3887 start = start
3888 )
3889 }
3890 SequenceOptions::Cache(cache) => {
3891 write!(f, " CACHE {}", *cache)
3892 }
3893 SequenceOptions::Cycle(no) => {
3894 write!(f, " {}CYCLE", if *no { "NO " } else { "" })
3895 }
3896 }
3897 }
3898}
3899
3900#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3903#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3904#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3905pub enum MinMaxValue {
3906 Empty,
3908 None,
3910 Some(Expr),
3912}
3913
3914#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3915#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3916#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3917#[non_exhaustive]
3918pub enum OnInsert {
3919 DuplicateKeyUpdate(Vec<Assignment>),
3921 OnConflict(OnConflict),
3923}
3924
3925#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3926#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3927#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3928pub struct OnConflict {
3929 pub conflict_target: Option<ConflictTarget>,
3930 pub action: OnConflictAction,
3931}
3932#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3933#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3934#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3935pub enum ConflictTarget {
3936 Columns(Vec<Ident>),
3937 OnConstraint(ObjectName),
3938}
3939#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3940#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3941#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3942pub enum OnConflictAction {
3943 DoNothing,
3944 DoUpdate(DoUpdate),
3945}
3946
3947#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3948#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3949#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3950pub struct DoUpdate {
3951 pub assignments: Vec<Assignment>,
3953 pub selection: Option<Expr>,
3955}
3956
3957impl fmt::Display for OnInsert {
3958 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3959 match self {
3960 Self::DuplicateKeyUpdate(expr) => write!(
3961 f,
3962 " ON DUPLICATE KEY UPDATE {}",
3963 display_comma_separated(expr)
3964 ),
3965 Self::OnConflict(o) => write!(f, "{o}"),
3966 }
3967 }
3968}
3969impl fmt::Display for OnConflict {
3970 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3971 write!(f, " ON CONFLICT")?;
3972 if let Some(target) = &self.conflict_target {
3973 write!(f, "{target}")?;
3974 }
3975 write!(f, " {}", self.action)
3976 }
3977}
3978impl fmt::Display for ConflictTarget {
3979 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3980 match self {
3981 ConflictTarget::Columns(cols) => write!(f, "({})", display_comma_separated(cols)),
3982 ConflictTarget::OnConstraint(name) => write!(f, " ON CONSTRAINT {name}"),
3983 }
3984 }
3985}
3986impl fmt::Display for OnConflictAction {
3987 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3988 match self {
3989 Self::DoNothing => write!(f, "DO NOTHING"),
3990 Self::DoUpdate(do_update) => {
3991 write!(f, "DO UPDATE")?;
3992 if !do_update.assignments.is_empty() {
3993 write!(
3994 f,
3995 " SET {}",
3996 display_comma_separated(&do_update.assignments)
3997 )?;
3998 }
3999 if let Some(selection) = &do_update.selection {
4000 write!(f, " WHERE {selection}")?;
4001 }
4002 Ok(())
4003 }
4004 }
4005 }
4006}
4007
4008#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4010#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4011#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4012pub enum Privileges {
4013 All {
4015 with_privileges_keyword: bool,
4017 },
4018 Actions(Vec<Action>),
4020}
4021
4022impl fmt::Display for Privileges {
4023 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4024 match self {
4025 Privileges::All {
4026 with_privileges_keyword,
4027 } => {
4028 write!(
4029 f,
4030 "ALL{}",
4031 if *with_privileges_keyword {
4032 " PRIVILEGES"
4033 } else {
4034 ""
4035 }
4036 )
4037 }
4038 Privileges::Actions(actions) => {
4039 write!(f, "{}", display_comma_separated(actions))
4040 }
4041 }
4042 }
4043}
4044
4045#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4047#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4048#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4049pub enum FetchDirection {
4050 Count { limit: Value },
4051 Next,
4052 Prior,
4053 First,
4054 Last,
4055 Absolute { limit: Value },
4056 Relative { limit: Value },
4057 All,
4058 Forward { limit: Option<Value> },
4061 ForwardAll,
4062 Backward { limit: Option<Value> },
4065 BackwardAll,
4066}
4067
4068impl fmt::Display for FetchDirection {
4069 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4070 match self {
4071 FetchDirection::Count { limit } => f.write_str(&limit.to_string())?,
4072 FetchDirection::Next => f.write_str("NEXT")?,
4073 FetchDirection::Prior => f.write_str("PRIOR")?,
4074 FetchDirection::First => f.write_str("FIRST")?,
4075 FetchDirection::Last => f.write_str("LAST")?,
4076 FetchDirection::Absolute { limit } => {
4077 f.write_str("ABSOLUTE ")?;
4078 f.write_str(&limit.to_string())?;
4079 }
4080 FetchDirection::Relative { limit } => {
4081 f.write_str("RELATIVE ")?;
4082 f.write_str(&limit.to_string())?;
4083 }
4084 FetchDirection::All => f.write_str("ALL")?,
4085 FetchDirection::Forward { limit } => {
4086 f.write_str("FORWARD")?;
4087
4088 if let Some(l) = limit {
4089 f.write_str(" ")?;
4090 f.write_str(&l.to_string())?;
4091 }
4092 }
4093 FetchDirection::ForwardAll => f.write_str("FORWARD ALL")?,
4094 FetchDirection::Backward { limit } => {
4095 f.write_str("BACKWARD")?;
4096
4097 if let Some(l) = limit {
4098 f.write_str(" ")?;
4099 f.write_str(&l.to_string())?;
4100 }
4101 }
4102 FetchDirection::BackwardAll => f.write_str("BACKWARD ALL")?,
4103 };
4104
4105 Ok(())
4106 }
4107}
4108
4109#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4111#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4112#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4113pub enum Action {
4114 Connect,
4115 Create,
4116 Delete,
4117 Execute,
4118 Insert { columns: Option<Vec<Ident>> },
4119 References { columns: Option<Vec<Ident>> },
4120 Select { columns: Option<Vec<Ident>> },
4121 Temporary,
4122 Trigger,
4123 Truncate,
4124 Update { columns: Option<Vec<Ident>> },
4125 Usage,
4126}
4127
4128impl fmt::Display for Action {
4129 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4130 match self {
4131 Action::Connect => f.write_str("CONNECT")?,
4132 Action::Create => f.write_str("CREATE")?,
4133 Action::Delete => f.write_str("DELETE")?,
4134 Action::Execute => f.write_str("EXECUTE")?,
4135 Action::Insert { .. } => f.write_str("INSERT")?,
4136 Action::References { .. } => f.write_str("REFERENCES")?,
4137 Action::Select { .. } => f.write_str("SELECT")?,
4138 Action::Temporary => f.write_str("TEMPORARY")?,
4139 Action::Trigger => f.write_str("TRIGGER")?,
4140 Action::Truncate => f.write_str("TRUNCATE")?,
4141 Action::Update { .. } => f.write_str("UPDATE")?,
4142 Action::Usage => f.write_str("USAGE")?,
4143 };
4144 match self {
4145 Action::Insert { columns }
4146 | Action::References { columns }
4147 | Action::Select { columns }
4148 | Action::Update { columns } => {
4149 if let Some(columns) = columns {
4150 write!(f, " ({})", display_comma_separated(columns))?;
4151 }
4152 }
4153 _ => (),
4154 };
4155 Ok(())
4156 }
4157}
4158
4159#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4161#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4162#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4163pub enum GrantObjects {
4164 AllSequencesInSchema { schemas: Vec<ObjectName> },
4166 AllTablesInSchema { schemas: Vec<ObjectName> },
4168 Schemas(Vec<ObjectName>),
4170 Sequences(Vec<ObjectName>),
4172 Tables(Vec<ObjectName>),
4174}
4175
4176impl fmt::Display for GrantObjects {
4177 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4178 match self {
4179 GrantObjects::Sequences(sequences) => {
4180 write!(f, "SEQUENCE {}", display_comma_separated(sequences))
4181 }
4182 GrantObjects::Schemas(schemas) => {
4183 write!(f, "SCHEMA {}", display_comma_separated(schemas))
4184 }
4185 GrantObjects::Tables(tables) => {
4186 write!(f, "{}", display_comma_separated(tables))
4187 }
4188 GrantObjects::AllSequencesInSchema { schemas } => {
4189 write!(
4190 f,
4191 "ALL SEQUENCES IN SCHEMA {}",
4192 display_comma_separated(schemas)
4193 )
4194 }
4195 GrantObjects::AllTablesInSchema { schemas } => {
4196 write!(
4197 f,
4198 "ALL TABLES IN SCHEMA {}",
4199 display_comma_separated(schemas)
4200 )
4201 }
4202 }
4203 }
4204}
4205
4206#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4208#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4209#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4210pub struct Assignment {
4211 pub id: Vec<Ident>,
4212 pub value: Expr,
4213}
4214
4215impl fmt::Display for Assignment {
4216 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4217 write!(f, "{} = {}", display_separated(&self.id, "."), self.value)
4218 }
4219}
4220
4221#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4222#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4223#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4224pub enum FunctionArgExpr {
4225 Expr(Expr),
4226 QualifiedWildcard(ObjectName),
4228 Wildcard,
4230}
4231
4232impl From<Expr> for FunctionArgExpr {
4233 fn from(wildcard_expr: Expr) -> Self {
4234 match wildcard_expr {
4235 Expr::QualifiedWildcard(prefix) => Self::QualifiedWildcard(prefix),
4236 Expr::Wildcard => Self::Wildcard,
4237 expr => Self::Expr(expr),
4238 }
4239 }
4240}
4241
4242impl fmt::Display for FunctionArgExpr {
4243 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4244 match self {
4245 FunctionArgExpr::Expr(expr) => write!(f, "{expr}"),
4246 FunctionArgExpr::QualifiedWildcard(prefix) => write!(f, "{prefix}.*"),
4247 FunctionArgExpr::Wildcard => f.write_str("*"),
4248 }
4249 }
4250}
4251
4252#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4253#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4254#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4255pub enum FunctionArg {
4256 Named { name: Ident, arg: FunctionArgExpr },
4257 Unnamed(FunctionArgExpr),
4258}
4259
4260impl fmt::Display for FunctionArg {
4261 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4262 match self {
4263 FunctionArg::Named { name, arg } => write!(f, "{name} => {arg}"),
4264 FunctionArg::Unnamed(unnamed_arg) => write!(f, "{unnamed_arg}"),
4265 }
4266 }
4267}
4268
4269#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4270#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4271#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4272pub enum CloseCursor {
4273 All,
4274 Specific { name: Ident },
4275}
4276
4277impl fmt::Display for CloseCursor {
4278 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4279 match self {
4280 CloseCursor::All => write!(f, "ALL"),
4281 CloseCursor::Specific { name } => write!(f, "{name}"),
4282 }
4283 }
4284}
4285
4286#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4288#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4289#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4290pub struct Function {
4291 pub name: ObjectName,
4292 pub args: Vec<FunctionArg>,
4293 pub filter: Option<Box<Expr>>,
4295 pub null_treatment: Option<NullTreatment>,
4297 pub over: Option<WindowType>,
4298 pub distinct: bool,
4300 pub special: bool,
4303 pub order_by: Vec<OrderByExpr>,
4305}
4306
4307#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4308#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4309#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4310pub enum AnalyzeFormat {
4311 TEXT,
4312 GRAPHVIZ,
4313 JSON,
4314}
4315
4316impl fmt::Display for AnalyzeFormat {
4317 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4318 f.write_str(match self {
4319 AnalyzeFormat::TEXT => "TEXT",
4320 AnalyzeFormat::GRAPHVIZ => "GRAPHVIZ",
4321 AnalyzeFormat::JSON => "JSON",
4322 })
4323 }
4324}
4325
4326impl fmt::Display for Function {
4327 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4328 if self.special {
4329 write!(f, "{}", self.name)?;
4330 } else {
4331 let order_by = if !self.order_by.is_empty() {
4332 " ORDER BY "
4333 } else {
4334 ""
4335 };
4336 write!(
4337 f,
4338 "{}({}{}{order_by}{})",
4339 self.name,
4340 if self.distinct { "DISTINCT " } else { "" },
4341 display_comma_separated(&self.args),
4342 display_comma_separated(&self.order_by),
4343 )?;
4344
4345 if let Some(filter_cond) = &self.filter {
4346 write!(f, " FILTER (WHERE {filter_cond})")?;
4347 }
4348
4349 if let Some(o) = &self.null_treatment {
4350 write!(f, " {o}")?;
4351 }
4352
4353 if let Some(o) = &self.over {
4354 write!(f, " OVER {o}")?;
4355 }
4356 }
4357
4358 Ok(())
4359 }
4360}
4361
4362#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4364#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4365#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4366pub enum FileFormat {
4367 TEXTFILE,
4368 SEQUENCEFILE,
4369 ORC,
4370 PARQUET,
4371 AVRO,
4372 RCFILE,
4373 JSONFILE,
4374}
4375
4376impl fmt::Display for FileFormat {
4377 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4378 use self::FileFormat::*;
4379 f.write_str(match self {
4380 TEXTFILE => "TEXTFILE",
4381 SEQUENCEFILE => "SEQUENCEFILE",
4382 ORC => "ORC",
4383 PARQUET => "PARQUET",
4384 AVRO => "AVRO",
4385 RCFILE => "RCFILE",
4386 JSONFILE => "JSONFILE",
4387 })
4388 }
4389}
4390
4391#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4394#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4395#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4396pub struct ListAgg {
4397 pub distinct: bool,
4398 pub expr: Box<Expr>,
4399 pub separator: Option<Box<Expr>>,
4400 pub on_overflow: Option<ListAggOnOverflow>,
4401 pub within_group: Vec<OrderByExpr>,
4402}
4403
4404impl fmt::Display for ListAgg {
4405 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4406 write!(
4407 f,
4408 "LISTAGG({}{}",
4409 if self.distinct { "DISTINCT " } else { "" },
4410 self.expr
4411 )?;
4412 if let Some(separator) = &self.separator {
4413 write!(f, ", {separator}")?;
4414 }
4415 if let Some(on_overflow) = &self.on_overflow {
4416 write!(f, "{on_overflow}")?;
4417 }
4418 write!(f, ")")?;
4419 if !self.within_group.is_empty() {
4420 write!(
4421 f,
4422 " WITHIN GROUP (ORDER BY {})",
4423 display_comma_separated(&self.within_group)
4424 )?;
4425 }
4426 Ok(())
4427 }
4428}
4429
4430#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4432#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4433#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4434pub enum ListAggOnOverflow {
4435 Error,
4437
4438 Truncate {
4440 filler: Option<Box<Expr>>,
4441 with_count: bool,
4442 },
4443}
4444
4445impl fmt::Display for ListAggOnOverflow {
4446 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4447 write!(f, " ON OVERFLOW")?;
4448 match self {
4449 ListAggOnOverflow::Error => write!(f, " ERROR"),
4450 ListAggOnOverflow::Truncate { filler, with_count } => {
4451 write!(f, " TRUNCATE")?;
4452 if let Some(filler) = filler {
4453 write!(f, " {filler}")?;
4454 }
4455 if *with_count {
4456 write!(f, " WITH")?;
4457 } else {
4458 write!(f, " WITHOUT")?;
4459 }
4460 write!(f, " COUNT")
4461 }
4462 }
4463 }
4464}
4465
4466#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4470#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4471#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4472pub struct ArrayAgg {
4473 pub distinct: bool,
4474 pub expr: Box<Expr>,
4475 pub order_by: Option<Vec<OrderByExpr>>,
4476 pub limit: Option<Box<Expr>>,
4477 pub within_group: bool, }
4479
4480impl fmt::Display for ArrayAgg {
4481 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4482 write!(
4483 f,
4484 "ARRAY_AGG({}{}",
4485 if self.distinct { "DISTINCT " } else { "" },
4486 self.expr
4487 )?;
4488 if !self.within_group {
4489 if let Some(order_by) = &self.order_by {
4490 write!(f, " ORDER BY {}", display_comma_separated(order_by))?;
4491 }
4492 if let Some(limit) = &self.limit {
4493 write!(f, " LIMIT {limit}")?;
4494 }
4495 }
4496 write!(f, ")")?;
4497 if self.within_group {
4498 if let Some(order_by) = &self.order_by {
4499 write!(
4500 f,
4501 " WITHIN GROUP (ORDER BY {})",
4502 display_comma_separated(order_by)
4503 )?;
4504 }
4505 }
4506 Ok(())
4507 }
4508}
4509
4510#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4511#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4512#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4513pub enum ObjectType {
4514 Table,
4515 View,
4516 Index,
4517 Schema,
4518 Role,
4519 Sequence,
4520 Stage,
4521}
4522
4523impl fmt::Display for ObjectType {
4524 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4525 f.write_str(match self {
4526 ObjectType::Table => "TABLE",
4527 ObjectType::View => "VIEW",
4528 ObjectType::Index => "INDEX",
4529 ObjectType::Schema => "SCHEMA",
4530 ObjectType::Role => "ROLE",
4531 ObjectType::Sequence => "SEQUENCE",
4532 ObjectType::Stage => "STAGE",
4533 })
4534 }
4535}
4536
4537#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4538#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4539#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4540pub enum KillType {
4541 Connection,
4542 Query,
4543 Mutation,
4544}
4545
4546impl fmt::Display for KillType {
4547 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4548 f.write_str(match self {
4549 KillType::Connection => "CONNECTION",
4551 KillType::Query => "QUERY",
4552 KillType::Mutation => "MUTATION",
4554 })
4555 }
4556}
4557
4558#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4559#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4560#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4561pub enum HiveDistributionStyle {
4562 PARTITIONED {
4563 columns: Vec<ColumnDef>,
4564 },
4565 CLUSTERED {
4566 columns: Vec<Ident>,
4567 sorted_by: Vec<ColumnDef>,
4568 num_buckets: i32,
4569 },
4570 SKEWED {
4571 columns: Vec<ColumnDef>,
4572 on: Vec<ColumnDef>,
4573 stored_as_directories: bool,
4574 },
4575 NONE,
4576}
4577
4578#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4579#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4580#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4581pub enum HiveRowFormat {
4582 SERDE { class: String },
4583 DELIMITED,
4584}
4585
4586#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4587#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4588#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4589#[allow(clippy::large_enum_variant)]
4590pub enum HiveIOFormat {
4591 IOF {
4592 input_format: Expr,
4593 output_format: Expr,
4594 },
4595 FileFormat {
4596 format: FileFormat,
4597 },
4598}
4599
4600#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
4601#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4602#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4603pub struct HiveFormat {
4604 pub row_format: Option<HiveRowFormat>,
4605 pub storage: Option<HiveIOFormat>,
4606 pub location: Option<String>,
4607}
4608
4609#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4610#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4611#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4612pub struct SqlOption {
4613 pub name: Ident,
4614 pub value: Expr,
4615}
4616
4617impl fmt::Display for SqlOption {
4618 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4619 write!(f, "{} = {}", self.name, self.value)
4620 }
4621}
4622
4623#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4624#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4625#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4626pub enum TransactionMode {
4627 AccessMode(TransactionAccessMode),
4628 IsolationLevel(TransactionIsolationLevel),
4629}
4630
4631impl fmt::Display for TransactionMode {
4632 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4633 use TransactionMode::*;
4634 match self {
4635 AccessMode(access_mode) => write!(f, "{access_mode}"),
4636 IsolationLevel(iso_level) => write!(f, "ISOLATION LEVEL {iso_level}"),
4637 }
4638 }
4639}
4640
4641#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4642#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4643#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4644pub enum TransactionAccessMode {
4645 ReadOnly,
4646 ReadWrite,
4647}
4648
4649impl fmt::Display for TransactionAccessMode {
4650 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4651 use TransactionAccessMode::*;
4652 f.write_str(match self {
4653 ReadOnly => "READ ONLY",
4654 ReadWrite => "READ WRITE",
4655 })
4656 }
4657}
4658
4659#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4660#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4661#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4662pub enum TransactionIsolationLevel {
4663 ReadUncommitted,
4664 ReadCommitted,
4665 RepeatableRead,
4666 Serializable,
4667}
4668
4669impl fmt::Display for TransactionIsolationLevel {
4670 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4671 use TransactionIsolationLevel::*;
4672 f.write_str(match self {
4673 ReadUncommitted => "READ UNCOMMITTED",
4674 ReadCommitted => "READ COMMITTED",
4675 RepeatableRead => "REPEATABLE READ",
4676 Serializable => "SERIALIZABLE",
4677 })
4678 }
4679}
4680
4681#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4685#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4686#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4687pub enum TransactionModifier {
4688 Deferred,
4689 Immediate,
4690 Exclusive,
4691}
4692
4693impl fmt::Display for TransactionModifier {
4694 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4695 use TransactionModifier::*;
4696 f.write_str(match self {
4697 Deferred => "DEFERRED",
4698 Immediate => "IMMEDIATE",
4699 Exclusive => "EXCLUSIVE",
4700 })
4701 }
4702}
4703
4704#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4705#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4706#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4707pub enum ShowStatementFilter {
4708 Like(String),
4709 ILike(String),
4710 Where(Expr),
4711}
4712
4713impl fmt::Display for ShowStatementFilter {
4714 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4715 use ShowStatementFilter::*;
4716 match self {
4717 Like(pattern) => write!(f, "LIKE '{}'", value::escape_single_quote_string(pattern)),
4718 ILike(pattern) => write!(f, "ILIKE {}", value::escape_single_quote_string(pattern)),
4719 Where(expr) => write!(f, "WHERE {expr}"),
4720 }
4721 }
4722}
4723
4724#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4729#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4730#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4731pub enum SqliteOnConflict {
4732 Rollback,
4733 Abort,
4734 Fail,
4735 Ignore,
4736 Replace,
4737}
4738
4739impl fmt::Display for SqliteOnConflict {
4740 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4741 use SqliteOnConflict::*;
4742 match self {
4743 Rollback => write!(f, "ROLLBACK"),
4744 Abort => write!(f, "ABORT"),
4745 Fail => write!(f, "FAIL"),
4746 Ignore => write!(f, "IGNORE"),
4747 Replace => write!(f, "REPLACE"),
4748 }
4749 }
4750}
4751
4752#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4758#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4759#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4760pub enum MysqlInsertPriority {
4761 LowPriority,
4762 Delayed,
4763 HighPriority,
4764}
4765
4766impl fmt::Display for crate::ast::MysqlInsertPriority {
4767 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4768 use MysqlInsertPriority::*;
4769 match self {
4770 LowPriority => write!(f, "LOW_PRIORITY"),
4771 Delayed => write!(f, "DELAYED"),
4772 HighPriority => write!(f, "HIGH_PRIORITY"),
4773 }
4774 }
4775}
4776
4777#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4778#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4779#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4780pub enum CopySource {
4781 Table {
4782 table_name: ObjectName,
4784 columns: Vec<Ident>,
4787 },
4788 Query(Box<Query>),
4789}
4790
4791#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4792#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4793#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4794pub enum CopyTarget {
4795 Stdin,
4796 Stdout,
4797 File {
4798 filename: String,
4800 },
4801 Program {
4802 command: String,
4804 },
4805}
4806
4807impl fmt::Display for CopyTarget {
4808 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4809 use CopyTarget::*;
4810 match self {
4811 Stdin { .. } => write!(f, "STDIN"),
4812 Stdout => write!(f, "STDOUT"),
4813 File { filename } => write!(f, "'{}'", value::escape_single_quote_string(filename)),
4814 Program { command } => write!(
4815 f,
4816 "PROGRAM '{}'",
4817 value::escape_single_quote_string(command)
4818 ),
4819 }
4820 }
4821}
4822
4823#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4824#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4825#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4826pub enum OnCommit {
4827 DeleteRows,
4828 PreserveRows,
4829 Drop,
4830}
4831
4832#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4836#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4837#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4838pub enum CopyOption {
4839 Format(Ident),
4841 Freeze(bool),
4843 Delimiter(char),
4845 Null(String),
4847 Header(bool),
4849 Quote(char),
4851 Escape(char),
4853 ForceQuote(Vec<Ident>),
4855 ForceNotNull(Vec<Ident>),
4857 ForceNull(Vec<Ident>),
4859 Encoding(String),
4861}
4862
4863impl fmt::Display for CopyOption {
4864 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4865 use CopyOption::*;
4866 match self {
4867 Format(name) => write!(f, "FORMAT {name}"),
4868 Freeze(true) => write!(f, "FREEZE"),
4869 Freeze(false) => write!(f, "FREEZE FALSE"),
4870 Delimiter(char) => write!(f, "DELIMITER '{char}'"),
4871 Null(string) => write!(f, "NULL '{}'", value::escape_single_quote_string(string)),
4872 Header(true) => write!(f, "HEADER"),
4873 Header(false) => write!(f, "HEADER FALSE"),
4874 Quote(char) => write!(f, "QUOTE '{char}'"),
4875 Escape(char) => write!(f, "ESCAPE '{char}'"),
4876 ForceQuote(columns) => write!(f, "FORCE_QUOTE ({})", display_comma_separated(columns)),
4877 ForceNotNull(columns) => {
4878 write!(f, "FORCE_NOT_NULL ({})", display_comma_separated(columns))
4879 }
4880 ForceNull(columns) => write!(f, "FORCE_NULL ({})", display_comma_separated(columns)),
4881 Encoding(name) => write!(f, "ENCODING '{}'", value::escape_single_quote_string(name)),
4882 }
4883 }
4884}
4885
4886#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4890#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4891#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4892pub enum CopyLegacyOption {
4893 Binary,
4895 Delimiter(char),
4897 Null(String),
4899 Csv(Vec<CopyLegacyCsvOption>),
4901}
4902
4903impl fmt::Display for CopyLegacyOption {
4904 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4905 use CopyLegacyOption::*;
4906 match self {
4907 Binary => write!(f, "BINARY"),
4908 Delimiter(char) => write!(f, "DELIMITER '{char}'"),
4909 Null(string) => write!(f, "NULL '{}'", value::escape_single_quote_string(string)),
4910 Csv(opts) => write!(f, "CSV {}", display_separated(opts, " ")),
4911 }
4912 }
4913}
4914
4915#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4919#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4920#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4921pub enum CopyLegacyCsvOption {
4922 Header,
4924 Quote(char),
4926 Escape(char),
4928 ForceQuote(Vec<Ident>),
4930 ForceNotNull(Vec<Ident>),
4932}
4933
4934impl fmt::Display for CopyLegacyCsvOption {
4935 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4936 use CopyLegacyCsvOption::*;
4937 match self {
4938 Header => write!(f, "HEADER"),
4939 Quote(char) => write!(f, "QUOTE '{char}'"),
4940 Escape(char) => write!(f, "ESCAPE '{char}'"),
4941 ForceQuote(columns) => write!(f, "FORCE QUOTE {}", display_comma_separated(columns)),
4942 ForceNotNull(columns) => {
4943 write!(f, "FORCE NOT NULL {}", display_comma_separated(columns))
4944 }
4945 }
4946 }
4947}
4948
4949#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4951#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4952#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4953pub enum MergeClause {
4954 MatchedUpdate {
4955 predicate: Option<Expr>,
4956 assignments: Vec<Assignment>,
4957 },
4958 MatchedDelete(Option<Expr>),
4959 NotMatched {
4960 predicate: Option<Expr>,
4961 columns: Vec<Ident>,
4962 values: Values,
4963 },
4964}
4965
4966impl fmt::Display for MergeClause {
4967 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4968 use MergeClause::*;
4969 write!(f, "WHEN")?;
4970 match self {
4971 MatchedUpdate {
4972 predicate,
4973 assignments,
4974 } => {
4975 write!(f, " MATCHED")?;
4976 if let Some(pred) = predicate {
4977 write!(f, " AND {pred}")?;
4978 }
4979 write!(
4980 f,
4981 " THEN UPDATE SET {}",
4982 display_comma_separated(assignments)
4983 )
4984 }
4985 MatchedDelete(predicate) => {
4986 write!(f, " MATCHED")?;
4987 if let Some(pred) = predicate {
4988 write!(f, " AND {pred}")?;
4989 }
4990 write!(f, " THEN DELETE")
4991 }
4992 NotMatched {
4993 predicate,
4994 columns,
4995 values,
4996 } => {
4997 write!(f, " NOT MATCHED")?;
4998 if let Some(pred) = predicate {
4999 write!(f, " AND {pred}")?;
5000 }
5001 write!(
5002 f,
5003 " THEN INSERT ({}) {}",
5004 display_comma_separated(columns),
5005 values
5006 )
5007 }
5008 }
5009 }
5010}
5011
5012#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5013#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5014#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5015pub enum DiscardObject {
5016 ALL,
5017 PLANS,
5018 SEQUENCES,
5019 TEMP,
5020}
5021
5022impl fmt::Display for DiscardObject {
5023 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5024 match self {
5025 DiscardObject::ALL => f.write_str("ALL"),
5026 DiscardObject::PLANS => f.write_str("PLANS"),
5027 DiscardObject::SEQUENCES => f.write_str("SEQUENCES"),
5028 DiscardObject::TEMP => f.write_str("TEMP"),
5029 }
5030 }
5031}
5032
5033#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5034#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5035#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5036pub enum FlushType {
5037 BinaryLogs,
5038 EngineLogs,
5039 ErrorLogs,
5040 GeneralLogs,
5041 Hosts,
5042 Logs,
5043 Privileges,
5044 OptimizerCosts,
5045 RelayLogs,
5046 SlowLogs,
5047 Status,
5048 UserResources,
5049 Tables,
5050}
5051
5052impl fmt::Display for FlushType {
5053 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5054 match self {
5055 FlushType::BinaryLogs => f.write_str("BINARY LOGS"),
5056 FlushType::EngineLogs => f.write_str("ENGINE LOGS"),
5057 FlushType::ErrorLogs => f.write_str("ERROR LOGS"),
5058 FlushType::GeneralLogs => f.write_str("GENERAL LOGS"),
5059 FlushType::Hosts => f.write_str("HOSTS"),
5060 FlushType::Logs => f.write_str("LOGS"),
5061 FlushType::Privileges => f.write_str("PRIVILEGES"),
5062 FlushType::OptimizerCosts => f.write_str("OPTIMIZER_COSTS"),
5063 FlushType::RelayLogs => f.write_str("RELAY LOGS"),
5064 FlushType::SlowLogs => f.write_str("SLOW LOGS"),
5065 FlushType::Status => f.write_str("STATUS"),
5066 FlushType::UserResources => f.write_str("USER_RESOURCES"),
5067 FlushType::Tables => f.write_str("TABLES"),
5068 }
5069 }
5070}
5071
5072#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5073#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5074#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5075pub enum FlushLocation {
5076 NoWriteToBinlog,
5077 Local,
5078}
5079
5080impl fmt::Display for FlushLocation {
5081 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5082 match self {
5083 FlushLocation::NoWriteToBinlog => f.write_str("NO_WRITE_TO_BINLOG"),
5084 FlushLocation::Local => f.write_str("LOCAL"),
5085 }
5086 }
5087}
5088
5089#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5091#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5092#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5093pub enum ContextModifier {
5094 None,
5096 Local,
5098 Session,
5100}
5101
5102impl fmt::Display for ContextModifier {
5103 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5104 match self {
5105 Self::None => {
5106 write!(f, "")
5107 }
5108 Self::Local => {
5109 write!(f, " LOCAL")
5110 }
5111 Self::Session => {
5112 write!(f, " SESSION")
5113 }
5114 }
5115 }
5116}
5117
5118#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5120#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5121pub enum DropFunctionOption {
5122 Restrict,
5123 Cascade,
5124}
5125
5126impl fmt::Display for DropFunctionOption {
5127 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5128 match self {
5129 DropFunctionOption::Restrict => write!(f, "RESTRICT "),
5130 DropFunctionOption::Cascade => write!(f, "CASCADE "),
5131 }
5132 }
5133}
5134
5135#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5137#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5138#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5139pub struct DropFunctionDesc {
5140 pub name: ObjectName,
5141 pub args: Option<Vec<OperateFunctionArg>>,
5142}
5143
5144impl fmt::Display for DropFunctionDesc {
5145 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5146 write!(f, "{}", self.name)?;
5147 if let Some(args) = &self.args {
5148 write!(f, "({})", display_comma_separated(args))?;
5149 }
5150 Ok(())
5151 }
5152}
5153
5154#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5156#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5157#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5158pub struct OperateFunctionArg {
5159 pub mode: Option<ArgMode>,
5160 pub name: Option<Ident>,
5161 pub data_type: DataType,
5162 pub default_expr: Option<Expr>,
5163}
5164
5165impl OperateFunctionArg {
5166 pub fn unnamed(data_type: DataType) -> Self {
5168 Self {
5169 mode: None,
5170 name: None,
5171 data_type,
5172 default_expr: None,
5173 }
5174 }
5175
5176 pub fn with_name(name: &str, data_type: DataType) -> Self {
5178 Self {
5179 mode: None,
5180 name: Some(name.into()),
5181 data_type,
5182 default_expr: None,
5183 }
5184 }
5185}
5186
5187impl fmt::Display for OperateFunctionArg {
5188 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5189 if let Some(mode) = &self.mode {
5190 write!(f, "{mode} ")?;
5191 }
5192 if let Some(name) = &self.name {
5193 write!(f, "{name} ")?;
5194 }
5195 write!(f, "{}", self.data_type)?;
5196 if let Some(default_expr) = &self.default_expr {
5197 write!(f, " = {default_expr}")?;
5198 }
5199 Ok(())
5200 }
5201}
5202
5203#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5205#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5206#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5207pub enum ArgMode {
5208 In,
5209 Out,
5210 InOut,
5211}
5212
5213impl fmt::Display for ArgMode {
5214 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5215 match self {
5216 ArgMode::In => write!(f, "IN"),
5217 ArgMode::Out => write!(f, "OUT"),
5218 ArgMode::InOut => write!(f, "INOUT"),
5219 }
5220 }
5221}
5222
5223#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5225#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5226#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5227pub enum FunctionBehavior {
5228 Immutable,
5229 Stable,
5230 Volatile,
5231}
5232
5233impl fmt::Display for FunctionBehavior {
5234 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5235 match self {
5236 FunctionBehavior::Immutable => write!(f, "IMMUTABLE"),
5237 FunctionBehavior::Stable => write!(f, "STABLE"),
5238 FunctionBehavior::Volatile => write!(f, "VOLATILE"),
5239 }
5240 }
5241}
5242
5243#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5244#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5245#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5246pub enum FunctionDefinition {
5247 SingleQuotedDef(String),
5248 DoubleDollarDef(String),
5249}
5250
5251impl fmt::Display for FunctionDefinition {
5252 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5253 match self {
5254 FunctionDefinition::SingleQuotedDef(s) => write!(f, "'{s}'")?,
5255 FunctionDefinition::DoubleDollarDef(s) => write!(f, "$${s}$$")?,
5256 }
5257 Ok(())
5258 }
5259}
5260
5261#[derive(Debug, Default, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5266#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5267#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5268pub struct CreateFunctionBody {
5269 pub language: Option<Ident>,
5271 pub behavior: Option<FunctionBehavior>,
5273 pub as_: Option<FunctionDefinition>,
5277 pub return_: Option<Expr>,
5279 pub using: Option<CreateFunctionUsing>,
5281}
5282
5283impl fmt::Display for CreateFunctionBody {
5284 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5285 if let Some(language) = &self.language {
5286 write!(f, " LANGUAGE {language}")?;
5287 }
5288 if let Some(behavior) = &self.behavior {
5289 write!(f, " {behavior}")?;
5290 }
5291 if let Some(definition) = &self.as_ {
5292 write!(f, " AS {definition}")?;
5293 }
5294 if let Some(expr) = &self.return_ {
5295 write!(f, " RETURN {expr}")?;
5296 }
5297 if let Some(using) = &self.using {
5298 write!(f, " {using}")?;
5299 }
5300 Ok(())
5301 }
5302}
5303
5304#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5305#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5306#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5307pub enum CreateFunctionUsing {
5308 Jar(String),
5309 File(String),
5310 Archive(String),
5311}
5312
5313impl fmt::Display for CreateFunctionUsing {
5314 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5315 write!(f, "USING ")?;
5316 match self {
5317 CreateFunctionUsing::Jar(uri) => write!(f, "JAR '{uri}'"),
5318 CreateFunctionUsing::File(uri) => write!(f, "FILE '{uri}'"),
5319 CreateFunctionUsing::Archive(uri) => write!(f, "ARCHIVE '{uri}'"),
5320 }
5321 }
5322}
5323
5324#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5329#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5330#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5331pub struct MacroArg {
5332 pub name: Ident,
5333 pub default_expr: Option<Expr>,
5334}
5335
5336impl MacroArg {
5337 pub fn new(name: &str) -> Self {
5339 Self {
5340 name: name.into(),
5341 default_expr: None,
5342 }
5343 }
5344}
5345
5346impl fmt::Display for MacroArg {
5347 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5348 write!(f, "{}", self.name)?;
5349 if let Some(default_expr) = &self.default_expr {
5350 write!(f, " := {default_expr}")?;
5351 }
5352 Ok(())
5353 }
5354}
5355
5356#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5357#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5358#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5359pub enum MacroDefinition {
5360 Expr(Expr),
5361 Table(Query),
5362}
5363
5364impl fmt::Display for MacroDefinition {
5365 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5366 match self {
5367 MacroDefinition::Expr(expr) => write!(f, "{expr}")?,
5368 MacroDefinition::Table(query) => write!(f, "{query}")?,
5369 }
5370 Ok(())
5371 }
5372}
5373
5374#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5378#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5379#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5380pub enum SchemaName {
5381 Simple(ObjectName),
5383 UnnamedAuthorization(Ident),
5385 NamedAuthorization(ObjectName, Ident),
5387}
5388
5389impl fmt::Display for SchemaName {
5390 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5391 match self {
5392 SchemaName::Simple(name) => {
5393 write!(f, "{name}")
5394 }
5395 SchemaName::UnnamedAuthorization(authorization) => {
5396 write!(f, "AUTHORIZATION {authorization}")
5397 }
5398 SchemaName::NamedAuthorization(name, authorization) => {
5399 write!(f, "{name} AUTHORIZATION {authorization}")
5400 }
5401 }
5402 }
5403}
5404
5405#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5409#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5410#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5411pub enum SearchModifier {
5412 InNaturalLanguageMode,
5414 InNaturalLanguageModeWithQueryExpansion,
5416 InBooleanMode,
5418 WithQueryExpansion,
5420}
5421
5422impl fmt::Display for SearchModifier {
5423 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5424 match self {
5425 Self::InNaturalLanguageMode => {
5426 write!(f, "IN NATURAL LANGUAGE MODE")?;
5427 }
5428 Self::InNaturalLanguageModeWithQueryExpansion => {
5429 write!(f, "IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION")?;
5430 }
5431 Self::InBooleanMode => {
5432 write!(f, "IN BOOLEAN MODE")?;
5433 }
5434 Self::WithQueryExpansion => {
5435 write!(f, "WITH QUERY EXPANSION")?;
5436 }
5437 }
5438
5439 Ok(())
5440 }
5441}
5442
5443#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5444#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5445#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5446pub struct LockTable {
5447 pub table: Ident,
5448 pub alias: Option<Ident>,
5449 pub lock_type: LockTableType,
5450}
5451
5452impl fmt::Display for LockTable {
5453 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5454 let Self {
5455 table: tbl_name,
5456 alias,
5457 lock_type,
5458 } = self;
5459
5460 write!(f, "{tbl_name} ")?;
5461 if let Some(alias) = alias {
5462 write!(f, "AS {alias} ")?;
5463 }
5464 write!(f, "{lock_type}")?;
5465 Ok(())
5466 }
5467}
5468
5469#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5470#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5471#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5472pub enum LockTableType {
5473 Read { local: bool },
5474 Write { low_priority: bool },
5475}
5476
5477impl fmt::Display for LockTableType {
5478 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5479 match self {
5480 Self::Read { local } => {
5481 write!(f, "READ")?;
5482 if *local {
5483 write!(f, " LOCAL")?;
5484 }
5485 }
5486 Self::Write { low_priority } => {
5487 if *low_priority {
5488 write!(f, "LOW_PRIORITY ")?;
5489 }
5490 write!(f, "WRITE")?;
5491 }
5492 }
5493
5494 Ok(())
5495 }
5496}
5497
5498#[cfg(test)]
5499mod tests {
5500 use super::*;
5501
5502 #[test]
5503 fn test_window_frame_default() {
5504 let window_frame = WindowFrame::default();
5505 assert_eq!(WindowFrameBound::Preceding(None), window_frame.start_bound);
5506 }
5507
5508 #[test]
5509 fn test_grouping_sets_display() {
5510 let grouping_sets = Expr::GroupingSets(vec![
5512 vec![Expr::Identifier(Ident::new("a"))],
5513 vec![Expr::Identifier(Ident::new("b"))],
5514 ]);
5515 assert_eq!("GROUPING SETS ((a), (b))", format!("{grouping_sets}"));
5516
5517 let grouping_sets = Expr::GroupingSets(vec![vec![
5519 Expr::Identifier(Ident::new("a")),
5520 Expr::Identifier(Ident::new("b")),
5521 ]]);
5522 assert_eq!("GROUPING SETS ((a, b))", format!("{grouping_sets}"));
5523
5524 let grouping_sets = Expr::GroupingSets(vec![
5526 vec![
5527 Expr::Identifier(Ident::new("a")),
5528 Expr::Identifier(Ident::new("b")),
5529 ],
5530 vec![
5531 Expr::Identifier(Ident::new("c")),
5532 Expr::Identifier(Ident::new("d")),
5533 ],
5534 ]);
5535 assert_eq!("GROUPING SETS ((a, b), (c, d))", format!("{grouping_sets}"));
5536 }
5537
5538 #[test]
5539 fn test_rollup_display() {
5540 let rollup = Expr::Rollup(vec![vec![Expr::Identifier(Ident::new("a"))]]);
5541 assert_eq!("ROLLUP (a)", format!("{rollup}"));
5542
5543 let rollup = Expr::Rollup(vec![vec![
5544 Expr::Identifier(Ident::new("a")),
5545 Expr::Identifier(Ident::new("b")),
5546 ]]);
5547 assert_eq!("ROLLUP ((a, b))", format!("{rollup}"));
5548
5549 let rollup = Expr::Rollup(vec![
5550 vec![Expr::Identifier(Ident::new("a"))],
5551 vec![Expr::Identifier(Ident::new("b"))],
5552 ]);
5553 assert_eq!("ROLLUP (a, b)", format!("{rollup}"));
5554
5555 let rollup = Expr::Rollup(vec![
5556 vec![Expr::Identifier(Ident::new("a"))],
5557 vec![
5558 Expr::Identifier(Ident::new("b")),
5559 Expr::Identifier(Ident::new("c")),
5560 ],
5561 vec![Expr::Identifier(Ident::new("d"))],
5562 ]);
5563 assert_eq!("ROLLUP (a, (b, c), d)", format!("{rollup}"));
5564 }
5565
5566 #[test]
5567 fn test_cube_display() {
5568 let cube = Expr::Cube(vec![vec![Expr::Identifier(Ident::new("a"))]]);
5569 assert_eq!("CUBE (a)", format!("{cube}"));
5570
5571 let cube = Expr::Cube(vec![vec![
5572 Expr::Identifier(Ident::new("a")),
5573 Expr::Identifier(Ident::new("b")),
5574 ]]);
5575 assert_eq!("CUBE ((a, b))", format!("{cube}"));
5576
5577 let cube = Expr::Cube(vec![
5578 vec![Expr::Identifier(Ident::new("a"))],
5579 vec![Expr::Identifier(Ident::new("b"))],
5580 ]);
5581 assert_eq!("CUBE (a, b)", format!("{cube}"));
5582
5583 let cube = Expr::Cube(vec![
5584 vec![Expr::Identifier(Ident::new("a"))],
5585 vec![
5586 Expr::Identifier(Ident::new("b")),
5587 Expr::Identifier(Ident::new("c")),
5588 ],
5589 vec![Expr::Identifier(Ident::new("d"))],
5590 ]);
5591 assert_eq!("CUBE (a, (b, c), d)", format!("{cube}"));
5592 }
5593
5594 #[test]
5595 fn test_interval_display() {
5596 let interval = Expr::Interval(Interval {
5597 value: Box::new(Expr::Value(Value::SingleQuotedString(String::from(
5598 "123:45.67",
5599 )))),
5600 leading_field: Some(DateTimeField::Minute),
5601 leading_precision: Some(10),
5602 last_field: Some(DateTimeField::Second),
5603 fractional_seconds_precision: Some(9),
5604 });
5605 assert_eq!(
5606 "INTERVAL '123:45.67' MINUTE (10) TO SECOND (9)",
5607 format!("{interval}"),
5608 );
5609
5610 let interval = Expr::Interval(Interval {
5611 value: Box::new(Expr::Value(Value::SingleQuotedString(String::from("5")))),
5612 leading_field: Some(DateTimeField::Second),
5613 leading_precision: Some(1),
5614 last_field: None,
5615 fractional_seconds_precision: Some(3),
5616 });
5617 assert_eq!("INTERVAL '5' SECOND (1, 3)", format!("{interval}"));
5618 }
5619}