1use snafu::{ensure, ResultExt};
16use sqlparser::dialect::keywords::Keyword;
17use sqlparser::tokenizer::Token;
18
19use crate::error::{self, InvalidFlowNameSnafu, InvalidTableNameSnafu, Result};
20use crate::parser::{ParserContext, FLOW};
21#[cfg(feature = "enterprise")]
22use crate::statements::drop::trigger::DropTrigger;
23use crate::statements::drop::{DropDatabase, DropFlow, DropTable, DropView};
24use crate::statements::statement::Statement;
25
26impl ParserContext<'_> {
28 pub(crate) fn parse_drop(&mut self) -> Result<Statement> {
29 let _ = self.parser.next_token();
30 match self.parser.peek_token().token {
31 Token::Word(w) => match w.keyword {
32 Keyword::TABLE => self.parse_drop_table(),
33 Keyword::VIEW => self.parse_drop_view(),
34 #[cfg(feature = "enterprise")]
35 Keyword::TRIGGER => self.parse_drop_trigger(),
36 Keyword::SCHEMA | Keyword::DATABASE => self.parse_drop_database(),
37 Keyword::NoKeyword => {
38 let uppercase = w.value.to_uppercase();
39 match uppercase.as_str() {
40 FLOW => self.parse_drop_flow(),
41 _ => self.unsupported(w.to_string()),
42 }
43 }
44 _ => self.unsupported(w.to_string()),
45 },
46 unexpected => self.unsupported(unexpected.to_string()),
47 }
48 }
49
50 #[cfg(feature = "enterprise")]
51 fn parse_drop_trigger(&mut self) -> Result<Statement> {
52 let _ = self.parser.next_token();
53
54 let if_exists = self.parser.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
55 let raw_trigger_ident =
56 self.parse_object_name()
57 .with_context(|_| error::UnexpectedSnafu {
58 expected: "a trigger name",
59 actual: self.peek_token_as_string(),
60 })?;
61 let trigger_ident = Self::canonicalize_object_name(raw_trigger_ident);
62 ensure!(
63 !trigger_ident.0.is_empty(),
64 error::InvalidTriggerNameSnafu {
65 name: trigger_ident.to_string()
66 }
67 );
68
69 Ok(Statement::DropTrigger(DropTrigger::new(
70 trigger_ident,
71 if_exists,
72 )))
73 }
74
75 fn parse_drop_view(&mut self) -> Result<Statement> {
76 let _ = self.parser.next_token();
77
78 let if_exists = self.parser.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
79 let raw_view_ident = self
80 .parse_object_name()
81 .with_context(|_| error::UnexpectedSnafu {
82 expected: "a view name",
83 actual: self.peek_token_as_string(),
84 })?;
85 let view_ident = Self::canonicalize_object_name(raw_view_ident);
86 ensure!(
87 !view_ident.0.is_empty(),
88 InvalidTableNameSnafu {
89 name: view_ident.to_string()
90 }
91 );
92
93 Ok(Statement::DropView(DropView {
94 view_name: view_ident,
95 drop_if_exists: if_exists,
96 }))
97 }
98
99 fn parse_drop_flow(&mut self) -> Result<Statement> {
100 let _ = self.parser.next_token();
101
102 let if_exists = self.parser.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
103 let raw_flow_ident = self
104 .parse_object_name()
105 .with_context(|_| error::UnexpectedSnafu {
106 expected: "a flow name",
107 actual: self.peek_token_as_string(),
108 })?;
109 let flow_ident = Self::canonicalize_object_name(raw_flow_ident);
110 ensure!(
111 !flow_ident.0.is_empty(),
112 InvalidFlowNameSnafu {
113 name: flow_ident.to_string()
114 }
115 );
116
117 Ok(Statement::DropFlow(DropFlow::new(flow_ident, if_exists)))
118 }
119
120 fn parse_drop_table(&mut self) -> Result<Statement> {
121 let _ = self.parser.next_token();
122
123 let if_exists = self.parser.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
124 let mut table_names = Vec::with_capacity(1);
125 loop {
126 let raw_table_ident =
127 self.parse_object_name()
128 .with_context(|_| error::UnexpectedSnafu {
129 expected: "a table name",
130 actual: self.peek_token_as_string(),
131 })?;
132 let table_ident = Self::canonicalize_object_name(raw_table_ident);
133 ensure!(
134 !table_ident.0.is_empty(),
135 InvalidTableNameSnafu {
136 name: table_ident.to_string()
137 }
138 );
139 table_names.push(table_ident);
140 if !self.parser.consume_token(&Token::Comma) {
141 break;
142 }
143 }
144
145 Ok(Statement::DropTable(DropTable::new(table_names, if_exists)))
146 }
147
148 fn parse_drop_database(&mut self) -> Result<Statement> {
149 let _ = self.parser.next_token();
150
151 let if_exists = self.parser.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
152 let database_name = self
153 .parse_object_name()
154 .with_context(|_| error::UnexpectedSnafu {
155 expected: "a database name",
156 actual: self.peek_token_as_string(),
157 })?;
158 let database_name = Self::canonicalize_object_name(database_name);
159
160 Ok(Statement::DropDatabase(DropDatabase::new(
161 database_name,
162 if_exists,
163 )))
164 }
165}
166
167#[cfg(test)]
168mod tests {
169 use sqlparser::ast::{Ident, ObjectName};
170
171 use super::*;
172 use crate::dialect::GreptimeDbDialect;
173 use crate::parser::ParseOptions;
174
175 #[test]
176 pub fn test_drop_table() {
177 let sql = "DROP TABLE foo";
178 let result =
179 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
180 let mut stmts = result.unwrap();
181 assert_eq!(
182 stmts.pop().unwrap(),
183 Statement::DropTable(DropTable::new(
184 vec![ObjectName(vec![Ident::new("foo")])],
185 false
186 ))
187 );
188
189 let sql = "DROP TABLE IF EXISTS foo";
190 let result =
191 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
192 let mut stmts = result.unwrap();
193 assert_eq!(
194 stmts.pop().unwrap(),
195 Statement::DropTable(DropTable::new(
196 vec![ObjectName(vec![Ident::new("foo")])],
197 true
198 ))
199 );
200
201 let sql = "DROP TABLE my_schema.foo";
202 let result =
203 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
204 let mut stmts = result.unwrap();
205 assert_eq!(
206 stmts.pop().unwrap(),
207 Statement::DropTable(DropTable::new(
208 vec![ObjectName(vec![Ident::new("my_schema"), Ident::new("foo")])],
209 false
210 ))
211 );
212
213 let sql = "DROP TABLE my_catalog.my_schema.foo";
214 let result =
215 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
216 let mut stmts = result.unwrap();
217 assert_eq!(
218 stmts.pop().unwrap(),
219 Statement::DropTable(DropTable::new(
220 vec![ObjectName(vec![
221 Ident::new("my_catalog"),
222 Ident::new("my_schema"),
223 Ident::new("foo")
224 ])],
225 false
226 ))
227 )
228 }
229
230 #[test]
231 pub fn test_drop_database() {
232 let sql = "DROP DATABASE public";
233 let result =
234 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
235 let mut stmts = result.unwrap();
236 assert_eq!(
237 stmts.pop().unwrap(),
238 Statement::DropDatabase(DropDatabase::new(
239 ObjectName(vec![Ident::new("public")]),
240 false
241 ))
242 );
243
244 let sql = "DROP DATABASE IF EXISTS public";
245 let result =
246 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
247 let mut stmts = result.unwrap();
248 assert_eq!(
249 stmts.pop().unwrap(),
250 Statement::DropDatabase(DropDatabase::new(
251 ObjectName(vec![Ident::new("public")]),
252 true
253 ))
254 );
255
256 let sql = "DROP DATABASE `fOo`";
257 let result =
258 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
259 let mut stmts = result.unwrap();
260 assert_eq!(
261 stmts.pop().unwrap(),
262 Statement::DropDatabase(DropDatabase::new(
263 ObjectName(vec![Ident::with_quote('`', "fOo"),]),
264 false
265 ))
266 );
267 }
268
269 #[test]
270 pub fn test_drop_flow() {
271 let sql = "DROP FLOW foo";
272 let result =
273 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
274 let mut stmts: Vec<Statement> = result.unwrap();
275 assert_eq!(
276 stmts.pop().unwrap(),
277 Statement::DropFlow(DropFlow::new(ObjectName(vec![Ident::new("foo")]), false))
278 );
279
280 let sql = "DROP FLOW IF EXISTS foo";
281 let result =
282 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
283 let mut stmts = result.unwrap();
284 assert_eq!(
285 stmts.pop().unwrap(),
286 Statement::DropFlow(DropFlow::new(ObjectName(vec![Ident::new("foo")]), true))
287 );
288
289 let sql = "DROP FLOW my_schema.foo";
290 let result =
291 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
292 let mut stmts = result.unwrap();
293 assert_eq!(
294 stmts.pop().unwrap(),
295 Statement::DropFlow(DropFlow::new(
296 ObjectName(vec![Ident::new("my_schema"), Ident::new("foo")]),
297 false
298 ))
299 );
300
301 let sql = "DROP FLOW my_catalog.my_schema.foo";
302 let result =
303 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
304 let mut stmts = result.unwrap();
305 assert_eq!(
306 stmts.pop().unwrap(),
307 Statement::DropFlow(DropFlow::new(
308 ObjectName(vec![
309 Ident::new("my_catalog"),
310 Ident::new("my_schema"),
311 Ident::new("foo")
312 ]),
313 false
314 ))
315 )
316 }
317
318 #[test]
319 pub fn test_drop_view() {
320 let sql = "DROP VIEW foo";
321 let result =
322 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
323 let mut stmts: Vec<Statement> = result.unwrap();
324 let stmt = stmts.pop().unwrap();
325 assert_eq!(
326 stmt,
327 Statement::DropView(DropView {
328 view_name: ObjectName(vec![Ident::new("foo")]),
329 drop_if_exists: false,
330 })
331 );
332 assert_eq!(sql, stmt.to_string());
333
334 let sql = "DROP VIEW greptime.public.foo";
335 let result =
336 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
337 let mut stmts: Vec<Statement> = result.unwrap();
338 let stmt = stmts.pop().unwrap();
339 assert_eq!(
340 stmt,
341 Statement::DropView(DropView {
342 view_name: ObjectName(vec![
343 Ident::new("greptime"),
344 Ident::new("public"),
345 Ident::new("foo")
346 ]),
347 drop_if_exists: false,
348 })
349 );
350 assert_eq!(sql, stmt.to_string());
351
352 let sql = "DROP VIEW IF EXISTS foo";
353 let result =
354 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
355 let mut stmts: Vec<Statement> = result.unwrap();
356 let stmt = stmts.pop().unwrap();
357 assert_eq!(
358 stmt,
359 Statement::DropView(DropView {
360 view_name: ObjectName(vec![Ident::new("foo")]),
361 drop_if_exists: true,
362 })
363 );
364 assert_eq!(sql, stmt.to_string());
365 }
366}