Skip to main content

sql/statements/
drop.rs

1// Copyright 2023 Greptime Team
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
15#[cfg(feature = "enterprise")]
16pub mod trigger;
17
18use std::fmt::Display;
19
20use serde::Serialize;
21use sqlparser::ast::ObjectName;
22use sqlparser_derive::{Visit, VisitMut};
23
24/// DROP TABLE statement.
25#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
26pub struct DropTable {
27    table_names: Vec<ObjectName>,
28
29    /// drop table if exists
30    drop_if_exists: bool,
31}
32
33impl DropTable {
34    /// Creates a statement for `DROP TABLE`
35    pub fn new(table_names: Vec<ObjectName>, if_exists: bool) -> Self {
36        Self {
37            table_names,
38            drop_if_exists: if_exists,
39        }
40    }
41
42    pub fn table_names(&self) -> &[ObjectName] {
43        &self.table_names
44    }
45
46    pub fn drop_if_exists(&self) -> bool {
47        self.drop_if_exists
48    }
49}
50
51impl Display for DropTable {
52    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53        f.write_str("DROP TABLE")?;
54        if self.drop_if_exists() {
55            f.write_str(" IF EXISTS")?;
56        }
57        let table_names = self.table_names();
58        for (i, table_name) in table_names.iter().enumerate() {
59            if i > 0 {
60                f.write_str(",")?;
61            }
62            write!(f, " {}", table_name)?;
63        }
64        Ok(())
65    }
66}
67
68/// `UNDROP TABLE` statement.
69#[cfg(feature = "enterprise")]
70#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
71pub struct UndropTable {
72    table_name: ObjectName,
73}
74
75#[cfg(feature = "enterprise")]
76impl UndropTable {
77    pub fn new(table_name: ObjectName) -> Self {
78        Self { table_name }
79    }
80
81    pub fn table_name(&self) -> &ObjectName {
82        &self.table_name
83    }
84}
85
86#[cfg(feature = "enterprise")]
87impl Display for UndropTable {
88    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89        write!(f, "UNDROP TABLE {}", self.table_name)
90    }
91}
92
93/// DROP DATABASE statement.
94#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
95pub struct DropDatabase {
96    name: ObjectName,
97    /// drop table if exists
98    drop_if_exists: bool,
99}
100
101impl DropDatabase {
102    /// Creates a statement for `DROP DATABASE`
103    pub fn new(name: ObjectName, if_exists: bool) -> Self {
104        Self {
105            name,
106            drop_if_exists: if_exists,
107        }
108    }
109
110    pub fn name(&self) -> &ObjectName {
111        &self.name
112    }
113
114    pub fn drop_if_exists(&self) -> bool {
115        self.drop_if_exists
116    }
117}
118
119impl Display for DropDatabase {
120    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121        f.write_str("DROP DATABASE")?;
122        if self.drop_if_exists() {
123            f.write_str(" IF EXISTS")?;
124        }
125        let name = self.name();
126        write!(f, r#" {name}"#)
127    }
128}
129
130/// DROP FLOW statement.
131#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
132pub struct DropFlow {
133    flow_name: ObjectName,
134    /// drop flow if exists
135    drop_if_exists: bool,
136}
137
138impl DropFlow {
139    /// Creates a statement for `DROP DATABASE`
140    pub fn new(flow_name: ObjectName, if_exists: bool) -> Self {
141        Self {
142            flow_name,
143            drop_if_exists: if_exists,
144        }
145    }
146
147    /// Returns the flow name.
148    pub fn flow_name(&self) -> &ObjectName {
149        &self.flow_name
150    }
151
152    /// Return the `drop_if_exists`.
153    pub fn drop_if_exists(&self) -> bool {
154        self.drop_if_exists
155    }
156}
157
158impl Display for DropFlow {
159    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
160        f.write_str("DROP FLOW")?;
161        if self.drop_if_exists() {
162            f.write_str(" IF EXISTS")?;
163        }
164        let flow_name = self.flow_name();
165        write!(f, r#" {flow_name}"#)
166    }
167}
168
169/// `DROP VIEW` statement.
170#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
171pub struct DropView {
172    // The view name
173    pub view_name: ObjectName,
174    // drop view if exists
175    pub drop_if_exists: bool,
176}
177
178impl Display for DropView {
179    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
180        write!(
181            f,
182            "DROP VIEW{} {}",
183            if self.drop_if_exists {
184                " IF EXISTS"
185            } else {
186                ""
187            },
188            self.view_name
189        )
190    }
191}
192
193#[cfg(test)]
194mod tests {
195    use std::assert_matches;
196
197    use crate::dialect::GreptimeDbDialect;
198    use crate::parser::{ParseOptions, ParserContext};
199    use crate::statements::statement::Statement;
200
201    #[test]
202    fn test_display_drop_database() {
203        let sql = r"drop database test;";
204        let stmts =
205            ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
206                .unwrap();
207        assert_eq!(1, stmts.len());
208        assert_matches!(&stmts[0], Statement::DropDatabase { .. });
209
210        match &stmts[0] {
211            Statement::DropDatabase(set) => {
212                let new_sql = format!("\n{}", set);
213                assert_eq!(
214                    r#"
215DROP DATABASE test"#,
216                    &new_sql
217                );
218            }
219            _ => {
220                unreachable!();
221            }
222        }
223
224        let sql = r"drop database if exists test;";
225        let stmts =
226            ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
227                .unwrap();
228        assert_eq!(1, stmts.len());
229        assert_matches!(&stmts[0], Statement::DropDatabase { .. });
230
231        match &stmts[0] {
232            Statement::DropDatabase(set) => {
233                let new_sql = format!("\n{}", set);
234                assert_eq!(
235                    r#"
236DROP DATABASE IF EXISTS test"#,
237                    &new_sql
238                );
239            }
240            _ => {
241                unreachable!();
242            }
243        }
244    }
245
246    #[test]
247    fn test_display_drop_table() {
248        let sql = r"drop table test;";
249        let stmts =
250            ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
251                .unwrap();
252        assert_eq!(1, stmts.len());
253        assert_matches!(&stmts[0], Statement::DropTable { .. });
254
255        match &stmts[0] {
256            Statement::DropTable(set) => {
257                let new_sql = format!("\n{}", set);
258                assert_eq!(
259                    r#"
260DROP TABLE test"#,
261                    &new_sql
262                );
263            }
264            _ => {
265                unreachable!();
266            }
267        }
268
269        let sql = r"drop table test1, test2;";
270        let stmts =
271            ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
272                .unwrap();
273        assert_eq!(1, stmts.len());
274        assert_matches!(&stmts[0], Statement::DropTable { .. });
275
276        match &stmts[0] {
277            Statement::DropTable(set) => {
278                let new_sql = format!("\n{}", set);
279                assert_eq!(
280                    r#"
281DROP TABLE test1, test2"#,
282                    &new_sql
283                );
284            }
285            _ => {
286                unreachable!();
287            }
288        }
289
290        let sql = r"drop table if exists test;";
291        let stmts =
292            ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
293                .unwrap();
294        assert_eq!(1, stmts.len());
295        assert_matches!(&stmts[0], Statement::DropTable { .. });
296
297        match &stmts[0] {
298            Statement::DropTable(set) => {
299                let new_sql = format!("\n{}", set);
300                assert_eq!(
301                    r#"
302DROP TABLE IF EXISTS test"#,
303                    &new_sql
304                );
305            }
306            _ => {
307                unreachable!();
308            }
309        }
310    }
311
312    #[test]
313    fn test_display_drop_flow() {
314        let sql = r"drop flow test;";
315        let stmts =
316            ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
317                .unwrap();
318        assert_eq!(1, stmts.len());
319        assert_matches!(&stmts[0], Statement::DropFlow { .. });
320
321        match &stmts[0] {
322            Statement::DropFlow(set) => {
323                let new_sql = format!("\n{}", set);
324                assert_eq!(
325                    r#"
326DROP FLOW test"#,
327                    &new_sql
328                );
329            }
330            _ => {
331                unreachable!();
332            }
333        }
334
335        let sql = r"drop flow if exists test;";
336        let stmts =
337            ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
338                .unwrap();
339        assert_eq!(1, stmts.len());
340        assert_matches!(&stmts[0], Statement::DropFlow { .. });
341
342        match &stmts[0] {
343            Statement::DropFlow(set) => {
344                let new_sql = format!("\n{}", set);
345                assert_eq!(
346                    r#"
347DROP FLOW IF EXISTS test"#,
348                    &new_sql
349                );
350            }
351            _ => {
352                unreachable!();
353            }
354        }
355    }
356}