feat: impl DROP TABLE on memory catalog based standalone mode (#630)

* feat: implement drop table for standalone mode

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* update integration test

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* enhancement test

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
This commit is contained in:
Ruihang Xia
2022-11-25 11:53:46 +08:00
committed by GitHub
parent b371ce0f48
commit 30940e692a
26 changed files with 437 additions and 69 deletions

View File

@@ -22,6 +22,7 @@ use crate::error::{
self, InvalidDatabaseNameSnafu, InvalidTableNameSnafu, Result, SyntaxSnafu, TokenizerSnafu,
};
use crate::statements::describe::DescribeTable;
use crate::statements::drop::DropTable;
use crate::statements::explain::Explain;
use crate::statements::show::{ShowCreateTable, ShowDatabases, ShowKind, ShowTables};
use crate::statements::statement::Statement;
@@ -99,6 +100,8 @@ impl<'a> ParserContext<'a> {
Keyword::ALTER => self.parse_alter(),
Keyword::DROP => self.parse_drop(),
// todo(hl) support more statements.
_ => self.unsupported(self.peek_token_as_string()),
}
@@ -271,6 +274,36 @@ impl<'a> ParserContext<'a> {
Ok(Statement::Explain(Explain::try_from(explain_statement)?))
}
fn parse_drop(&mut self) -> Result<Statement> {
self.parser.next_token();
if !self.matches_keyword(Keyword::TABLE) {
return self.unsupported(self.peek_token_as_string());
}
self.parser.next_token();
let table_ident =
self.parser
.parse_object_name()
.with_context(|_| error::UnexpectedSnafu {
sql: self.sql,
expected: "a table name",
actual: self.peek_token_as_string(),
})?;
ensure!(
!table_ident.0.is_empty(),
InvalidTableNameSnafu {
name: table_ident.to_string()
}
);
let (catalog_name, schema_name, table_name) = table_idents_to_full_name(&table_ident)?;
Ok(Statement::DropTable(DropTable {
catalog_name,
schema_name,
table_name,
}))
}
// Report unexpected token
pub(crate) fn expected<T>(&self, expected: &str, found: Token) -> Result<T> {
Err(ParserError::ParserError(format!(
@@ -338,6 +371,7 @@ impl<'a> ParserContext<'a> {
mod tests {
use std::assert_matches::assert_matches;
use common_catalog::consts::{DEFAULT_CATALOG_NAME, DEFAULT_SCHEMA_NAME};
use sqlparser::ast::{Query as SpQuery, Statement as SpStatement};
use sqlparser::dialect::GenericDialect;
@@ -532,4 +566,43 @@ mod tests {
assert_eq!(stmts[0], Statement::Explain(explain))
}
#[test]
pub fn test_drop_table() {
let sql = "DROP TABLE foo";
let result = ParserContext::create_with_dialect(sql, &GenericDialect {});
let mut stmts = result.unwrap();
assert_eq!(
stmts.pop().unwrap(),
Statement::DropTable(DropTable {
catalog_name: DEFAULT_CATALOG_NAME.to_string(),
schema_name: DEFAULT_SCHEMA_NAME.to_string(),
table_name: "foo".to_string()
})
);
let sql = "DROP TABLE my_schema.foo";
let result = ParserContext::create_with_dialect(sql, &GenericDialect {});
let mut stmts = result.unwrap();
assert_eq!(
stmts.pop().unwrap(),
Statement::DropTable(DropTable {
catalog_name: DEFAULT_CATALOG_NAME.to_string(),
schema_name: "my_schema".to_string(),
table_name: "foo".to_string()
})
);
let sql = "DROP TABLE my_catalog.my_schema.foo";
let result = ParserContext::create_with_dialect(sql, &GenericDialect {});
let mut stmts = result.unwrap();
assert_eq!(
stmts.pop().unwrap(),
Statement::DropTable(DropTable {
catalog_name: "my_catalog".to_string(),
schema_name: "my_schema".to_string(),
table_name: "foo".to_string()
})
)
}
}

View File

@@ -15,6 +15,7 @@
pub mod alter;
pub mod create;
pub mod describe;
pub mod drop;
pub mod explain;
pub mod insert;
pub mod query;

View File

@@ -0,0 +1,32 @@
// Copyright 2022 Greptime Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// DROP TABLE statement.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DropTable {
pub catalog_name: String,
pub schema_name: String,
pub table_name: String,
}
impl DropTable {
/// Creates a statement for `DROP TABLE`
pub fn new(catalog_name: String, schema_name: String, table_name: String) -> Self {
DropTable {
catalog_name,
schema_name,
table_name,
}
}
}

View File

@@ -18,6 +18,7 @@ use sqlparser::parser::ParserError;
use crate::statements::alter::AlterTable;
use crate::statements::create::{CreateDatabase, CreateTable};
use crate::statements::describe::DescribeTable;
use crate::statements::drop::DropTable;
use crate::statements::explain::Explain;
use crate::statements::insert::Insert;
use crate::statements::query::Query;
@@ -33,6 +34,8 @@ pub enum Statement {
Insert(Box<Insert>),
/// CREATE TABLE
CreateTable(CreateTable),
// DROP TABLE
DropTable(DropTable),
// CREATE DATABASE
CreateDatabase(CreateDatabase),
/// ALTER TABLE
@@ -67,6 +70,9 @@ impl TryFrom<Statement> for SpStatement {
Statement::DescribeTable(_) => Err(ParserError::ParserError(
"sqlparser does not support DESCRIBE TABLE query.".to_string(),
)),
Statement::DropTable(_) => Err(ParserError::ParserError(
"sqlparser does not support DROP TABLE query.".to_string(),
)),
Statement::Query(s) => Ok(SpStatement::Query(Box::new(s.inner))),
Statement::Insert(i) => Ok(i.inner),
Statement::CreateDatabase(_) | Statement::CreateTable(_) | Statement::Alter(_) => {