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