From fdb27b81f7c1c395c55a7db30e853922946f3c78 Mon Sep 17 00:00:00 2001 From: Zhiyuan Liang <132966438+Ami11111@users.noreply.github.com> Date: Sun, 4 Aug 2024 19:50:45 +0800 Subject: [PATCH] Enable http api delete with empty filter (#1577) ### What problem does this PR solve? Http api now can delete row with empty filter. ### Type of change - [x] New Feature (non-breaking change which adds functionality) --------- Co-authored-by: Jin Hai --- python/test/internal_cases/test_delete.py | 2 - python/test/internal_cases/test_index.py | 1 - src/network/http_server.cpp | 69 +++++++++++++++-------- 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/python/test/internal_cases/test_delete.py b/python/test/internal_cases/test_delete.py index 4db83b8eb0..c1a45d4f89 100644 --- a/python/test/internal_cases/test_delete.py +++ b/python/test/internal_cases/test_delete.py @@ -328,7 +328,6 @@ def test_various_expression_in_where_clause(self, column_types, column_types_exa res = db_obj.drop_table("test_various_expression_in_where_clause", ConflictType.Error) assert res.error_code == ErrorCode.OK - @pytest.mark.usefixtures("skip_if_http") def test_delete_one_block_without_expression(self): # connect db_obj = self.infinity_obj.get_database("default_db") @@ -349,7 +348,6 @@ def test_delete_one_block_without_expression(self): res = db_obj.drop_table("test_delete_one_block_without_expression", ConflictType.Error) assert res.error_code == ErrorCode.OK - @pytest.mark.usefixtures("skip_if_http") def test_delete_one_segment_without_expression(self): # connect db_obj = self.infinity_obj.get_database("default_db") diff --git a/python/test/internal_cases/test_index.py b/python/test/internal_cases/test_index.py index 3440770ba0..705f46e3b3 100644 --- a/python/test/internal_cases/test_index.py +++ b/python/test/internal_cases/test_index.py @@ -609,7 +609,6 @@ def test_fulltext_match_with_invalid_analyzer(self, check_data): res = db_obj.drop_table("test_fulltext_match_with_invalid_analyzer", ConflictType.Ignore) assert res.error_code == ErrorCode.OK - @pytest.mark.usefixtures("skip_if_http") def test_create_index_on_deleted_table(self): db_obj = self.infinity_obj.get_database("default_db") db_obj.drop_table( diff --git a/src/network/http_server.cpp b/src/network/http_server.cpp index a8c20dd232..b1b4733a9e 100644 --- a/src/network/http_server.cpp +++ b/src/network/http_server.cpp @@ -1243,34 +1243,55 @@ class DeleteHandler final : public HttpRequestHandler { nlohmann::json http_body_json = nlohmann::json::parse(data_body); const String filter_string = http_body_json["filter"]; + if(filter_string != "") { + UniquePtr expr_parsed_result = MakeUnique(); + ExprParser expr_parser; + expr_parser.Parse(filter_string, expr_parsed_result.get()); + if (expr_parsed_result->IsError() || expr_parsed_result->exprs_ptr_->size() != 1) { + json_response["error_code"] = ErrorCode::kInvalidFilterExpression; + json_response["error_message"] = fmt::format("Invalid filter expression: {}", filter_string); + return ResponseFactory::createResponse(http_status, json_response.dump()); + } - UniquePtr expr_parsed_result = MakeUnique(); - ExprParser expr_parser; - expr_parser.Parse(filter_string, expr_parsed_result.get()); - if (expr_parsed_result->IsError() || expr_parsed_result->exprs_ptr_->size() != 1) { - json_response["error_code"] = ErrorCode::kInvalidFilterExpression; - json_response["error_message"] = fmt::format("Invalid filter expression: {}", filter_string); - return ResponseFactory::createResponse(http_status, json_response.dump()); - } + auto database_name = request->getPathVariable("database_name"); + auto table_name = request->getPathVariable("table_name"); + const QueryResult result = infinity->Delete(database_name, table_name, expr_parsed_result->exprs_ptr_->at(0)); + expr_parsed_result->exprs_ptr_->at(0) = nullptr; - auto database_name = request->getPathVariable("database_name"); - auto table_name = request->getPathVariable("table_name"); - const QueryResult result = infinity->Delete(database_name, table_name, expr_parsed_result->exprs_ptr_->at(0)); - expr_parsed_result->exprs_ptr_->at(0) = nullptr; + if (result.IsOk()) { + json_response["error_code"] = 0; + http_status = HTTPStatus::CODE_200; - if (result.IsOk()) { - json_response["error_code"] = 0; - http_status = HTTPStatus::CODE_200; + // Only one block + DataBlock *data_block = result.result_table_->GetDataBlockById(0).get(); + // Get sum delete rows + Value value = data_block->GetValue(1, 0); + json_response["delete_row_count"] = value.value_.big_int; + } else { + json_response["error_code"] = result.ErrorCode(); + json_response["error_message"] = result.ErrorMsg(); + http_status = HTTPStatus::CODE_500; + } + } + else { + auto database_name = request->getPathVariable("database_name"); + auto table_name = request->getPathVariable("table_name"); + const QueryResult result = infinity->Delete(database_name, table_name, nullptr); - // Only one block - DataBlock *data_block = result.result_table_->GetDataBlockById(0).get(); - // Get sum delete rows - Value value = data_block->GetValue(1, 0); - json_response["delete_row_count"] = value.value_.big_int; - } else { - json_response["error_code"] = result.ErrorCode(); - json_response["error_message"] = result.ErrorMsg(); - http_status = HTTPStatus::CODE_500; + if (result.IsOk()) { + json_response["error_code"] = 0; + http_status = HTTPStatus::CODE_200; + + // Only one block + DataBlock *data_block = result.result_table_->GetDataBlockById(0).get(); + // Get sum delete rows + Value value = data_block->GetValue(1, 0); + json_response["delete_row_count"] = value.value_.big_int; + } else { + json_response["error_code"] = result.ErrorCode(); + json_response["error_message"] = result.ErrorMsg(); + http_status = HTTPStatus::CODE_500; + } } } catch (nlohmann::json::exception &e) { json_response["error_code"] = ErrorCode::kInvalidJsonFormat;