databend_common_ast/ast/statements/
insert_multi_table.rs1use std::fmt::Display;
16
17use derive_visitor::Drive;
18use derive_visitor::DriveMut;
19
20use crate::ast::write_comma_separated_list;
21use crate::ast::Expr;
22use crate::ast::Identifier;
23use crate::ast::Query;
24#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
25pub struct IntoClause {
26 pub catalog: Option<Identifier>,
27 pub database: Option<Identifier>,
28 pub table: Identifier,
29 pub target_columns: Vec<Identifier>,
30 pub source_columns: Vec<SourceExpr>,
31}
32
33#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
34#[allow(clippy::large_enum_variant)]
35pub enum SourceExpr {
36 Expr(Expr),
37 Default,
38}
39
40impl Display for SourceExpr {
41 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
42 match self {
43 SourceExpr::Expr(expr) => expr.fmt(f),
44 SourceExpr::Default => write!(f, "DEFAULT"),
45 }
46 }
47}
48
49impl Display for IntoClause {
50 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
51 write!(f, "INTO ")?;
52 if let Some(catalog) = &self.catalog {
53 write!(f, "{}.", catalog)?;
54 }
55 if let Some(database) = &self.database {
56 write!(f, "{}.", database)?;
57 }
58 write!(f, "{}", self.table)?;
59 if !self.target_columns.is_empty() {
60 write!(f, " (")?;
61 write_comma_separated_list(f, &self.target_columns)?;
62 write!(f, ")")?;
63 }
64 if !self.source_columns.is_empty() {
65 write!(f, " VALUES ")?;
66 write!(f, " (")?;
67 write_comma_separated_list(f, &self.source_columns)?;
68 write!(f, ")")?;
69 }
70 Ok(())
71 }
72}
73
74#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
75pub struct WhenClause {
76 pub condition: Expr,
77 pub into_clauses: Vec<IntoClause>,
78}
79
80impl Display for WhenClause {
81 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
82 write!(f, "WHEN ")?;
83 self.condition.fmt(f)?;
84 write!(f, " THEN ")?;
85 for into_clause in &self.into_clauses {
86 write!(f, "{} ", into_clause)?;
87 }
88 Ok(())
89 }
90}
91
92#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
93pub struct ElseClause {
94 pub into_clauses: Vec<IntoClause>,
95}
96
97impl Display for ElseClause {
98 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
99 write!(f, "ELSE ")?;
100 for into_clause in &self.into_clauses {
101 write!(f, "{} ", into_clause)?;
102 }
103 Ok(())
104 }
105}
106
107#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
108pub struct InsertMultiTableStmt {
109 pub overwrite: bool,
110 pub is_first: bool,
111 pub when_clauses: Vec<WhenClause>,
112 pub else_clause: Option<ElseClause>,
113 pub into_clauses: Vec<IntoClause>,
114 pub source: Query,
115}
116
117#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
118pub enum InsertMultiTableKind {
119 First,
120 All,
121}
122
123impl Display for InsertMultiTableStmt {
124 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
125 write!(f, "INSERT ")?;
126 if self.overwrite {
127 write!(f, "OVERWRITE ")?;
128 }
129 match &self.is_first {
130 true => write!(f, "FIRST ")?,
131 false => write!(f, "ALL ")?,
132 }
133 for when in &self.when_clauses {
134 write!(f, "{} ", when)?;
135 }
136 if let Some(else_clause) = &self.else_clause {
137 write!(f, "{} ", else_clause)?;
138 }
139 for into_clause in &self.into_clauses {
140 write!(f, "{} ", into_clause)?;
141 }
142 write!(f, "{}", self.source)
143 }
144}