mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-01-17 10:42:55 +00:00
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:
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
67
src/sql/src/parsers/delete_parser.rs
Normal file
67
src/sql/src/parsers/delete_parser.rs
Normal 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:?}");
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
69
src/sql/src/statements/delete.rs
Normal file
69
src/sql/src/statements/delete.rs
Normal 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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user