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