sql/parsers/
truncate_parser.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
15use snafu::{ensure, ResultExt};
16use sqlparser::keywords::Keyword;
17
18use crate::error::{self, InvalidTableNameSnafu, Result};
19use crate::parser::ParserContext;
20use crate::statements::statement::Statement;
21use crate::statements::truncate::TruncateTable;
22
23/// `TRUNCATE [TABLE] table_name;`
24impl ParserContext<'_> {
25    pub(crate) fn parse_truncate(&mut self) -> Result<Statement> {
26        let _ = self.parser.next_token();
27        let _ = self.parser.parse_keyword(Keyword::TABLE);
28
29        let raw_table_ident =
30            self.parse_object_name()
31                .with_context(|_| error::UnexpectedSnafu {
32                    expected: "a table name",
33                    actual: self.peek_token_as_string(),
34                })?;
35        let table_ident = Self::canonicalize_object_name(raw_table_ident);
36
37        ensure!(
38            !table_ident.0.is_empty(),
39            InvalidTableNameSnafu {
40                name: table_ident.to_string()
41            }
42        );
43
44        Ok(Statement::TruncateTable(TruncateTable::new(table_ident)))
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use sqlparser::ast::{Ident, ObjectName};
51
52    use super::*;
53    use crate::dialect::GreptimeDbDialect;
54    use crate::parser::ParseOptions;
55
56    #[test]
57    pub fn test_parse_truncate() {
58        let sql = "TRUNCATE foo";
59        let mut stmts =
60            ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
61                .unwrap();
62        assert_eq!(
63            stmts.pop().unwrap(),
64            Statement::TruncateTable(TruncateTable::new(ObjectName(vec![Ident::new("foo")])))
65        );
66
67        let sql = "TRUNCATE TABLE foo";
68        let mut stmts =
69            ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
70                .unwrap();
71        assert_eq!(
72            stmts.pop().unwrap(),
73            Statement::TruncateTable(TruncateTable::new(ObjectName(vec![Ident::new("foo")])))
74        );
75
76        let sql = "TRUNCATE TABLE my_schema.foo";
77        let mut stmts =
78            ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
79                .unwrap();
80        assert_eq!(
81            stmts.pop().unwrap(),
82            Statement::TruncateTable(TruncateTable::new(ObjectName(vec![
83                Ident::new("my_schema"),
84                Ident::new("foo")
85            ])))
86        );
87
88        let sql = "TRUNCATE my_schema.foo";
89        let mut stmts =
90            ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
91                .unwrap();
92        assert_eq!(
93            stmts.pop().unwrap(),
94            Statement::TruncateTable(TruncateTable::new(ObjectName(vec![
95                Ident::new("my_schema"),
96                Ident::new("foo")
97            ])))
98        );
99
100        let sql = "TRUNCATE TABLE my_catalog.my_schema.foo";
101        let mut stmts =
102            ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
103                .unwrap();
104        assert_eq!(
105            stmts.pop().unwrap(),
106            Statement::TruncateTable(TruncateTable::new(ObjectName(vec![
107                Ident::new("my_catalog"),
108                Ident::new("my_schema"),
109                Ident::new("foo")
110            ])))
111        );
112
113        let sql = "TRUNCATE drop";
114        let mut stmts =
115            ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
116                .unwrap();
117        assert_eq!(
118            stmts.pop().unwrap(),
119            Statement::TruncateTable(TruncateTable::new(ObjectName(vec![Ident::new("drop")])))
120        );
121
122        let sql = "TRUNCATE `drop`";
123        let mut stmts =
124            ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
125                .unwrap();
126        assert_eq!(
127            stmts.pop().unwrap(),
128            Statement::TruncateTable(TruncateTable::new(ObjectName(vec![Ident::with_quote(
129                '`', "drop"
130            ),])))
131        );
132
133        let sql = "TRUNCATE \"drop\"";
134        let mut stmts =
135            ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
136                .unwrap();
137        assert_eq!(
138            stmts.pop().unwrap(),
139            Statement::TruncateTable(TruncateTable::new(ObjectName(vec![Ident::with_quote(
140                '"', "drop"
141            ),])))
142        );
143    }
144
145    #[test]
146    pub fn test_parse_invalid_truncate() {
147        let sql = "TRUNCATE SCHEMA foo";
148        let result =
149            ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
150        assert!(result.is_err(), "result is: {result:?}");
151
152        let sql = "TRUNCATE";
153        let result =
154            ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
155        assert!(result.is_err(), "result is: {result:?}");
156    }
157}