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_ids: Vec<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_ids,
2519 operation,
2520 } => {
2521 write!(
2522 f,
2523 "ALTER FRAGMENT {} {}",
2524 display_comma_separated(fragment_ids),
2525 operation
2526 )
2527 }
2528 Statement::AlterDefaultPrivileges {
2529 target_users,
2530 schema_names,
2531 operation,
2532 } => {
2533 write!(f, "ALTER DEFAULT PRIVILEGES")?;
2534 if let Some(target_users) = target_users {
2535 write!(f, " FOR {}", display_comma_separated(target_users))?;
2536 }
2537 if let Some(schema_names) = schema_names {
2538 write!(f, " IN SCHEMA {}", display_comma_separated(schema_names))?;
2539 }
2540 write!(f, " {}", operation)
2541 }
2542 }
2543 }
2544
2545 pub fn is_create(&self) -> bool {
2546 matches!(
2547 self,
2548 Statement::CreateTable { .. }
2549 | Statement::CreateView { .. }
2550 | Statement::CreateSource { .. }
2551 | Statement::CreateSink { .. }
2552 | Statement::CreateSubscription { .. }
2553 | Statement::CreateConnection { .. }
2554 | Statement::CreateSecret { .. }
2555 | Statement::CreateUser { .. }
2556 | Statement::CreateDatabase { .. }
2557 | Statement::CreateFunction { .. }
2558 | Statement::CreateAggregate { .. }
2559 | Statement::CreateIndex { .. }
2560 | Statement::CreateSchema { .. }
2561 )
2562 }
2563}
2564
2565impl Display for IncludeOptionItem {
2566 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2567 let Self {
2568 column_type,
2569 inner_field,
2570 header_inner_expect_type,
2571 column_alias,
2572 } = self;
2573 write!(f, "INCLUDE {}", column_type)?;
2574 if let Some(inner_field) = inner_field {
2575 write!(f, " '{}'", value::escape_single_quote_string(inner_field))?;
2576 if let Some(expected_type) = header_inner_expect_type {
2577 write!(f, " {}", expected_type)?;
2578 }
2579 }
2580 if let Some(alias) = column_alias {
2581 write!(f, " AS {}", alias)?;
2582 }
2583 Ok(())
2584 }
2585}
2586
2587#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2588#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2589#[non_exhaustive]
2590pub enum OnInsert {
2591 DuplicateKeyUpdate(Vec<Assignment>),
2593}
2594
2595impl fmt::Display for OnInsert {
2596 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2597 match self {
2598 Self::DuplicateKeyUpdate(expr) => write!(
2599 f,
2600 " ON DUPLICATE KEY UPDATE {}",
2601 display_comma_separated(expr)
2602 ),
2603 }
2604 }
2605}
2606
2607#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2609#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2610pub enum Privileges {
2611 All {
2613 with_privileges_keyword: bool,
2615 },
2616 Actions(Vec<Action>),
2618}
2619
2620impl fmt::Display for Privileges {
2621 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2622 match self {
2623 Privileges::All {
2624 with_privileges_keyword,
2625 } => {
2626 write!(
2627 f,
2628 "ALL{}",
2629 if *with_privileges_keyword {
2630 " PRIVILEGES"
2631 } else {
2632 ""
2633 }
2634 )
2635 }
2636 Privileges::Actions(actions) => {
2637 write!(f, "{}", display_comma_separated(actions))
2638 }
2639 }
2640 }
2641}
2642
2643#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2645#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2646pub enum Action {
2647 Connect,
2648 Create,
2649 Delete,
2650 Execute,
2651 Insert { columns: Option<Vec<Ident>> },
2652 References { columns: Option<Vec<Ident>> },
2653 Select { columns: Option<Vec<Ident>> },
2654 Temporary,
2655 Trigger,
2656 Truncate,
2657 Update { columns: Option<Vec<Ident>> },
2658 Usage,
2659}
2660
2661impl fmt::Display for Action {
2662 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2663 match self {
2664 Action::Connect => f.write_str("CONNECT")?,
2665 Action::Create => f.write_str("CREATE")?,
2666 Action::Delete => f.write_str("DELETE")?,
2667 Action::Execute => f.write_str("EXECUTE")?,
2668 Action::Insert { .. } => f.write_str("INSERT")?,
2669 Action::References { .. } => f.write_str("REFERENCES")?,
2670 Action::Select { .. } => f.write_str("SELECT")?,
2671 Action::Temporary => f.write_str("TEMPORARY")?,
2672 Action::Trigger => f.write_str("TRIGGER")?,
2673 Action::Truncate => f.write_str("TRUNCATE")?,
2674 Action::Update { .. } => f.write_str("UPDATE")?,
2675 Action::Usage => f.write_str("USAGE")?,
2676 };
2677 match self {
2678 Action::Insert { columns }
2679 | Action::References { columns }
2680 | Action::Select { columns }
2681 | Action::Update { columns } => {
2682 if let Some(columns) = columns {
2683 write!(f, " ({})", display_comma_separated(columns))?;
2684 }
2685 }
2686 _ => (),
2687 };
2688 Ok(())
2689 }
2690}
2691
2692#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2694#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2695pub enum GrantObjects {
2696 AllSequencesInSchema { schemas: Vec<ObjectName> },
2698 AllTablesInSchema { schemas: Vec<ObjectName> },
2700 AllSourcesInSchema { schemas: Vec<ObjectName> },
2702 AllSinksInSchema { schemas: Vec<ObjectName> },
2704 AllMviewsInSchema { schemas: Vec<ObjectName> },
2706 AllViewsInSchema { schemas: Vec<ObjectName> },
2708 AllFunctionsInSchema { schemas: Vec<ObjectName> },
2710 AllSecretsInSchema { schemas: Vec<ObjectName> },
2712 AllSubscriptionsInSchema { schemas: Vec<ObjectName> },
2714 AllConnectionsInSchema { schemas: Vec<ObjectName> },
2716 Databases(Vec<ObjectName>),
2718 Schemas(Vec<ObjectName>),
2720 Sources(Vec<ObjectName>),
2722 Mviews(Vec<ObjectName>),
2724 Sequences(Vec<ObjectName>),
2726 Tables(Vec<ObjectName>),
2728 Sinks(Vec<ObjectName>),
2730 Views(Vec<ObjectName>),
2732 Connections(Vec<ObjectName>),
2734 Subscriptions(Vec<ObjectName>),
2736 Functions(Vec<FunctionDesc>),
2738 Secrets(Vec<ObjectName>),
2740}
2741
2742impl fmt::Display for GrantObjects {
2743 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2744 match self {
2745 GrantObjects::Sequences(sequences) => {
2746 write!(f, "SEQUENCE {}", display_comma_separated(sequences))
2747 }
2748 GrantObjects::Schemas(schemas) => {
2749 write!(f, "SCHEMA {}", display_comma_separated(schemas))
2750 }
2751 GrantObjects::Tables(tables) => {
2752 write!(f, "{}", display_comma_separated(tables))
2753 }
2754 GrantObjects::AllSequencesInSchema { schemas } => {
2755 write!(
2756 f,
2757 "ALL SEQUENCES IN SCHEMA {}",
2758 display_comma_separated(schemas)
2759 )
2760 }
2761 GrantObjects::AllTablesInSchema { schemas } => {
2762 write!(
2763 f,
2764 "ALL TABLES IN SCHEMA {}",
2765 display_comma_separated(schemas)
2766 )
2767 }
2768 GrantObjects::AllSourcesInSchema { schemas } => {
2769 write!(
2770 f,
2771 "ALL SOURCES IN SCHEMA {}",
2772 display_comma_separated(schemas)
2773 )
2774 }
2775 GrantObjects::AllMviewsInSchema { schemas } => {
2776 write!(
2777 f,
2778 "ALL MATERIALIZED VIEWS IN SCHEMA {}",
2779 display_comma_separated(schemas)
2780 )
2781 }
2782 GrantObjects::AllSinksInSchema { schemas } => {
2783 write!(
2784 f,
2785 "ALL SINKS IN SCHEMA {}",
2786 display_comma_separated(schemas)
2787 )
2788 }
2789 GrantObjects::AllViewsInSchema { schemas } => {
2790 write!(
2791 f,
2792 "ALL VIEWS IN SCHEMA {}",
2793 display_comma_separated(schemas)
2794 )
2795 }
2796 GrantObjects::AllFunctionsInSchema { schemas } => {
2797 write!(
2798 f,
2799 "ALL FUNCTIONS IN SCHEMA {}",
2800 display_comma_separated(schemas)
2801 )
2802 }
2803 GrantObjects::AllSecretsInSchema { schemas } => {
2804 write!(
2805 f,
2806 "ALL SECRETS IN SCHEMA {}",
2807 display_comma_separated(schemas)
2808 )
2809 }
2810 GrantObjects::AllSubscriptionsInSchema { schemas } => {
2811 write!(
2812 f,
2813 "ALL SUBSCRIPTIONS IN SCHEMA {}",
2814 display_comma_separated(schemas)
2815 )
2816 }
2817 GrantObjects::AllConnectionsInSchema { schemas } => {
2818 write!(
2819 f,
2820 "ALL CONNECTIONS IN SCHEMA {}",
2821 display_comma_separated(schemas)
2822 )
2823 }
2824 GrantObjects::Databases(databases) => {
2825 write!(f, "DATABASE {}", display_comma_separated(databases))
2826 }
2827 GrantObjects::Sources(sources) => {
2828 write!(f, "SOURCE {}", display_comma_separated(sources))
2829 }
2830 GrantObjects::Mviews(mviews) => {
2831 write!(f, "MATERIALIZED VIEW {}", display_comma_separated(mviews))
2832 }
2833 GrantObjects::Sinks(sinks) => {
2834 write!(f, "SINK {}", display_comma_separated(sinks))
2835 }
2836 GrantObjects::Views(views) => {
2837 write!(f, "VIEW {}", display_comma_separated(views))
2838 }
2839 GrantObjects::Connections(connections) => {
2840 write!(f, "CONNECTION {}", display_comma_separated(connections))
2841 }
2842 GrantObjects::Subscriptions(subscriptions) => {
2843 write!(f, "SUBSCRIPTION {}", display_comma_separated(subscriptions))
2844 }
2845 GrantObjects::Functions(func_descs) => {
2846 write!(f, "FUNCTION {}", display_comma_separated(func_descs))
2847 }
2848 GrantObjects::Secrets(secrets) => {
2849 write!(f, "SECRET {}", display_comma_separated(secrets))
2850 }
2851 }
2852 }
2853}
2854
2855#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2856#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2857pub enum PrivilegeObjectType {
2858 Tables,
2859 Sources,
2860 Sinks,
2861 Mviews,
2862 Views,
2863 Functions,
2864 Connections,
2865 Secrets,
2866 Subscriptions,
2867 Schemas,
2868}
2869
2870impl fmt::Display for PrivilegeObjectType {
2871 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2872 match self {
2873 PrivilegeObjectType::Tables => f.write_str("TABLES")?,
2874 PrivilegeObjectType::Sources => f.write_str("SOURCES")?,
2875 PrivilegeObjectType::Sinks => f.write_str("SINKS")?,
2876 PrivilegeObjectType::Mviews => f.write_str("MATERIALIZED VIEWS")?,
2877 PrivilegeObjectType::Views => f.write_str("VIEWS")?,
2878 PrivilegeObjectType::Functions => f.write_str("FUNCTIONS")?,
2879 PrivilegeObjectType::Connections => f.write_str("CONNECTIONS")?,
2880 PrivilegeObjectType::Secrets => f.write_str("SECRETS")?,
2881 PrivilegeObjectType::Subscriptions => f.write_str("SUBSCRIPTIONS")?,
2882 PrivilegeObjectType::Schemas => f.write_str("SCHEMAS")?,
2883 };
2884 Ok(())
2885 }
2886}
2887
2888#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2889#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2890pub enum DefaultPrivilegeOperation {
2891 Grant {
2892 privileges: Privileges,
2893 object_type: PrivilegeObjectType,
2894 grantees: Vec<Ident>,
2895 with_grant_option: bool,
2896 },
2897 Revoke {
2898 privileges: Privileges,
2899 object_type: PrivilegeObjectType,
2900 grantees: Vec<Ident>,
2901 revoke_grant_option: bool,
2902 cascade: bool,
2903 },
2904}
2905
2906impl fmt::Display for DefaultPrivilegeOperation {
2907 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2908 match self {
2909 DefaultPrivilegeOperation::Grant {
2910 privileges,
2911 object_type,
2912 grantees,
2913 with_grant_option,
2914 } => {
2915 write!(
2916 f,
2917 "GRANT {} ON {} TO {}",
2918 privileges,
2919 object_type,
2920 display_comma_separated(grantees)
2921 )?;
2922 if *with_grant_option {
2923 write!(f, " WITH GRANT OPTION")?;
2924 }
2925 }
2926 DefaultPrivilegeOperation::Revoke {
2927 privileges,
2928 object_type,
2929 grantees,
2930 revoke_grant_option,
2931 cascade,
2932 } => {
2933 write!(f, "REVOKE")?;
2934 if *revoke_grant_option {
2935 write!(f, " GRANT OPTION FOR")?;
2936 }
2937 write!(
2938 f,
2939 " {} ON {} FROM {}",
2940 privileges,
2941 object_type,
2942 display_comma_separated(grantees)
2943 )?;
2944 write!(f, " {}", if *cascade { "CASCADE" } else { "RESTRICT" })?;
2945 }
2946 }
2947 Ok(())
2948 }
2949}
2950
2951impl DefaultPrivilegeOperation {
2952 pub fn for_schemas(&self) -> bool {
2953 match &self {
2954 DefaultPrivilegeOperation::Grant { object_type, .. } => {
2955 object_type == &PrivilegeObjectType::Schemas
2956 }
2957 DefaultPrivilegeOperation::Revoke { object_type, .. } => {
2958 object_type == &PrivilegeObjectType::Schemas
2959 }
2960 }
2961 }
2962}
2963
2964#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2965#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2966pub enum AssignmentValue {
2967 Expr(Expr),
2969 Default,
2971}
2972
2973impl fmt::Display for AssignmentValue {
2974 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2975 match self {
2976 AssignmentValue::Expr(expr) => write!(f, "{}", expr),
2977 AssignmentValue::Default => f.write_str("DEFAULT"),
2978 }
2979 }
2980}
2981
2982#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2984#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2985pub struct Assignment {
2986 pub id: Vec<Ident>,
2987 pub value: AssignmentValue,
2988}
2989
2990impl fmt::Display for Assignment {
2991 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2992 write!(f, "{} = {}", display_separated(&self.id, "."), self.value)
2993 }
2994}
2995
2996#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2997#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2998pub enum FunctionArgExpr {
2999 Expr(Expr),
3000 ExprQualifiedWildcard(Expr, Vec<Ident>),
3004 QualifiedWildcard(ObjectName, Option<Vec<Expr>>),
3007 Wildcard(Option<Vec<Expr>>),
3009}
3010
3011impl fmt::Display for FunctionArgExpr {
3012 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3013 match self {
3014 FunctionArgExpr::Expr(expr) => write!(f, "{}", expr),
3015 FunctionArgExpr::ExprQualifiedWildcard(expr, prefix) => {
3016 write!(
3017 f,
3018 "({}){}.*",
3019 expr,
3020 prefix
3021 .iter()
3022 .format_with("", |i, f| f(&format_args!(".{i}")))
3023 )
3024 }
3025 FunctionArgExpr::QualifiedWildcard(prefix, except) => match except {
3026 Some(exprs) => write!(
3027 f,
3028 "{}.* EXCEPT ({})",
3029 prefix,
3030 exprs
3031 .iter()
3032 .map(|v| v.to_string())
3033 .collect::<Vec<String>>()
3034 .as_slice()
3035 .join(", ")
3036 ),
3037 None => write!(f, "{}.*", prefix),
3038 },
3039
3040 FunctionArgExpr::Wildcard(except) => match except {
3041 Some(exprs) => write!(
3042 f,
3043 "* EXCEPT ({})",
3044 exprs
3045 .iter()
3046 .map(|v| v.to_string())
3047 .collect::<Vec<String>>()
3048 .as_slice()
3049 .join(", ")
3050 ),
3051 None => f.write_str("*"),
3052 },
3053 }
3054 }
3055}
3056
3057#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3058#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3059pub enum FunctionArg {
3060 Named { name: Ident, arg: FunctionArgExpr },
3061 Unnamed(FunctionArgExpr),
3062}
3063
3064impl FunctionArg {
3065 pub fn get_expr(&self) -> FunctionArgExpr {
3066 match self {
3067 FunctionArg::Named { name: _, arg } => arg.clone(),
3068 FunctionArg::Unnamed(arg) => arg.clone(),
3069 }
3070 }
3071}
3072
3073impl fmt::Display for FunctionArg {
3074 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3075 match self {
3076 FunctionArg::Named { name, arg } => write!(f, "{} => {}", name, arg),
3077 FunctionArg::Unnamed(unnamed_arg) => write!(f, "{}", unnamed_arg),
3078 }
3079 }
3080}
3081
3082#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3085#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3086pub struct FunctionArgList {
3087 pub distinct: bool,
3089 pub args: Vec<FunctionArg>,
3090 pub variadic: bool,
3092 pub order_by: Vec<OrderByExpr>,
3094 pub ignore_nulls: bool,
3096}
3097
3098impl fmt::Display for FunctionArgList {
3099 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3100 write!(f, "(")?;
3101 if self.distinct {
3102 write!(f, "DISTINCT ")?;
3103 }
3104 if self.variadic {
3105 for arg in &self.args[0..self.args.len() - 1] {
3106 write!(f, "{}, ", arg)?;
3107 }
3108 write!(f, "VARIADIC {}", self.args.last().unwrap())?;
3109 } else {
3110 write!(f, "{}", display_comma_separated(&self.args))?;
3111 }
3112 if !self.order_by.is_empty() {
3113 write!(f, " ORDER BY {}", display_comma_separated(&self.order_by))?;
3114 }
3115 if self.ignore_nulls {
3116 write!(f, " IGNORE NULLS")?;
3117 }
3118 write!(f, ")")?;
3119 Ok(())
3120 }
3121}
3122
3123impl FunctionArgList {
3124 pub fn empty() -> Self {
3125 Self {
3126 distinct: false,
3127 args: vec![],
3128 variadic: false,
3129 order_by: vec![],
3130 ignore_nulls: false,
3131 }
3132 }
3133
3134 pub fn args_only(args: Vec<FunctionArg>) -> Self {
3135 Self {
3136 distinct: false,
3137 args,
3138 variadic: false,
3139 order_by: vec![],
3140 ignore_nulls: false,
3141 }
3142 }
3143
3144 pub fn is_args_only(&self) -> bool {
3145 !self.distinct && !self.variadic && self.order_by.is_empty() && !self.ignore_nulls
3146 }
3147
3148 pub fn for_agg(distinct: bool, args: Vec<FunctionArg>, order_by: Vec<OrderByExpr>) -> Self {
3149 Self {
3150 distinct,
3151 args,
3152 variadic: false,
3153 order_by,
3154 ignore_nulls: false,
3155 }
3156 }
3157}
3158
3159#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3161#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3162pub struct Function {
3163 pub scalar_as_agg: bool,
3165 pub name: ObjectName,
3167 pub arg_list: FunctionArgList,
3169 pub within_group: Option<Box<OrderByExpr>>,
3172 pub filter: Option<Box<Expr>>,
3174 pub over: Option<Window>,
3176}
3177
3178impl Function {
3179 pub fn no_arg(name: ObjectName) -> Self {
3180 Self {
3181 scalar_as_agg: false,
3182 name,
3183 arg_list: FunctionArgList::empty(),
3184 within_group: None,
3185 filter: None,
3186 over: None,
3187 }
3188 }
3189}
3190
3191impl fmt::Display for Function {
3192 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3193 if self.scalar_as_agg {
3194 write!(f, "AGGREGATE:")?;
3195 }
3196 write!(f, "{}{}", self.name, self.arg_list)?;
3197 if let Some(within_group) = &self.within_group {
3198 write!(f, " WITHIN GROUP (ORDER BY {})", within_group)?;
3199 }
3200 if let Some(filter) = &self.filter {
3201 write!(f, " FILTER (WHERE {})", filter)?;
3202 }
3203 if let Some(o) = &self.over {
3204 write!(f, " OVER {}", o)?;
3205 }
3206 Ok(())
3207 }
3208}
3209
3210#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3211#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3212pub enum ObjectType {
3213 Table,
3214 View,
3215 MaterializedView,
3216 Index,
3217 Schema,
3218 Source,
3219 Sink,
3220 Database,
3221 User,
3222 Connection,
3223 Secret,
3224 Subscription,
3225}
3226
3227impl fmt::Display for ObjectType {
3228 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3229 f.write_str(match self {
3230 ObjectType::Table => "TABLE",
3231 ObjectType::View => "VIEW",
3232 ObjectType::MaterializedView => "MATERIALIZED VIEW",
3233 ObjectType::Index => "INDEX",
3234 ObjectType::Schema => "SCHEMA",
3235 ObjectType::Source => "SOURCE",
3236 ObjectType::Sink => "SINK",
3237 ObjectType::Database => "DATABASE",
3238 ObjectType::User => "USER",
3239 ObjectType::Secret => "SECRET",
3240 ObjectType::Connection => "CONNECTION",
3241 ObjectType::Subscription => "SUBSCRIPTION",
3242 })
3243 }
3244}
3245
3246impl ParseTo for ObjectType {
3247 fn parse_to(parser: &mut Parser<'_>) -> ModalResult<Self> {
3248 let object_type = if parser.parse_keyword(Keyword::TABLE) {
3249 ObjectType::Table
3250 } else if parser.parse_keyword(Keyword::VIEW) {
3251 ObjectType::View
3252 } else if parser.parse_keywords(&[Keyword::MATERIALIZED, Keyword::VIEW]) {
3253 ObjectType::MaterializedView
3254 } else if parser.parse_keyword(Keyword::SOURCE) {
3255 ObjectType::Source
3256 } else if parser.parse_keyword(Keyword::SINK) {
3257 ObjectType::Sink
3258 } else if parser.parse_keyword(Keyword::INDEX) {
3259 ObjectType::Index
3260 } else if parser.parse_keyword(Keyword::SCHEMA) {
3261 ObjectType::Schema
3262 } else if parser.parse_keyword(Keyword::DATABASE) {
3263 ObjectType::Database
3264 } else if parser.parse_keyword(Keyword::USER) {
3265 ObjectType::User
3266 } else if parser.parse_keyword(Keyword::CONNECTION) {
3267 ObjectType::Connection
3268 } else if parser.parse_keyword(Keyword::SECRET) {
3269 ObjectType::Secret
3270 } else if parser.parse_keyword(Keyword::SUBSCRIPTION) {
3271 ObjectType::Subscription
3272 } else {
3273 return parser.expected(
3274 "TABLE, VIEW, INDEX, MATERIALIZED VIEW, SOURCE, SINK, SUBSCRIPTION, SCHEMA, DATABASE, USER, SECRET or CONNECTION after DROP",
3275 );
3276 };
3277 Ok(object_type)
3278 }
3279}
3280
3281#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3282#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3283pub struct SqlOption {
3284 pub name: ObjectName,
3285 pub value: SqlOptionValue,
3286}
3287
3288impl fmt::Display for SqlOption {
3289 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3290 let should_redact = REDACT_SQL_OPTION_KEYWORDS
3291 .try_with(|keywords| {
3292 let sql_option_name = self.name.real_value().to_lowercase();
3293 keywords.iter().any(|k| sql_option_name.contains(k))
3294 })
3295 .unwrap_or(false);
3296 if should_redact {
3297 write!(f, "{} = [REDACTED]", self.name)
3298 } else {
3299 write!(f, "{} = {}", self.name, self.value)
3300 }
3301 }
3302}
3303
3304impl TryFrom<(&String, &String)> for SqlOption {
3305 type Error = ParserError;
3306
3307 fn try_from((name, value): (&String, &String)) -> Result<Self, Self::Error> {
3308 let query = format!("{} = {}", name, value);
3309 let mut tokenizer = Tokenizer::new(query.as_str());
3310 let tokens = tokenizer.tokenize_with_location()?;
3311 let mut parser = Parser(&tokens);
3312 parser
3313 .parse_sql_option()
3314 .map_err(|e| ParserError::ParserError(e.to_string()))
3315 }
3316}
3317
3318#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3319#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3320pub enum SqlOptionValue {
3321 Value(Value),
3322 SecretRef(SecretRefValue),
3323 ConnectionRef(ConnectionRefValue),
3324 BackfillOrder(BackfillOrderStrategy),
3325}
3326
3327impl fmt::Display for SqlOptionValue {
3328 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3329 match self {
3330 SqlOptionValue::Value(value) => write!(f, "{}", value),
3331 SqlOptionValue::SecretRef(secret_ref) => write!(f, "secret {}", secret_ref),
3332 SqlOptionValue::ConnectionRef(connection_ref) => {
3333 write!(f, "{}", connection_ref)
3334 }
3335 SqlOptionValue::BackfillOrder(order) => {
3336 write!(f, "{}", order)
3337 }
3338 }
3339 }
3340}
3341
3342impl From<Value> for SqlOptionValue {
3343 fn from(value: Value) -> Self {
3344 SqlOptionValue::Value(value)
3345 }
3346}
3347
3348#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3349#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3350pub enum EmitMode {
3351 Immediately,
3352 OnWindowClose,
3353}
3354
3355impl fmt::Display for EmitMode {
3356 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3357 f.write_str(match self {
3358 EmitMode::Immediately => "IMMEDIATELY",
3359 EmitMode::OnWindowClose => "ON WINDOW CLOSE",
3360 })
3361 }
3362}
3363
3364#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3365#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3366pub enum OnConflict {
3367 UpdateFull,
3368 Nothing,
3369 UpdateIfNotNull,
3370}
3371
3372impl fmt::Display for OnConflict {
3373 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3374 f.write_str(match self {
3375 OnConflict::UpdateFull => "DO UPDATE FULL",
3376 OnConflict::Nothing => "DO NOTHING",
3377 OnConflict::UpdateIfNotNull => "DO UPDATE IF NOT NULL",
3378 })
3379 }
3380}
3381
3382#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3383#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3384pub enum Engine {
3385 Hummock,
3386 Iceberg,
3387}
3388
3389impl fmt::Display for crate::ast::Engine {
3390 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3391 f.write_str(match self {
3392 crate::ast::Engine::Hummock => "HUMMOCK",
3393 crate::ast::Engine::Iceberg => "ICEBERG",
3394 })
3395 }
3396}
3397
3398#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3399#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3400pub enum SetTimeZoneValue {
3401 Ident(Ident),
3402 Literal(Value),
3403 Local,
3404 Default,
3405}
3406
3407impl fmt::Display for SetTimeZoneValue {
3408 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3409 match self {
3410 SetTimeZoneValue::Ident(ident) => write!(f, "{}", ident),
3411 SetTimeZoneValue::Literal(value) => write!(f, "{}", value),
3412 SetTimeZoneValue::Local => f.write_str("LOCAL"),
3413 SetTimeZoneValue::Default => f.write_str("DEFAULT"),
3414 }
3415 }
3416}
3417
3418#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3419#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3420pub enum TransactionMode {
3421 AccessMode(TransactionAccessMode),
3422 IsolationLevel(TransactionIsolationLevel),
3423}
3424
3425impl fmt::Display for TransactionMode {
3426 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3427 use TransactionMode::*;
3428 match self {
3429 AccessMode(access_mode) => write!(f, "{}", access_mode),
3430 IsolationLevel(iso_level) => write!(f, "ISOLATION LEVEL {}", iso_level),
3431 }
3432 }
3433}
3434
3435#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3436#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3437pub enum TransactionAccessMode {
3438 ReadOnly,
3439 ReadWrite,
3440}
3441
3442impl fmt::Display for TransactionAccessMode {
3443 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3444 use TransactionAccessMode::*;
3445 f.write_str(match self {
3446 ReadOnly => "READ ONLY",
3447 ReadWrite => "READ WRITE",
3448 })
3449 }
3450}
3451
3452#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3453#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3454pub enum TransactionIsolationLevel {
3455 ReadUncommitted,
3456 ReadCommitted,
3457 RepeatableRead,
3458 Serializable,
3459}
3460
3461impl fmt::Display for TransactionIsolationLevel {
3462 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3463 use TransactionIsolationLevel::*;
3464 f.write_str(match self {
3465 ReadUncommitted => "READ UNCOMMITTED",
3466 ReadCommitted => "READ COMMITTED",
3467 RepeatableRead => "REPEATABLE READ",
3468 Serializable => "SERIALIZABLE",
3469 })
3470 }
3471}
3472
3473#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3474#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3475pub enum ShowStatementFilter {
3476 Like(String),
3477 ILike(String),
3478 Where(Expr),
3479}
3480
3481impl fmt::Display for ShowStatementFilter {
3482 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3483 use ShowStatementFilter::*;
3484 match self {
3485 Like(pattern) => write!(f, "LIKE '{}'", value::escape_single_quote_string(pattern)),
3486 ILike(pattern) => write!(f, "ILIKE {}", value::escape_single_quote_string(pattern)),
3487 Where(expr) => write!(f, "WHERE {}", expr),
3488 }
3489 }
3490}
3491
3492#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3494#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3495pub enum DropFunctionOption {
3496 Restrict,
3497 Cascade,
3498}
3499
3500impl fmt::Display for DropFunctionOption {
3501 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3502 match self {
3503 DropFunctionOption::Restrict => write!(f, "RESTRICT "),
3504 DropFunctionOption::Cascade => write!(f, "CASCADE "),
3505 }
3506 }
3507}
3508
3509#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3511#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3512pub struct FunctionDesc {
3513 pub name: ObjectName,
3514 pub args: Option<Vec<OperateFunctionArg>>,
3515}
3516
3517impl fmt::Display for FunctionDesc {
3518 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3519 write!(f, "{}", self.name)?;
3520 if let Some(args) = &self.args {
3521 write!(f, "({})", display_comma_separated(args))?;
3522 }
3523 Ok(())
3524 }
3525}
3526
3527#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3529#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3530pub struct OperateFunctionArg {
3531 pub mode: Option<ArgMode>,
3532 pub name: Option<Ident>,
3533 pub data_type: DataType,
3534 pub default_expr: Option<Expr>,
3535}
3536
3537impl OperateFunctionArg {
3538 pub fn unnamed(data_type: DataType) -> Self {
3540 Self {
3541 mode: None,
3542 name: None,
3543 data_type,
3544 default_expr: None,
3545 }
3546 }
3547
3548 pub fn with_name(name: &str, data_type: DataType) -> Self {
3550 Self {
3551 mode: None,
3552 name: Some(name.into()),
3553 data_type,
3554 default_expr: None,
3555 }
3556 }
3557}
3558
3559impl fmt::Display for OperateFunctionArg {
3560 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3561 if let Some(mode) = &self.mode {
3562 write!(f, "{} ", mode)?;
3563 }
3564 if let Some(name) = &self.name {
3565 write!(f, "{} ", name)?;
3566 }
3567 write!(f, "{}", self.data_type)?;
3568 if let Some(default_expr) = &self.default_expr {
3569 write!(f, " = {}", default_expr)?;
3570 }
3571 Ok(())
3572 }
3573}
3574
3575#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3577#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3578pub enum ArgMode {
3579 In,
3580 Out,
3581 InOut,
3582}
3583
3584impl fmt::Display for ArgMode {
3585 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3586 match self {
3587 ArgMode::In => write!(f, "IN"),
3588 ArgMode::Out => write!(f, "OUT"),
3589 ArgMode::InOut => write!(f, "INOUT"),
3590 }
3591 }
3592}
3593
3594#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3596#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3597pub enum FunctionBehavior {
3598 Immutable,
3599 Stable,
3600 Volatile,
3601}
3602
3603impl fmt::Display for FunctionBehavior {
3604 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3605 match self {
3606 FunctionBehavior::Immutable => write!(f, "IMMUTABLE"),
3607 FunctionBehavior::Stable => write!(f, "STABLE"),
3608 FunctionBehavior::Volatile => write!(f, "VOLATILE"),
3609 }
3610 }
3611}
3612
3613#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3614#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3615pub enum FunctionDefinition {
3616 Identifier(String),
3617 SingleQuotedDef(String),
3618 DoubleDollarDef(String),
3619}
3620
3621impl fmt::Display for FunctionDefinition {
3622 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3623 match self {
3624 FunctionDefinition::Identifier(s) => write!(f, "{s}")?,
3625 FunctionDefinition::SingleQuotedDef(s) => write!(f, "'{s}'")?,
3626 FunctionDefinition::DoubleDollarDef(s) => write!(f, "$${s}$$")?,
3627 }
3628 Ok(())
3629 }
3630}
3631
3632impl FunctionDefinition {
3633 pub fn as_str(&self) -> &str {
3635 match self {
3636 FunctionDefinition::Identifier(s) => s,
3637 FunctionDefinition::SingleQuotedDef(s) => s,
3638 FunctionDefinition::DoubleDollarDef(s) => s,
3639 }
3640 }
3641
3642 pub fn into_string(self) -> String {
3644 match self {
3645 FunctionDefinition::Identifier(s) => s,
3646 FunctionDefinition::SingleQuotedDef(s) => s,
3647 FunctionDefinition::DoubleDollarDef(s) => s,
3648 }
3649 }
3650}
3651
3652#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3654#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3655pub enum CreateFunctionReturns {
3656 Value(DataType),
3658 Table(Vec<TableColumnDef>),
3660}
3661
3662impl fmt::Display for CreateFunctionReturns {
3663 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3664 match self {
3665 Self::Value(data_type) => write!(f, "RETURNS {}", data_type),
3666 Self::Table(columns) => {
3667 write!(f, "RETURNS TABLE ({})", display_comma_separated(columns))
3668 }
3669 }
3670 }
3671}
3672
3673#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3675#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3676pub struct TableColumnDef {
3677 pub name: Ident,
3678 pub data_type: DataType,
3679}
3680
3681impl fmt::Display for TableColumnDef {
3682 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3683 write!(f, "{} {}", self.name, self.data_type)
3684 }
3685}
3686
3687#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
3692#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3693pub struct CreateFunctionBody {
3694 pub language: Option<Ident>,
3696 pub runtime: Option<Ident>,
3698
3699 pub behavior: Option<FunctionBehavior>,
3701 pub as_: Option<FunctionDefinition>,
3705 pub return_: Option<Expr>,
3707 pub using: Option<CreateFunctionUsing>,
3709}
3710
3711impl fmt::Display for CreateFunctionBody {
3712 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3713 if let Some(language) = &self.language {
3714 write!(f, " LANGUAGE {language}")?;
3715 }
3716 if let Some(runtime) = &self.runtime {
3717 write!(f, " RUNTIME {runtime}")?;
3718 }
3719 if let Some(behavior) = &self.behavior {
3720 write!(f, " {behavior}")?;
3721 }
3722 if let Some(definition) = &self.as_ {
3723 write!(f, " AS {definition}")?;
3724 }
3725 if let Some(expr) = &self.return_ {
3726 write!(f, " RETURN {expr}")?;
3727 }
3728 if let Some(using) = &self.using {
3729 write!(f, " {using}")?;
3730 }
3731 Ok(())
3732 }
3733}
3734
3735#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
3736#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3737pub struct CreateFunctionWithOptions {
3738 pub always_retry_on_network_error: Option<bool>,
3740 pub r#async: Option<bool>,
3742 pub batch: Option<bool>,
3744}
3745
3746impl TryFrom<Vec<SqlOption>> for CreateFunctionWithOptions {
3748 type Error = StrError;
3749
3750 fn try_from(with_options: Vec<SqlOption>) -> Result<Self, Self::Error> {
3751 let mut options = Self::default();
3752 for option in with_options {
3753 match option.name.to_string().to_lowercase().as_str() {
3754 "always_retry_on_network_error" => {
3755 options.always_retry_on_network_error = Some(matches!(
3756 option.value,
3757 SqlOptionValue::Value(Value::Boolean(true))
3758 ));
3759 }
3760 "async" => {
3761 options.r#async = Some(matches!(
3762 option.value,
3763 SqlOptionValue::Value(Value::Boolean(true))
3764 ))
3765 }
3766 "batch" => {
3767 options.batch = Some(matches!(
3768 option.value,
3769 SqlOptionValue::Value(Value::Boolean(true))
3770 ))
3771 }
3772 _ => {
3773 return Err(StrError(format!("unknown option: {}", option.name)));
3774 }
3775 }
3776 }
3777 Ok(options)
3778 }
3779}
3780
3781impl Display for CreateFunctionWithOptions {
3782 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3783 if self == &Self::default() {
3784 return Ok(());
3785 }
3786 let mut options = vec![];
3787 if let Some(v) = self.always_retry_on_network_error {
3788 options.push(format!("always_retry_on_network_error = {}", v));
3789 }
3790 if let Some(v) = self.r#async {
3791 options.push(format!("async = {}", v));
3792 }
3793 if let Some(v) = self.batch {
3794 options.push(format!("batch = {}", v));
3795 }
3796 write!(f, " WITH ( {} )", display_comma_separated(&options))
3797 }
3798}
3799
3800#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3801#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3802pub enum CreateFunctionUsing {
3803 Link(String),
3804 Base64(String),
3805}
3806
3807impl fmt::Display for CreateFunctionUsing {
3808 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3809 write!(f, "USING ")?;
3810 match self {
3811 CreateFunctionUsing::Link(uri) => write!(f, "LINK '{uri}'"),
3812 CreateFunctionUsing::Base64(s) => {
3813 write!(f, "BASE64 '{s}'")
3814 }
3815 }
3816 }
3817}
3818
3819#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3820#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3821pub struct ConfigParam {
3822 pub param: Ident,
3823 pub value: SetVariableValue,
3824}
3825
3826impl fmt::Display for ConfigParam {
3827 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3828 write!(f, "SET {} = {}", self.param, self.value)
3829 }
3830}
3831
3832#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3833#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3834pub enum SetVariableValue {
3835 Single(SetVariableValueSingle),
3836 List(Vec<SetVariableValueSingle>),
3837 Default,
3838}
3839
3840impl From<SetVariableValueSingle> for SetVariableValue {
3841 fn from(value: SetVariableValueSingle) -> Self {
3842 SetVariableValue::Single(value)
3843 }
3844}
3845
3846impl fmt::Display for SetVariableValue {
3847 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3848 use SetVariableValue::*;
3849 match self {
3850 Single(val) => write!(f, "{}", val),
3851 List(list) => write!(f, "{}", display_comma_separated(list),),
3852 Default => write!(f, "DEFAULT"),
3853 }
3854 }
3855}
3856
3857#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3858#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3859pub enum SetVariableValueSingle {
3860 Ident(Ident),
3861 Literal(Value),
3862}
3863
3864impl SetVariableValueSingle {
3865 pub fn to_string_unquoted(&self) -> String {
3866 match self {
3867 Self::Literal(Value::SingleQuotedString(s))
3868 | Self::Literal(Value::DoubleQuotedString(s)) => s.clone(),
3869 _ => self.to_string(),
3870 }
3871 }
3872}
3873
3874impl fmt::Display for SetVariableValueSingle {
3875 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3876 use SetVariableValueSingle::*;
3877 match self {
3878 Ident(ident) => write!(f, "{}", ident),
3879 Literal(literal) => write!(f, "{}", literal),
3880 }
3881 }
3882}
3883
3884#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3885#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3886pub enum AsOf {
3887 ProcessTime,
3888 ProcessTimeWithInterval((String, DateTimeField)),
3890 TimestampNum(i64),
3892 TimestampString(String),
3893 VersionNum(i64),
3894 VersionString(String),
3895}
3896
3897impl fmt::Display for AsOf {
3898 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3899 use AsOf::*;
3900 match self {
3901 ProcessTime => write!(f, " FOR SYSTEM_TIME AS OF PROCTIME()"),
3902 ProcessTimeWithInterval((value, leading_field)) => write!(
3903 f,
3904 " FOR SYSTEM_TIME AS OF NOW() - '{}' {}",
3905 value, leading_field
3906 ),
3907 TimestampNum(ts) => write!(f, " FOR SYSTEM_TIME AS OF {}", ts),
3908 TimestampString(ts) => write!(f, " FOR SYSTEM_TIME AS OF '{}'", ts),
3909 VersionNum(v) => write!(f, " FOR SYSTEM_VERSION AS OF {}", v),
3910 VersionString(v) => write!(f, " FOR SYSTEM_VERSION AS OF '{}'", v),
3911 }
3912 }
3913}
3914
3915#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3916#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3917pub enum DiscardType {
3918 All,
3919}
3920
3921impl fmt::Display for DiscardType {
3922 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3923 use DiscardType::*;
3924 match self {
3925 All => write!(f, "ALL"),
3926 }
3927 }
3928}
3929
3930#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
3933#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3934pub enum BackfillOrderStrategy {
3935 #[default]
3936 Default,
3937 None,
3938 Auto,
3939 Fixed(Vec<(ObjectName, ObjectName)>),
3940}
3941
3942impl fmt::Display for BackfillOrderStrategy {
3943 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3944 use BackfillOrderStrategy::*;
3945 match self {
3946 Default => write!(f, "DEFAULT"),
3947 None => write!(f, "NONE"),
3948 Auto => write!(f, "AUTO"),
3949 Fixed(map) => {
3950 let mut parts = vec![];
3951 for (start, end) in map {
3952 parts.push(format!("{} -> {}", start, end));
3953 }
3954 write!(f, "FIXED({})", display_comma_separated(&parts))
3955 }
3956 }
3957 }
3958}
3959
3960impl Statement {
3961 pub fn to_redacted_string(&self, keywords: RedactSqlOptionKeywordsRef) -> String {
3962 REDACT_SQL_OPTION_KEYWORDS.sync_scope(keywords, || self.to_string_unchecked())
3963 }
3964
3965 pub fn default_create_table(name: ObjectName) -> Self {
3967 Self::CreateTable {
3968 name,
3969 or_replace: false,
3970 temporary: false,
3971 if_not_exists: false,
3972 columns: Vec::new(),
3973 wildcard_idx: None,
3974 constraints: Vec::new(),
3975 with_options: Vec::new(),
3976 format_encode: None,
3977 source_watermarks: Vec::new(),
3978 append_only: false,
3979 on_conflict: None,
3980 with_version_columns: Vec::new(),
3981 query: None,
3982 cdc_table_info: None,
3983 include_column_options: Vec::new(),
3984 webhook_info: None,
3985 engine: Engine::Hummock,
3986 }
3987 }
3988}
3989
3990#[cfg(test)]
3991mod tests {
3992 use super::*;
3993
3994 #[test]
3995 fn test_grouping_sets_display() {
3996 let grouping_sets = Expr::GroupingSets(vec![
3998 vec![Expr::Identifier(Ident::new_unchecked("a"))],
3999 vec![Expr::Identifier(Ident::new_unchecked("b"))],
4000 ]);
4001 assert_eq!("GROUPING SETS ((a), (b))", format!("{}", grouping_sets));
4002
4003 let grouping_sets = Expr::GroupingSets(vec![vec![
4005 Expr::Identifier(Ident::new_unchecked("a")),
4006 Expr::Identifier(Ident::new_unchecked("b")),
4007 ]]);
4008 assert_eq!("GROUPING SETS ((a, b))", format!("{}", grouping_sets));
4009
4010 let grouping_sets = Expr::GroupingSets(vec![
4012 vec![
4013 Expr::Identifier(Ident::new_unchecked("a")),
4014 Expr::Identifier(Ident::new_unchecked("b")),
4015 ],
4016 vec![
4017 Expr::Identifier(Ident::new_unchecked("c")),
4018 Expr::Identifier(Ident::new_unchecked("d")),
4019 ],
4020 ]);
4021 assert_eq!(
4022 "GROUPING SETS ((a, b), (c, d))",
4023 format!("{}", grouping_sets)
4024 );
4025 }
4026
4027 #[test]
4028 fn test_rollup_display() {
4029 let rollup = Expr::Rollup(vec![vec![Expr::Identifier(Ident::new_unchecked("a"))]]);
4030 assert_eq!("ROLLUP (a)", format!("{}", rollup));
4031
4032 let rollup = Expr::Rollup(vec![vec![
4033 Expr::Identifier(Ident::new_unchecked("a")),
4034 Expr::Identifier(Ident::new_unchecked("b")),
4035 ]]);
4036 assert_eq!("ROLLUP ((a, b))", format!("{}", rollup));
4037
4038 let rollup = Expr::Rollup(vec![
4039 vec![Expr::Identifier(Ident::new_unchecked("a"))],
4040 vec![Expr::Identifier(Ident::new_unchecked("b"))],
4041 ]);
4042 assert_eq!("ROLLUP (a, b)", format!("{}", rollup));
4043
4044 let rollup = Expr::Rollup(vec![
4045 vec![Expr::Identifier(Ident::new_unchecked("a"))],
4046 vec![
4047 Expr::Identifier(Ident::new_unchecked("b")),
4048 Expr::Identifier(Ident::new_unchecked("c")),
4049 ],
4050 vec![Expr::Identifier(Ident::new_unchecked("d"))],
4051 ]);
4052 assert_eq!("ROLLUP (a, (b, c), d)", format!("{}", rollup));
4053 }
4054
4055 #[test]
4056 fn test_cube_display() {
4057 let cube = Expr::Cube(vec![vec![Expr::Identifier(Ident::new_unchecked("a"))]]);
4058 assert_eq!("CUBE (a)", format!("{}", cube));
4059
4060 let cube = Expr::Cube(vec![vec![
4061 Expr::Identifier(Ident::new_unchecked("a")),
4062 Expr::Identifier(Ident::new_unchecked("b")),
4063 ]]);
4064 assert_eq!("CUBE ((a, b))", format!("{}", cube));
4065
4066 let cube = Expr::Cube(vec![
4067 vec![Expr::Identifier(Ident::new_unchecked("a"))],
4068 vec![Expr::Identifier(Ident::new_unchecked("b"))],
4069 ]);
4070 assert_eq!("CUBE (a, b)", format!("{}", cube));
4071
4072 let cube = Expr::Cube(vec![
4073 vec![Expr::Identifier(Ident::new_unchecked("a"))],
4074 vec![
4075 Expr::Identifier(Ident::new_unchecked("b")),
4076 Expr::Identifier(Ident::new_unchecked("c")),
4077 ],
4078 vec![Expr::Identifier(Ident::new_unchecked("d"))],
4079 ]);
4080 assert_eq!("CUBE (a, (b, c), d)", format!("{}", cube));
4081 }
4082
4083 #[test]
4084 fn test_array_index_display() {
4085 let array_index = Expr::Index {
4086 obj: Box::new(Expr::Identifier(Ident::new_unchecked("v1"))),
4087 index: Box::new(Expr::Value(Value::Number("1".into()))),
4088 };
4089 assert_eq!("v1[1]", format!("{}", array_index));
4090
4091 let array_index2 = Expr::Index {
4092 obj: Box::new(array_index),
4093 index: Box::new(Expr::Value(Value::Number("1".into()))),
4094 };
4095 assert_eq!("v1[1][1]", format!("{}", array_index2));
4096 }
4097
4098 #[test]
4099 fn test_nested_op_display() {
4101 let binary_op = Expr::BinaryOp {
4102 left: Box::new(Expr::Value(Value::Boolean(true))),
4103 op: BinaryOperator::Or,
4104 right: Box::new(Expr::IsNotFalse(Box::new(Expr::Value(Value::Boolean(
4105 true,
4106 ))))),
4107 };
4108 assert_eq!("true OR true IS NOT FALSE", format!("{}", binary_op));
4109
4110 let unary_op = Expr::UnaryOp {
4111 op: UnaryOperator::Not,
4112 expr: Box::new(Expr::IsNotFalse(Box::new(Expr::Value(Value::Boolean(
4113 true,
4114 ))))),
4115 };
4116 assert_eq!("NOT true IS NOT FALSE", format!("{}", unary_op));
4117 }
4118
4119 #[test]
4120 fn test_create_function_display() {
4121 let create_function = Statement::CreateFunction {
4122 or_replace: false,
4123 temporary: false,
4124 if_not_exists: false,
4125 name: ObjectName(vec![Ident::new_unchecked("foo")]),
4126 args: Some(vec![OperateFunctionArg::unnamed(DataType::Int)]),
4127 returns: Some(CreateFunctionReturns::Value(DataType::Int)),
4128 params: CreateFunctionBody {
4129 language: Some(Ident::new_unchecked("python")),
4130 runtime: None,
4131 behavior: Some(FunctionBehavior::Immutable),
4132 as_: Some(FunctionDefinition::SingleQuotedDef("SELECT 1".to_owned())),
4133 return_: None,
4134 using: None,
4135 },
4136 with_options: CreateFunctionWithOptions {
4137 always_retry_on_network_error: None,
4138 r#async: None,
4139 batch: None,
4140 },
4141 };
4142 assert_eq!(
4143 "CREATE FUNCTION foo(INT) RETURNS INT LANGUAGE python IMMUTABLE AS 'SELECT 1'",
4144 format!("{}", create_function)
4145 );
4146 let create_function = Statement::CreateFunction {
4147 or_replace: false,
4148 temporary: false,
4149 if_not_exists: false,
4150 name: ObjectName(vec![Ident::new_unchecked("foo")]),
4151 args: Some(vec![OperateFunctionArg::unnamed(DataType::Int)]),
4152 returns: Some(CreateFunctionReturns::Value(DataType::Int)),
4153 params: CreateFunctionBody {
4154 language: Some(Ident::new_unchecked("python")),
4155 runtime: None,
4156 behavior: Some(FunctionBehavior::Immutable),
4157 as_: Some(FunctionDefinition::SingleQuotedDef("SELECT 1".to_owned())),
4158 return_: None,
4159 using: None,
4160 },
4161 with_options: CreateFunctionWithOptions {
4162 always_retry_on_network_error: Some(true),
4163 r#async: None,
4164 batch: None,
4165 },
4166 };
4167 assert_eq!(
4168 "CREATE FUNCTION foo(INT) RETURNS INT LANGUAGE python IMMUTABLE AS 'SELECT 1' WITH ( always_retry_on_network_error = true )",
4169 format!("{}", create_function)
4170 );
4171 }
4172}