databend_common_ast/ast/statements/
insert_multi_table.rs

1// Copyright 2021 Datafuse Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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}