feat: Support the DELETE SQL statement (#942)

* [WIP]:delete sql

* [fix]:time parser bug

* [fix]:resolve conflict

* [fmt]:cargo fmt

* [fix]:remove unless log

* [fix]:test

* [feat]:add error parse

* [fix]:resolve conflict

* [fix]:remove unless code

* [fix]:remove unless code

* [test]:add IT

* [fix]:add license

* [fix]:ci

* [fix]:ci

* [fix]:ci

* [fix]:remove

* [fix]:ci

* [feat]:add sql

* [fix]:modify sql

* [feat]:refactor parser_expr

* [feat]:rm backtrace

* [fix]:ci

* [fix]: conversation

* [fix]: conversation

* feat:refactor delete

* feat:refactor delete

* fix:resolve conversation

* fix:ut

* fix:ut

* fix:conversation

* fix:conversation

* fix:conservation

---------

Co-authored-by: xieqijun <qijun@apache.org>
This commit is contained in:
Xieqijun
2023-02-15 13:13:17 +08:00
committed by GitHub
parent 63e396e9e9
commit de0b8aa0a0
21 changed files with 484 additions and 17 deletions

View File

@@ -13,6 +13,7 @@
// limitations under the License.
pub use sqlparser::ast::{
ColumnDef, ColumnOption, ColumnOptionDef, DataType, Expr, Function, FunctionArg,
FunctionArgExpr, Ident, ObjectName, SqlOption, TableConstraint, TimezoneInfo, Value,
BinaryOperator, ColumnDef, ColumnOption, ColumnOptionDef, DataType, Expr, Function,
FunctionArg, FunctionArgExpr, Ident, ObjectName, SqlOption, TableConstraint, TimezoneInfo,
Value,
};

View File

@@ -88,6 +88,8 @@ impl<'a> ParserContext<'a> {
self.parse_show()
}
Keyword::DELETE => self.parse_delete(),
Keyword::DESCRIBE | Keyword::DESC => {
self.parser.next_token();
self.parse_describe()

View File

@@ -14,5 +14,6 @@
mod alter_parser;
pub(crate) mod create_parser;
pub(crate) mod delete_parser;
pub(crate) mod insert_parser;
pub(crate) mod query_parser;

View File

@@ -0,0 +1,67 @@
// Copyright 2023 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.
use snafu::ResultExt;
use sqlparser::ast::Statement as SpStatement;
use crate::error::{self, Result};
use crate::parser::ParserContext;
use crate::statements::delete::Delete;
use crate::statements::statement::Statement;
/// DELETE statement parser implementation
impl<'a> ParserContext<'a> {
pub(crate) fn parse_delete(&mut self) -> Result<Statement> {
self.parser.next_token();
let spstatement = self
.parser
.parse_delete()
.context(error::SyntaxSnafu { sql: self.sql })?;
match spstatement {
SpStatement::Delete { .. } => {
Ok(Statement::Delete(Box::new(Delete::try_from(spstatement)?)))
}
unexp => error::UnsupportedSnafu {
sql: self.sql.to_string(),
keyword: unexp.to_string(),
}
.fail(),
}
}
}
#[cfg(test)]
mod tests {
use std::assert_matches::assert_matches;
use sqlparser::dialect::GenericDialect;
use super::*;
#[test]
pub fn test_parse_insert() {
let sql = r"delete from my_table where k1 = xxx and k2 = xxx and timestamp = xxx;";
let result = ParserContext::create_with_dialect(sql, &GenericDialect {}).unwrap();
assert_eq!(1, result.len());
assert_matches!(result[0], Statement::Delete { .. })
}
#[test]
pub fn test_parse_invalid_insert() {
let sql = r"delete my_table where "; // intentionally a bad sql
let result = ParserContext::create_with_dialect(sql, &GenericDialect {});
assert!(result.is_err(), "result is: {result:?}");
}
}

View File

@@ -14,6 +14,7 @@
pub mod alter;
pub mod create;
pub mod delete;
pub mod describe;
pub mod drop;
pub mod explain;
@@ -21,6 +22,7 @@ pub mod insert;
pub mod query;
pub mod show;
pub mod statement;
use std::str::FromStr;
use api::helper::ColumnDataTypeWrapper;

View File

@@ -0,0 +1,69 @@
// Copyright 2023 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.
use sqlparser::ast::{Expr, ObjectName, Statement, TableFactor};
use crate::error::{Error, InvalidSqlSnafu, Result};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Delete {
table_name: ObjectName,
selection: Option<Expr>,
}
impl Delete {
pub fn table_name(&self) -> &ObjectName {
&self.table_name
}
pub fn selection(&self) -> &Option<Expr> {
&self.selection
}
}
impl TryFrom<Statement> for Delete {
type Error = Error;
fn try_from(stmt: Statement) -> Result<Self> {
match stmt {
Statement::Delete {
table_name,
using,
selection,
returning,
} => {
if using.is_some() || returning.is_some() {
return InvalidSqlSnafu {
msg: "delete sql isn't support using and returning.".to_string(),
}
.fail();
}
match table_name {
TableFactor::Table { name, .. } => Ok(Delete {
table_name: name,
selection,
}),
_ => InvalidSqlSnafu {
msg: "can't find table name, tableFactor is not Table type".to_string(),
}
.fail(),
}
}
unexp => InvalidSqlSnafu {
msg: format!("Not expected to be {unexp}"),
}
.fail(),
}
}
}

View File

@@ -14,6 +14,7 @@
use crate::statements::alter::AlterTable;
use crate::statements::create::{CreateDatabase, CreateTable};
use crate::statements::delete::Delete;
use crate::statements::describe::DescribeTable;
use crate::statements::drop::DropTable;
use crate::statements::explain::Explain;
@@ -29,6 +30,8 @@ pub enum Statement {
Query(Box<Query>),
// Insert
Insert(Box<Insert>),
// Delete
Delete(Box<Delete>),
/// CREATE TABLE
CreateTable(CreateTable),
// DROP TABLE