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