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