-
Notifications
You must be signed in to change notification settings - Fork 478
feat: Support the DELETE SQL statement #942
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+484
−17
Merged
Changes from 14 commits
Commits
Show all changes
38 commits
Select commit
Hold shift + click to select a range
e3f5b83
[WIP]:delete sql
jun0315 e8da65e
[fix]:time parser bug
jun0315 56448e0
Merge branch 'develop' into xqj_delete
jun0315 f96c345
[fix]:resolve conflict
jun0315 76581cc
[fmt]:cargo fmt
jun0315 3782bb8
[fix]:remove unless log
jun0315 821df85
[fix]:test
jun0315 42ea2a7
[feat]:add error parse
c1307a0
Merge branch 'develop' into xqj_delete
d7beacb
[fix]:resolve conflict
c01d77c
[fix]:remove unless code
e2f872b
[fix]:remove unless code
b32f62a
[test]:add IT
5be930f
[fix]:add license
452b0e1
[fix]:ci
83f5fe3
[fix]:ci
43b73bf
[fix]:ci
81c8bd9
[fix]:remove
b082769
[fix]:ci
f679429
[feat]:add sql
2e1dceb
[fix]:modify sql
0c7a9cd
[feat]:refactor parser_expr
6c36f38
[feat]:rm backtrace
jun0315 5fb29df
Merge branch 'develop' into xqj_delete
jun0315 c28d3a3
[fix]:ci
jun0315 d5eebe4
[fix]: conversation
jun0315 558a3f6
[fix]: conversation
jun0315 f70f3cd
feat:refactor delete
jun0315 3afdb2e
feat:refactor delete
jun0315 6f0ad69
fix:resolve conversation
jun0315 86789ca
fix:ut
jun0315 83b6f5c
Merge branch 'develop' into xqj_delete
jun0315 593555a
fix:ut
jun0315 d38d87c
fix:conversation
jun0315 9f0efaa
Merge branch 'develop' into xqj_delete
jun0315 83038e5
Merge branch 'develop' into xqj_delete
jun0315 d339ce1
fix:conversation
jun0315 6e8f17a
fix:conservation
jun0315 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,146 @@ | ||
| // 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 std::collections::HashMap; | ||
| use std::ops::Deref; | ||
| use std::str::FromStr; | ||
| use std::sync::Arc; | ||
|
|
||
| use common_query::Output; | ||
| use common_telemetry::warn; | ||
| use datatypes::prelude::VectorRef; | ||
| use datatypes::vectors::{BooleanVector, Float64Vector, StringVector, TimestampMillisecondVector}; | ||
| use session::context::QueryContextRef; | ||
| use snafu::ResultExt; | ||
| use sql::ast::{BinaryOperator, Expr, Value}; | ||
| use sql::statements::delete::Delete; | ||
| use table::engine::TableReference; | ||
| use table::requests::DeleteRequest; | ||
|
|
||
| use crate::error::{DeleteSnafu, InvalidSqlSnafu, Result}; | ||
| use crate::instance::sql::table_idents_to_full_name; | ||
| use crate::sql::{SqlHandler, SqlRequest}; | ||
|
|
||
| impl SqlHandler { | ||
| pub(crate) async fn delete(&self, req: DeleteRequest) -> Result<Output> { | ||
| let table_ref = TableReference { | ||
| catalog: &req.catalog_name.to_string(), | ||
| schema: &req.schema_name.to_string(), | ||
| table: &req.table_name.to_string(), | ||
| }; | ||
|
|
||
| let table = self.get_table(&table_ref)?; | ||
|
|
||
| let affected_rows = table.delete(req).await.with_context(|_| DeleteSnafu { | ||
| table_name: table_ref.to_string(), | ||
| })?; | ||
|
|
||
| Ok(Output::AffectedRows(affected_rows)) | ||
| } | ||
|
|
||
| pub(crate) fn delete_to_request( | ||
| &self, | ||
| stmt: Delete, | ||
| query_ctx: QueryContextRef, | ||
| ) -> Result<SqlRequest> { | ||
| let (catalog_name, schema_name, table_name) = | ||
| table_idents_to_full_name(stmt.table_name(), query_ctx.clone())?; | ||
| let key_column_values = parser_selection(stmt.selection())?; | ||
| Ok(SqlRequest::Delete(DeleteRequest { | ||
| key_column_values, | ||
| catalog_name, | ||
| schema_name, | ||
| table_name, | ||
| })) | ||
| } | ||
| } | ||
|
|
||
| /// parser selection, currently supported format is `tagkey1 = 'tagvalue1' and tagkey2 = 'tagvalue2'`. | ||
|
jun0315 marked this conversation as resolved.
Outdated
|
||
| /// (only uses =, and in the where clause and provides all columns needed by the key.) | ||
| fn parser_selection(selection: &Option<Expr>) -> Result<HashMap<String, VectorRef>> { | ||
|
jun0315 marked this conversation as resolved.
Outdated
|
||
| let mut key_column_values = HashMap::new(); | ||
| match selection { | ||
| Some(expr) => { | ||
| parser_expr(&expr, &mut key_column_values)?; | ||
| } | ||
| _ => {} | ||
| } | ||
| return Ok(key_column_values); | ||
| } | ||
|
|
||
| fn parser_expr(expr: &Expr, key_column_values: &mut HashMap<String, VectorRef>) -> Result<()> { | ||
|
jun0315 marked this conversation as resolved.
Outdated
|
||
| // match BinaryOp | ||
| if let Expr::BinaryOp { left, op, right } = expr { | ||
| // match And operator | ||
| if let BinaryOperator::And = op { | ||
| if let Expr::BinaryOp { .. } = left.deref() { | ||
| if let Expr::BinaryOp { .. } = right.deref() { | ||
| parser_expr(left.deref(), key_column_values)?; | ||
| parser_expr(right.deref(), key_column_values)?; | ||
| return Ok(()); | ||
| } | ||
| } | ||
| } | ||
| // match eq operator | ||
| else if let BinaryOperator::Eq = op { | ||
|
jun0315 marked this conversation as resolved.
Outdated
|
||
| if let Expr::Identifier(column_name) = left.deref() { | ||
| if let Expr::Value(value) = right.deref() { | ||
| key_column_values.insert( | ||
| column_name.to_string(), | ||
| value_to_vector(&column_name.to_string(), &value)?, | ||
| ); | ||
| return Ok(()); | ||
| } else if let Expr::Identifier(value) = right.deref() { | ||
| key_column_values.insert( | ||
| column_name.to_string(), | ||
| Arc::new(StringVector::from(vec![value.to_string()])), | ||
| ); | ||
| return Ok(()); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return InvalidSqlSnafu { | ||
| msg: format!("Failed to parse expr:{expr}"), | ||
| } | ||
| .fail(); | ||
| } | ||
|
|
||
| /// parse value to vector | ||
| fn value_to_vector(column_name: &String, value: &Value) -> Result<VectorRef> { | ||
| match value { | ||
| Value::Number(n, _) => { | ||
| return if column_name == "ts" { | ||
| Ok(Arc::new(TimestampMillisecondVector::from_vec(vec![ | ||
| i64::from_str(n).unwrap(), | ||
| ]))) | ||
| } else { | ||
| Ok(Arc::new(Float64Vector::from_vec(vec![ | ||
| f64::from_str(n).unwrap() | ||
| ]))) | ||
| }; | ||
| } | ||
| Value::SingleQuotedString(s) | sql::ast::Value::DoubleQuotedString(s) => { | ||
| Ok(Arc::new(StringVector::from(vec![s.to_string()]))) | ||
| } | ||
| Value::Boolean(b) => Ok(Arc::new(BooleanVector::from(vec![*b]))), | ||
| _ => { | ||
| warn!("Current value type is not supported, value:{value}"); | ||
| return InvalidSqlSnafu { | ||
| msg: format!("Failed to parse value:{value}"), | ||
| } | ||
| .fail(); | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| // 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 { inner: 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(); | ||
| println!("result is: {:#?}", result); | ||
| 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:?}"); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.