1mod analyze;
15mod data_type;
16pub(crate) mod ddl;
17mod legacy_source;
18mod operator;
19mod query;
20mod statement;
21mod value;
22
23#[cfg(not(feature = "std"))]
24use alloc::{
25 boxed::Box,
26 string::{String, ToString},
27 vec::Vec,
28};
29use core::fmt;
30use core::fmt::Display;
31use std::collections::HashSet;
32use std::sync::Arc;
33
34use itertools::Itertools;
35#[cfg(feature = "serde")]
36use serde::{Deserialize, Serialize};
37use winnow::ModalResult;
38
39pub use self::data_type::{DataType, StructField};
40pub use self::ddl::{
41 AlterColumnOperation, AlterConnectionOperation, AlterDatabaseOperation, AlterFragmentOperation,
42 AlterFunctionOperation, AlterSchemaOperation, AlterSecretOperation, AlterTableOperation,
43 ColumnDef, ColumnOption, ColumnOptionDef, ReferentialAction, SourceWatermark, TableConstraint,
44 WebhookSourceInfo,
45};
46pub use self::legacy_source::{CompatibleFormatEncode, get_delimiter};
47pub use self::operator::{BinaryOperator, QualifiedOperator, UnaryOperator};
48pub use self::query::{
49 Corresponding, Cte, CteInner, Distinct, Fetch, Join, JoinConstraint, JoinOperator, LateralView,
50 NamedWindow, OrderByExpr, Query, Select, SelectItem, SetExpr, SetOperator, TableAlias,
51 TableFactor, TableWithJoins, Top, Values, With,
52};
53pub use self::statement::*;
54pub use self::value::{
55 ConnectionRefValue, CstyleEscapedString, DateTimeField, DollarQuotedString, JsonPredicateType,
56 SecretRefAsType, SecretRefValue, TrimWhereField, Value,
57};
58pub use crate::ast::analyze::AnalyzeTarget;
59pub use crate::ast::ddl::{
60 AlterIndexOperation, AlterSinkOperation, AlterSourceOperation, AlterSubscriptionOperation,
61 AlterViewOperation,
62};
63use crate::keywords::Keyword;
64use crate::parser::{IncludeOption, IncludeOptionItem, Parser, ParserError, StrError};
65use crate::tokenizer::Tokenizer;
66
67pub type RedactSqlOptionKeywordsRef = Arc<HashSet<String>>;
68
69task_local::task_local! {
70 pub static REDACT_SQL_OPTION_KEYWORDS: RedactSqlOptionKeywordsRef;
71}
72
73pub struct DisplaySeparated<'a, T>
74where
75 T: fmt::Display,
76{
77 slice: &'a [T],
78 sep: &'static str,
79}
80
81impl<T> fmt::Display for DisplaySeparated<'_, T>
82where
83 T: fmt::Display,
84{
85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86 let mut delim = "";
87 for t in self.slice {
88 write!(f, "{}", delim)?;
89 delim = self.sep;
90 write!(f, "{}", t)?;
91 }
92 Ok(())
93 }
94}
95
96pub fn display_separated<'a, T>(slice: &'a [T], sep: &'static str) -> DisplaySeparated<'a, T>
97where
98 T: fmt::Display,
99{
100 DisplaySeparated { slice, sep }
101}
102
103pub fn display_comma_separated<T>(slice: &[T]) -> DisplaySeparated<'_, T>
104where
105 T: fmt::Display,
106{
107 DisplaySeparated { slice, sep: ", " }
108}
109
110#[derive(Debug, Clone, PartialEq, Eq, Hash)]
112#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
113pub struct Ident {
114 pub(crate) value: String,
116 pub(crate) quote_style: Option<char>,
119}
120
121impl Ident {
122 pub fn new_unchecked<S>(value: S) -> Self
126 where
127 S: Into<String>,
128 {
129 Ident {
130 value: value.into(),
131 quote_style: None,
132 }
133 }
134
135 pub fn with_quote_unchecked<S>(quote: char, value: S) -> Self
139 where
140 S: Into<String>,
141 {
142 Ident {
143 value: value.into(),
144 quote_style: Some(quote),
145 }
146 }
147
148 pub fn with_quote_check<S>(quote: char, value: S) -> Result<Ident, ParserError>
151 where
152 S: Into<String>,
153 {
154 let value_str = value.into();
155 if value_str.is_empty() {
156 return Err(ParserError::ParserError(format!(
157 "zero-length delimited identifier at or near \"{value_str}\""
158 )));
159 }
160
161 if !(quote == '\'' || quote == '"' || quote == '`' || quote == '[') {
162 return Err(ParserError::ParserError(
163 "unexpected quote style".to_owned(),
164 ));
165 }
166
167 Ok(Ident {
168 value: value_str,
169 quote_style: Some(quote),
170 })
171 }
172
173 pub fn real_value(&self) -> String {
177 match self.quote_style {
178 Some('"') => self.value.clone(),
179 _ => self.value.to_lowercase(),
180 }
181 }
182
183 pub fn from_real_value(value: &str) -> Self {
186 let needs_quotes = value
187 .chars()
188 .any(|c| !matches!(c, 'a'..='z' | '0'..='9' | '_'));
189
190 if needs_quotes {
191 Self::with_quote_unchecked('"', value.replace('"', "\"\""))
192 } else {
193 Self::new_unchecked(value)
194 }
195 }
196
197 pub fn quote_style(&self) -> Option<char> {
198 self.quote_style
199 }
200}
201
202impl From<&str> for Ident {
203 fn from(value: &str) -> Self {
204 Self::from_real_value(value)
205 }
206}
207
208impl ParseTo for Ident {
209 fn parse_to(parser: &mut Parser<'_>) -> ModalResult<Self> {
210 parser.parse_identifier()
211 }
212}
213
214impl fmt::Display for Ident {
215 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
216 match self.quote_style {
217 Some(q) if q == '"' || q == '\'' || q == '`' => write!(f, "{}{}{}", q, self.value, q),
218 Some('[') => write!(f, "[{}]", self.value),
219 None => f.write_str(&self.value),
220 _ => panic!("unexpected quote style"),
221 }
222 }
223}
224
225#[derive(Debug, Clone, PartialEq, Eq, Hash)]
229#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
230pub struct ObjectName(pub Vec<Ident>);
231
232impl ObjectName {
233 pub fn real_value(&self) -> String {
234 self.0
235 .iter()
236 .map(|ident| ident.real_value())
237 .collect::<Vec<_>>()
238 .join(".")
239 }
240
241 pub fn from_test_str(s: &str) -> Self {
242 ObjectName::from(vec![s.into()])
243 }
244
245 pub fn base_name(&self) -> String {
246 self.0
247 .iter()
248 .last()
249 .expect("should have base name")
250 .real_value()
251 }
252}
253
254impl fmt::Display for ObjectName {
255 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
256 write!(f, "{}", display_separated(&self.0, "."))
257 }
258}
259
260impl ParseTo for ObjectName {
261 fn parse_to(p: &mut Parser<'_>) -> ModalResult<Self> {
262 p.parse_object_name()
263 }
264}
265
266impl From<Vec<Ident>> for ObjectName {
267 fn from(value: Vec<Ident>) -> Self {
268 Self(value)
269 }
270}
271
272#[derive(Debug, Clone, PartialEq, Eq, Hash)]
274#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
275pub struct Array {
276 pub elem: Vec<Expr>,
278
279 pub named: bool,
281}
282
283impl fmt::Display for Array {
284 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
285 write!(
286 f,
287 "{}[{}]",
288 if self.named { "ARRAY" } else { "" },
289 display_comma_separated(&self.elem)
290 )
291 }
292}
293
294#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
296#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
297pub struct EscapeChar(Option<char>);
298
299impl EscapeChar {
300 pub fn escape(ch: char) -> Self {
301 Self(Some(ch))
302 }
303
304 pub fn empty() -> Self {
305 Self(None)
306 }
307}
308
309impl fmt::Display for EscapeChar {
310 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
311 match self.0 {
312 Some(ch) => write!(f, "{}", ch),
313 None => f.write_str(""),
314 }
315 }
316}
317
318#[derive(Debug, Clone, PartialEq, Eq, Hash)]
324#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
325pub enum Expr {
326 Identifier(Ident),
328 CompoundIdentifier(Vec<Ident>),
330 FieldIdentifier(Box<Expr>, Vec<Ident>),
342 IsNull(Box<Expr>),
344 IsNotNull(Box<Expr>),
346 IsTrue(Box<Expr>),
348 IsNotTrue(Box<Expr>),
350 IsFalse(Box<Expr>),
352 IsNotFalse(Box<Expr>),
354 IsUnknown(Box<Expr>),
356 IsNotUnknown(Box<Expr>),
358 IsDistinctFrom(Box<Expr>, Box<Expr>),
360 IsNotDistinctFrom(Box<Expr>, Box<Expr>),
362 IsJson {
367 expr: Box<Expr>,
368 negated: bool,
369 item_type: JsonPredicateType,
370 unique_keys: bool,
371 },
372 InList {
374 expr: Box<Expr>,
375 list: Vec<Expr>,
376 negated: bool,
377 },
378 InSubquery {
380 expr: Box<Expr>,
381 subquery: Box<Query>,
382 negated: bool,
383 },
384 Between {
386 expr: Box<Expr>,
387 negated: bool,
388 low: Box<Expr>,
389 high: Box<Expr>,
390 },
391 Like {
393 negated: bool,
394 expr: Box<Expr>,
395 pattern: Box<Expr>,
396 escape_char: Option<EscapeChar>,
397 },
398 ILike {
400 negated: bool,
401 expr: Box<Expr>,
402 pattern: Box<Expr>,
403 escape_char: Option<EscapeChar>,
404 },
405 SimilarTo {
407 negated: bool,
408 expr: Box<Expr>,
409 pattern: Box<Expr>,
410 escape_char: Option<EscapeChar>,
411 },
412 BinaryOp {
414 left: Box<Expr>,
415 op: BinaryOperator,
416 right: Box<Expr>,
417 },
418 SomeOp(Box<Expr>),
420 AllOp(Box<Expr>),
422 UnaryOp {
424 op: UnaryOperator,
425 expr: Box<Expr>,
426 },
427 Cast {
429 expr: Box<Expr>,
430 data_type: DataType,
431 },
432 TryCast {
435 expr: Box<Expr>,
436 data_type: DataType,
437 },
438 AtTimeZone {
441 timestamp: Box<Expr>,
442 time_zone: Box<Expr>,
443 },
444 Extract {
446 field: String,
447 expr: Box<Expr>,
448 },
449 Substring {
451 expr: Box<Expr>,
452 substring_from: Option<Box<Expr>>,
453 substring_for: Option<Box<Expr>>,
454 },
455 Position {
457 substring: Box<Expr>,
458 string: Box<Expr>,
459 },
460 Overlay {
462 expr: Box<Expr>,
463 new_substring: Box<Expr>,
464 start: Box<Expr>,
465 count: Option<Box<Expr>>,
466 },
467 Trim {
471 expr: Box<Expr>,
472 trim_where: Option<TrimWhereField>,
474 trim_what: Option<Box<Expr>>,
475 },
476 Collate {
478 expr: Box<Expr>,
479 collation: ObjectName,
480 },
481 Nested(Box<Expr>),
483 Value(Value),
485 Parameter {
487 index: u64,
488 },
489 TypedString {
493 data_type: DataType,
494 value: String,
495 },
496 Function(Function),
498 Case {
504 operand: Option<Box<Expr>>,
505 conditions: Vec<Expr>,
506 results: Vec<Expr>,
507 else_result: Option<Box<Expr>>,
508 },
509 Exists(Box<Query>),
512 Subquery(Box<Query>),
515 GroupingSets(Vec<Vec<Expr>>),
517 Cube(Vec<Vec<Expr>>),
519 Rollup(Vec<Vec<Expr>>),
521 Row(Vec<Expr>),
523 Array(Array),
525 ArraySubquery(Box<Query>),
527 Index {
529 obj: Box<Expr>,
530 index: Box<Expr>,
531 },
532 ArrayRangeIndex {
534 obj: Box<Expr>,
535 start: Option<Box<Expr>>,
536 end: Option<Box<Expr>>,
537 },
538 LambdaFunction {
539 args: Vec<Ident>,
540 body: Box<Expr>,
541 },
542 Map {
543 entries: Vec<(Expr, Expr)>,
544 },
545}
546
547impl fmt::Display for Expr {
548 #[expect(clippy::disallowed_methods, reason = "use zip_eq")]
549 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
550 match self {
551 Expr::Identifier(s) => write!(f, "{}", s),
552 Expr::CompoundIdentifier(s) => write!(f, "{}", display_separated(s, ".")),
553 Expr::FieldIdentifier(ast, s) => write!(f, "({}).{}", ast, display_separated(s, ".")),
554 Expr::IsNull(ast) => write!(f, "{} IS NULL", ast),
555 Expr::IsNotNull(ast) => write!(f, "{} IS NOT NULL", ast),
556 Expr::IsTrue(ast) => write!(f, "{} IS TRUE", ast),
557 Expr::IsNotTrue(ast) => write!(f, "{} IS NOT TRUE", ast),
558 Expr::IsFalse(ast) => write!(f, "{} IS FALSE", ast),
559 Expr::IsNotFalse(ast) => write!(f, "{} IS NOT FALSE", ast),
560 Expr::IsUnknown(ast) => write!(f, "{} IS UNKNOWN", ast),
561 Expr::IsNotUnknown(ast) => write!(f, "{} IS NOT UNKNOWN", ast),
562 Expr::IsJson {
563 expr,
564 negated,
565 item_type,
566 unique_keys,
567 } => write!(
568 f,
569 "{} IS {}JSON{}{}",
570 expr,
571 if *negated { "NOT " } else { "" },
572 item_type,
573 if *unique_keys {
574 " WITH UNIQUE KEYS"
575 } else {
576 ""
577 },
578 ),
579 Expr::InList {
580 expr,
581 list,
582 negated,
583 } => write!(
584 f,
585 "{} {}IN ({})",
586 expr,
587 if *negated { "NOT " } else { "" },
588 display_comma_separated(list)
589 ),
590 Expr::InSubquery {
591 expr,
592 subquery,
593 negated,
594 } => write!(
595 f,
596 "{} {}IN ({})",
597 expr,
598 if *negated { "NOT " } else { "" },
599 subquery
600 ),
601 Expr::Between {
602 expr,
603 negated,
604 low,
605 high,
606 } => write!(
607 f,
608 "{} {}BETWEEN {} AND {}",
609 expr,
610 if *negated { "NOT " } else { "" },
611 low,
612 high
613 ),
614 Expr::Like {
615 negated,
616 expr,
617 pattern,
618 escape_char,
619 } => match escape_char {
620 Some(ch) => write!(
621 f,
622 "{} {}LIKE {} ESCAPE '{}'",
623 expr,
624 if *negated { "NOT " } else { "" },
625 pattern,
626 ch
627 ),
628 _ => write!(
629 f,
630 "{} {}LIKE {}",
631 expr,
632 if *negated { "NOT " } else { "" },
633 pattern
634 ),
635 },
636 Expr::ILike {
637 negated,
638 expr,
639 pattern,
640 escape_char,
641 } => match escape_char {
642 Some(ch) => write!(
643 f,
644 "{} {}ILIKE {} ESCAPE '{}'",
645 expr,
646 if *negated { "NOT " } else { "" },
647 pattern,
648 ch
649 ),
650 _ => write!(
651 f,
652 "{} {}ILIKE {}",
653 expr,
654 if *negated { "NOT " } else { "" },
655 pattern
656 ),
657 },
658 Expr::SimilarTo {
659 negated,
660 expr,
661 pattern,
662 escape_char,
663 } => match escape_char {
664 Some(ch) => write!(
665 f,
666 "{} {}SIMILAR TO {} ESCAPE '{}'",
667 expr,
668 if *negated { "NOT " } else { "" },
669 pattern,
670 ch
671 ),
672 _ => write!(
673 f,
674 "{} {}SIMILAR TO {}",
675 expr,
676 if *negated { "NOT " } else { "" },
677 pattern
678 ),
679 },
680 Expr::BinaryOp { left, op, right } => write!(f, "{} {} {}", left, op, right),
681 Expr::SomeOp(expr) => write!(f, "SOME({})", expr),
682 Expr::AllOp(expr) => write!(f, "ALL({})", expr),
683 Expr::UnaryOp { op, expr } => {
684 write!(f, "{} {}", op, expr)
685 }
686 Expr::Cast { expr, data_type } => write!(f, "CAST({} AS {})", expr, data_type),
687 Expr::TryCast { expr, data_type } => write!(f, "TRY_CAST({} AS {})", expr, data_type),
688 Expr::AtTimeZone {
689 timestamp,
690 time_zone,
691 } => write!(f, "{} AT TIME ZONE {}", timestamp, time_zone),
692 Expr::Extract { field, expr } => write!(f, "EXTRACT({} FROM {})", field, expr),
693 Expr::Collate { expr, collation } => write!(f, "{} COLLATE {}", expr, collation),
694 Expr::Nested(ast) => write!(f, "({})", ast),
695 Expr::Value(v) => write!(f, "{}", v),
696 Expr::Parameter { index } => write!(f, "${}", index),
697 Expr::TypedString { data_type, value } => {
698 write!(f, "{}", data_type)?;
699 write!(f, " '{}'", &value::escape_single_quote_string(value))
700 }
701 Expr::Function(fun) => write!(f, "{}", fun),
702 Expr::Case {
703 operand,
704 conditions,
705 results,
706 else_result,
707 } => {
708 write!(f, "CASE")?;
709 if let Some(operand) = operand {
710 write!(f, " {}", operand)?;
711 }
712 for (c, r) in conditions.iter().zip_eq(results) {
713 write!(f, " WHEN {} THEN {}", c, r)?;
714 }
715
716 if let Some(else_result) = else_result {
717 write!(f, " ELSE {}", else_result)?;
718 }
719 write!(f, " END")
720 }
721 Expr::Exists(s) => write!(f, "EXISTS ({})", s),
722 Expr::Subquery(s) => write!(f, "({})", s),
723 Expr::GroupingSets(sets) => {
724 write!(f, "GROUPING SETS (")?;
725 let mut sep = "";
726 for set in sets {
727 write!(f, "{}", sep)?;
728 sep = ", ";
729 write!(f, "({})", display_comma_separated(set))?;
730 }
731 write!(f, ")")
732 }
733 Expr::Cube(sets) => {
734 write!(f, "CUBE (")?;
735 let mut sep = "";
736 for set in sets {
737 write!(f, "{}", sep)?;
738 sep = ", ";
739 if set.len() == 1 {
740 write!(f, "{}", set[0])?;
741 } else {
742 write!(f, "({})", display_comma_separated(set))?;
743 }
744 }
745 write!(f, ")")
746 }
747 Expr::Rollup(sets) => {
748 write!(f, "ROLLUP (")?;
749 let mut sep = "";
750 for set in sets {
751 write!(f, "{}", sep)?;
752 sep = ", ";
753 if set.len() == 1 {
754 write!(f, "{}", set[0])?;
755 } else {
756 write!(f, "({})", display_comma_separated(set))?;
757 }
758 }
759 write!(f, ")")
760 }
761 Expr::Substring {
762 expr,
763 substring_from,
764 substring_for,
765 } => {
766 write!(f, "SUBSTRING({}", expr)?;
767 if let Some(from_part) = substring_from {
768 write!(f, " FROM {}", from_part)?;
769 }
770 if let Some(from_part) = substring_for {
771 write!(f, " FOR {}", from_part)?;
772 }
773
774 write!(f, ")")
775 }
776 Expr::Position { substring, string } => {
777 write!(f, "POSITION({} IN {})", substring, string)
778 }
779 Expr::Overlay {
780 expr,
781 new_substring,
782 start,
783 count,
784 } => {
785 write!(f, "OVERLAY({}", expr)?;
786 write!(f, " PLACING {}", new_substring)?;
787 write!(f, " FROM {}", start)?;
788
789 if let Some(count_expr) = count {
790 write!(f, " FOR {}", count_expr)?;
791 }
792
793 write!(f, ")")
794 }
795 Expr::IsDistinctFrom(a, b) => write!(f, "{} IS DISTINCT FROM {}", a, b),
796 Expr::IsNotDistinctFrom(a, b) => write!(f, "{} IS NOT DISTINCT FROM {}", a, b),
797 Expr::Trim {
798 expr,
799 trim_where,
800 trim_what,
801 } => {
802 write!(f, "TRIM(")?;
803 if let Some(ident) = trim_where {
804 write!(f, "{} ", ident)?;
805 }
806 if let Some(trim_char) = trim_what {
807 write!(f, "{} ", trim_char)?;
808 }
809 write!(f, "FROM {})", expr)
810 }
811 Expr::Row(exprs) => write!(
812 f,
813 "ROW({})",
814 exprs
815 .iter()
816 .map(|v| v.to_string())
817 .collect::<Vec<String>>()
818 .as_slice()
819 .join(", ")
820 ),
821 Expr::Index { obj, index } => {
822 write!(f, "{}[{}]", obj, index)?;
823 Ok(())
824 }
825 Expr::ArrayRangeIndex { obj, start, end } => {
826 let start_str = match start {
827 None => "".to_owned(),
828 Some(start) => format!("{}", start),
829 };
830 let end_str = match end {
831 None => "".to_owned(),
832 Some(end) => format!("{}", end),
833 };
834 write!(f, "{}[{}:{}]", obj, start_str, end_str)?;
835 Ok(())
836 }
837 Expr::Array(exprs) => write!(f, "{}", exprs),
838 Expr::ArraySubquery(s) => write!(f, "ARRAY ({})", s),
839 Expr::LambdaFunction { args, body } => {
840 write!(
841 f,
842 "|{}| {}",
843 args.iter().map(ToString::to_string).join(", "),
844 body
845 )
846 }
847 Expr::Map { entries } => {
848 write!(
849 f,
850 "MAP {{{}}}",
851 entries
852 .iter()
853 .map(|(k, v)| format!("{}: {}", k, v))
854 .join(", ")
855 )
856 }
857 }
858 }
859}
860
861#[derive(Debug, Clone, PartialEq, Eq, Hash)]
864#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
865pub struct WindowSpec {
866 pub partition_by: Vec<Expr>,
867 pub order_by: Vec<OrderByExpr>,
868 pub window_frame: Option<WindowFrame>,
869}
870
871#[derive(Debug, Clone, PartialEq, Eq, Hash)]
874#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
875pub enum Window {
876 Spec(WindowSpec),
878 Name(Ident),
880}
881
882impl fmt::Display for WindowSpec {
883 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
884 let mut delim = "";
885 if !self.partition_by.is_empty() {
886 delim = " ";
887 write!(
888 f,
889 "PARTITION BY {}",
890 display_comma_separated(&self.partition_by)
891 )?;
892 }
893 if !self.order_by.is_empty() {
894 f.write_str(delim)?;
895 delim = " ";
896 write!(f, "ORDER BY {}", display_comma_separated(&self.order_by))?;
897 }
898 if let Some(window_frame) = &self.window_frame {
899 f.write_str(delim)?;
900 window_frame.fmt(f)?;
901 }
902 Ok(())
903 }
904}
905
906impl fmt::Display for Window {
907 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
908 match self {
909 Window::Spec(spec) => write!(f, "({})", spec),
910 Window::Name(name) => write!(f, "{}", name),
911 }
912 }
913}
914
915#[derive(Debug, Clone, PartialEq, Eq, Hash)]
921#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
922pub struct WindowFrame {
923 pub units: WindowFrameUnits,
924 pub bounds: WindowFrameBounds,
925 pub exclusion: Option<WindowFrameExclusion>,
926}
927
928#[derive(Debug, Clone, PartialEq, Eq, Hash)]
929#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
930pub enum WindowFrameUnits {
931 Rows,
932 Range,
933 Groups,
934 Session,
935}
936
937#[derive(Debug, Clone, PartialEq, Eq, Hash)]
938#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
939pub enum WindowFrameBounds {
940 Bounds {
941 start: WindowFrameBound,
942 end: Option<WindowFrameBound>,
946 },
947 Gap(Box<Expr>),
948}
949
950impl fmt::Display for WindowFrame {
951 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
952 write!(f, "{} ", self.units)?;
953 match &self.bounds {
954 WindowFrameBounds::Bounds { start, end } => {
955 if let Some(end) = end {
956 write!(f, "BETWEEN {} AND {}", start, end)
957 } else {
958 write!(f, "{}", start)
959 }
960 }
961 WindowFrameBounds::Gap(gap) => {
962 write!(f, "WITH GAP {}", gap)
963 }
964 }
965 }
966}
967
968impl fmt::Display for WindowFrameUnits {
969 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
970 f.write_str(match self {
971 WindowFrameUnits::Rows => "ROWS",
972 WindowFrameUnits::Range => "RANGE",
973 WindowFrameUnits::Groups => "GROUPS",
974 WindowFrameUnits::Session => "SESSION",
975 })
976 }
977}
978
979#[derive(Debug, Clone, PartialEq, Eq, Hash)]
981#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
982pub enum WindowFrameBound {
983 CurrentRow,
985 Preceding(Option<Box<Expr>>),
987 Following(Option<Box<Expr>>),
989}
990
991impl fmt::Display for WindowFrameBound {
992 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
993 match self {
994 WindowFrameBound::CurrentRow => f.write_str("CURRENT ROW"),
995 WindowFrameBound::Preceding(None) => f.write_str("UNBOUNDED PRECEDING"),
996 WindowFrameBound::Following(None) => f.write_str("UNBOUNDED FOLLOWING"),
997 WindowFrameBound::Preceding(Some(n)) => write!(f, "{} PRECEDING", n),
998 WindowFrameBound::Following(Some(n)) => write!(f, "{} FOLLOWING", n),
999 }
1000 }
1001}
1002
1003#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1005#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1006pub enum WindowFrameExclusion {
1007 CurrentRow,
1008 Group,
1009 Ties,
1010 NoOthers,
1011}
1012
1013impl fmt::Display for WindowFrameExclusion {
1014 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1015 match self {
1016 WindowFrameExclusion::CurrentRow => f.write_str("EXCLUDE CURRENT ROW"),
1017 WindowFrameExclusion::Group => f.write_str("EXCLUDE GROUP"),
1018 WindowFrameExclusion::Ties => f.write_str("EXCLUDE TIES"),
1019 WindowFrameExclusion::NoOthers => f.write_str("EXCLUDE NO OTHERS"),
1020 }
1021 }
1022}
1023
1024#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1025#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1026pub enum AddDropSync {
1027 ADD,
1028 DROP,
1029 SYNC,
1030}
1031
1032impl fmt::Display for AddDropSync {
1033 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1034 match self {
1035 AddDropSync::SYNC => f.write_str("SYNC PARTITIONS"),
1036 AddDropSync::DROP => f.write_str("DROP PARTITIONS"),
1037 AddDropSync::ADD => f.write_str("ADD PARTITIONS"),
1038 }
1039 }
1040}
1041
1042#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1043#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1044pub enum ShowObject {
1045 Table { schema: Option<Ident> },
1046 InternalTable { schema: Option<Ident> },
1047 Database,
1048 Schema,
1049 View { schema: Option<Ident> },
1050 MaterializedView { schema: Option<Ident> },
1051 Source { schema: Option<Ident> },
1052 Sink { schema: Option<Ident> },
1053 Subscription { schema: Option<Ident> },
1054 Columns { table: ObjectName },
1055 Connection { schema: Option<Ident> },
1056 Secret { schema: Option<Ident> },
1057 Function { schema: Option<Ident> },
1058 Indexes { table: ObjectName },
1059 Cluster,
1060 Jobs,
1061 ProcessList,
1062 Cursor,
1063 SubscriptionCursor,
1064}
1065
1066#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1067#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1068pub struct JobIdents(pub Vec<u32>);
1069
1070impl fmt::Display for ShowObject {
1071 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1072 fn fmt_schema(schema: &Option<Ident>) -> String {
1073 if let Some(schema) = schema {
1074 format!(" FROM {}", schema.value)
1075 } else {
1076 "".to_owned()
1077 }
1078 }
1079
1080 match self {
1081 ShowObject::Database => f.write_str("DATABASES"),
1082 ShowObject::Schema => f.write_str("SCHEMAS"),
1083 ShowObject::Table { schema } => {
1084 write!(f, "TABLES{}", fmt_schema(schema))
1085 }
1086 ShowObject::InternalTable { schema } => {
1087 write!(f, "INTERNAL TABLES{}", fmt_schema(schema))
1088 }
1089 ShowObject::View { schema } => {
1090 write!(f, "VIEWS{}", fmt_schema(schema))
1091 }
1092 ShowObject::MaterializedView { schema } => {
1093 write!(f, "MATERIALIZED VIEWS{}", fmt_schema(schema))
1094 }
1095 ShowObject::Source { schema } => write!(f, "SOURCES{}", fmt_schema(schema)),
1096 ShowObject::Sink { schema } => write!(f, "SINKS{}", fmt_schema(schema)),
1097 ShowObject::Columns { table } => write!(f, "COLUMNS FROM {}", table),
1098 ShowObject::Connection { schema } => write!(f, "CONNECTIONS{}", fmt_schema(schema)),
1099 ShowObject::Function { schema } => write!(f, "FUNCTIONS{}", fmt_schema(schema)),
1100 ShowObject::Indexes { table } => write!(f, "INDEXES FROM {}", table),
1101 ShowObject::Cluster => {
1102 write!(f, "CLUSTER")
1103 }
1104 ShowObject::Jobs => write!(f, "JOBS"),
1105 ShowObject::ProcessList => write!(f, "PROCESSLIST"),
1106 ShowObject::Subscription { schema } => write!(f, "SUBSCRIPTIONS{}", fmt_schema(schema)),
1107 ShowObject::Secret { schema } => write!(f, "SECRETS{}", fmt_schema(schema)),
1108 ShowObject::Cursor => write!(f, "CURSORS"),
1109 ShowObject::SubscriptionCursor => write!(f, "SUBSCRIPTION CURSORS"),
1110 }
1111 }
1112}
1113
1114#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1115#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1116pub enum ShowCreateType {
1117 Table,
1118 MaterializedView,
1119 View,
1120 Index,
1121 Source,
1122 Sink,
1123 Function,
1124 Subscription,
1125}
1126
1127impl fmt::Display for ShowCreateType {
1128 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1129 match self {
1130 ShowCreateType::Table => f.write_str("TABLE"),
1131 ShowCreateType::MaterializedView => f.write_str("MATERIALIZED VIEW"),
1132 ShowCreateType::View => f.write_str("VIEW"),
1133 ShowCreateType::Index => f.write_str("INDEX"),
1134 ShowCreateType::Source => f.write_str("SOURCE"),
1135 ShowCreateType::Sink => f.write_str("SINK"),
1136 ShowCreateType::Function => f.write_str("FUNCTION"),
1137 ShowCreateType::Subscription => f.write_str("SUBSCRIPTION"),
1138 }
1139 }
1140}
1141
1142#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1143#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1144pub enum CommentObject {
1145 Column,
1146 Table,
1147}
1148
1149impl fmt::Display for CommentObject {
1150 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1151 match self {
1152 CommentObject::Column => f.write_str("COLUMN"),
1153 CommentObject::Table => f.write_str("TABLE"),
1154 }
1155 }
1156}
1157
1158#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1159#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1160pub enum ExplainType {
1161 Logical,
1162 Physical,
1163 DistSql,
1164}
1165
1166impl fmt::Display for ExplainType {
1167 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1168 match self {
1169 ExplainType::Logical => f.write_str("Logical"),
1170 ExplainType::Physical => f.write_str("Physical"),
1171 ExplainType::DistSql => f.write_str("DistSQL"),
1172 }
1173 }
1174}
1175
1176#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1177#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1178pub enum ExplainFormat {
1179 Text,
1180 Json,
1181 Xml,
1182 Yaml,
1183 Dot,
1184}
1185
1186impl fmt::Display for ExplainFormat {
1187 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1188 match self {
1189 ExplainFormat::Text => f.write_str("TEXT"),
1190 ExplainFormat::Json => f.write_str("JSON"),
1191 ExplainFormat::Xml => f.write_str("XML"),
1192 ExplainFormat::Yaml => f.write_str("YAML"),
1193 ExplainFormat::Dot => f.write_str("DOT"),
1194 }
1195 }
1196}
1197
1198#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1199#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1200pub struct ExplainOptions {
1201 pub verbose: bool,
1203 pub trace: bool,
1205 pub backfill: bool,
1207 pub explain_type: ExplainType,
1209 pub explain_format: ExplainFormat,
1211}
1212
1213impl Default for ExplainOptions {
1214 fn default() -> Self {
1215 Self {
1216 verbose: false,
1217 trace: false,
1218 backfill: false,
1219 explain_type: ExplainType::Physical,
1220 explain_format: ExplainFormat::Text,
1221 }
1222 }
1223}
1224
1225impl fmt::Display for ExplainOptions {
1226 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1227 let default = Self::default();
1228 if *self == default {
1229 Ok(())
1230 } else {
1231 let mut option_strs = vec![];
1232 if self.verbose {
1233 option_strs.push("VERBOSE".to_owned());
1234 }
1235 if self.trace {
1236 option_strs.push("TRACE".to_owned());
1237 }
1238 if self.backfill {
1239 option_strs.push("BACKFILL".to_owned());
1240 }
1241 if self.explain_type == default.explain_type {
1242 option_strs.push(self.explain_type.to_string());
1243 }
1244 if self.explain_format == default.explain_format {
1245 option_strs.push(self.explain_format.to_string());
1246 }
1247 write!(f, "{}", option_strs.iter().format(","))
1248 }
1249 }
1250}
1251
1252#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1253#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1254pub struct CdcTableInfo {
1255 pub source_name: ObjectName,
1256 pub external_table_name: String,
1257}
1258
1259#[allow(clippy::large_enum_variant)]
1261#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1262#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1263pub enum Statement {
1264 Analyze {
1266 table_name: ObjectName,
1267 },
1268 Truncate {
1270 table_name: ObjectName,
1271 },
1272 Query(Box<Query>),
1274 Insert {
1276 table_name: ObjectName,
1278 columns: Vec<Ident>,
1280 source: Box<Query>,
1282 returning: Vec<SelectItem>,
1284 },
1285 Copy {
1286 table_name: ObjectName,
1288 columns: Vec<Ident>,
1290 values: Vec<Option<String>>,
1292 },
1293 Update {
1295 table_name: ObjectName,
1297 assignments: Vec<Assignment>,
1299 selection: Option<Expr>,
1301 returning: Vec<SelectItem>,
1303 },
1304 Delete {
1306 table_name: ObjectName,
1308 selection: Option<Expr>,
1310 returning: Vec<SelectItem>,
1312 },
1313 Discard(DiscardType),
1315 CreateView {
1317 or_replace: bool,
1318 materialized: bool,
1319 if_not_exists: bool,
1320 name: ObjectName,
1322 columns: Vec<Ident>,
1323 query: Box<Query>,
1324 emit_mode: Option<EmitMode>,
1325 with_options: Vec<SqlOption>,
1326 },
1327 CreateTable {
1329 or_replace: bool,
1330 temporary: bool,
1331 if_not_exists: bool,
1332 name: ObjectName,
1334 columns: Vec<ColumnDef>,
1336 wildcard_idx: Option<usize>,
1338 constraints: Vec<TableConstraint>,
1339 with_options: Vec<SqlOption>,
1340 format_encode: Option<CompatibleFormatEncode>,
1342 source_watermarks: Vec<SourceWatermark>,
1344 append_only: bool,
1346 on_conflict: Option<OnConflict>,
1348 with_version_column: Option<Ident>,
1350 query: Option<Box<Query>>,
1352 cdc_table_info: Option<CdcTableInfo>,
1354 include_column_options: IncludeOption,
1356 webhook_info: Option<WebhookSourceInfo>,
1358 engine: Engine,
1360 },
1361 CreateIndex {
1363 name: ObjectName,
1365 table_name: ObjectName,
1366 columns: Vec<OrderByExpr>,
1367 include: Vec<Ident>,
1368 distributed_by: Vec<Expr>,
1369 unique: bool,
1370 if_not_exists: bool,
1371 },
1372 CreateSource {
1374 stmt: CreateSourceStatement,
1375 },
1376 CreateSink {
1378 stmt: CreateSinkStatement,
1379 },
1380 CreateSubscription {
1382 stmt: CreateSubscriptionStatement,
1383 },
1384 CreateConnection {
1386 stmt: CreateConnectionStatement,
1387 },
1388 CreateSecret {
1389 stmt: CreateSecretStatement,
1390 },
1391 CreateFunction {
1395 or_replace: bool,
1396 temporary: bool,
1397 if_not_exists: bool,
1398 name: ObjectName,
1399 args: Option<Vec<OperateFunctionArg>>,
1400 returns: Option<CreateFunctionReturns>,
1401 params: CreateFunctionBody,
1403 with_options: CreateFunctionWithOptions, },
1405 CreateAggregate {
1409 or_replace: bool,
1410 if_not_exists: bool,
1411 name: ObjectName,
1412 args: Vec<OperateFunctionArg>,
1413 returns: DataType,
1414 append_only: bool,
1416 params: CreateFunctionBody,
1417 },
1418
1419 DeclareCursor {
1421 stmt: DeclareCursorStatement,
1422 },
1423
1424 FetchCursor {
1426 stmt: FetchCursorStatement,
1427 },
1428
1429 CloseCursor {
1431 stmt: CloseCursorStatement,
1432 },
1433
1434 AlterDatabase {
1436 name: ObjectName,
1437 operation: AlterDatabaseOperation,
1438 },
1439 AlterSchema {
1441 name: ObjectName,
1442 operation: AlterSchemaOperation,
1443 },
1444 AlterTable {
1446 name: ObjectName,
1448 operation: AlterTableOperation,
1449 },
1450 AlterIndex {
1452 name: ObjectName,
1454 operation: AlterIndexOperation,
1455 },
1456 AlterView {
1458 name: ObjectName,
1460 materialized: bool,
1461 operation: AlterViewOperation,
1462 },
1463 AlterSink {
1465 name: ObjectName,
1467 operation: AlterSinkOperation,
1468 },
1469 AlterSubscription {
1470 name: ObjectName,
1471 operation: AlterSubscriptionOperation,
1472 },
1473 AlterSource {
1475 name: ObjectName,
1477 operation: AlterSourceOperation,
1478 },
1479 AlterFunction {
1481 name: ObjectName,
1483 args: Option<Vec<OperateFunctionArg>>,
1484 operation: AlterFunctionOperation,
1485 },
1486 AlterConnection {
1488 name: ObjectName,
1490 operation: AlterConnectionOperation,
1491 },
1492 AlterSecret {
1494 name: ObjectName,
1496 with_options: Vec<SqlOption>,
1497 operation: AlterSecretOperation,
1498 },
1499 AlterFragment {
1501 fragment_id: u32,
1502 operation: AlterFragmentOperation,
1503 },
1504 AlterDefaultPrivileges {
1507 target_users: Option<Vec<Ident>>,
1508 schema_names: Option<Vec<ObjectName>>,
1509 operation: DefaultPrivilegeOperation,
1510 },
1511 Describe {
1513 name: ObjectName,
1515 kind: DescribeKind,
1516 },
1517 DescribeFragment {
1519 fragment_id: u32,
1520 },
1521 ShowObjects {
1523 object: ShowObject,
1524 filter: Option<ShowStatementFilter>,
1525 },
1526 ShowCreateObject {
1528 create_type: ShowCreateType,
1530 name: ObjectName,
1532 },
1533 ShowTransactionIsolationLevel,
1534 CancelJobs(JobIdents),
1536 Kill(String),
1539 Drop(DropStatement),
1541 DropFunction {
1543 if_exists: bool,
1544 func_desc: Vec<FunctionDesc>,
1546 option: Option<ReferentialAction>,
1548 },
1549 DropAggregate {
1551 if_exists: bool,
1552 func_desc: Vec<FunctionDesc>,
1554 option: Option<ReferentialAction>,
1556 },
1557 SetVariable {
1563 local: bool,
1564 variable: Ident,
1565 value: SetVariableValue,
1566 },
1567 ShowVariable {
1571 variable: Vec<Ident>,
1572 },
1573 StartTransaction {
1575 modes: Vec<TransactionMode>,
1576 },
1577 Begin {
1579 modes: Vec<TransactionMode>,
1580 },
1581 Abort,
1583 SetTransaction {
1585 modes: Vec<TransactionMode>,
1586 snapshot: Option<Value>,
1587 session: bool,
1588 },
1589 SetTimeZone {
1591 local: bool,
1592 value: SetTimeZoneValue,
1593 },
1594 Comment {
1598 object_type: CommentObject,
1599 object_name: ObjectName,
1600 comment: Option<String>,
1601 },
1602 Commit {
1604 chain: bool,
1605 },
1606 Rollback {
1608 chain: bool,
1609 },
1610 CreateSchema {
1612 schema_name: ObjectName,
1613 if_not_exists: bool,
1614 owner: Option<ObjectName>,
1615 },
1616 CreateDatabase {
1618 db_name: ObjectName,
1619 if_not_exists: bool,
1620 owner: Option<ObjectName>,
1621 resource_group: Option<SetVariableValue>,
1622 barrier_interval_ms: Option<u32>,
1623 checkpoint_frequency: Option<u64>,
1624 },
1625 Grant {
1627 privileges: Privileges,
1628 objects: GrantObjects,
1629 grantees: Vec<Ident>,
1630 with_grant_option: bool,
1631 granted_by: Option<Ident>,
1632 },
1633 Revoke {
1635 privileges: Privileges,
1636 objects: GrantObjects,
1637 grantees: Vec<Ident>,
1638 granted_by: Option<Ident>,
1639 revoke_grant_option: bool,
1640 cascade: bool,
1641 },
1642 Deallocate {
1646 name: Option<Ident>,
1647 prepare: bool,
1648 },
1649 Execute {
1653 name: Ident,
1654 parameters: Vec<Expr>,
1655 },
1656 Prepare {
1660 name: Ident,
1661 data_types: Vec<DataType>,
1662 statement: Box<Statement>,
1663 },
1664 Explain {
1666 analyze: bool,
1668 statement: Box<Statement>,
1670 options: ExplainOptions,
1672 },
1673 ExplainAnalyzeStreamJob {
1678 target: AnalyzeTarget,
1679 duration_secs: Option<u64>,
1680 },
1681 CreateUser(CreateUserStatement),
1683 AlterUser(AlterUserStatement),
1685 AlterSystem {
1687 param: Ident,
1688 value: SetVariableValue,
1689 },
1690 Flush,
1694 Wait,
1697 Recover,
1699 Use {
1703 db_name: ObjectName,
1704 },
1705}
1706
1707#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1708#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1709pub enum DescribeKind {
1710 Plain,
1712
1713 Fragments,
1715}
1716
1717impl fmt::Display for Statement {
1718 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1723 let sql = self
1725 .try_to_string()
1726 .expect("normalized SQL should be parsable");
1727 f.write_str(&sql)
1728 }
1729}
1730
1731impl Statement {
1732 pub fn try_to_string(&self) -> Result<String, ParserError> {
1736 let sql = self.to_string_unchecked();
1737
1738 if matches!(
1740 self,
1741 Statement::CreateTable { .. } | Statement::CreateSource { .. }
1742 ) {
1743 let _ = Parser::parse_sql(&sql)?;
1744 }
1745 Ok(sql)
1746 }
1747
1748 pub fn to_string_unchecked(&self) -> String {
1754 let mut buf = String::new();
1755 self.fmt_unchecked(&mut buf).unwrap();
1756 buf
1757 }
1758
1759 #[allow(clippy::cognitive_complexity)]
1766 fn fmt_unchecked(&self, mut f: impl std::fmt::Write) -> fmt::Result {
1767 match self {
1768 Statement::Explain {
1769 analyze,
1770 statement,
1771 options,
1772 } => {
1773 write!(f, "EXPLAIN ")?;
1774
1775 if *analyze {
1776 write!(f, "ANALYZE ")?;
1777 }
1778 write!(f, "{}", options)?;
1779
1780 statement.fmt_unchecked(f)
1781 }
1782 Statement::ExplainAnalyzeStreamJob {
1783 target,
1784 duration_secs,
1785 } => {
1786 write!(f, "EXPLAIN ANALYZE {}", target)?;
1787 if let Some(duration_secs) = duration_secs {
1788 write!(f, " (DURATION_SECS {})", duration_secs)?;
1789 }
1790 Ok(())
1791 }
1792 Statement::Query(s) => write!(f, "{}", s),
1793 Statement::Truncate { table_name } => {
1794 write!(f, "TRUNCATE TABLE {}", table_name)?;
1795 Ok(())
1796 }
1797 Statement::Analyze { table_name } => {
1798 write!(f, "ANALYZE TABLE {}", table_name)?;
1799 Ok(())
1800 }
1801 Statement::Describe { name, kind } => {
1802 write!(f, "DESCRIBE {}", name)?;
1803 match kind {
1804 DescribeKind::Plain => {}
1805
1806 DescribeKind::Fragments => {
1807 write!(f, " FRAGMENTS")?;
1808 }
1809 }
1810 Ok(())
1811 }
1812 Statement::DescribeFragment { fragment_id } => {
1813 write!(f, "DESCRIBE FRAGMENT {}", fragment_id)?;
1814 Ok(())
1815 }
1816 Statement::ShowObjects {
1817 object: show_object,
1818 filter,
1819 } => {
1820 write!(f, "SHOW {}", show_object)?;
1821 if let Some(filter) = filter {
1822 write!(f, " {}", filter)?;
1823 }
1824 Ok(())
1825 }
1826 Statement::ShowCreateObject {
1827 create_type: show_type,
1828 name,
1829 } => {
1830 write!(f, "SHOW CREATE {} {}", show_type, name)?;
1831 Ok(())
1832 }
1833 Statement::ShowTransactionIsolationLevel => {
1834 write!(f, "SHOW TRANSACTION ISOLATION LEVEL")?;
1835 Ok(())
1836 }
1837 Statement::Insert {
1838 table_name,
1839 columns,
1840 source,
1841 returning,
1842 } => {
1843 write!(f, "INSERT INTO {table_name} ", table_name = table_name,)?;
1844 if !columns.is_empty() {
1845 write!(f, "({}) ", display_comma_separated(columns))?;
1846 }
1847 write!(f, "{}", source)?;
1848 if !returning.is_empty() {
1849 write!(f, " RETURNING ({})", display_comma_separated(returning))?;
1850 }
1851 Ok(())
1852 }
1853 Statement::Copy {
1854 table_name,
1855 columns,
1856 values,
1857 } => {
1858 write!(f, "COPY {}", table_name)?;
1859 if !columns.is_empty() {
1860 write!(f, " ({})", display_comma_separated(columns))?;
1861 }
1862 write!(f, " FROM stdin; ")?;
1863 if !values.is_empty() {
1864 writeln!(f)?;
1865 let mut delim = "";
1866 for v in values {
1867 write!(f, "{}", delim)?;
1868 delim = "\t";
1869 if let Some(v) = v {
1870 write!(f, "{}", v)?;
1871 } else {
1872 write!(f, "\\N")?;
1873 }
1874 }
1875 }
1876 write!(f, "\n\\.")
1877 }
1878 Statement::Update {
1879 table_name,
1880 assignments,
1881 selection,
1882 returning,
1883 } => {
1884 write!(f, "UPDATE {}", table_name)?;
1885 if !assignments.is_empty() {
1886 write!(f, " SET {}", display_comma_separated(assignments))?;
1887 }
1888 if let Some(selection) = selection {
1889 write!(f, " WHERE {}", selection)?;
1890 }
1891 if !returning.is_empty() {
1892 write!(f, " RETURNING ({})", display_comma_separated(returning))?;
1893 }
1894 Ok(())
1895 }
1896 Statement::Delete {
1897 table_name,
1898 selection,
1899 returning,
1900 } => {
1901 write!(f, "DELETE FROM {}", table_name)?;
1902 if let Some(selection) = selection {
1903 write!(f, " WHERE {}", selection)?;
1904 }
1905 if !returning.is_empty() {
1906 write!(f, " RETURNING {}", display_comma_separated(returning))?;
1907 }
1908 Ok(())
1909 }
1910 Statement::CreateDatabase {
1911 db_name,
1912 if_not_exists,
1913 owner,
1914 resource_group,
1915 barrier_interval_ms,
1916 checkpoint_frequency,
1917 } => {
1918 write!(f, "CREATE DATABASE")?;
1919 if *if_not_exists {
1920 write!(f, " IF NOT EXISTS")?;
1921 }
1922 write!(f, " {}", db_name)?;
1923 if let Some(owner) = owner {
1924 write!(f, " WITH OWNER = {}", owner)?;
1925 }
1926 if let Some(resource_group) = resource_group {
1927 write!(f, " RESOURCE_GROUP = {}", resource_group)?;
1928 }
1929 if let Some(barrier_interval_ms) = barrier_interval_ms {
1930 write!(f, " BARRIER_INTERVAL_MS = {}", barrier_interval_ms)?;
1931 }
1932 if let Some(checkpoint_frequency) = checkpoint_frequency {
1933 write!(f, " CHECKPOINT_FREQUENCY = {}", checkpoint_frequency)?;
1934 }
1935
1936 Ok(())
1937 }
1938 Statement::CreateFunction {
1939 or_replace,
1940 temporary,
1941 if_not_exists,
1942 name,
1943 args,
1944 returns,
1945 params,
1946 with_options,
1947 } => {
1948 write!(
1949 f,
1950 "CREATE {or_replace}{temp}FUNCTION {if_not_exists}{name}",
1951 temp = if *temporary { "TEMPORARY " } else { "" },
1952 or_replace = if *or_replace { "OR REPLACE " } else { "" },
1953 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
1954 )?;
1955 if let Some(args) = args {
1956 write!(f, "({})", display_comma_separated(args))?;
1957 }
1958 if let Some(return_type) = returns {
1959 write!(f, " {}", return_type)?;
1960 }
1961 write!(f, "{params}")?;
1962 write!(f, "{with_options}")?;
1963 Ok(())
1964 }
1965 Statement::CreateAggregate {
1966 or_replace,
1967 if_not_exists,
1968 name,
1969 args,
1970 returns,
1971 append_only,
1972 params,
1973 } => {
1974 write!(
1975 f,
1976 "CREATE {or_replace}AGGREGATE {if_not_exists}{name}",
1977 or_replace = if *or_replace { "OR REPLACE " } else { "" },
1978 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
1979 )?;
1980 write!(f, "({})", display_comma_separated(args))?;
1981 write!(f, " RETURNS {}", returns)?;
1982 if *append_only {
1983 write!(f, " APPEND ONLY")?;
1984 }
1985 write!(f, "{params}")?;
1986 Ok(())
1987 }
1988 Statement::CreateView {
1989 name,
1990 or_replace,
1991 if_not_exists,
1992 columns,
1993 query,
1994 materialized,
1995 with_options,
1996 emit_mode,
1997 } => {
1998 write!(
1999 f,
2000 "CREATE {or_replace}{materialized}VIEW {if_not_exists}{name}",
2001 or_replace = if *or_replace { "OR REPLACE " } else { "" },
2002 materialized = if *materialized { "MATERIALIZED " } else { "" },
2003 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
2004 name = name
2005 )?;
2006 if !with_options.is_empty() {
2007 write!(f, " WITH ({})", display_comma_separated(with_options))?;
2008 }
2009 if !columns.is_empty() {
2010 write!(f, " ({})", display_comma_separated(columns))?;
2011 }
2012 write!(f, " AS {}", query)?;
2013 if let Some(emit_mode) = emit_mode {
2014 write!(f, " EMIT {}", emit_mode)?;
2015 }
2016 Ok(())
2017 }
2018 Statement::CreateTable {
2019 name,
2020 columns,
2021 wildcard_idx,
2022 constraints,
2023 with_options,
2024 or_replace,
2025 if_not_exists,
2026 temporary,
2027 format_encode,
2028 source_watermarks,
2029 append_only,
2030 on_conflict,
2031 with_version_column,
2032 query,
2033 cdc_table_info,
2034 include_column_options,
2035 webhook_info,
2036 engine,
2037 } => {
2038 write!(
2046 f,
2047 "CREATE {or_replace}{temporary}TABLE {if_not_exists}{name}",
2048 or_replace = if *or_replace { "OR REPLACE " } else { "" },
2049 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
2050 temporary = if *temporary { "TEMPORARY " } else { "" },
2051 name = name,
2052 )?;
2053 if !columns.is_empty() || !constraints.is_empty() {
2054 write!(
2055 f,
2056 " {}",
2057 fmt_create_items(columns, constraints, source_watermarks, *wildcard_idx)?
2058 )?;
2059 } else if query.is_none() {
2060 write!(f, " ()")?;
2062 }
2063 if *append_only {
2064 write!(f, " APPEND ONLY")?;
2065 }
2066
2067 if let Some(on_conflict_behavior) = on_conflict {
2068 write!(f, " ON CONFLICT {}", on_conflict_behavior)?;
2069 }
2070 if let Some(version_column) = with_version_column {
2071 write!(f, " WITH VERSION COLUMN({})", version_column)?;
2072 }
2073 if !include_column_options.is_empty() {
2074 write!(f, " {}", display_separated(include_column_options, " "))?;
2075 }
2076 if !with_options.is_empty() {
2077 write!(f, " WITH ({})", display_comma_separated(with_options))?;
2078 }
2079 if let Some(format_encode) = format_encode {
2080 write!(f, " {}", format_encode)?;
2081 }
2082 if let Some(query) = query {
2083 write!(f, " AS {}", query)?;
2084 }
2085 if let Some(info) = cdc_table_info {
2086 write!(f, " FROM {}", info.source_name)?;
2087 write!(f, " TABLE '{}'", info.external_table_name)?;
2088 }
2089 if let Some(info) = webhook_info {
2090 if let Some(secret) = &info.secret_ref {
2091 write!(f, " VALIDATE SECRET {}", secret.secret_name)?;
2092 } else {
2093 write!(f, " VALIDATE")?;
2094 }
2095 write!(f, " AS {}", info.signature_expr)?;
2096 }
2097 match engine {
2098 Engine::Hummock => {}
2099 Engine::Iceberg => {
2100 write!(f, " ENGINE = {}", engine)?;
2101 }
2102 }
2103 Ok(())
2104 }
2105 Statement::CreateIndex {
2106 name,
2107 table_name,
2108 columns,
2109 include,
2110 distributed_by,
2111 unique,
2112 if_not_exists,
2113 } => write!(
2114 f,
2115 "CREATE {unique}INDEX {if_not_exists}{name} ON {table_name}({columns}){include}{distributed_by}",
2116 unique = if *unique { "UNIQUE " } else { "" },
2117 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
2118 name = name,
2119 table_name = table_name,
2120 columns = display_comma_separated(columns),
2121 include = if include.is_empty() {
2122 "".to_owned()
2123 } else {
2124 format!(" INCLUDE({})", display_separated(include, ","))
2125 },
2126 distributed_by = if distributed_by.is_empty() {
2127 "".to_owned()
2128 } else {
2129 format!(
2130 " DISTRIBUTED BY({})",
2131 display_separated(distributed_by, ",")
2132 )
2133 }
2134 ),
2135 Statement::CreateSource { stmt } => write!(f, "CREATE SOURCE {}", stmt,),
2136 Statement::CreateSink { stmt } => write!(f, "CREATE SINK {}", stmt,),
2137 Statement::CreateSubscription { stmt } => write!(f, "CREATE SUBSCRIPTION {}", stmt,),
2138 Statement::CreateConnection { stmt } => write!(f, "CREATE CONNECTION {}", stmt,),
2139 Statement::DeclareCursor { stmt } => write!(f, "DECLARE {}", stmt,),
2140 Statement::FetchCursor { stmt } => write!(f, "FETCH {}", stmt),
2141 Statement::CloseCursor { stmt } => write!(f, "CLOSE {}", stmt),
2142 Statement::CreateSecret { stmt } => write!(f, "CREATE SECRET {}", stmt),
2143 Statement::AlterDatabase { name, operation } => {
2144 write!(f, "ALTER DATABASE {} {}", name, operation)
2145 }
2146 Statement::AlterSchema { name, operation } => {
2147 write!(f, "ALTER SCHEMA {} {}", name, operation)
2148 }
2149 Statement::AlterTable { name, operation } => {
2150 write!(f, "ALTER TABLE {} {}", name, operation)
2151 }
2152 Statement::AlterIndex { name, operation } => {
2153 write!(f, "ALTER INDEX {} {}", name, operation)
2154 }
2155 Statement::AlterView {
2156 materialized,
2157 name,
2158 operation,
2159 } => {
2160 write!(
2161 f,
2162 "ALTER {}VIEW {} {}",
2163 if *materialized { "MATERIALIZED " } else { "" },
2164 name,
2165 operation
2166 )
2167 }
2168 Statement::AlterSink { name, operation } => {
2169 write!(f, "ALTER SINK {} {}", name, operation)
2170 }
2171 Statement::AlterSubscription { name, operation } => {
2172 write!(f, "ALTER SUBSCRIPTION {} {}", name, operation)
2173 }
2174 Statement::AlterSource { name, operation } => {
2175 write!(f, "ALTER SOURCE {} {}", name, operation)
2176 }
2177 Statement::AlterFunction {
2178 name,
2179 args,
2180 operation,
2181 } => {
2182 write!(f, "ALTER FUNCTION {}", name)?;
2183 if let Some(args) = args {
2184 write!(f, "({})", display_comma_separated(args))?;
2185 }
2186 write!(f, " {}", operation)
2187 }
2188 Statement::AlterConnection { name, operation } => {
2189 write!(f, "ALTER CONNECTION {} {}", name, operation)
2190 }
2191 Statement::AlterSecret {
2192 name,
2193 with_options,
2194 operation,
2195 } => {
2196 write!(f, "ALTER SECRET {}", name)?;
2197 if !with_options.is_empty() {
2198 write!(f, " WITH ({})", display_comma_separated(with_options))?;
2199 }
2200 write!(f, " {}", operation)
2201 }
2202 Statement::Discard(t) => write!(f, "DISCARD {}", t),
2203 Statement::Drop(stmt) => write!(f, "DROP {}", stmt),
2204 Statement::DropFunction {
2205 if_exists,
2206 func_desc,
2207 option,
2208 } => {
2209 write!(
2210 f,
2211 "DROP FUNCTION{} {}",
2212 if *if_exists { " IF EXISTS" } else { "" },
2213 display_comma_separated(func_desc),
2214 )?;
2215 if let Some(op) = option {
2216 write!(f, " {}", op)?;
2217 }
2218 Ok(())
2219 }
2220 Statement::DropAggregate {
2221 if_exists,
2222 func_desc,
2223 option,
2224 } => {
2225 write!(
2226 f,
2227 "DROP AGGREGATE{} {}",
2228 if *if_exists { " IF EXISTS" } else { "" },
2229 display_comma_separated(func_desc),
2230 )?;
2231 if let Some(op) = option {
2232 write!(f, " {}", op)?;
2233 }
2234 Ok(())
2235 }
2236 Statement::SetVariable {
2237 local,
2238 variable,
2239 value,
2240 } => {
2241 f.write_str("SET ")?;
2242 if *local {
2243 f.write_str("LOCAL ")?;
2244 }
2245 write!(f, "{name} = {value}", name = variable,)
2246 }
2247 Statement::ShowVariable { variable } => {
2248 write!(f, "SHOW")?;
2249 if !variable.is_empty() {
2250 write!(f, " {}", display_separated(variable, " "))?;
2251 }
2252 Ok(())
2253 }
2254 Statement::StartTransaction { modes } => {
2255 write!(f, "START TRANSACTION")?;
2256 if !modes.is_empty() {
2257 write!(f, " {}", display_comma_separated(modes))?;
2258 }
2259 Ok(())
2260 }
2261 Statement::Abort => {
2262 write!(f, "ABORT")?;
2263 Ok(())
2264 }
2265 Statement::SetTransaction {
2266 modes,
2267 snapshot,
2268 session,
2269 } => {
2270 if *session {
2271 write!(f, "SET SESSION CHARACTERISTICS AS TRANSACTION")?;
2272 } else {
2273 write!(f, "SET TRANSACTION")?;
2274 }
2275 if !modes.is_empty() {
2276 write!(f, " {}", display_comma_separated(modes))?;
2277 }
2278 if let Some(snapshot_id) = snapshot {
2279 write!(f, " SNAPSHOT {}", snapshot_id)?;
2280 }
2281 Ok(())
2282 }
2283 Statement::SetTimeZone { local, value } => {
2284 write!(f, "SET")?;
2285 if *local {
2286 write!(f, " LOCAL")?;
2287 }
2288 write!(f, " TIME ZONE {}", value)?;
2289 Ok(())
2290 }
2291 Statement::Commit { chain } => {
2292 write!(f, "COMMIT{}", if *chain { " AND CHAIN" } else { "" },)
2293 }
2294 Statement::Rollback { chain } => {
2295 write!(f, "ROLLBACK{}", if *chain { " AND CHAIN" } else { "" },)
2296 }
2297 Statement::CreateSchema {
2298 schema_name,
2299 if_not_exists,
2300 owner,
2301 } => {
2302 write!(
2303 f,
2304 "CREATE SCHEMA {if_not_exists}{name}",
2305 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
2306 name = schema_name
2307 )?;
2308 if let Some(user) = owner {
2309 write!(f, " AUTHORIZATION {}", user)?;
2310 }
2311 Ok(())
2312 }
2313 Statement::Grant {
2314 privileges,
2315 objects,
2316 grantees,
2317 with_grant_option,
2318 granted_by,
2319 } => {
2320 write!(f, "GRANT {} ", privileges)?;
2321 write!(f, "ON {} ", objects)?;
2322 write!(f, "TO {}", display_comma_separated(grantees))?;
2323 if *with_grant_option {
2324 write!(f, " WITH GRANT OPTION")?;
2325 }
2326 if let Some(grantor) = granted_by {
2327 write!(f, " GRANTED BY {}", grantor)?;
2328 }
2329 Ok(())
2330 }
2331 Statement::Revoke {
2332 privileges,
2333 objects,
2334 grantees,
2335 granted_by,
2336 revoke_grant_option,
2337 cascade,
2338 } => {
2339 write!(
2340 f,
2341 "REVOKE {}{} ",
2342 if *revoke_grant_option {
2343 "GRANT OPTION FOR "
2344 } else {
2345 ""
2346 },
2347 privileges
2348 )?;
2349 write!(f, "ON {} ", objects)?;
2350 write!(f, "FROM {}", display_comma_separated(grantees))?;
2351 if let Some(grantor) = granted_by {
2352 write!(f, " GRANTED BY {}", grantor)?;
2353 }
2354 write!(f, " {}", if *cascade { "CASCADE" } else { "RESTRICT" })?;
2355 Ok(())
2356 }
2357 Statement::Deallocate { name, prepare } => {
2358 if let Some(name) = name {
2359 write!(
2360 f,
2361 "DEALLOCATE {prepare}{name}",
2362 prepare = if *prepare { "PREPARE " } else { "" },
2363 name = name,
2364 )
2365 } else {
2366 write!(
2367 f,
2368 "DEALLOCATE {prepare}ALL",
2369 prepare = if *prepare { "PREPARE " } else { "" },
2370 )
2371 }
2372 }
2373 Statement::Execute { name, parameters } => {
2374 write!(f, "EXECUTE {}", name)?;
2375 if !parameters.is_empty() {
2376 write!(f, "({})", display_comma_separated(parameters))?;
2377 }
2378 Ok(())
2379 }
2380 Statement::Prepare {
2381 name,
2382 data_types,
2383 statement,
2384 } => {
2385 write!(f, "PREPARE {} ", name)?;
2386 if !data_types.is_empty() {
2387 write!(f, "({}) ", display_comma_separated(data_types))?;
2388 }
2389 write!(f, "AS ")?;
2390 statement.fmt_unchecked(f)
2391 }
2392 Statement::Comment {
2393 object_type,
2394 object_name,
2395 comment,
2396 } => {
2397 write!(f, "COMMENT ON {} {} IS ", object_type, object_name)?;
2398 if let Some(c) = comment {
2399 write!(f, "'{}'", c)
2400 } else {
2401 write!(f, "NULL")
2402 }
2403 }
2404 Statement::CreateUser(statement) => {
2405 write!(f, "CREATE USER {}", statement)
2406 }
2407 Statement::AlterUser(statement) => {
2408 write!(f, "ALTER USER {}", statement)
2409 }
2410 Statement::AlterSystem { param, value } => {
2411 f.write_str("ALTER SYSTEM SET ")?;
2412 write!(f, "{param} = {value}",)
2413 }
2414 Statement::Flush => {
2415 write!(f, "FLUSH")
2416 }
2417 Statement::Wait => {
2418 write!(f, "WAIT")
2419 }
2420 Statement::Begin { modes } => {
2421 write!(f, "BEGIN")?;
2422 if !modes.is_empty() {
2423 write!(f, " {}", display_comma_separated(modes))?;
2424 }
2425 Ok(())
2426 }
2427 Statement::CancelJobs(jobs) => {
2428 write!(f, "CANCEL JOBS {}", display_comma_separated(&jobs.0))?;
2429 Ok(())
2430 }
2431 Statement::Kill(worker_process_id) => {
2432 write!(f, "KILL '{}'", worker_process_id)?;
2433 Ok(())
2434 }
2435 Statement::Recover => {
2436 write!(f, "RECOVER")?;
2437 Ok(())
2438 }
2439 Statement::Use { db_name } => {
2440 write!(f, "USE {}", db_name)?;
2441 Ok(())
2442 }
2443 Statement::AlterFragment {
2444 fragment_id,
2445 operation,
2446 } => {
2447 write!(f, "ALTER FRAGMENT {} {}", fragment_id, operation)
2448 }
2449 Statement::AlterDefaultPrivileges {
2450 target_users,
2451 schema_names,
2452 operation,
2453 } => {
2454 write!(f, "ALTER DEFAULT PRIVILEGES")?;
2455 if let Some(target_users) = target_users {
2456 write!(f, " FOR {}", display_comma_separated(target_users))?;
2457 }
2458 if let Some(schema_names) = schema_names {
2459 write!(f, " IN SCHEMA {}", display_comma_separated(schema_names))?;
2460 }
2461 write!(f, " {}", operation)
2462 }
2463 }
2464 }
2465
2466 pub fn is_create(&self) -> bool {
2467 matches!(
2468 self,
2469 Statement::CreateTable { .. }
2470 | Statement::CreateView { .. }
2471 | Statement::CreateSource { .. }
2472 | Statement::CreateSink { .. }
2473 | Statement::CreateSubscription { .. }
2474 | Statement::CreateConnection { .. }
2475 | Statement::CreateSecret { .. }
2476 | Statement::CreateUser { .. }
2477 | Statement::CreateDatabase { .. }
2478 | Statement::CreateFunction { .. }
2479 | Statement::CreateAggregate { .. }
2480 | Statement::CreateIndex { .. }
2481 | Statement::CreateSchema { .. }
2482 )
2483 }
2484}
2485
2486impl Display for IncludeOptionItem {
2487 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2488 let Self {
2489 column_type,
2490 inner_field,
2491 header_inner_expect_type,
2492 column_alias,
2493 } = self;
2494 write!(f, "INCLUDE {}", column_type)?;
2495 if let Some(inner_field) = inner_field {
2496 write!(f, " '{}'", value::escape_single_quote_string(inner_field))?;
2497 if let Some(expected_type) = header_inner_expect_type {
2498 write!(f, " {}", expected_type)?;
2499 }
2500 }
2501 if let Some(alias) = column_alias {
2502 write!(f, " AS {}", alias)?;
2503 }
2504 Ok(())
2505 }
2506}
2507
2508#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2509#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2510#[non_exhaustive]
2511pub enum OnInsert {
2512 DuplicateKeyUpdate(Vec<Assignment>),
2514}
2515
2516impl fmt::Display for OnInsert {
2517 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2518 match self {
2519 Self::DuplicateKeyUpdate(expr) => write!(
2520 f,
2521 " ON DUPLICATE KEY UPDATE {}",
2522 display_comma_separated(expr)
2523 ),
2524 }
2525 }
2526}
2527
2528#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2530#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2531pub enum Privileges {
2532 All {
2534 with_privileges_keyword: bool,
2536 },
2537 Actions(Vec<Action>),
2539}
2540
2541impl fmt::Display for Privileges {
2542 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2543 match self {
2544 Privileges::All {
2545 with_privileges_keyword,
2546 } => {
2547 write!(
2548 f,
2549 "ALL{}",
2550 if *with_privileges_keyword {
2551 " PRIVILEGES"
2552 } else {
2553 ""
2554 }
2555 )
2556 }
2557 Privileges::Actions(actions) => {
2558 write!(f, "{}", display_comma_separated(actions))
2559 }
2560 }
2561 }
2562}
2563
2564#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2566#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2567pub enum Action {
2568 Connect,
2569 Create,
2570 Delete,
2571 Execute,
2572 Insert { columns: Option<Vec<Ident>> },
2573 References { columns: Option<Vec<Ident>> },
2574 Select { columns: Option<Vec<Ident>> },
2575 Temporary,
2576 Trigger,
2577 Truncate,
2578 Update { columns: Option<Vec<Ident>> },
2579 Usage,
2580}
2581
2582impl fmt::Display for Action {
2583 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2584 match self {
2585 Action::Connect => f.write_str("CONNECT")?,
2586 Action::Create => f.write_str("CREATE")?,
2587 Action::Delete => f.write_str("DELETE")?,
2588 Action::Execute => f.write_str("EXECUTE")?,
2589 Action::Insert { .. } => f.write_str("INSERT")?,
2590 Action::References { .. } => f.write_str("REFERENCES")?,
2591 Action::Select { .. } => f.write_str("SELECT")?,
2592 Action::Temporary => f.write_str("TEMPORARY")?,
2593 Action::Trigger => f.write_str("TRIGGER")?,
2594 Action::Truncate => f.write_str("TRUNCATE")?,
2595 Action::Update { .. } => f.write_str("UPDATE")?,
2596 Action::Usage => f.write_str("USAGE")?,
2597 };
2598 match self {
2599 Action::Insert { columns }
2600 | Action::References { columns }
2601 | Action::Select { columns }
2602 | Action::Update { columns } => {
2603 if let Some(columns) = columns {
2604 write!(f, " ({})", display_comma_separated(columns))?;
2605 }
2606 }
2607 _ => (),
2608 };
2609 Ok(())
2610 }
2611}
2612
2613#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2615#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2616pub enum GrantObjects {
2617 AllSequencesInSchema { schemas: Vec<ObjectName> },
2619 AllTablesInSchema { schemas: Vec<ObjectName> },
2621 AllSourcesInSchema { schemas: Vec<ObjectName> },
2623 AllSinksInSchema { schemas: Vec<ObjectName> },
2625 AllMviewsInSchema { schemas: Vec<ObjectName> },
2627 AllViewsInSchema { schemas: Vec<ObjectName> },
2629 AllFunctionsInSchema { schemas: Vec<ObjectName> },
2631 AllSecretsInSchema { schemas: Vec<ObjectName> },
2633 AllSubscriptionsInSchema { schemas: Vec<ObjectName> },
2635 AllConnectionsInSchema { schemas: Vec<ObjectName> },
2637 Databases(Vec<ObjectName>),
2639 Schemas(Vec<ObjectName>),
2641 Sources(Vec<ObjectName>),
2643 Mviews(Vec<ObjectName>),
2645 Sequences(Vec<ObjectName>),
2647 Tables(Vec<ObjectName>),
2649 Sinks(Vec<ObjectName>),
2651 Views(Vec<ObjectName>),
2653 Connections(Vec<ObjectName>),
2655 Subscriptions(Vec<ObjectName>),
2657 Functions(Vec<FunctionDesc>),
2659 Secrets(Vec<ObjectName>),
2661}
2662
2663impl fmt::Display for GrantObjects {
2664 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2665 match self {
2666 GrantObjects::Sequences(sequences) => {
2667 write!(f, "SEQUENCE {}", display_comma_separated(sequences))
2668 }
2669 GrantObjects::Schemas(schemas) => {
2670 write!(f, "SCHEMA {}", display_comma_separated(schemas))
2671 }
2672 GrantObjects::Tables(tables) => {
2673 write!(f, "{}", display_comma_separated(tables))
2674 }
2675 GrantObjects::AllSequencesInSchema { schemas } => {
2676 write!(
2677 f,
2678 "ALL SEQUENCES IN SCHEMA {}",
2679 display_comma_separated(schemas)
2680 )
2681 }
2682 GrantObjects::AllTablesInSchema { schemas } => {
2683 write!(
2684 f,
2685 "ALL TABLES IN SCHEMA {}",
2686 display_comma_separated(schemas)
2687 )
2688 }
2689 GrantObjects::AllSourcesInSchema { schemas } => {
2690 write!(
2691 f,
2692 "ALL SOURCES IN SCHEMA {}",
2693 display_comma_separated(schemas)
2694 )
2695 }
2696 GrantObjects::AllMviewsInSchema { schemas } => {
2697 write!(
2698 f,
2699 "ALL MATERIALIZED VIEWS IN SCHEMA {}",
2700 display_comma_separated(schemas)
2701 )
2702 }
2703 GrantObjects::AllSinksInSchema { schemas } => {
2704 write!(
2705 f,
2706 "ALL SINKS IN SCHEMA {}",
2707 display_comma_separated(schemas)
2708 )
2709 }
2710 GrantObjects::AllViewsInSchema { schemas } => {
2711 write!(
2712 f,
2713 "ALL VIEWS IN SCHEMA {}",
2714 display_comma_separated(schemas)
2715 )
2716 }
2717 GrantObjects::AllFunctionsInSchema { schemas } => {
2718 write!(
2719 f,
2720 "ALL FUNCTIONS IN SCHEMA {}",
2721 display_comma_separated(schemas)
2722 )
2723 }
2724 GrantObjects::AllSecretsInSchema { schemas } => {
2725 write!(
2726 f,
2727 "ALL SECRETS IN SCHEMA {}",
2728 display_comma_separated(schemas)
2729 )
2730 }
2731 GrantObjects::AllSubscriptionsInSchema { schemas } => {
2732 write!(
2733 f,
2734 "ALL SUBSCRIPTIONS IN SCHEMA {}",
2735 display_comma_separated(schemas)
2736 )
2737 }
2738 GrantObjects::AllConnectionsInSchema { schemas } => {
2739 write!(
2740 f,
2741 "ALL CONNECTIONS IN SCHEMA {}",
2742 display_comma_separated(schemas)
2743 )
2744 }
2745 GrantObjects::Databases(databases) => {
2746 write!(f, "DATABASE {}", display_comma_separated(databases))
2747 }
2748 GrantObjects::Sources(sources) => {
2749 write!(f, "SOURCE {}", display_comma_separated(sources))
2750 }
2751 GrantObjects::Mviews(mviews) => {
2752 write!(f, "MATERIALIZED VIEW {}", display_comma_separated(mviews))
2753 }
2754 GrantObjects::Sinks(sinks) => {
2755 write!(f, "SINK {}", display_comma_separated(sinks))
2756 }
2757 GrantObjects::Views(views) => {
2758 write!(f, "VIEW {}", display_comma_separated(views))
2759 }
2760 GrantObjects::Connections(connections) => {
2761 write!(f, "CONNECTION {}", display_comma_separated(connections))
2762 }
2763 GrantObjects::Subscriptions(subscriptions) => {
2764 write!(f, "SUBSCRIPTION {}", display_comma_separated(subscriptions))
2765 }
2766 GrantObjects::Functions(func_descs) => {
2767 write!(f, "FUNCTION {}", display_comma_separated(func_descs))
2768 }
2769 GrantObjects::Secrets(secrets) => {
2770 write!(f, "SECRET {}", display_comma_separated(secrets))
2771 }
2772 }
2773 }
2774}
2775
2776#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2777#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2778pub enum PrivilegeObjectType {
2779 Tables,
2780 Sources,
2781 Sinks,
2782 Mviews,
2783 Views,
2784 Functions,
2785 Connections,
2786 Secrets,
2787 Subscriptions,
2788 Schemas,
2789}
2790
2791impl fmt::Display for PrivilegeObjectType {
2792 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2793 match self {
2794 PrivilegeObjectType::Tables => f.write_str("TABLES")?,
2795 PrivilegeObjectType::Sources => f.write_str("SOURCES")?,
2796 PrivilegeObjectType::Sinks => f.write_str("SINKS")?,
2797 PrivilegeObjectType::Mviews => f.write_str("MATERIALIZED VIEWS")?,
2798 PrivilegeObjectType::Views => f.write_str("VIEWS")?,
2799 PrivilegeObjectType::Functions => f.write_str("FUNCTIONS")?,
2800 PrivilegeObjectType::Connections => f.write_str("CONNECTIONS")?,
2801 PrivilegeObjectType::Secrets => f.write_str("SECRETS")?,
2802 PrivilegeObjectType::Subscriptions => f.write_str("SUBSCRIPTIONS")?,
2803 PrivilegeObjectType::Schemas => f.write_str("SCHEMAS")?,
2804 };
2805 Ok(())
2806 }
2807}
2808
2809#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2810#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2811pub enum DefaultPrivilegeOperation {
2812 Grant {
2813 privileges: Privileges,
2814 object_type: PrivilegeObjectType,
2815 grantees: Vec<Ident>,
2816 with_grant_option: bool,
2817 },
2818 Revoke {
2819 privileges: Privileges,
2820 object_type: PrivilegeObjectType,
2821 grantees: Vec<Ident>,
2822 revoke_grant_option: bool,
2823 cascade: bool,
2824 },
2825}
2826
2827impl fmt::Display for DefaultPrivilegeOperation {
2828 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2829 match self {
2830 DefaultPrivilegeOperation::Grant {
2831 privileges,
2832 object_type,
2833 grantees,
2834 with_grant_option,
2835 } => {
2836 write!(
2837 f,
2838 "GRANT {} ON {} TO {}",
2839 privileges,
2840 object_type,
2841 display_comma_separated(grantees)
2842 )?;
2843 if *with_grant_option {
2844 write!(f, " WITH GRANT OPTION")?;
2845 }
2846 }
2847 DefaultPrivilegeOperation::Revoke {
2848 privileges,
2849 object_type,
2850 grantees,
2851 revoke_grant_option,
2852 cascade,
2853 } => {
2854 write!(f, "REVOKE")?;
2855 if *revoke_grant_option {
2856 write!(f, " GRANT OPTION FOR")?;
2857 }
2858 write!(
2859 f,
2860 " {} ON {} FROM {}",
2861 privileges,
2862 object_type,
2863 display_comma_separated(grantees)
2864 )?;
2865 write!(f, " {}", if *cascade { "CASCADE" } else { "RESTRICT" })?;
2866 }
2867 }
2868 Ok(())
2869 }
2870}
2871
2872impl DefaultPrivilegeOperation {
2873 pub fn for_schemas(&self) -> bool {
2874 match &self {
2875 DefaultPrivilegeOperation::Grant { object_type, .. } => {
2876 object_type == &PrivilegeObjectType::Schemas
2877 }
2878 DefaultPrivilegeOperation::Revoke { object_type, .. } => {
2879 object_type == &PrivilegeObjectType::Schemas
2880 }
2881 }
2882 }
2883}
2884
2885#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2886#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2887pub enum AssignmentValue {
2888 Expr(Expr),
2890 Default,
2892}
2893
2894impl fmt::Display for AssignmentValue {
2895 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2896 match self {
2897 AssignmentValue::Expr(expr) => write!(f, "{}", expr),
2898 AssignmentValue::Default => f.write_str("DEFAULT"),
2899 }
2900 }
2901}
2902
2903#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2905#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2906pub struct Assignment {
2907 pub id: Vec<Ident>,
2908 pub value: AssignmentValue,
2909}
2910
2911impl fmt::Display for Assignment {
2912 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2913 write!(f, "{} = {}", display_separated(&self.id, "."), self.value)
2914 }
2915}
2916
2917#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2918#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2919pub enum FunctionArgExpr {
2920 Expr(Expr),
2921 ExprQualifiedWildcard(Expr, Vec<Ident>),
2925 QualifiedWildcard(ObjectName, Option<Vec<Expr>>),
2928 Wildcard(Option<Vec<Expr>>),
2930}
2931
2932impl fmt::Display for FunctionArgExpr {
2933 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2934 match self {
2935 FunctionArgExpr::Expr(expr) => write!(f, "{}", expr),
2936 FunctionArgExpr::ExprQualifiedWildcard(expr, prefix) => {
2937 write!(
2938 f,
2939 "({}){}.*",
2940 expr,
2941 prefix
2942 .iter()
2943 .format_with("", |i, f| f(&format_args!(".{i}")))
2944 )
2945 }
2946 FunctionArgExpr::QualifiedWildcard(prefix, except) => match except {
2947 Some(exprs) => write!(
2948 f,
2949 "{}.* EXCEPT ({})",
2950 prefix,
2951 exprs
2952 .iter()
2953 .map(|v| v.to_string())
2954 .collect::<Vec<String>>()
2955 .as_slice()
2956 .join(", ")
2957 ),
2958 None => write!(f, "{}.*", prefix),
2959 },
2960
2961 FunctionArgExpr::Wildcard(except) => match except {
2962 Some(exprs) => write!(
2963 f,
2964 "* EXCEPT ({})",
2965 exprs
2966 .iter()
2967 .map(|v| v.to_string())
2968 .collect::<Vec<String>>()
2969 .as_slice()
2970 .join(", ")
2971 ),
2972 None => f.write_str("*"),
2973 },
2974 }
2975 }
2976}
2977
2978#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2979#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2980pub enum FunctionArg {
2981 Named { name: Ident, arg: FunctionArgExpr },
2982 Unnamed(FunctionArgExpr),
2983}
2984
2985impl FunctionArg {
2986 pub fn get_expr(&self) -> FunctionArgExpr {
2987 match self {
2988 FunctionArg::Named { name: _, arg } => arg.clone(),
2989 FunctionArg::Unnamed(arg) => arg.clone(),
2990 }
2991 }
2992}
2993
2994impl fmt::Display for FunctionArg {
2995 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2996 match self {
2997 FunctionArg::Named { name, arg } => write!(f, "{} => {}", name, arg),
2998 FunctionArg::Unnamed(unnamed_arg) => write!(f, "{}", unnamed_arg),
2999 }
3000 }
3001}
3002
3003#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3006#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3007pub struct FunctionArgList {
3008 pub distinct: bool,
3010 pub args: Vec<FunctionArg>,
3011 pub variadic: bool,
3013 pub order_by: Vec<OrderByExpr>,
3015 pub ignore_nulls: bool,
3017}
3018
3019impl fmt::Display for FunctionArgList {
3020 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3021 write!(f, "(")?;
3022 if self.distinct {
3023 write!(f, "DISTINCT ")?;
3024 }
3025 if self.variadic {
3026 for arg in &self.args[0..self.args.len() - 1] {
3027 write!(f, "{}, ", arg)?;
3028 }
3029 write!(f, "VARIADIC {}", self.args.last().unwrap())?;
3030 } else {
3031 write!(f, "{}", display_comma_separated(&self.args))?;
3032 }
3033 if !self.order_by.is_empty() {
3034 write!(f, " ORDER BY {}", display_comma_separated(&self.order_by))?;
3035 }
3036 if self.ignore_nulls {
3037 write!(f, " IGNORE NULLS")?;
3038 }
3039 write!(f, ")")?;
3040 Ok(())
3041 }
3042}
3043
3044impl FunctionArgList {
3045 pub fn empty() -> Self {
3046 Self {
3047 distinct: false,
3048 args: vec![],
3049 variadic: false,
3050 order_by: vec![],
3051 ignore_nulls: false,
3052 }
3053 }
3054
3055 pub fn args_only(args: Vec<FunctionArg>) -> Self {
3056 Self {
3057 distinct: false,
3058 args,
3059 variadic: false,
3060 order_by: vec![],
3061 ignore_nulls: false,
3062 }
3063 }
3064
3065 pub fn is_args_only(&self) -> bool {
3066 !self.distinct && !self.variadic && self.order_by.is_empty() && !self.ignore_nulls
3067 }
3068
3069 pub fn for_agg(distinct: bool, args: Vec<FunctionArg>, order_by: Vec<OrderByExpr>) -> Self {
3070 Self {
3071 distinct,
3072 args,
3073 variadic: false,
3074 order_by,
3075 ignore_nulls: false,
3076 }
3077 }
3078}
3079
3080#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3082#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3083pub struct Function {
3084 pub scalar_as_agg: bool,
3086 pub name: ObjectName,
3088 pub arg_list: FunctionArgList,
3090 pub within_group: Option<Box<OrderByExpr>>,
3093 pub filter: Option<Box<Expr>>,
3095 pub over: Option<Window>,
3097}
3098
3099impl Function {
3100 pub fn no_arg(name: ObjectName) -> Self {
3101 Self {
3102 scalar_as_agg: false,
3103 name,
3104 arg_list: FunctionArgList::empty(),
3105 within_group: None,
3106 filter: None,
3107 over: None,
3108 }
3109 }
3110}
3111
3112impl fmt::Display for Function {
3113 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3114 if self.scalar_as_agg {
3115 write!(f, "AGGREGATE:")?;
3116 }
3117 write!(f, "{}{}", self.name, self.arg_list)?;
3118 if let Some(within_group) = &self.within_group {
3119 write!(f, " WITHIN GROUP (ORDER BY {})", within_group)?;
3120 }
3121 if let Some(filter) = &self.filter {
3122 write!(f, " FILTER (WHERE {})", filter)?;
3123 }
3124 if let Some(o) = &self.over {
3125 write!(f, " OVER {}", o)?;
3126 }
3127 Ok(())
3128 }
3129}
3130
3131#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3132#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3133pub enum ObjectType {
3134 Table,
3135 View,
3136 MaterializedView,
3137 Index,
3138 Schema,
3139 Source,
3140 Sink,
3141 Database,
3142 User,
3143 Connection,
3144 Secret,
3145 Subscription,
3146}
3147
3148impl fmt::Display for ObjectType {
3149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3150 f.write_str(match self {
3151 ObjectType::Table => "TABLE",
3152 ObjectType::View => "VIEW",
3153 ObjectType::MaterializedView => "MATERIALIZED VIEW",
3154 ObjectType::Index => "INDEX",
3155 ObjectType::Schema => "SCHEMA",
3156 ObjectType::Source => "SOURCE",
3157 ObjectType::Sink => "SINK",
3158 ObjectType::Database => "DATABASE",
3159 ObjectType::User => "USER",
3160 ObjectType::Secret => "SECRET",
3161 ObjectType::Connection => "CONNECTION",
3162 ObjectType::Subscription => "SUBSCRIPTION",
3163 })
3164 }
3165}
3166
3167impl ParseTo for ObjectType {
3168 fn parse_to(parser: &mut Parser<'_>) -> ModalResult<Self> {
3169 let object_type = if parser.parse_keyword(Keyword::TABLE) {
3170 ObjectType::Table
3171 } else if parser.parse_keyword(Keyword::VIEW) {
3172 ObjectType::View
3173 } else if parser.parse_keywords(&[Keyword::MATERIALIZED, Keyword::VIEW]) {
3174 ObjectType::MaterializedView
3175 } else if parser.parse_keyword(Keyword::SOURCE) {
3176 ObjectType::Source
3177 } else if parser.parse_keyword(Keyword::SINK) {
3178 ObjectType::Sink
3179 } else if parser.parse_keyword(Keyword::INDEX) {
3180 ObjectType::Index
3181 } else if parser.parse_keyword(Keyword::SCHEMA) {
3182 ObjectType::Schema
3183 } else if parser.parse_keyword(Keyword::DATABASE) {
3184 ObjectType::Database
3185 } else if parser.parse_keyword(Keyword::USER) {
3186 ObjectType::User
3187 } else if parser.parse_keyword(Keyword::CONNECTION) {
3188 ObjectType::Connection
3189 } else if parser.parse_keyword(Keyword::SECRET) {
3190 ObjectType::Secret
3191 } else if parser.parse_keyword(Keyword::SUBSCRIPTION) {
3192 ObjectType::Subscription
3193 } else {
3194 return parser.expected(
3195 "TABLE, VIEW, INDEX, MATERIALIZED VIEW, SOURCE, SINK, SUBSCRIPTION, SCHEMA, DATABASE, USER, SECRET or CONNECTION after DROP",
3196 );
3197 };
3198 Ok(object_type)
3199 }
3200}
3201
3202#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3203#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3204pub struct SqlOption {
3205 pub name: ObjectName,
3206 pub value: SqlOptionValue,
3207}
3208
3209impl fmt::Display for SqlOption {
3210 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3211 let should_redact = REDACT_SQL_OPTION_KEYWORDS
3212 .try_with(|keywords| {
3213 let sql_option_name = self.name.real_value().to_lowercase();
3214 keywords.iter().any(|k| sql_option_name.contains(k))
3215 })
3216 .unwrap_or(false);
3217 if should_redact {
3218 write!(f, "{} = [REDACTED]", self.name)
3219 } else {
3220 write!(f, "{} = {}", self.name, self.value)
3221 }
3222 }
3223}
3224
3225impl TryFrom<(&String, &String)> for SqlOption {
3226 type Error = ParserError;
3227
3228 fn try_from((name, value): (&String, &String)) -> Result<Self, Self::Error> {
3229 let query = format!("{} = {}", name, value);
3230 let mut tokenizer = Tokenizer::new(query.as_str());
3231 let tokens = tokenizer.tokenize_with_location()?;
3232 let mut parser = Parser(&tokens);
3233 parser
3234 .parse_sql_option()
3235 .map_err(|e| ParserError::ParserError(e.to_string()))
3236 }
3237}
3238
3239#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3240#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3241pub enum SqlOptionValue {
3242 Value(Value),
3243 SecretRef(SecretRefValue),
3244 ConnectionRef(ConnectionRefValue),
3245 BackfillOrder(BackfillOrderStrategy),
3246}
3247
3248impl fmt::Display for SqlOptionValue {
3249 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3250 match self {
3251 SqlOptionValue::Value(value) => write!(f, "{}", value),
3252 SqlOptionValue::SecretRef(secret_ref) => write!(f, "secret {}", secret_ref),
3253 SqlOptionValue::ConnectionRef(connection_ref) => {
3254 write!(f, "{}", connection_ref)
3255 }
3256 SqlOptionValue::BackfillOrder(order) => {
3257 write!(f, "{}", order)
3258 }
3259 }
3260 }
3261}
3262
3263impl From<Value> for SqlOptionValue {
3264 fn from(value: Value) -> Self {
3265 SqlOptionValue::Value(value)
3266 }
3267}
3268
3269#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3270#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3271pub enum EmitMode {
3272 Immediately,
3273 OnWindowClose,
3274}
3275
3276impl fmt::Display for EmitMode {
3277 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3278 f.write_str(match self {
3279 EmitMode::Immediately => "IMMEDIATELY",
3280 EmitMode::OnWindowClose => "ON WINDOW CLOSE",
3281 })
3282 }
3283}
3284
3285#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3286#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3287pub enum OnConflict {
3288 UpdateFull,
3289 Nothing,
3290 UpdateIfNotNull,
3291}
3292
3293impl fmt::Display for OnConflict {
3294 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3295 f.write_str(match self {
3296 OnConflict::UpdateFull => "DO UPDATE FULL",
3297 OnConflict::Nothing => "DO NOTHING",
3298 OnConflict::UpdateIfNotNull => "DO UPDATE IF NOT NULL",
3299 })
3300 }
3301}
3302
3303#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3304#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3305pub enum Engine {
3306 Hummock,
3307 Iceberg,
3308}
3309
3310impl fmt::Display for crate::ast::Engine {
3311 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3312 f.write_str(match self {
3313 crate::ast::Engine::Hummock => "HUMMOCK",
3314 crate::ast::Engine::Iceberg => "ICEBERG",
3315 })
3316 }
3317}
3318
3319#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3320#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3321pub enum SetTimeZoneValue {
3322 Ident(Ident),
3323 Literal(Value),
3324 Local,
3325 Default,
3326}
3327
3328impl fmt::Display for SetTimeZoneValue {
3329 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3330 match self {
3331 SetTimeZoneValue::Ident(ident) => write!(f, "{}", ident),
3332 SetTimeZoneValue::Literal(value) => write!(f, "{}", value),
3333 SetTimeZoneValue::Local => f.write_str("LOCAL"),
3334 SetTimeZoneValue::Default => f.write_str("DEFAULT"),
3335 }
3336 }
3337}
3338
3339#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3340#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3341pub enum TransactionMode {
3342 AccessMode(TransactionAccessMode),
3343 IsolationLevel(TransactionIsolationLevel),
3344}
3345
3346impl fmt::Display for TransactionMode {
3347 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3348 use TransactionMode::*;
3349 match self {
3350 AccessMode(access_mode) => write!(f, "{}", access_mode),
3351 IsolationLevel(iso_level) => write!(f, "ISOLATION LEVEL {}", iso_level),
3352 }
3353 }
3354}
3355
3356#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3357#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3358pub enum TransactionAccessMode {
3359 ReadOnly,
3360 ReadWrite,
3361}
3362
3363impl fmt::Display for TransactionAccessMode {
3364 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3365 use TransactionAccessMode::*;
3366 f.write_str(match self {
3367 ReadOnly => "READ ONLY",
3368 ReadWrite => "READ WRITE",
3369 })
3370 }
3371}
3372
3373#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3374#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3375pub enum TransactionIsolationLevel {
3376 ReadUncommitted,
3377 ReadCommitted,
3378 RepeatableRead,
3379 Serializable,
3380}
3381
3382impl fmt::Display for TransactionIsolationLevel {
3383 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3384 use TransactionIsolationLevel::*;
3385 f.write_str(match self {
3386 ReadUncommitted => "READ UNCOMMITTED",
3387 ReadCommitted => "READ COMMITTED",
3388 RepeatableRead => "REPEATABLE READ",
3389 Serializable => "SERIALIZABLE",
3390 })
3391 }
3392}
3393
3394#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3395#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3396pub enum ShowStatementFilter {
3397 Like(String),
3398 ILike(String),
3399 Where(Expr),
3400}
3401
3402impl fmt::Display for ShowStatementFilter {
3403 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3404 use ShowStatementFilter::*;
3405 match self {
3406 Like(pattern) => write!(f, "LIKE '{}'", value::escape_single_quote_string(pattern)),
3407 ILike(pattern) => write!(f, "ILIKE {}", value::escape_single_quote_string(pattern)),
3408 Where(expr) => write!(f, "WHERE {}", expr),
3409 }
3410 }
3411}
3412
3413#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3415#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3416pub enum DropFunctionOption {
3417 Restrict,
3418 Cascade,
3419}
3420
3421impl fmt::Display for DropFunctionOption {
3422 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3423 match self {
3424 DropFunctionOption::Restrict => write!(f, "RESTRICT "),
3425 DropFunctionOption::Cascade => write!(f, "CASCADE "),
3426 }
3427 }
3428}
3429
3430#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3432#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3433pub struct FunctionDesc {
3434 pub name: ObjectName,
3435 pub args: Option<Vec<OperateFunctionArg>>,
3436}
3437
3438impl fmt::Display for FunctionDesc {
3439 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3440 write!(f, "{}", self.name)?;
3441 if let Some(args) = &self.args {
3442 write!(f, "({})", display_comma_separated(args))?;
3443 }
3444 Ok(())
3445 }
3446}
3447
3448#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3450#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3451pub struct OperateFunctionArg {
3452 pub mode: Option<ArgMode>,
3453 pub name: Option<Ident>,
3454 pub data_type: DataType,
3455 pub default_expr: Option<Expr>,
3456}
3457
3458impl OperateFunctionArg {
3459 pub fn unnamed(data_type: DataType) -> Self {
3461 Self {
3462 mode: None,
3463 name: None,
3464 data_type,
3465 default_expr: None,
3466 }
3467 }
3468
3469 pub fn with_name(name: &str, data_type: DataType) -> Self {
3471 Self {
3472 mode: None,
3473 name: Some(name.into()),
3474 data_type,
3475 default_expr: None,
3476 }
3477 }
3478}
3479
3480impl fmt::Display for OperateFunctionArg {
3481 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3482 if let Some(mode) = &self.mode {
3483 write!(f, "{} ", mode)?;
3484 }
3485 if let Some(name) = &self.name {
3486 write!(f, "{} ", name)?;
3487 }
3488 write!(f, "{}", self.data_type)?;
3489 if let Some(default_expr) = &self.default_expr {
3490 write!(f, " = {}", default_expr)?;
3491 }
3492 Ok(())
3493 }
3494}
3495
3496#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3498#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3499pub enum ArgMode {
3500 In,
3501 Out,
3502 InOut,
3503}
3504
3505impl fmt::Display for ArgMode {
3506 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3507 match self {
3508 ArgMode::In => write!(f, "IN"),
3509 ArgMode::Out => write!(f, "OUT"),
3510 ArgMode::InOut => write!(f, "INOUT"),
3511 }
3512 }
3513}
3514
3515#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3517#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3518pub enum FunctionBehavior {
3519 Immutable,
3520 Stable,
3521 Volatile,
3522}
3523
3524impl fmt::Display for FunctionBehavior {
3525 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3526 match self {
3527 FunctionBehavior::Immutable => write!(f, "IMMUTABLE"),
3528 FunctionBehavior::Stable => write!(f, "STABLE"),
3529 FunctionBehavior::Volatile => write!(f, "VOLATILE"),
3530 }
3531 }
3532}
3533
3534#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3535#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3536pub enum FunctionDefinition {
3537 Identifier(String),
3538 SingleQuotedDef(String),
3539 DoubleDollarDef(String),
3540}
3541
3542impl fmt::Display for FunctionDefinition {
3543 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3544 match self {
3545 FunctionDefinition::Identifier(s) => write!(f, "{s}")?,
3546 FunctionDefinition::SingleQuotedDef(s) => write!(f, "'{s}'")?,
3547 FunctionDefinition::DoubleDollarDef(s) => write!(f, "$${s}$$")?,
3548 }
3549 Ok(())
3550 }
3551}
3552
3553impl FunctionDefinition {
3554 pub fn as_str(&self) -> &str {
3556 match self {
3557 FunctionDefinition::Identifier(s) => s,
3558 FunctionDefinition::SingleQuotedDef(s) => s,
3559 FunctionDefinition::DoubleDollarDef(s) => s,
3560 }
3561 }
3562
3563 pub fn into_string(self) -> String {
3565 match self {
3566 FunctionDefinition::Identifier(s) => s,
3567 FunctionDefinition::SingleQuotedDef(s) => s,
3568 FunctionDefinition::DoubleDollarDef(s) => s,
3569 }
3570 }
3571}
3572
3573#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3575#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3576pub enum CreateFunctionReturns {
3577 Value(DataType),
3579 Table(Vec<TableColumnDef>),
3581}
3582
3583impl fmt::Display for CreateFunctionReturns {
3584 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3585 match self {
3586 Self::Value(data_type) => write!(f, "RETURNS {}", data_type),
3587 Self::Table(columns) => {
3588 write!(f, "RETURNS TABLE ({})", display_comma_separated(columns))
3589 }
3590 }
3591 }
3592}
3593
3594#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3596#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3597pub struct TableColumnDef {
3598 pub name: Ident,
3599 pub data_type: DataType,
3600}
3601
3602impl fmt::Display for TableColumnDef {
3603 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3604 write!(f, "{} {}", self.name, self.data_type)
3605 }
3606}
3607
3608#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
3613#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3614pub struct CreateFunctionBody {
3615 pub language: Option<Ident>,
3617 pub runtime: Option<Ident>,
3619
3620 pub behavior: Option<FunctionBehavior>,
3622 pub as_: Option<FunctionDefinition>,
3626 pub return_: Option<Expr>,
3628 pub using: Option<CreateFunctionUsing>,
3630}
3631
3632impl fmt::Display for CreateFunctionBody {
3633 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3634 if let Some(language) = &self.language {
3635 write!(f, " LANGUAGE {language}")?;
3636 }
3637 if let Some(runtime) = &self.runtime {
3638 write!(f, " RUNTIME {runtime}")?;
3639 }
3640 if let Some(behavior) = &self.behavior {
3641 write!(f, " {behavior}")?;
3642 }
3643 if let Some(definition) = &self.as_ {
3644 write!(f, " AS {definition}")?;
3645 }
3646 if let Some(expr) = &self.return_ {
3647 write!(f, " RETURN {expr}")?;
3648 }
3649 if let Some(using) = &self.using {
3650 write!(f, " {using}")?;
3651 }
3652 Ok(())
3653 }
3654}
3655
3656#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
3657#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3658pub struct CreateFunctionWithOptions {
3659 pub always_retry_on_network_error: Option<bool>,
3661 pub r#async: Option<bool>,
3663 pub batch: Option<bool>,
3665}
3666
3667impl TryFrom<Vec<SqlOption>> for CreateFunctionWithOptions {
3669 type Error = StrError;
3670
3671 fn try_from(with_options: Vec<SqlOption>) -> Result<Self, Self::Error> {
3672 let mut options = Self::default();
3673 for option in with_options {
3674 match option.name.to_string().to_lowercase().as_str() {
3675 "always_retry_on_network_error" => {
3676 options.always_retry_on_network_error = Some(matches!(
3677 option.value,
3678 SqlOptionValue::Value(Value::Boolean(true))
3679 ));
3680 }
3681 "async" => {
3682 options.r#async = Some(matches!(
3683 option.value,
3684 SqlOptionValue::Value(Value::Boolean(true))
3685 ))
3686 }
3687 "batch" => {
3688 options.batch = Some(matches!(
3689 option.value,
3690 SqlOptionValue::Value(Value::Boolean(true))
3691 ))
3692 }
3693 _ => {
3694 return Err(StrError(format!("unknown option: {}", option.name)));
3695 }
3696 }
3697 }
3698 Ok(options)
3699 }
3700}
3701
3702impl Display for CreateFunctionWithOptions {
3703 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3704 if self == &Self::default() {
3705 return Ok(());
3706 }
3707 let mut options = vec![];
3708 if let Some(v) = self.always_retry_on_network_error {
3709 options.push(format!("always_retry_on_network_error = {}", v));
3710 }
3711 if let Some(v) = self.r#async {
3712 options.push(format!("async = {}", v));
3713 }
3714 if let Some(v) = self.batch {
3715 options.push(format!("batch = {}", v));
3716 }
3717 write!(f, " WITH ( {} )", display_comma_separated(&options))
3718 }
3719}
3720
3721#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3722#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3723pub enum CreateFunctionUsing {
3724 Link(String),
3725 Base64(String),
3726}
3727
3728impl fmt::Display for CreateFunctionUsing {
3729 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3730 write!(f, "USING ")?;
3731 match self {
3732 CreateFunctionUsing::Link(uri) => write!(f, "LINK '{uri}'"),
3733 CreateFunctionUsing::Base64(s) => {
3734 write!(f, "BASE64 '{s}'")
3735 }
3736 }
3737 }
3738}
3739
3740#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3741#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3742pub struct ConfigParam {
3743 pub param: Ident,
3744 pub value: SetVariableValue,
3745}
3746
3747impl fmt::Display for ConfigParam {
3748 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3749 write!(f, "SET {} = {}", self.param, self.value)
3750 }
3751}
3752
3753#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3754#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3755pub enum SetVariableValue {
3756 Single(SetVariableValueSingle),
3757 List(Vec<SetVariableValueSingle>),
3758 Default,
3759}
3760
3761impl From<SetVariableValueSingle> for SetVariableValue {
3762 fn from(value: SetVariableValueSingle) -> Self {
3763 SetVariableValue::Single(value)
3764 }
3765}
3766
3767impl fmt::Display for SetVariableValue {
3768 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3769 use SetVariableValue::*;
3770 match self {
3771 Single(val) => write!(f, "{}", val),
3772 List(list) => write!(f, "{}", display_comma_separated(list),),
3773 Default => write!(f, "DEFAULT"),
3774 }
3775 }
3776}
3777
3778#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3779#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3780pub enum SetVariableValueSingle {
3781 Ident(Ident),
3782 Literal(Value),
3783}
3784
3785impl SetVariableValueSingle {
3786 pub fn to_string_unquoted(&self) -> String {
3787 match self {
3788 Self::Literal(Value::SingleQuotedString(s))
3789 | Self::Literal(Value::DoubleQuotedString(s)) => s.clone(),
3790 _ => self.to_string(),
3791 }
3792 }
3793}
3794
3795impl fmt::Display for SetVariableValueSingle {
3796 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3797 use SetVariableValueSingle::*;
3798 match self {
3799 Ident(ident) => write!(f, "{}", ident),
3800 Literal(literal) => write!(f, "{}", literal),
3801 }
3802 }
3803}
3804
3805#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3806#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3807pub enum AsOf {
3808 ProcessTime,
3809 ProcessTimeWithInterval((String, DateTimeField)),
3811 TimestampNum(i64),
3813 TimestampString(String),
3814 VersionNum(i64),
3815 VersionString(String),
3816}
3817
3818impl fmt::Display for AsOf {
3819 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3820 use AsOf::*;
3821 match self {
3822 ProcessTime => write!(f, " FOR SYSTEM_TIME AS OF PROCTIME()"),
3823 ProcessTimeWithInterval((value, leading_field)) => write!(
3824 f,
3825 " FOR SYSTEM_TIME AS OF NOW() - {} {}",
3826 value, leading_field
3827 ),
3828 TimestampNum(ts) => write!(f, " FOR SYSTEM_TIME AS OF {}", ts),
3829 TimestampString(ts) => write!(f, " FOR SYSTEM_TIME AS OF '{}'", ts),
3830 VersionNum(v) => write!(f, " FOR SYSTEM_VERSION AS OF {}", v),
3831 VersionString(v) => write!(f, " FOR SYSTEM_VERSION AS OF '{}'", v),
3832 }
3833 }
3834}
3835
3836#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3837#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3838pub enum DiscardType {
3839 All,
3840}
3841
3842impl fmt::Display for DiscardType {
3843 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3844 use DiscardType::*;
3845 match self {
3846 All => write!(f, "ALL"),
3847 }
3848 }
3849}
3850
3851#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
3854#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3855pub enum BackfillOrderStrategy {
3856 #[default]
3857 Default,
3858 None,
3859 Auto,
3860 Fixed(Vec<(ObjectName, ObjectName)>),
3861}
3862
3863impl fmt::Display for BackfillOrderStrategy {
3864 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3865 use BackfillOrderStrategy::*;
3866 match self {
3867 Default => write!(f, "DEFAULT"),
3868 None => write!(f, "NONE"),
3869 Auto => write!(f, "AUTO"),
3870 Fixed(map) => {
3871 let mut parts = vec![];
3872 for (start, end) in map {
3873 parts.push(format!("{} -> {}", start, end));
3874 }
3875 write!(f, "{}", display_comma_separated(&parts))
3876 }
3877 }
3878 }
3879}
3880
3881impl Statement {
3882 pub fn to_redacted_string(&self, keywords: RedactSqlOptionKeywordsRef) -> String {
3883 REDACT_SQL_OPTION_KEYWORDS.sync_scope(keywords, || self.to_string_unchecked())
3884 }
3885
3886 pub fn default_create_table(name: ObjectName) -> Self {
3888 Self::CreateTable {
3889 name,
3890 or_replace: false,
3891 temporary: false,
3892 if_not_exists: false,
3893 columns: Vec::new(),
3894 wildcard_idx: None,
3895 constraints: Vec::new(),
3896 with_options: Vec::new(),
3897 format_encode: None,
3898 source_watermarks: Vec::new(),
3899 append_only: false,
3900 on_conflict: None,
3901 with_version_column: None,
3902 query: None,
3903 cdc_table_info: None,
3904 include_column_options: Vec::new(),
3905 webhook_info: None,
3906 engine: Engine::Hummock,
3907 }
3908 }
3909}
3910
3911#[cfg(test)]
3912mod tests {
3913 use super::*;
3914
3915 #[test]
3916 fn test_grouping_sets_display() {
3917 let grouping_sets = Expr::GroupingSets(vec![
3919 vec![Expr::Identifier(Ident::new_unchecked("a"))],
3920 vec![Expr::Identifier(Ident::new_unchecked("b"))],
3921 ]);
3922 assert_eq!("GROUPING SETS ((a), (b))", format!("{}", grouping_sets));
3923
3924 let grouping_sets = Expr::GroupingSets(vec![vec![
3926 Expr::Identifier(Ident::new_unchecked("a")),
3927 Expr::Identifier(Ident::new_unchecked("b")),
3928 ]]);
3929 assert_eq!("GROUPING SETS ((a, b))", format!("{}", grouping_sets));
3930
3931 let grouping_sets = Expr::GroupingSets(vec![
3933 vec![
3934 Expr::Identifier(Ident::new_unchecked("a")),
3935 Expr::Identifier(Ident::new_unchecked("b")),
3936 ],
3937 vec![
3938 Expr::Identifier(Ident::new_unchecked("c")),
3939 Expr::Identifier(Ident::new_unchecked("d")),
3940 ],
3941 ]);
3942 assert_eq!(
3943 "GROUPING SETS ((a, b), (c, d))",
3944 format!("{}", grouping_sets)
3945 );
3946 }
3947
3948 #[test]
3949 fn test_rollup_display() {
3950 let rollup = Expr::Rollup(vec![vec![Expr::Identifier(Ident::new_unchecked("a"))]]);
3951 assert_eq!("ROLLUP (a)", format!("{}", rollup));
3952
3953 let rollup = Expr::Rollup(vec![vec![
3954 Expr::Identifier(Ident::new_unchecked("a")),
3955 Expr::Identifier(Ident::new_unchecked("b")),
3956 ]]);
3957 assert_eq!("ROLLUP ((a, b))", format!("{}", rollup));
3958
3959 let rollup = Expr::Rollup(vec![
3960 vec![Expr::Identifier(Ident::new_unchecked("a"))],
3961 vec![Expr::Identifier(Ident::new_unchecked("b"))],
3962 ]);
3963 assert_eq!("ROLLUP (a, b)", format!("{}", rollup));
3964
3965 let rollup = Expr::Rollup(vec![
3966 vec![Expr::Identifier(Ident::new_unchecked("a"))],
3967 vec![
3968 Expr::Identifier(Ident::new_unchecked("b")),
3969 Expr::Identifier(Ident::new_unchecked("c")),
3970 ],
3971 vec![Expr::Identifier(Ident::new_unchecked("d"))],
3972 ]);
3973 assert_eq!("ROLLUP (a, (b, c), d)", format!("{}", rollup));
3974 }
3975
3976 #[test]
3977 fn test_cube_display() {
3978 let cube = Expr::Cube(vec![vec![Expr::Identifier(Ident::new_unchecked("a"))]]);
3979 assert_eq!("CUBE (a)", format!("{}", cube));
3980
3981 let cube = Expr::Cube(vec![vec![
3982 Expr::Identifier(Ident::new_unchecked("a")),
3983 Expr::Identifier(Ident::new_unchecked("b")),
3984 ]]);
3985 assert_eq!("CUBE ((a, b))", format!("{}", cube));
3986
3987 let cube = Expr::Cube(vec![
3988 vec![Expr::Identifier(Ident::new_unchecked("a"))],
3989 vec![Expr::Identifier(Ident::new_unchecked("b"))],
3990 ]);
3991 assert_eq!("CUBE (a, b)", format!("{}", cube));
3992
3993 let cube = Expr::Cube(vec![
3994 vec![Expr::Identifier(Ident::new_unchecked("a"))],
3995 vec![
3996 Expr::Identifier(Ident::new_unchecked("b")),
3997 Expr::Identifier(Ident::new_unchecked("c")),
3998 ],
3999 vec![Expr::Identifier(Ident::new_unchecked("d"))],
4000 ]);
4001 assert_eq!("CUBE (a, (b, c), d)", format!("{}", cube));
4002 }
4003
4004 #[test]
4005 fn test_array_index_display() {
4006 let array_index = Expr::Index {
4007 obj: Box::new(Expr::Identifier(Ident::new_unchecked("v1"))),
4008 index: Box::new(Expr::Value(Value::Number("1".into()))),
4009 };
4010 assert_eq!("v1[1]", format!("{}", array_index));
4011
4012 let array_index2 = Expr::Index {
4013 obj: Box::new(array_index),
4014 index: Box::new(Expr::Value(Value::Number("1".into()))),
4015 };
4016 assert_eq!("v1[1][1]", format!("{}", array_index2));
4017 }
4018
4019 #[test]
4020 fn test_nested_op_display() {
4022 let binary_op = Expr::BinaryOp {
4023 left: Box::new(Expr::Value(Value::Boolean(true))),
4024 op: BinaryOperator::Or,
4025 right: Box::new(Expr::IsNotFalse(Box::new(Expr::Value(Value::Boolean(
4026 true,
4027 ))))),
4028 };
4029 assert_eq!("true OR true IS NOT FALSE", format!("{}", binary_op));
4030
4031 let unary_op = Expr::UnaryOp {
4032 op: UnaryOperator::Not,
4033 expr: Box::new(Expr::IsNotFalse(Box::new(Expr::Value(Value::Boolean(
4034 true,
4035 ))))),
4036 };
4037 assert_eq!("NOT true IS NOT FALSE", format!("{}", unary_op));
4038 }
4039
4040 #[test]
4041 fn test_create_function_display() {
4042 let create_function = Statement::CreateFunction {
4043 or_replace: false,
4044 temporary: false,
4045 if_not_exists: false,
4046 name: ObjectName(vec![Ident::new_unchecked("foo")]),
4047 args: Some(vec![OperateFunctionArg::unnamed(DataType::Int)]),
4048 returns: Some(CreateFunctionReturns::Value(DataType::Int)),
4049 params: CreateFunctionBody {
4050 language: Some(Ident::new_unchecked("python")),
4051 runtime: None,
4052 behavior: Some(FunctionBehavior::Immutable),
4053 as_: Some(FunctionDefinition::SingleQuotedDef("SELECT 1".to_owned())),
4054 return_: None,
4055 using: None,
4056 },
4057 with_options: CreateFunctionWithOptions {
4058 always_retry_on_network_error: None,
4059 r#async: None,
4060 batch: None,
4061 },
4062 };
4063 assert_eq!(
4064 "CREATE FUNCTION foo(INT) RETURNS INT LANGUAGE python IMMUTABLE AS 'SELECT 1'",
4065 format!("{}", create_function)
4066 );
4067 let create_function = Statement::CreateFunction {
4068 or_replace: false,
4069 temporary: false,
4070 if_not_exists: false,
4071 name: ObjectName(vec![Ident::new_unchecked("foo")]),
4072 args: Some(vec![OperateFunctionArg::unnamed(DataType::Int)]),
4073 returns: Some(CreateFunctionReturns::Value(DataType::Int)),
4074 params: CreateFunctionBody {
4075 language: Some(Ident::new_unchecked("python")),
4076 runtime: None,
4077 behavior: Some(FunctionBehavior::Immutable),
4078 as_: Some(FunctionDefinition::SingleQuotedDef("SELECT 1".to_owned())),
4079 return_: None,
4080 using: None,
4081 },
4082 with_options: CreateFunctionWithOptions {
4083 always_retry_on_network_error: Some(true),
4084 r#async: None,
4085 batch: None,
4086 },
4087 };
4088 assert_eq!(
4089 "CREATE FUNCTION foo(INT) RETURNS INT LANGUAGE python IMMUTABLE AS 'SELECT 1' WITH ( always_retry_on_network_error = true )",
4090 format!("{}", create_function)
4091 );
4092 }
4093}