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 Refresh {
1274 table_name: ObjectName,
1275 },
1276 Query(Box<Query>),
1278 Insert {
1280 table_name: ObjectName,
1282 columns: Vec<Ident>,
1284 source: Box<Query>,
1286 returning: Vec<SelectItem>,
1288 },
1289 Copy {
1290 table_name: ObjectName,
1292 columns: Vec<Ident>,
1294 values: Vec<Option<String>>,
1296 },
1297 Update {
1299 table_name: ObjectName,
1301 assignments: Vec<Assignment>,
1303 selection: Option<Expr>,
1305 returning: Vec<SelectItem>,
1307 },
1308 Delete {
1310 table_name: ObjectName,
1312 selection: Option<Expr>,
1314 returning: Vec<SelectItem>,
1316 },
1317 Discard(DiscardType),
1319 CreateView {
1321 or_replace: bool,
1322 materialized: bool,
1323 if_not_exists: bool,
1324 name: ObjectName,
1326 columns: Vec<Ident>,
1327 query: Box<Query>,
1328 emit_mode: Option<EmitMode>,
1329 with_options: Vec<SqlOption>,
1330 },
1331 CreateTable {
1333 or_replace: bool,
1334 temporary: bool,
1335 if_not_exists: bool,
1336 name: ObjectName,
1338 columns: Vec<ColumnDef>,
1340 wildcard_idx: Option<usize>,
1342 constraints: Vec<TableConstraint>,
1343 with_options: Vec<SqlOption>,
1344 format_encode: Option<CompatibleFormatEncode>,
1346 source_watermarks: Vec<SourceWatermark>,
1348 append_only: bool,
1350 on_conflict: Option<OnConflict>,
1352 with_version_column: Option<Ident>,
1354 query: Option<Box<Query>>,
1356 cdc_table_info: Option<CdcTableInfo>,
1358 include_column_options: IncludeOption,
1360 webhook_info: Option<WebhookSourceInfo>,
1362 engine: Engine,
1364 },
1365 CreateIndex {
1367 name: ObjectName,
1369 table_name: ObjectName,
1370 columns: Vec<OrderByExpr>,
1371 include: Vec<Ident>,
1372 distributed_by: Vec<Expr>,
1373 unique: bool,
1374 if_not_exists: bool,
1375 },
1376 CreateSource {
1378 stmt: CreateSourceStatement,
1379 },
1380 CreateSink {
1382 stmt: CreateSinkStatement,
1383 },
1384 CreateSubscription {
1386 stmt: CreateSubscriptionStatement,
1387 },
1388 CreateConnection {
1390 stmt: CreateConnectionStatement,
1391 },
1392 CreateSecret {
1393 stmt: CreateSecretStatement,
1394 },
1395 CreateFunction {
1399 or_replace: bool,
1400 temporary: bool,
1401 if_not_exists: bool,
1402 name: ObjectName,
1403 args: Option<Vec<OperateFunctionArg>>,
1404 returns: Option<CreateFunctionReturns>,
1405 params: CreateFunctionBody,
1407 with_options: CreateFunctionWithOptions, },
1409 CreateAggregate {
1413 or_replace: bool,
1414 if_not_exists: bool,
1415 name: ObjectName,
1416 args: Vec<OperateFunctionArg>,
1417 returns: DataType,
1418 append_only: bool,
1420 params: CreateFunctionBody,
1421 },
1422
1423 DeclareCursor {
1425 stmt: DeclareCursorStatement,
1426 },
1427
1428 FetchCursor {
1430 stmt: FetchCursorStatement,
1431 },
1432
1433 CloseCursor {
1435 stmt: CloseCursorStatement,
1436 },
1437
1438 AlterDatabase {
1440 name: ObjectName,
1441 operation: AlterDatabaseOperation,
1442 },
1443 AlterSchema {
1445 name: ObjectName,
1446 operation: AlterSchemaOperation,
1447 },
1448 AlterTable {
1450 name: ObjectName,
1452 operation: AlterTableOperation,
1453 },
1454 AlterIndex {
1456 name: ObjectName,
1458 operation: AlterIndexOperation,
1459 },
1460 AlterView {
1462 name: ObjectName,
1464 materialized: bool,
1465 operation: AlterViewOperation,
1466 },
1467 AlterSink {
1469 name: ObjectName,
1471 operation: AlterSinkOperation,
1472 },
1473 AlterSubscription {
1474 name: ObjectName,
1475 operation: AlterSubscriptionOperation,
1476 },
1477 AlterSource {
1479 name: ObjectName,
1481 operation: AlterSourceOperation,
1482 },
1483 AlterFunction {
1485 name: ObjectName,
1487 args: Option<Vec<OperateFunctionArg>>,
1488 operation: AlterFunctionOperation,
1489 },
1490 AlterConnection {
1492 name: ObjectName,
1494 operation: AlterConnectionOperation,
1495 },
1496 AlterSecret {
1498 name: ObjectName,
1500 with_options: Vec<SqlOption>,
1501 operation: AlterSecretOperation,
1502 },
1503 AlterFragment {
1505 fragment_id: u32,
1506 operation: AlterFragmentOperation,
1507 },
1508 AlterDefaultPrivileges {
1511 target_users: Option<Vec<Ident>>,
1512 schema_names: Option<Vec<ObjectName>>,
1513 operation: DefaultPrivilegeOperation,
1514 },
1515 Describe {
1517 name: ObjectName,
1519 kind: DescribeKind,
1520 },
1521 DescribeFragment {
1523 fragment_id: u32,
1524 },
1525 ShowObjects {
1527 object: ShowObject,
1528 filter: Option<ShowStatementFilter>,
1529 },
1530 ShowCreateObject {
1532 create_type: ShowCreateType,
1534 name: ObjectName,
1536 },
1537 ShowTransactionIsolationLevel,
1538 CancelJobs(JobIdents),
1540 Kill(String),
1543 Drop(DropStatement),
1545 DropFunction {
1547 if_exists: bool,
1548 func_desc: Vec<FunctionDesc>,
1550 option: Option<ReferentialAction>,
1552 },
1553 DropAggregate {
1555 if_exists: bool,
1556 func_desc: Vec<FunctionDesc>,
1558 option: Option<ReferentialAction>,
1560 },
1561 SetVariable {
1567 local: bool,
1568 variable: Ident,
1569 value: SetVariableValue,
1570 },
1571 ShowVariable {
1575 variable: Vec<Ident>,
1576 },
1577 StartTransaction {
1579 modes: Vec<TransactionMode>,
1580 },
1581 Begin {
1583 modes: Vec<TransactionMode>,
1584 },
1585 Abort,
1587 SetTransaction {
1589 modes: Vec<TransactionMode>,
1590 snapshot: Option<Value>,
1591 session: bool,
1592 },
1593 SetTimeZone {
1595 local: bool,
1596 value: SetTimeZoneValue,
1597 },
1598 Comment {
1602 object_type: CommentObject,
1603 object_name: ObjectName,
1604 comment: Option<String>,
1605 },
1606 Commit {
1608 chain: bool,
1609 },
1610 Rollback {
1612 chain: bool,
1613 },
1614 CreateSchema {
1616 schema_name: ObjectName,
1617 if_not_exists: bool,
1618 owner: Option<ObjectName>,
1619 },
1620 CreateDatabase {
1622 db_name: ObjectName,
1623 if_not_exists: bool,
1624 owner: Option<ObjectName>,
1625 resource_group: Option<SetVariableValue>,
1626 barrier_interval_ms: Option<u32>,
1627 checkpoint_frequency: Option<u64>,
1628 },
1629 Grant {
1631 privileges: Privileges,
1632 objects: GrantObjects,
1633 grantees: Vec<Ident>,
1634 with_grant_option: bool,
1635 granted_by: Option<Ident>,
1636 },
1637 Revoke {
1639 privileges: Privileges,
1640 objects: GrantObjects,
1641 grantees: Vec<Ident>,
1642 granted_by: Option<Ident>,
1643 revoke_grant_option: bool,
1644 cascade: bool,
1645 },
1646 Deallocate {
1650 name: Option<Ident>,
1651 prepare: bool,
1652 },
1653 Execute {
1657 name: Ident,
1658 parameters: Vec<Expr>,
1659 },
1660 Prepare {
1664 name: Ident,
1665 data_types: Vec<DataType>,
1666 statement: Box<Statement>,
1667 },
1668 Explain {
1670 analyze: bool,
1672 statement: Box<Statement>,
1674 options: ExplainOptions,
1676 },
1677 ExplainAnalyzeStreamJob {
1682 target: AnalyzeTarget,
1683 duration_secs: Option<u64>,
1684 },
1685 CreateUser(CreateUserStatement),
1687 AlterUser(AlterUserStatement),
1689 AlterSystem {
1691 param: Ident,
1692 value: SetVariableValue,
1693 },
1694 Flush,
1698 Wait,
1701 Recover,
1703 Use {
1707 db_name: ObjectName,
1708 },
1709 Vacuum {
1713 object_name: ObjectName,
1714 },
1715}
1716
1717#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1718#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1719pub enum DescribeKind {
1720 Plain,
1722
1723 Fragments,
1725}
1726
1727impl fmt::Display for Statement {
1728 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1733 let sql = self
1735 .try_to_string()
1736 .expect("normalized SQL should be parsable");
1737 f.write_str(&sql)
1738 }
1739}
1740
1741impl Statement {
1742 pub fn try_to_string(&self) -> Result<String, ParserError> {
1746 let sql = self.to_string_unchecked();
1747
1748 if matches!(
1750 self,
1751 Statement::CreateTable { .. } | Statement::CreateSource { .. }
1752 ) {
1753 let _ = Parser::parse_sql(&sql)?;
1754 }
1755 Ok(sql)
1756 }
1757
1758 pub fn to_string_unchecked(&self) -> String {
1764 let mut buf = String::new();
1765 self.fmt_unchecked(&mut buf).unwrap();
1766 buf
1767 }
1768
1769 #[allow(clippy::cognitive_complexity)]
1776 fn fmt_unchecked(&self, mut f: impl std::fmt::Write) -> fmt::Result {
1777 match self {
1778 Statement::Explain {
1779 analyze,
1780 statement,
1781 options,
1782 } => {
1783 write!(f, "EXPLAIN ")?;
1784
1785 if *analyze {
1786 write!(f, "ANALYZE ")?;
1787 }
1788 write!(f, "{}", options)?;
1789
1790 statement.fmt_unchecked(f)
1791 }
1792 Statement::ExplainAnalyzeStreamJob {
1793 target,
1794 duration_secs,
1795 } => {
1796 write!(f, "EXPLAIN ANALYZE {}", target)?;
1797 if let Some(duration_secs) = duration_secs {
1798 write!(f, " (DURATION_SECS {})", duration_secs)?;
1799 }
1800 Ok(())
1801 }
1802 Statement::Query(s) => write!(f, "{}", s),
1803 Statement::Truncate { table_name } => {
1804 write!(f, "TRUNCATE TABLE {}", table_name)?;
1805 Ok(())
1806 }
1807 Statement::Refresh { table_name } => {
1808 write!(f, "REFRESH TABLE {}", table_name)?;
1809 Ok(())
1810 }
1811 Statement::Analyze { table_name } => {
1812 write!(f, "ANALYZE TABLE {}", table_name)?;
1813 Ok(())
1814 }
1815 Statement::Describe { name, kind } => {
1816 write!(f, "DESCRIBE {}", name)?;
1817 match kind {
1818 DescribeKind::Plain => {}
1819
1820 DescribeKind::Fragments => {
1821 write!(f, " FRAGMENTS")?;
1822 }
1823 }
1824 Ok(())
1825 }
1826 Statement::DescribeFragment { fragment_id } => {
1827 write!(f, "DESCRIBE FRAGMENT {}", fragment_id)?;
1828 Ok(())
1829 }
1830 Statement::ShowObjects {
1831 object: show_object,
1832 filter,
1833 } => {
1834 write!(f, "SHOW {}", show_object)?;
1835 if let Some(filter) = filter {
1836 write!(f, " {}", filter)?;
1837 }
1838 Ok(())
1839 }
1840 Statement::ShowCreateObject {
1841 create_type: show_type,
1842 name,
1843 } => {
1844 write!(f, "SHOW CREATE {} {}", show_type, name)?;
1845 Ok(())
1846 }
1847 Statement::ShowTransactionIsolationLevel => {
1848 write!(f, "SHOW TRANSACTION ISOLATION LEVEL")?;
1849 Ok(())
1850 }
1851 Statement::Insert {
1852 table_name,
1853 columns,
1854 source,
1855 returning,
1856 } => {
1857 write!(f, "INSERT INTO {table_name} ", table_name = table_name,)?;
1858 if !columns.is_empty() {
1859 write!(f, "({}) ", display_comma_separated(columns))?;
1860 }
1861 write!(f, "{}", source)?;
1862 if !returning.is_empty() {
1863 write!(f, " RETURNING ({})", display_comma_separated(returning))?;
1864 }
1865 Ok(())
1866 }
1867 Statement::Copy {
1868 table_name,
1869 columns,
1870 values,
1871 } => {
1872 write!(f, "COPY {}", table_name)?;
1873 if !columns.is_empty() {
1874 write!(f, " ({})", display_comma_separated(columns))?;
1875 }
1876 write!(f, " FROM stdin; ")?;
1877 if !values.is_empty() {
1878 writeln!(f)?;
1879 let mut delim = "";
1880 for v in values {
1881 write!(f, "{}", delim)?;
1882 delim = "\t";
1883 if let Some(v) = v {
1884 write!(f, "{}", v)?;
1885 } else {
1886 write!(f, "\\N")?;
1887 }
1888 }
1889 }
1890 write!(f, "\n\\.")
1891 }
1892 Statement::Update {
1893 table_name,
1894 assignments,
1895 selection,
1896 returning,
1897 } => {
1898 write!(f, "UPDATE {}", table_name)?;
1899 if !assignments.is_empty() {
1900 write!(f, " SET {}", display_comma_separated(assignments))?;
1901 }
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::Delete {
1911 table_name,
1912 selection,
1913 returning,
1914 } => {
1915 write!(f, "DELETE FROM {}", table_name)?;
1916 if let Some(selection) = selection {
1917 write!(f, " WHERE {}", selection)?;
1918 }
1919 if !returning.is_empty() {
1920 write!(f, " RETURNING {}", display_comma_separated(returning))?;
1921 }
1922 Ok(())
1923 }
1924 Statement::CreateDatabase {
1925 db_name,
1926 if_not_exists,
1927 owner,
1928 resource_group,
1929 barrier_interval_ms,
1930 checkpoint_frequency,
1931 } => {
1932 write!(f, "CREATE DATABASE")?;
1933 if *if_not_exists {
1934 write!(f, " IF NOT EXISTS")?;
1935 }
1936 write!(f, " {}", db_name)?;
1937 if let Some(owner) = owner {
1938 write!(f, " WITH OWNER = {}", owner)?;
1939 }
1940 if let Some(resource_group) = resource_group {
1941 write!(f, " RESOURCE_GROUP = {}", resource_group)?;
1942 }
1943 if let Some(barrier_interval_ms) = barrier_interval_ms {
1944 write!(f, " BARRIER_INTERVAL_MS = {}", barrier_interval_ms)?;
1945 }
1946 if let Some(checkpoint_frequency) = checkpoint_frequency {
1947 write!(f, " CHECKPOINT_FREQUENCY = {}", checkpoint_frequency)?;
1948 }
1949
1950 Ok(())
1951 }
1952 Statement::CreateFunction {
1953 or_replace,
1954 temporary,
1955 if_not_exists,
1956 name,
1957 args,
1958 returns,
1959 params,
1960 with_options,
1961 } => {
1962 write!(
1963 f,
1964 "CREATE {or_replace}{temp}FUNCTION {if_not_exists}{name}",
1965 temp = if *temporary { "TEMPORARY " } else { "" },
1966 or_replace = if *or_replace { "OR REPLACE " } else { "" },
1967 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
1968 )?;
1969 if let Some(args) = args {
1970 write!(f, "({})", display_comma_separated(args))?;
1971 }
1972 if let Some(return_type) = returns {
1973 write!(f, " {}", return_type)?;
1974 }
1975 write!(f, "{params}")?;
1976 write!(f, "{with_options}")?;
1977 Ok(())
1978 }
1979 Statement::CreateAggregate {
1980 or_replace,
1981 if_not_exists,
1982 name,
1983 args,
1984 returns,
1985 append_only,
1986 params,
1987 } => {
1988 write!(
1989 f,
1990 "CREATE {or_replace}AGGREGATE {if_not_exists}{name}",
1991 or_replace = if *or_replace { "OR REPLACE " } else { "" },
1992 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
1993 )?;
1994 write!(f, "({})", display_comma_separated(args))?;
1995 write!(f, " RETURNS {}", returns)?;
1996 if *append_only {
1997 write!(f, " APPEND ONLY")?;
1998 }
1999 write!(f, "{params}")?;
2000 Ok(())
2001 }
2002 Statement::CreateView {
2003 name,
2004 or_replace,
2005 if_not_exists,
2006 columns,
2007 query,
2008 materialized,
2009 with_options,
2010 emit_mode,
2011 } => {
2012 write!(
2013 f,
2014 "CREATE {or_replace}{materialized}VIEW {if_not_exists}{name}",
2015 or_replace = if *or_replace { "OR REPLACE " } else { "" },
2016 materialized = if *materialized { "MATERIALIZED " } else { "" },
2017 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
2018 name = name
2019 )?;
2020 if !with_options.is_empty() {
2021 write!(f, " WITH ({})", display_comma_separated(with_options))?;
2022 }
2023 if !columns.is_empty() {
2024 write!(f, " ({})", display_comma_separated(columns))?;
2025 }
2026 write!(f, " AS {}", query)?;
2027 if let Some(emit_mode) = emit_mode {
2028 write!(f, " EMIT {}", emit_mode)?;
2029 }
2030 Ok(())
2031 }
2032 Statement::CreateTable {
2033 name,
2034 columns,
2035 wildcard_idx,
2036 constraints,
2037 with_options,
2038 or_replace,
2039 if_not_exists,
2040 temporary,
2041 format_encode,
2042 source_watermarks,
2043 append_only,
2044 on_conflict,
2045 with_version_column,
2046 query,
2047 cdc_table_info,
2048 include_column_options,
2049 webhook_info,
2050 engine,
2051 } => {
2052 write!(
2060 f,
2061 "CREATE {or_replace}{temporary}TABLE {if_not_exists}{name}",
2062 or_replace = if *or_replace { "OR REPLACE " } else { "" },
2063 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
2064 temporary = if *temporary { "TEMPORARY " } else { "" },
2065 name = name,
2066 )?;
2067 if !columns.is_empty() || !constraints.is_empty() {
2068 write!(
2069 f,
2070 " {}",
2071 fmt_create_items(columns, constraints, source_watermarks, *wildcard_idx)?
2072 )?;
2073 } else if query.is_none() {
2074 write!(f, " ()")?;
2076 }
2077 if *append_only {
2078 write!(f, " APPEND ONLY")?;
2079 }
2080
2081 if let Some(on_conflict_behavior) = on_conflict {
2082 write!(f, " ON CONFLICT {}", on_conflict_behavior)?;
2083 }
2084 if let Some(version_column) = with_version_column {
2085 write!(f, " WITH VERSION COLUMN({})", version_column)?;
2086 }
2087 if !include_column_options.is_empty() {
2088 write!(f, " {}", display_separated(include_column_options, " "))?;
2089 }
2090 if !with_options.is_empty() {
2091 write!(f, " WITH ({})", display_comma_separated(with_options))?;
2092 }
2093 if let Some(format_encode) = format_encode {
2094 write!(f, " {}", format_encode)?;
2095 }
2096 if let Some(query) = query {
2097 write!(f, " AS {}", query)?;
2098 }
2099 if let Some(info) = cdc_table_info {
2100 write!(f, " FROM {}", info.source_name)?;
2101 write!(f, " TABLE '{}'", info.external_table_name)?;
2102 }
2103 if let Some(info) = webhook_info {
2104 if let Some(secret) = &info.secret_ref {
2105 write!(f, " VALIDATE SECRET {}", secret.secret_name)?;
2106 } else {
2107 write!(f, " VALIDATE")?;
2108 }
2109 write!(f, " AS {}", info.signature_expr)?;
2110 }
2111 match engine {
2112 Engine::Hummock => {}
2113 Engine::Iceberg => {
2114 write!(f, " ENGINE = {}", engine)?;
2115 }
2116 }
2117 Ok(())
2118 }
2119 Statement::CreateIndex {
2120 name,
2121 table_name,
2122 columns,
2123 include,
2124 distributed_by,
2125 unique,
2126 if_not_exists,
2127 } => write!(
2128 f,
2129 "CREATE {unique}INDEX {if_not_exists}{name} ON {table_name}({columns}){include}{distributed_by}",
2130 unique = if *unique { "UNIQUE " } else { "" },
2131 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
2132 name = name,
2133 table_name = table_name,
2134 columns = display_comma_separated(columns),
2135 include = if include.is_empty() {
2136 "".to_owned()
2137 } else {
2138 format!(" INCLUDE({})", display_separated(include, ","))
2139 },
2140 distributed_by = if distributed_by.is_empty() {
2141 "".to_owned()
2142 } else {
2143 format!(
2144 " DISTRIBUTED BY({})",
2145 display_separated(distributed_by, ",")
2146 )
2147 }
2148 ),
2149 Statement::CreateSource { stmt } => write!(f, "CREATE SOURCE {}", stmt,),
2150 Statement::CreateSink { stmt } => write!(f, "CREATE SINK {}", stmt,),
2151 Statement::CreateSubscription { stmt } => write!(f, "CREATE SUBSCRIPTION {}", stmt,),
2152 Statement::CreateConnection { stmt } => write!(f, "CREATE CONNECTION {}", stmt,),
2153 Statement::DeclareCursor { stmt } => write!(f, "DECLARE {}", stmt,),
2154 Statement::FetchCursor { stmt } => write!(f, "FETCH {}", stmt),
2155 Statement::CloseCursor { stmt } => write!(f, "CLOSE {}", stmt),
2156 Statement::CreateSecret { stmt } => write!(f, "CREATE SECRET {}", stmt),
2157 Statement::AlterDatabase { name, operation } => {
2158 write!(f, "ALTER DATABASE {} {}", name, operation)
2159 }
2160 Statement::AlterSchema { name, operation } => {
2161 write!(f, "ALTER SCHEMA {} {}", name, operation)
2162 }
2163 Statement::AlterTable { name, operation } => {
2164 write!(f, "ALTER TABLE {} {}", name, operation)
2165 }
2166 Statement::AlterIndex { name, operation } => {
2167 write!(f, "ALTER INDEX {} {}", name, operation)
2168 }
2169 Statement::AlterView {
2170 materialized,
2171 name,
2172 operation,
2173 } => {
2174 write!(
2175 f,
2176 "ALTER {}VIEW {} {}",
2177 if *materialized { "MATERIALIZED " } else { "" },
2178 name,
2179 operation
2180 )
2181 }
2182 Statement::AlterSink { name, operation } => {
2183 write!(f, "ALTER SINK {} {}", name, operation)
2184 }
2185 Statement::AlterSubscription { name, operation } => {
2186 write!(f, "ALTER SUBSCRIPTION {} {}", name, operation)
2187 }
2188 Statement::AlterSource { name, operation } => {
2189 write!(f, "ALTER SOURCE {} {}", name, operation)
2190 }
2191 Statement::AlterFunction {
2192 name,
2193 args,
2194 operation,
2195 } => {
2196 write!(f, "ALTER FUNCTION {}", name)?;
2197 if let Some(args) = args {
2198 write!(f, "({})", display_comma_separated(args))?;
2199 }
2200 write!(f, " {}", operation)
2201 }
2202 Statement::AlterConnection { name, operation } => {
2203 write!(f, "ALTER CONNECTION {} {}", name, operation)
2204 }
2205 Statement::AlterSecret {
2206 name,
2207 with_options,
2208 operation,
2209 } => {
2210 write!(f, "ALTER SECRET {}", name)?;
2211 if !with_options.is_empty() {
2212 write!(f, " WITH ({})", display_comma_separated(with_options))?;
2213 }
2214 write!(f, " {}", operation)
2215 }
2216 Statement::Discard(t) => write!(f, "DISCARD {}", t),
2217 Statement::Drop(stmt) => write!(f, "DROP {}", stmt),
2218 Statement::DropFunction {
2219 if_exists,
2220 func_desc,
2221 option,
2222 } => {
2223 write!(
2224 f,
2225 "DROP FUNCTION{} {}",
2226 if *if_exists { " IF EXISTS" } else { "" },
2227 display_comma_separated(func_desc),
2228 )?;
2229 if let Some(op) = option {
2230 write!(f, " {}", op)?;
2231 }
2232 Ok(())
2233 }
2234 Statement::DropAggregate {
2235 if_exists,
2236 func_desc,
2237 option,
2238 } => {
2239 write!(
2240 f,
2241 "DROP AGGREGATE{} {}",
2242 if *if_exists { " IF EXISTS" } else { "" },
2243 display_comma_separated(func_desc),
2244 )?;
2245 if let Some(op) = option {
2246 write!(f, " {}", op)?;
2247 }
2248 Ok(())
2249 }
2250 Statement::SetVariable {
2251 local,
2252 variable,
2253 value,
2254 } => {
2255 f.write_str("SET ")?;
2256 if *local {
2257 f.write_str("LOCAL ")?;
2258 }
2259 write!(f, "{name} = {value}", name = variable,)
2260 }
2261 Statement::ShowVariable { variable } => {
2262 write!(f, "SHOW")?;
2263 if !variable.is_empty() {
2264 write!(f, " {}", display_separated(variable, " "))?;
2265 }
2266 Ok(())
2267 }
2268 Statement::StartTransaction { modes } => {
2269 write!(f, "START TRANSACTION")?;
2270 if !modes.is_empty() {
2271 write!(f, " {}", display_comma_separated(modes))?;
2272 }
2273 Ok(())
2274 }
2275 Statement::Abort => {
2276 write!(f, "ABORT")?;
2277 Ok(())
2278 }
2279 Statement::SetTransaction {
2280 modes,
2281 snapshot,
2282 session,
2283 } => {
2284 if *session {
2285 write!(f, "SET SESSION CHARACTERISTICS AS TRANSACTION")?;
2286 } else {
2287 write!(f, "SET TRANSACTION")?;
2288 }
2289 if !modes.is_empty() {
2290 write!(f, " {}", display_comma_separated(modes))?;
2291 }
2292 if let Some(snapshot_id) = snapshot {
2293 write!(f, " SNAPSHOT {}", snapshot_id)?;
2294 }
2295 Ok(())
2296 }
2297 Statement::SetTimeZone { local, value } => {
2298 write!(f, "SET")?;
2299 if *local {
2300 write!(f, " LOCAL")?;
2301 }
2302 write!(f, " TIME ZONE {}", value)?;
2303 Ok(())
2304 }
2305 Statement::Commit { chain } => {
2306 write!(f, "COMMIT{}", if *chain { " AND CHAIN" } else { "" },)
2307 }
2308 Statement::Rollback { chain } => {
2309 write!(f, "ROLLBACK{}", if *chain { " AND CHAIN" } else { "" },)
2310 }
2311 Statement::CreateSchema {
2312 schema_name,
2313 if_not_exists,
2314 owner,
2315 } => {
2316 write!(
2317 f,
2318 "CREATE SCHEMA {if_not_exists}{name}",
2319 if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
2320 name = schema_name
2321 )?;
2322 if let Some(user) = owner {
2323 write!(f, " AUTHORIZATION {}", user)?;
2324 }
2325 Ok(())
2326 }
2327 Statement::Grant {
2328 privileges,
2329 objects,
2330 grantees,
2331 with_grant_option,
2332 granted_by,
2333 } => {
2334 write!(f, "GRANT {} ", privileges)?;
2335 write!(f, "ON {} ", objects)?;
2336 write!(f, "TO {}", display_comma_separated(grantees))?;
2337 if *with_grant_option {
2338 write!(f, " WITH GRANT OPTION")?;
2339 }
2340 if let Some(grantor) = granted_by {
2341 write!(f, " GRANTED BY {}", grantor)?;
2342 }
2343 Ok(())
2344 }
2345 Statement::Revoke {
2346 privileges,
2347 objects,
2348 grantees,
2349 granted_by,
2350 revoke_grant_option,
2351 cascade,
2352 } => {
2353 write!(
2354 f,
2355 "REVOKE {}{} ",
2356 if *revoke_grant_option {
2357 "GRANT OPTION FOR "
2358 } else {
2359 ""
2360 },
2361 privileges
2362 )?;
2363 write!(f, "ON {} ", objects)?;
2364 write!(f, "FROM {}", display_comma_separated(grantees))?;
2365 if let Some(grantor) = granted_by {
2366 write!(f, " GRANTED BY {}", grantor)?;
2367 }
2368 write!(f, " {}", if *cascade { "CASCADE" } else { "RESTRICT" })?;
2369 Ok(())
2370 }
2371 Statement::Deallocate { name, prepare } => {
2372 if let Some(name) = name {
2373 write!(
2374 f,
2375 "DEALLOCATE {prepare}{name}",
2376 prepare = if *prepare { "PREPARE " } else { "" },
2377 name = name,
2378 )
2379 } else {
2380 write!(
2381 f,
2382 "DEALLOCATE {prepare}ALL",
2383 prepare = if *prepare { "PREPARE " } else { "" },
2384 )
2385 }
2386 }
2387 Statement::Execute { name, parameters } => {
2388 write!(f, "EXECUTE {}", name)?;
2389 if !parameters.is_empty() {
2390 write!(f, "({})", display_comma_separated(parameters))?;
2391 }
2392 Ok(())
2393 }
2394 Statement::Prepare {
2395 name,
2396 data_types,
2397 statement,
2398 } => {
2399 write!(f, "PREPARE {} ", name)?;
2400 if !data_types.is_empty() {
2401 write!(f, "({}) ", display_comma_separated(data_types))?;
2402 }
2403 write!(f, "AS ")?;
2404 statement.fmt_unchecked(f)
2405 }
2406 Statement::Comment {
2407 object_type,
2408 object_name,
2409 comment,
2410 } => {
2411 write!(f, "COMMENT ON {} {} IS ", object_type, object_name)?;
2412 if let Some(c) = comment {
2413 write!(f, "'{}'", c)
2414 } else {
2415 write!(f, "NULL")
2416 }
2417 }
2418 Statement::CreateUser(statement) => {
2419 write!(f, "CREATE USER {}", statement)
2420 }
2421 Statement::AlterUser(statement) => {
2422 write!(f, "ALTER USER {}", statement)
2423 }
2424 Statement::AlterSystem { param, value } => {
2425 f.write_str("ALTER SYSTEM SET ")?;
2426 write!(f, "{param} = {value}",)
2427 }
2428 Statement::Flush => {
2429 write!(f, "FLUSH")
2430 }
2431 Statement::Wait => {
2432 write!(f, "WAIT")
2433 }
2434 Statement::Begin { modes } => {
2435 write!(f, "BEGIN")?;
2436 if !modes.is_empty() {
2437 write!(f, " {}", display_comma_separated(modes))?;
2438 }
2439 Ok(())
2440 }
2441 Statement::CancelJobs(jobs) => {
2442 write!(f, "CANCEL JOBS {}", display_comma_separated(&jobs.0))?;
2443 Ok(())
2444 }
2445 Statement::Kill(worker_process_id) => {
2446 write!(f, "KILL '{}'", worker_process_id)?;
2447 Ok(())
2448 }
2449 Statement::Recover => {
2450 write!(f, "RECOVER")?;
2451 Ok(())
2452 }
2453 Statement::Use { db_name } => {
2454 write!(f, "USE {}", db_name)?;
2455 Ok(())
2456 }
2457 Statement::Vacuum { object_name } => {
2458 write!(f, "VACUUM {}", object_name)?;
2459 Ok(())
2460 }
2461 Statement::AlterFragment {
2462 fragment_id,
2463 operation,
2464 } => {
2465 write!(f, "ALTER FRAGMENT {} {}", fragment_id, operation)
2466 }
2467 Statement::AlterDefaultPrivileges {
2468 target_users,
2469 schema_names,
2470 operation,
2471 } => {
2472 write!(f, "ALTER DEFAULT PRIVILEGES")?;
2473 if let Some(target_users) = target_users {
2474 write!(f, " FOR {}", display_comma_separated(target_users))?;
2475 }
2476 if let Some(schema_names) = schema_names {
2477 write!(f, " IN SCHEMA {}", display_comma_separated(schema_names))?;
2478 }
2479 write!(f, " {}", operation)
2480 }
2481 }
2482 }
2483
2484 pub fn is_create(&self) -> bool {
2485 matches!(
2486 self,
2487 Statement::CreateTable { .. }
2488 | Statement::CreateView { .. }
2489 | Statement::CreateSource { .. }
2490 | Statement::CreateSink { .. }
2491 | Statement::CreateSubscription { .. }
2492 | Statement::CreateConnection { .. }
2493 | Statement::CreateSecret { .. }
2494 | Statement::CreateUser { .. }
2495 | Statement::CreateDatabase { .. }
2496 | Statement::CreateFunction { .. }
2497 | Statement::CreateAggregate { .. }
2498 | Statement::CreateIndex { .. }
2499 | Statement::CreateSchema { .. }
2500 )
2501 }
2502}
2503
2504impl Display for IncludeOptionItem {
2505 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2506 let Self {
2507 column_type,
2508 inner_field,
2509 header_inner_expect_type,
2510 column_alias,
2511 } = self;
2512 write!(f, "INCLUDE {}", column_type)?;
2513 if let Some(inner_field) = inner_field {
2514 write!(f, " '{}'", value::escape_single_quote_string(inner_field))?;
2515 if let Some(expected_type) = header_inner_expect_type {
2516 write!(f, " {}", expected_type)?;
2517 }
2518 }
2519 if let Some(alias) = column_alias {
2520 write!(f, " AS {}", alias)?;
2521 }
2522 Ok(())
2523 }
2524}
2525
2526#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2527#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2528#[non_exhaustive]
2529pub enum OnInsert {
2530 DuplicateKeyUpdate(Vec<Assignment>),
2532}
2533
2534impl fmt::Display for OnInsert {
2535 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2536 match self {
2537 Self::DuplicateKeyUpdate(expr) => write!(
2538 f,
2539 " ON DUPLICATE KEY UPDATE {}",
2540 display_comma_separated(expr)
2541 ),
2542 }
2543 }
2544}
2545
2546#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2548#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2549pub enum Privileges {
2550 All {
2552 with_privileges_keyword: bool,
2554 },
2555 Actions(Vec<Action>),
2557}
2558
2559impl fmt::Display for Privileges {
2560 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2561 match self {
2562 Privileges::All {
2563 with_privileges_keyword,
2564 } => {
2565 write!(
2566 f,
2567 "ALL{}",
2568 if *with_privileges_keyword {
2569 " PRIVILEGES"
2570 } else {
2571 ""
2572 }
2573 )
2574 }
2575 Privileges::Actions(actions) => {
2576 write!(f, "{}", display_comma_separated(actions))
2577 }
2578 }
2579 }
2580}
2581
2582#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2584#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2585pub enum Action {
2586 Connect,
2587 Create,
2588 Delete,
2589 Execute,
2590 Insert { columns: Option<Vec<Ident>> },
2591 References { columns: Option<Vec<Ident>> },
2592 Select { columns: Option<Vec<Ident>> },
2593 Temporary,
2594 Trigger,
2595 Truncate,
2596 Update { columns: Option<Vec<Ident>> },
2597 Usage,
2598}
2599
2600impl fmt::Display for Action {
2601 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2602 match self {
2603 Action::Connect => f.write_str("CONNECT")?,
2604 Action::Create => f.write_str("CREATE")?,
2605 Action::Delete => f.write_str("DELETE")?,
2606 Action::Execute => f.write_str("EXECUTE")?,
2607 Action::Insert { .. } => f.write_str("INSERT")?,
2608 Action::References { .. } => f.write_str("REFERENCES")?,
2609 Action::Select { .. } => f.write_str("SELECT")?,
2610 Action::Temporary => f.write_str("TEMPORARY")?,
2611 Action::Trigger => f.write_str("TRIGGER")?,
2612 Action::Truncate => f.write_str("TRUNCATE")?,
2613 Action::Update { .. } => f.write_str("UPDATE")?,
2614 Action::Usage => f.write_str("USAGE")?,
2615 };
2616 match self {
2617 Action::Insert { columns }
2618 | Action::References { columns }
2619 | Action::Select { columns }
2620 | Action::Update { columns } => {
2621 if let Some(columns) = columns {
2622 write!(f, " ({})", display_comma_separated(columns))?;
2623 }
2624 }
2625 _ => (),
2626 };
2627 Ok(())
2628 }
2629}
2630
2631#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2633#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2634pub enum GrantObjects {
2635 AllSequencesInSchema { schemas: Vec<ObjectName> },
2637 AllTablesInSchema { schemas: Vec<ObjectName> },
2639 AllSourcesInSchema { schemas: Vec<ObjectName> },
2641 AllSinksInSchema { schemas: Vec<ObjectName> },
2643 AllMviewsInSchema { schemas: Vec<ObjectName> },
2645 AllViewsInSchema { schemas: Vec<ObjectName> },
2647 AllFunctionsInSchema { schemas: Vec<ObjectName> },
2649 AllSecretsInSchema { schemas: Vec<ObjectName> },
2651 AllSubscriptionsInSchema { schemas: Vec<ObjectName> },
2653 AllConnectionsInSchema { schemas: Vec<ObjectName> },
2655 Databases(Vec<ObjectName>),
2657 Schemas(Vec<ObjectName>),
2659 Sources(Vec<ObjectName>),
2661 Mviews(Vec<ObjectName>),
2663 Sequences(Vec<ObjectName>),
2665 Tables(Vec<ObjectName>),
2667 Sinks(Vec<ObjectName>),
2669 Views(Vec<ObjectName>),
2671 Connections(Vec<ObjectName>),
2673 Subscriptions(Vec<ObjectName>),
2675 Functions(Vec<FunctionDesc>),
2677 Secrets(Vec<ObjectName>),
2679}
2680
2681impl fmt::Display for GrantObjects {
2682 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2683 match self {
2684 GrantObjects::Sequences(sequences) => {
2685 write!(f, "SEQUENCE {}", display_comma_separated(sequences))
2686 }
2687 GrantObjects::Schemas(schemas) => {
2688 write!(f, "SCHEMA {}", display_comma_separated(schemas))
2689 }
2690 GrantObjects::Tables(tables) => {
2691 write!(f, "{}", display_comma_separated(tables))
2692 }
2693 GrantObjects::AllSequencesInSchema { schemas } => {
2694 write!(
2695 f,
2696 "ALL SEQUENCES IN SCHEMA {}",
2697 display_comma_separated(schemas)
2698 )
2699 }
2700 GrantObjects::AllTablesInSchema { schemas } => {
2701 write!(
2702 f,
2703 "ALL TABLES IN SCHEMA {}",
2704 display_comma_separated(schemas)
2705 )
2706 }
2707 GrantObjects::AllSourcesInSchema { schemas } => {
2708 write!(
2709 f,
2710 "ALL SOURCES IN SCHEMA {}",
2711 display_comma_separated(schemas)
2712 )
2713 }
2714 GrantObjects::AllMviewsInSchema { schemas } => {
2715 write!(
2716 f,
2717 "ALL MATERIALIZED VIEWS IN SCHEMA {}",
2718 display_comma_separated(schemas)
2719 )
2720 }
2721 GrantObjects::AllSinksInSchema { schemas } => {
2722 write!(
2723 f,
2724 "ALL SINKS IN SCHEMA {}",
2725 display_comma_separated(schemas)
2726 )
2727 }
2728 GrantObjects::AllViewsInSchema { schemas } => {
2729 write!(
2730 f,
2731 "ALL VIEWS IN SCHEMA {}",
2732 display_comma_separated(schemas)
2733 )
2734 }
2735 GrantObjects::AllFunctionsInSchema { schemas } => {
2736 write!(
2737 f,
2738 "ALL FUNCTIONS IN SCHEMA {}",
2739 display_comma_separated(schemas)
2740 )
2741 }
2742 GrantObjects::AllSecretsInSchema { schemas } => {
2743 write!(
2744 f,
2745 "ALL SECRETS IN SCHEMA {}",
2746 display_comma_separated(schemas)
2747 )
2748 }
2749 GrantObjects::AllSubscriptionsInSchema { schemas } => {
2750 write!(
2751 f,
2752 "ALL SUBSCRIPTIONS IN SCHEMA {}",
2753 display_comma_separated(schemas)
2754 )
2755 }
2756 GrantObjects::AllConnectionsInSchema { schemas } => {
2757 write!(
2758 f,
2759 "ALL CONNECTIONS IN SCHEMA {}",
2760 display_comma_separated(schemas)
2761 )
2762 }
2763 GrantObjects::Databases(databases) => {
2764 write!(f, "DATABASE {}", display_comma_separated(databases))
2765 }
2766 GrantObjects::Sources(sources) => {
2767 write!(f, "SOURCE {}", display_comma_separated(sources))
2768 }
2769 GrantObjects::Mviews(mviews) => {
2770 write!(f, "MATERIALIZED VIEW {}", display_comma_separated(mviews))
2771 }
2772 GrantObjects::Sinks(sinks) => {
2773 write!(f, "SINK {}", display_comma_separated(sinks))
2774 }
2775 GrantObjects::Views(views) => {
2776 write!(f, "VIEW {}", display_comma_separated(views))
2777 }
2778 GrantObjects::Connections(connections) => {
2779 write!(f, "CONNECTION {}", display_comma_separated(connections))
2780 }
2781 GrantObjects::Subscriptions(subscriptions) => {
2782 write!(f, "SUBSCRIPTION {}", display_comma_separated(subscriptions))
2783 }
2784 GrantObjects::Functions(func_descs) => {
2785 write!(f, "FUNCTION {}", display_comma_separated(func_descs))
2786 }
2787 GrantObjects::Secrets(secrets) => {
2788 write!(f, "SECRET {}", display_comma_separated(secrets))
2789 }
2790 }
2791 }
2792}
2793
2794#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2795#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2796pub enum PrivilegeObjectType {
2797 Tables,
2798 Sources,
2799 Sinks,
2800 Mviews,
2801 Views,
2802 Functions,
2803 Connections,
2804 Secrets,
2805 Subscriptions,
2806 Schemas,
2807}
2808
2809impl fmt::Display for PrivilegeObjectType {
2810 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2811 match self {
2812 PrivilegeObjectType::Tables => f.write_str("TABLES")?,
2813 PrivilegeObjectType::Sources => f.write_str("SOURCES")?,
2814 PrivilegeObjectType::Sinks => f.write_str("SINKS")?,
2815 PrivilegeObjectType::Mviews => f.write_str("MATERIALIZED VIEWS")?,
2816 PrivilegeObjectType::Views => f.write_str("VIEWS")?,
2817 PrivilegeObjectType::Functions => f.write_str("FUNCTIONS")?,
2818 PrivilegeObjectType::Connections => f.write_str("CONNECTIONS")?,
2819 PrivilegeObjectType::Secrets => f.write_str("SECRETS")?,
2820 PrivilegeObjectType::Subscriptions => f.write_str("SUBSCRIPTIONS")?,
2821 PrivilegeObjectType::Schemas => f.write_str("SCHEMAS")?,
2822 };
2823 Ok(())
2824 }
2825}
2826
2827#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2828#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2829pub enum DefaultPrivilegeOperation {
2830 Grant {
2831 privileges: Privileges,
2832 object_type: PrivilegeObjectType,
2833 grantees: Vec<Ident>,
2834 with_grant_option: bool,
2835 },
2836 Revoke {
2837 privileges: Privileges,
2838 object_type: PrivilegeObjectType,
2839 grantees: Vec<Ident>,
2840 revoke_grant_option: bool,
2841 cascade: bool,
2842 },
2843}
2844
2845impl fmt::Display for DefaultPrivilegeOperation {
2846 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2847 match self {
2848 DefaultPrivilegeOperation::Grant {
2849 privileges,
2850 object_type,
2851 grantees,
2852 with_grant_option,
2853 } => {
2854 write!(
2855 f,
2856 "GRANT {} ON {} TO {}",
2857 privileges,
2858 object_type,
2859 display_comma_separated(grantees)
2860 )?;
2861 if *with_grant_option {
2862 write!(f, " WITH GRANT OPTION")?;
2863 }
2864 }
2865 DefaultPrivilegeOperation::Revoke {
2866 privileges,
2867 object_type,
2868 grantees,
2869 revoke_grant_option,
2870 cascade,
2871 } => {
2872 write!(f, "REVOKE")?;
2873 if *revoke_grant_option {
2874 write!(f, " GRANT OPTION FOR")?;
2875 }
2876 write!(
2877 f,
2878 " {} ON {} FROM {}",
2879 privileges,
2880 object_type,
2881 display_comma_separated(grantees)
2882 )?;
2883 write!(f, " {}", if *cascade { "CASCADE" } else { "RESTRICT" })?;
2884 }
2885 }
2886 Ok(())
2887 }
2888}
2889
2890impl DefaultPrivilegeOperation {
2891 pub fn for_schemas(&self) -> bool {
2892 match &self {
2893 DefaultPrivilegeOperation::Grant { object_type, .. } => {
2894 object_type == &PrivilegeObjectType::Schemas
2895 }
2896 DefaultPrivilegeOperation::Revoke { object_type, .. } => {
2897 object_type == &PrivilegeObjectType::Schemas
2898 }
2899 }
2900 }
2901}
2902
2903#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2904#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2905pub enum AssignmentValue {
2906 Expr(Expr),
2908 Default,
2910}
2911
2912impl fmt::Display for AssignmentValue {
2913 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2914 match self {
2915 AssignmentValue::Expr(expr) => write!(f, "{}", expr),
2916 AssignmentValue::Default => f.write_str("DEFAULT"),
2917 }
2918 }
2919}
2920
2921#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2923#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2924pub struct Assignment {
2925 pub id: Vec<Ident>,
2926 pub value: AssignmentValue,
2927}
2928
2929impl fmt::Display for Assignment {
2930 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2931 write!(f, "{} = {}", display_separated(&self.id, "."), self.value)
2932 }
2933}
2934
2935#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2936#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2937pub enum FunctionArgExpr {
2938 Expr(Expr),
2939 ExprQualifiedWildcard(Expr, Vec<Ident>),
2943 QualifiedWildcard(ObjectName, Option<Vec<Expr>>),
2946 Wildcard(Option<Vec<Expr>>),
2948}
2949
2950impl fmt::Display for FunctionArgExpr {
2951 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2952 match self {
2953 FunctionArgExpr::Expr(expr) => write!(f, "{}", expr),
2954 FunctionArgExpr::ExprQualifiedWildcard(expr, prefix) => {
2955 write!(
2956 f,
2957 "({}){}.*",
2958 expr,
2959 prefix
2960 .iter()
2961 .format_with("", |i, f| f(&format_args!(".{i}")))
2962 )
2963 }
2964 FunctionArgExpr::QualifiedWildcard(prefix, except) => match except {
2965 Some(exprs) => write!(
2966 f,
2967 "{}.* EXCEPT ({})",
2968 prefix,
2969 exprs
2970 .iter()
2971 .map(|v| v.to_string())
2972 .collect::<Vec<String>>()
2973 .as_slice()
2974 .join(", ")
2975 ),
2976 None => write!(f, "{}.*", prefix),
2977 },
2978
2979 FunctionArgExpr::Wildcard(except) => match except {
2980 Some(exprs) => write!(
2981 f,
2982 "* EXCEPT ({})",
2983 exprs
2984 .iter()
2985 .map(|v| v.to_string())
2986 .collect::<Vec<String>>()
2987 .as_slice()
2988 .join(", ")
2989 ),
2990 None => f.write_str("*"),
2991 },
2992 }
2993 }
2994}
2995
2996#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2997#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2998pub enum FunctionArg {
2999 Named { name: Ident, arg: FunctionArgExpr },
3000 Unnamed(FunctionArgExpr),
3001}
3002
3003impl FunctionArg {
3004 pub fn get_expr(&self) -> FunctionArgExpr {
3005 match self {
3006 FunctionArg::Named { name: _, arg } => arg.clone(),
3007 FunctionArg::Unnamed(arg) => arg.clone(),
3008 }
3009 }
3010}
3011
3012impl fmt::Display for FunctionArg {
3013 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3014 match self {
3015 FunctionArg::Named { name, arg } => write!(f, "{} => {}", name, arg),
3016 FunctionArg::Unnamed(unnamed_arg) => write!(f, "{}", unnamed_arg),
3017 }
3018 }
3019}
3020
3021#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3024#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3025pub struct FunctionArgList {
3026 pub distinct: bool,
3028 pub args: Vec<FunctionArg>,
3029 pub variadic: bool,
3031 pub order_by: Vec<OrderByExpr>,
3033 pub ignore_nulls: bool,
3035}
3036
3037impl fmt::Display for FunctionArgList {
3038 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3039 write!(f, "(")?;
3040 if self.distinct {
3041 write!(f, "DISTINCT ")?;
3042 }
3043 if self.variadic {
3044 for arg in &self.args[0..self.args.len() - 1] {
3045 write!(f, "{}, ", arg)?;
3046 }
3047 write!(f, "VARIADIC {}", self.args.last().unwrap())?;
3048 } else {
3049 write!(f, "{}", display_comma_separated(&self.args))?;
3050 }
3051 if !self.order_by.is_empty() {
3052 write!(f, " ORDER BY {}", display_comma_separated(&self.order_by))?;
3053 }
3054 if self.ignore_nulls {
3055 write!(f, " IGNORE NULLS")?;
3056 }
3057 write!(f, ")")?;
3058 Ok(())
3059 }
3060}
3061
3062impl FunctionArgList {
3063 pub fn empty() -> Self {
3064 Self {
3065 distinct: false,
3066 args: vec![],
3067 variadic: false,
3068 order_by: vec![],
3069 ignore_nulls: false,
3070 }
3071 }
3072
3073 pub fn args_only(args: Vec<FunctionArg>) -> Self {
3074 Self {
3075 distinct: false,
3076 args,
3077 variadic: false,
3078 order_by: vec![],
3079 ignore_nulls: false,
3080 }
3081 }
3082
3083 pub fn is_args_only(&self) -> bool {
3084 !self.distinct && !self.variadic && self.order_by.is_empty() && !self.ignore_nulls
3085 }
3086
3087 pub fn for_agg(distinct: bool, args: Vec<FunctionArg>, order_by: Vec<OrderByExpr>) -> Self {
3088 Self {
3089 distinct,
3090 args,
3091 variadic: false,
3092 order_by,
3093 ignore_nulls: false,
3094 }
3095 }
3096}
3097
3098#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3100#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3101pub struct Function {
3102 pub scalar_as_agg: bool,
3104 pub name: ObjectName,
3106 pub arg_list: FunctionArgList,
3108 pub within_group: Option<Box<OrderByExpr>>,
3111 pub filter: Option<Box<Expr>>,
3113 pub over: Option<Window>,
3115}
3116
3117impl Function {
3118 pub fn no_arg(name: ObjectName) -> Self {
3119 Self {
3120 scalar_as_agg: false,
3121 name,
3122 arg_list: FunctionArgList::empty(),
3123 within_group: None,
3124 filter: None,
3125 over: None,
3126 }
3127 }
3128}
3129
3130impl fmt::Display for Function {
3131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3132 if self.scalar_as_agg {
3133 write!(f, "AGGREGATE:")?;
3134 }
3135 write!(f, "{}{}", self.name, self.arg_list)?;
3136 if let Some(within_group) = &self.within_group {
3137 write!(f, " WITHIN GROUP (ORDER BY {})", within_group)?;
3138 }
3139 if let Some(filter) = &self.filter {
3140 write!(f, " FILTER (WHERE {})", filter)?;
3141 }
3142 if let Some(o) = &self.over {
3143 write!(f, " OVER {}", o)?;
3144 }
3145 Ok(())
3146 }
3147}
3148
3149#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3150#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3151pub enum ObjectType {
3152 Table,
3153 View,
3154 MaterializedView,
3155 Index,
3156 Schema,
3157 Source,
3158 Sink,
3159 Database,
3160 User,
3161 Connection,
3162 Secret,
3163 Subscription,
3164}
3165
3166impl fmt::Display for ObjectType {
3167 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3168 f.write_str(match self {
3169 ObjectType::Table => "TABLE",
3170 ObjectType::View => "VIEW",
3171 ObjectType::MaterializedView => "MATERIALIZED VIEW",
3172 ObjectType::Index => "INDEX",
3173 ObjectType::Schema => "SCHEMA",
3174 ObjectType::Source => "SOURCE",
3175 ObjectType::Sink => "SINK",
3176 ObjectType::Database => "DATABASE",
3177 ObjectType::User => "USER",
3178 ObjectType::Secret => "SECRET",
3179 ObjectType::Connection => "CONNECTION",
3180 ObjectType::Subscription => "SUBSCRIPTION",
3181 })
3182 }
3183}
3184
3185impl ParseTo for ObjectType {
3186 fn parse_to(parser: &mut Parser<'_>) -> ModalResult<Self> {
3187 let object_type = if parser.parse_keyword(Keyword::TABLE) {
3188 ObjectType::Table
3189 } else if parser.parse_keyword(Keyword::VIEW) {
3190 ObjectType::View
3191 } else if parser.parse_keywords(&[Keyword::MATERIALIZED, Keyword::VIEW]) {
3192 ObjectType::MaterializedView
3193 } else if parser.parse_keyword(Keyword::SOURCE) {
3194 ObjectType::Source
3195 } else if parser.parse_keyword(Keyword::SINK) {
3196 ObjectType::Sink
3197 } else if parser.parse_keyword(Keyword::INDEX) {
3198 ObjectType::Index
3199 } else if parser.parse_keyword(Keyword::SCHEMA) {
3200 ObjectType::Schema
3201 } else if parser.parse_keyword(Keyword::DATABASE) {
3202 ObjectType::Database
3203 } else if parser.parse_keyword(Keyword::USER) {
3204 ObjectType::User
3205 } else if parser.parse_keyword(Keyword::CONNECTION) {
3206 ObjectType::Connection
3207 } else if parser.parse_keyword(Keyword::SECRET) {
3208 ObjectType::Secret
3209 } else if parser.parse_keyword(Keyword::SUBSCRIPTION) {
3210 ObjectType::Subscription
3211 } else {
3212 return parser.expected(
3213 "TABLE, VIEW, INDEX, MATERIALIZED VIEW, SOURCE, SINK, SUBSCRIPTION, SCHEMA, DATABASE, USER, SECRET or CONNECTION after DROP",
3214 );
3215 };
3216 Ok(object_type)
3217 }
3218}
3219
3220#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3221#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3222pub struct SqlOption {
3223 pub name: ObjectName,
3224 pub value: SqlOptionValue,
3225}
3226
3227impl fmt::Display for SqlOption {
3228 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3229 let should_redact = REDACT_SQL_OPTION_KEYWORDS
3230 .try_with(|keywords| {
3231 let sql_option_name = self.name.real_value().to_lowercase();
3232 keywords.iter().any(|k| sql_option_name.contains(k))
3233 })
3234 .unwrap_or(false);
3235 if should_redact {
3236 write!(f, "{} = [REDACTED]", self.name)
3237 } else {
3238 write!(f, "{} = {}", self.name, self.value)
3239 }
3240 }
3241}
3242
3243impl TryFrom<(&String, &String)> for SqlOption {
3244 type Error = ParserError;
3245
3246 fn try_from((name, value): (&String, &String)) -> Result<Self, Self::Error> {
3247 let query = format!("{} = {}", name, value);
3248 let mut tokenizer = Tokenizer::new(query.as_str());
3249 let tokens = tokenizer.tokenize_with_location()?;
3250 let mut parser = Parser(&tokens);
3251 parser
3252 .parse_sql_option()
3253 .map_err(|e| ParserError::ParserError(e.to_string()))
3254 }
3255}
3256
3257#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3258#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3259pub enum SqlOptionValue {
3260 Value(Value),
3261 SecretRef(SecretRefValue),
3262 ConnectionRef(ConnectionRefValue),
3263 BackfillOrder(BackfillOrderStrategy),
3264}
3265
3266impl fmt::Display for SqlOptionValue {
3267 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3268 match self {
3269 SqlOptionValue::Value(value) => write!(f, "{}", value),
3270 SqlOptionValue::SecretRef(secret_ref) => write!(f, "secret {}", secret_ref),
3271 SqlOptionValue::ConnectionRef(connection_ref) => {
3272 write!(f, "{}", connection_ref)
3273 }
3274 SqlOptionValue::BackfillOrder(order) => {
3275 write!(f, "{}", order)
3276 }
3277 }
3278 }
3279}
3280
3281impl From<Value> for SqlOptionValue {
3282 fn from(value: Value) -> Self {
3283 SqlOptionValue::Value(value)
3284 }
3285}
3286
3287#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3288#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3289pub enum EmitMode {
3290 Immediately,
3291 OnWindowClose,
3292}
3293
3294impl fmt::Display for EmitMode {
3295 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3296 f.write_str(match self {
3297 EmitMode::Immediately => "IMMEDIATELY",
3298 EmitMode::OnWindowClose => "ON WINDOW CLOSE",
3299 })
3300 }
3301}
3302
3303#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3304#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3305pub enum OnConflict {
3306 UpdateFull,
3307 Nothing,
3308 UpdateIfNotNull,
3309}
3310
3311impl fmt::Display for OnConflict {
3312 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3313 f.write_str(match self {
3314 OnConflict::UpdateFull => "DO UPDATE FULL",
3315 OnConflict::Nothing => "DO NOTHING",
3316 OnConflict::UpdateIfNotNull => "DO UPDATE IF NOT NULL",
3317 })
3318 }
3319}
3320
3321#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3322#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3323pub enum Engine {
3324 Hummock,
3325 Iceberg,
3326}
3327
3328impl fmt::Display for crate::ast::Engine {
3329 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3330 f.write_str(match self {
3331 crate::ast::Engine::Hummock => "HUMMOCK",
3332 crate::ast::Engine::Iceberg => "ICEBERG",
3333 })
3334 }
3335}
3336
3337#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3338#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3339pub enum SetTimeZoneValue {
3340 Ident(Ident),
3341 Literal(Value),
3342 Local,
3343 Default,
3344}
3345
3346impl fmt::Display for SetTimeZoneValue {
3347 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3348 match self {
3349 SetTimeZoneValue::Ident(ident) => write!(f, "{}", ident),
3350 SetTimeZoneValue::Literal(value) => write!(f, "{}", value),
3351 SetTimeZoneValue::Local => f.write_str("LOCAL"),
3352 SetTimeZoneValue::Default => f.write_str("DEFAULT"),
3353 }
3354 }
3355}
3356
3357#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3358#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3359pub enum TransactionMode {
3360 AccessMode(TransactionAccessMode),
3361 IsolationLevel(TransactionIsolationLevel),
3362}
3363
3364impl fmt::Display for TransactionMode {
3365 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3366 use TransactionMode::*;
3367 match self {
3368 AccessMode(access_mode) => write!(f, "{}", access_mode),
3369 IsolationLevel(iso_level) => write!(f, "ISOLATION LEVEL {}", iso_level),
3370 }
3371 }
3372}
3373
3374#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3375#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3376pub enum TransactionAccessMode {
3377 ReadOnly,
3378 ReadWrite,
3379}
3380
3381impl fmt::Display for TransactionAccessMode {
3382 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3383 use TransactionAccessMode::*;
3384 f.write_str(match self {
3385 ReadOnly => "READ ONLY",
3386 ReadWrite => "READ WRITE",
3387 })
3388 }
3389}
3390
3391#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3392#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3393pub enum TransactionIsolationLevel {
3394 ReadUncommitted,
3395 ReadCommitted,
3396 RepeatableRead,
3397 Serializable,
3398}
3399
3400impl fmt::Display for TransactionIsolationLevel {
3401 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3402 use TransactionIsolationLevel::*;
3403 f.write_str(match self {
3404 ReadUncommitted => "READ UNCOMMITTED",
3405 ReadCommitted => "READ COMMITTED",
3406 RepeatableRead => "REPEATABLE READ",
3407 Serializable => "SERIALIZABLE",
3408 })
3409 }
3410}
3411
3412#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3413#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3414pub enum ShowStatementFilter {
3415 Like(String),
3416 ILike(String),
3417 Where(Expr),
3418}
3419
3420impl fmt::Display for ShowStatementFilter {
3421 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3422 use ShowStatementFilter::*;
3423 match self {
3424 Like(pattern) => write!(f, "LIKE '{}'", value::escape_single_quote_string(pattern)),
3425 ILike(pattern) => write!(f, "ILIKE {}", value::escape_single_quote_string(pattern)),
3426 Where(expr) => write!(f, "WHERE {}", expr),
3427 }
3428 }
3429}
3430
3431#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3433#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3434pub enum DropFunctionOption {
3435 Restrict,
3436 Cascade,
3437}
3438
3439impl fmt::Display for DropFunctionOption {
3440 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3441 match self {
3442 DropFunctionOption::Restrict => write!(f, "RESTRICT "),
3443 DropFunctionOption::Cascade => write!(f, "CASCADE "),
3444 }
3445 }
3446}
3447
3448#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3450#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3451pub struct FunctionDesc {
3452 pub name: ObjectName,
3453 pub args: Option<Vec<OperateFunctionArg>>,
3454}
3455
3456impl fmt::Display for FunctionDesc {
3457 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3458 write!(f, "{}", self.name)?;
3459 if let Some(args) = &self.args {
3460 write!(f, "({})", display_comma_separated(args))?;
3461 }
3462 Ok(())
3463 }
3464}
3465
3466#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3468#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3469pub struct OperateFunctionArg {
3470 pub mode: Option<ArgMode>,
3471 pub name: Option<Ident>,
3472 pub data_type: DataType,
3473 pub default_expr: Option<Expr>,
3474}
3475
3476impl OperateFunctionArg {
3477 pub fn unnamed(data_type: DataType) -> Self {
3479 Self {
3480 mode: None,
3481 name: None,
3482 data_type,
3483 default_expr: None,
3484 }
3485 }
3486
3487 pub fn with_name(name: &str, data_type: DataType) -> Self {
3489 Self {
3490 mode: None,
3491 name: Some(name.into()),
3492 data_type,
3493 default_expr: None,
3494 }
3495 }
3496}
3497
3498impl fmt::Display for OperateFunctionArg {
3499 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3500 if let Some(mode) = &self.mode {
3501 write!(f, "{} ", mode)?;
3502 }
3503 if let Some(name) = &self.name {
3504 write!(f, "{} ", name)?;
3505 }
3506 write!(f, "{}", self.data_type)?;
3507 if let Some(default_expr) = &self.default_expr {
3508 write!(f, " = {}", default_expr)?;
3509 }
3510 Ok(())
3511 }
3512}
3513
3514#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3516#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3517pub enum ArgMode {
3518 In,
3519 Out,
3520 InOut,
3521}
3522
3523impl fmt::Display for ArgMode {
3524 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3525 match self {
3526 ArgMode::In => write!(f, "IN"),
3527 ArgMode::Out => write!(f, "OUT"),
3528 ArgMode::InOut => write!(f, "INOUT"),
3529 }
3530 }
3531}
3532
3533#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3535#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3536pub enum FunctionBehavior {
3537 Immutable,
3538 Stable,
3539 Volatile,
3540}
3541
3542impl fmt::Display for FunctionBehavior {
3543 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3544 match self {
3545 FunctionBehavior::Immutable => write!(f, "IMMUTABLE"),
3546 FunctionBehavior::Stable => write!(f, "STABLE"),
3547 FunctionBehavior::Volatile => write!(f, "VOLATILE"),
3548 }
3549 }
3550}
3551
3552#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3553#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3554pub enum FunctionDefinition {
3555 Identifier(String),
3556 SingleQuotedDef(String),
3557 DoubleDollarDef(String),
3558}
3559
3560impl fmt::Display for FunctionDefinition {
3561 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3562 match self {
3563 FunctionDefinition::Identifier(s) => write!(f, "{s}")?,
3564 FunctionDefinition::SingleQuotedDef(s) => write!(f, "'{s}'")?,
3565 FunctionDefinition::DoubleDollarDef(s) => write!(f, "$${s}$$")?,
3566 }
3567 Ok(())
3568 }
3569}
3570
3571impl FunctionDefinition {
3572 pub fn as_str(&self) -> &str {
3574 match self {
3575 FunctionDefinition::Identifier(s) => s,
3576 FunctionDefinition::SingleQuotedDef(s) => s,
3577 FunctionDefinition::DoubleDollarDef(s) => s,
3578 }
3579 }
3580
3581 pub fn into_string(self) -> String {
3583 match self {
3584 FunctionDefinition::Identifier(s) => s,
3585 FunctionDefinition::SingleQuotedDef(s) => s,
3586 FunctionDefinition::DoubleDollarDef(s) => s,
3587 }
3588 }
3589}
3590
3591#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3593#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3594pub enum CreateFunctionReturns {
3595 Value(DataType),
3597 Table(Vec<TableColumnDef>),
3599}
3600
3601impl fmt::Display for CreateFunctionReturns {
3602 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3603 match self {
3604 Self::Value(data_type) => write!(f, "RETURNS {}", data_type),
3605 Self::Table(columns) => {
3606 write!(f, "RETURNS TABLE ({})", display_comma_separated(columns))
3607 }
3608 }
3609 }
3610}
3611
3612#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3614#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3615pub struct TableColumnDef {
3616 pub name: Ident,
3617 pub data_type: DataType,
3618}
3619
3620impl fmt::Display for TableColumnDef {
3621 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3622 write!(f, "{} {}", self.name, self.data_type)
3623 }
3624}
3625
3626#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
3631#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3632pub struct CreateFunctionBody {
3633 pub language: Option<Ident>,
3635 pub runtime: Option<Ident>,
3637
3638 pub behavior: Option<FunctionBehavior>,
3640 pub as_: Option<FunctionDefinition>,
3644 pub return_: Option<Expr>,
3646 pub using: Option<CreateFunctionUsing>,
3648}
3649
3650impl fmt::Display for CreateFunctionBody {
3651 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3652 if let Some(language) = &self.language {
3653 write!(f, " LANGUAGE {language}")?;
3654 }
3655 if let Some(runtime) = &self.runtime {
3656 write!(f, " RUNTIME {runtime}")?;
3657 }
3658 if let Some(behavior) = &self.behavior {
3659 write!(f, " {behavior}")?;
3660 }
3661 if let Some(definition) = &self.as_ {
3662 write!(f, " AS {definition}")?;
3663 }
3664 if let Some(expr) = &self.return_ {
3665 write!(f, " RETURN {expr}")?;
3666 }
3667 if let Some(using) = &self.using {
3668 write!(f, " {using}")?;
3669 }
3670 Ok(())
3671 }
3672}
3673
3674#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
3675#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3676pub struct CreateFunctionWithOptions {
3677 pub always_retry_on_network_error: Option<bool>,
3679 pub r#async: Option<bool>,
3681 pub batch: Option<bool>,
3683}
3684
3685impl TryFrom<Vec<SqlOption>> for CreateFunctionWithOptions {
3687 type Error = StrError;
3688
3689 fn try_from(with_options: Vec<SqlOption>) -> Result<Self, Self::Error> {
3690 let mut options = Self::default();
3691 for option in with_options {
3692 match option.name.to_string().to_lowercase().as_str() {
3693 "always_retry_on_network_error" => {
3694 options.always_retry_on_network_error = Some(matches!(
3695 option.value,
3696 SqlOptionValue::Value(Value::Boolean(true))
3697 ));
3698 }
3699 "async" => {
3700 options.r#async = Some(matches!(
3701 option.value,
3702 SqlOptionValue::Value(Value::Boolean(true))
3703 ))
3704 }
3705 "batch" => {
3706 options.batch = Some(matches!(
3707 option.value,
3708 SqlOptionValue::Value(Value::Boolean(true))
3709 ))
3710 }
3711 _ => {
3712 return Err(StrError(format!("unknown option: {}", option.name)));
3713 }
3714 }
3715 }
3716 Ok(options)
3717 }
3718}
3719
3720impl Display for CreateFunctionWithOptions {
3721 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3722 if self == &Self::default() {
3723 return Ok(());
3724 }
3725 let mut options = vec![];
3726 if let Some(v) = self.always_retry_on_network_error {
3727 options.push(format!("always_retry_on_network_error = {}", v));
3728 }
3729 if let Some(v) = self.r#async {
3730 options.push(format!("async = {}", v));
3731 }
3732 if let Some(v) = self.batch {
3733 options.push(format!("batch = {}", v));
3734 }
3735 write!(f, " WITH ( {} )", display_comma_separated(&options))
3736 }
3737}
3738
3739#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3740#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3741pub enum CreateFunctionUsing {
3742 Link(String),
3743 Base64(String),
3744}
3745
3746impl fmt::Display for CreateFunctionUsing {
3747 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3748 write!(f, "USING ")?;
3749 match self {
3750 CreateFunctionUsing::Link(uri) => write!(f, "LINK '{uri}'"),
3751 CreateFunctionUsing::Base64(s) => {
3752 write!(f, "BASE64 '{s}'")
3753 }
3754 }
3755 }
3756}
3757
3758#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3759#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3760pub struct ConfigParam {
3761 pub param: Ident,
3762 pub value: SetVariableValue,
3763}
3764
3765impl fmt::Display for ConfigParam {
3766 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3767 write!(f, "SET {} = {}", self.param, self.value)
3768 }
3769}
3770
3771#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3772#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3773pub enum SetVariableValue {
3774 Single(SetVariableValueSingle),
3775 List(Vec<SetVariableValueSingle>),
3776 Default,
3777}
3778
3779impl From<SetVariableValueSingle> for SetVariableValue {
3780 fn from(value: SetVariableValueSingle) -> Self {
3781 SetVariableValue::Single(value)
3782 }
3783}
3784
3785impl fmt::Display for SetVariableValue {
3786 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3787 use SetVariableValue::*;
3788 match self {
3789 Single(val) => write!(f, "{}", val),
3790 List(list) => write!(f, "{}", display_comma_separated(list),),
3791 Default => write!(f, "DEFAULT"),
3792 }
3793 }
3794}
3795
3796#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3797#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3798pub enum SetVariableValueSingle {
3799 Ident(Ident),
3800 Literal(Value),
3801}
3802
3803impl SetVariableValueSingle {
3804 pub fn to_string_unquoted(&self) -> String {
3805 match self {
3806 Self::Literal(Value::SingleQuotedString(s))
3807 | Self::Literal(Value::DoubleQuotedString(s)) => s.clone(),
3808 _ => self.to_string(),
3809 }
3810 }
3811}
3812
3813impl fmt::Display for SetVariableValueSingle {
3814 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3815 use SetVariableValueSingle::*;
3816 match self {
3817 Ident(ident) => write!(f, "{}", ident),
3818 Literal(literal) => write!(f, "{}", literal),
3819 }
3820 }
3821}
3822
3823#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3824#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3825pub enum AsOf {
3826 ProcessTime,
3827 ProcessTimeWithInterval((String, DateTimeField)),
3829 TimestampNum(i64),
3831 TimestampString(String),
3832 VersionNum(i64),
3833 VersionString(String),
3834}
3835
3836impl fmt::Display for AsOf {
3837 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3838 use AsOf::*;
3839 match self {
3840 ProcessTime => write!(f, " FOR SYSTEM_TIME AS OF PROCTIME()"),
3841 ProcessTimeWithInterval((value, leading_field)) => write!(
3842 f,
3843 " FOR SYSTEM_TIME AS OF NOW() - {} {}",
3844 value, leading_field
3845 ),
3846 TimestampNum(ts) => write!(f, " FOR SYSTEM_TIME AS OF {}", ts),
3847 TimestampString(ts) => write!(f, " FOR SYSTEM_TIME AS OF '{}'", ts),
3848 VersionNum(v) => write!(f, " FOR SYSTEM_VERSION AS OF {}", v),
3849 VersionString(v) => write!(f, " FOR SYSTEM_VERSION AS OF '{}'", v),
3850 }
3851 }
3852}
3853
3854#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3855#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3856pub enum DiscardType {
3857 All,
3858}
3859
3860impl fmt::Display for DiscardType {
3861 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3862 use DiscardType::*;
3863 match self {
3864 All => write!(f, "ALL"),
3865 }
3866 }
3867}
3868
3869#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
3872#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3873pub enum BackfillOrderStrategy {
3874 #[default]
3875 Default,
3876 None,
3877 Auto,
3878 Fixed(Vec<(ObjectName, ObjectName)>),
3879}
3880
3881impl fmt::Display for BackfillOrderStrategy {
3882 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3883 use BackfillOrderStrategy::*;
3884 match self {
3885 Default => write!(f, "DEFAULT"),
3886 None => write!(f, "NONE"),
3887 Auto => write!(f, "AUTO"),
3888 Fixed(map) => {
3889 let mut parts = vec![];
3890 for (start, end) in map {
3891 parts.push(format!("{} -> {}", start, end));
3892 }
3893 write!(f, "{}", display_comma_separated(&parts))
3894 }
3895 }
3896 }
3897}
3898
3899impl Statement {
3900 pub fn to_redacted_string(&self, keywords: RedactSqlOptionKeywordsRef) -> String {
3901 REDACT_SQL_OPTION_KEYWORDS.sync_scope(keywords, || self.to_string_unchecked())
3902 }
3903
3904 pub fn default_create_table(name: ObjectName) -> Self {
3906 Self::CreateTable {
3907 name,
3908 or_replace: false,
3909 temporary: false,
3910 if_not_exists: false,
3911 columns: Vec::new(),
3912 wildcard_idx: None,
3913 constraints: Vec::new(),
3914 with_options: Vec::new(),
3915 format_encode: None,
3916 source_watermarks: Vec::new(),
3917 append_only: false,
3918 on_conflict: None,
3919 with_version_column: None,
3920 query: None,
3921 cdc_table_info: None,
3922 include_column_options: Vec::new(),
3923 webhook_info: None,
3924 engine: Engine::Hummock,
3925 }
3926 }
3927}
3928
3929#[cfg(test)]
3930mod tests {
3931 use super::*;
3932
3933 #[test]
3934 fn test_grouping_sets_display() {
3935 let grouping_sets = Expr::GroupingSets(vec![
3937 vec![Expr::Identifier(Ident::new_unchecked("a"))],
3938 vec![Expr::Identifier(Ident::new_unchecked("b"))],
3939 ]);
3940 assert_eq!("GROUPING SETS ((a), (b))", format!("{}", grouping_sets));
3941
3942 let grouping_sets = Expr::GroupingSets(vec![vec![
3944 Expr::Identifier(Ident::new_unchecked("a")),
3945 Expr::Identifier(Ident::new_unchecked("b")),
3946 ]]);
3947 assert_eq!("GROUPING SETS ((a, b))", format!("{}", grouping_sets));
3948
3949 let grouping_sets = Expr::GroupingSets(vec![
3951 vec![
3952 Expr::Identifier(Ident::new_unchecked("a")),
3953 Expr::Identifier(Ident::new_unchecked("b")),
3954 ],
3955 vec![
3956 Expr::Identifier(Ident::new_unchecked("c")),
3957 Expr::Identifier(Ident::new_unchecked("d")),
3958 ],
3959 ]);
3960 assert_eq!(
3961 "GROUPING SETS ((a, b), (c, d))",
3962 format!("{}", grouping_sets)
3963 );
3964 }
3965
3966 #[test]
3967 fn test_rollup_display() {
3968 let rollup = Expr::Rollup(vec![vec![Expr::Identifier(Ident::new_unchecked("a"))]]);
3969 assert_eq!("ROLLUP (a)", format!("{}", rollup));
3970
3971 let rollup = Expr::Rollup(vec![vec![
3972 Expr::Identifier(Ident::new_unchecked("a")),
3973 Expr::Identifier(Ident::new_unchecked("b")),
3974 ]]);
3975 assert_eq!("ROLLUP ((a, b))", format!("{}", rollup));
3976
3977 let rollup = Expr::Rollup(vec![
3978 vec![Expr::Identifier(Ident::new_unchecked("a"))],
3979 vec![Expr::Identifier(Ident::new_unchecked("b"))],
3980 ]);
3981 assert_eq!("ROLLUP (a, b)", format!("{}", rollup));
3982
3983 let rollup = Expr::Rollup(vec![
3984 vec![Expr::Identifier(Ident::new_unchecked("a"))],
3985 vec![
3986 Expr::Identifier(Ident::new_unchecked("b")),
3987 Expr::Identifier(Ident::new_unchecked("c")),
3988 ],
3989 vec![Expr::Identifier(Ident::new_unchecked("d"))],
3990 ]);
3991 assert_eq!("ROLLUP (a, (b, c), d)", format!("{}", rollup));
3992 }
3993
3994 #[test]
3995 fn test_cube_display() {
3996 let cube = Expr::Cube(vec![vec![Expr::Identifier(Ident::new_unchecked("a"))]]);
3997 assert_eq!("CUBE (a)", format!("{}", cube));
3998
3999 let cube = Expr::Cube(vec![vec![
4000 Expr::Identifier(Ident::new_unchecked("a")),
4001 Expr::Identifier(Ident::new_unchecked("b")),
4002 ]]);
4003 assert_eq!("CUBE ((a, b))", format!("{}", cube));
4004
4005 let cube = Expr::Cube(vec![
4006 vec![Expr::Identifier(Ident::new_unchecked("a"))],
4007 vec![Expr::Identifier(Ident::new_unchecked("b"))],
4008 ]);
4009 assert_eq!("CUBE (a, b)", format!("{}", cube));
4010
4011 let cube = Expr::Cube(vec![
4012 vec![Expr::Identifier(Ident::new_unchecked("a"))],
4013 vec![
4014 Expr::Identifier(Ident::new_unchecked("b")),
4015 Expr::Identifier(Ident::new_unchecked("c")),
4016 ],
4017 vec![Expr::Identifier(Ident::new_unchecked("d"))],
4018 ]);
4019 assert_eq!("CUBE (a, (b, c), d)", format!("{}", cube));
4020 }
4021
4022 #[test]
4023 fn test_array_index_display() {
4024 let array_index = Expr::Index {
4025 obj: Box::new(Expr::Identifier(Ident::new_unchecked("v1"))),
4026 index: Box::new(Expr::Value(Value::Number("1".into()))),
4027 };
4028 assert_eq!("v1[1]", format!("{}", array_index));
4029
4030 let array_index2 = Expr::Index {
4031 obj: Box::new(array_index),
4032 index: Box::new(Expr::Value(Value::Number("1".into()))),
4033 };
4034 assert_eq!("v1[1][1]", format!("{}", array_index2));
4035 }
4036
4037 #[test]
4038 fn test_nested_op_display() {
4040 let binary_op = Expr::BinaryOp {
4041 left: Box::new(Expr::Value(Value::Boolean(true))),
4042 op: BinaryOperator::Or,
4043 right: Box::new(Expr::IsNotFalse(Box::new(Expr::Value(Value::Boolean(
4044 true,
4045 ))))),
4046 };
4047 assert_eq!("true OR true IS NOT FALSE", format!("{}", binary_op));
4048
4049 let unary_op = Expr::UnaryOp {
4050 op: UnaryOperator::Not,
4051 expr: Box::new(Expr::IsNotFalse(Box::new(Expr::Value(Value::Boolean(
4052 true,
4053 ))))),
4054 };
4055 assert_eq!("NOT true IS NOT FALSE", format!("{}", unary_op));
4056 }
4057
4058 #[test]
4059 fn test_create_function_display() {
4060 let create_function = Statement::CreateFunction {
4061 or_replace: false,
4062 temporary: false,
4063 if_not_exists: false,
4064 name: ObjectName(vec![Ident::new_unchecked("foo")]),
4065 args: Some(vec![OperateFunctionArg::unnamed(DataType::Int)]),
4066 returns: Some(CreateFunctionReturns::Value(DataType::Int)),
4067 params: CreateFunctionBody {
4068 language: Some(Ident::new_unchecked("python")),
4069 runtime: None,
4070 behavior: Some(FunctionBehavior::Immutable),
4071 as_: Some(FunctionDefinition::SingleQuotedDef("SELECT 1".to_owned())),
4072 return_: None,
4073 using: None,
4074 },
4075 with_options: CreateFunctionWithOptions {
4076 always_retry_on_network_error: None,
4077 r#async: None,
4078 batch: None,
4079 },
4080 };
4081 assert_eq!(
4082 "CREATE FUNCTION foo(INT) RETURNS INT LANGUAGE python IMMUTABLE AS 'SELECT 1'",
4083 format!("{}", create_function)
4084 );
4085 let create_function = Statement::CreateFunction {
4086 or_replace: false,
4087 temporary: false,
4088 if_not_exists: false,
4089 name: ObjectName(vec![Ident::new_unchecked("foo")]),
4090 args: Some(vec![OperateFunctionArg::unnamed(DataType::Int)]),
4091 returns: Some(CreateFunctionReturns::Value(DataType::Int)),
4092 params: CreateFunctionBody {
4093 language: Some(Ident::new_unchecked("python")),
4094 runtime: None,
4095 behavior: Some(FunctionBehavior::Immutable),
4096 as_: Some(FunctionDefinition::SingleQuotedDef("SELECT 1".to_owned())),
4097 return_: None,
4098 using: None,
4099 },
4100 with_options: CreateFunctionWithOptions {
4101 always_retry_on_network_error: Some(true),
4102 r#async: None,
4103 batch: None,
4104 },
4105 };
4106 assert_eq!(
4107 "CREATE FUNCTION foo(INT) RETURNS INT LANGUAGE python IMMUTABLE AS 'SELECT 1' WITH ( always_retry_on_network_error = true )",
4108 format!("{}", create_function)
4109 );
4110 }
4111}