From df1890b27cebfe67d5b9260c960dc67b28b3ddd6 Mon Sep 17 00:00:00 2001 From: eldenmoon <15605149486@163.com> Date: Tue, 3 Sep 2024 12:00:27 +0800 Subject: [PATCH] [Fix](ShortCircuit) consider delete sign flag when hits row If partial update with delete clause, the new rowset delete sign should be considered --- be/src/service/point_query_executor.cpp | 18 +++++++++++++ be/src/service/point_query_executor.h | 5 ++++ .../data/point_query_p0/test_point_query.out | 8 ++++++ .../point_query_p0/test_point_query.groovy | 27 +++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/be/src/service/point_query_executor.cpp b/be/src/service/point_query_executor.cpp index 88293ba9b03675..8058e1f1be6302 100644 --- a/be/src/service/point_query_executor.cpp +++ b/be/src/service/point_query_executor.cpp @@ -49,7 +49,9 @@ #include "runtime/thread_context.h" #include "util/key_util.h" #include "util/runtime_profile.h" +#include "util/simd/bits.h" #include "util/thrift_util.h" +#include "vec/columns/columns_number.h" #include "vec/data_types/serde/data_type_serde.h" #include "vec/exprs/vexpr.h" #include "vec/exprs/vexpr_context.h" @@ -143,6 +145,9 @@ Status Reusable::init(const TDescriptorTable& t_desc_tbl, const std::vectorroot(), tuple_desc(), output_slot_descs); } + // get the delete sign idx in block + _delete_sign_idx = _col_uid_to_idx[schema.columns()[schema.delete_sign_idx()]->unique_id()]; + if (schema.have_column(BeConsts::ROW_STORE_COL)) { const auto& column = *DORIS_TRY(schema.column(BeConsts::ROW_STORE_COL)); _row_store_column_ids = column.unique_id(); @@ -483,6 +488,19 @@ Status PointQueryExecutor::_lookup_row_data() { } } } + // filter rows by delete sign + if (_row_hits > 0 && _reusable->delete_sign_idx() != -1) { + vectorized::ColumnPtr delete_filter_columns = + _result_block->get_columns()[_reusable->delete_sign_idx()]; + const auto& filter = + assert_cast(delete_filter_columns.get())->get_data(); + size_t count = filter.size() - simd::count_zero_num((int8_t*)filter.data(), filter.size()); + if (count == filter.size()) { + _result_block->clear(); + } else if (count > 0) { + return Status::NotSupported("Not implemented since only single row at present"); + } + } return Status::OK(); } diff --git a/be/src/service/point_query_executor.h b/be/src/service/point_query_executor.h index 29c7348e3d5b97..19954479c97ec7 100644 --- a/be/src/service/point_query_executor.h +++ b/be/src/service/point_query_executor.h @@ -100,6 +100,9 @@ class Reusable { RuntimeState* runtime_state() { return _runtime_state.get(); } + // delete sign idx in block + int32_t delete_sign_idx() const { return _delete_sign_idx; } + private: // caching TupleDescriptor, output_expr, etc... std::unique_ptr _runtime_state; @@ -118,6 +121,8 @@ class Reusable { std::unordered_set _missing_col_uids; // included cids in rowstore(column group) std::unordered_set _include_col_uids; + // delete sign idx in block + int32_t _delete_sign_idx = -1; }; // RowCache is a LRU cache for row store diff --git a/regression-test/data/point_query_p0/test_point_query.out b/regression-test/data/point_query_p0/test_point_query.out index 5a4e0b6617826f..1cc4142e39f306 100644 --- a/regression-test/data/point_query_p0/test_point_query.out +++ b/regression-test/data/point_query_p0/test_point_query.out @@ -152,3 +152,11 @@ -- !sql -- 0 1111111 +-- !sql -- +10 20 aabc value + +-- !sql -- + +-- !sql -- +-10 20 aabc update val + diff --git a/regression-test/suites/point_query_p0/test_point_query.groovy b/regression-test/suites/point_query_p0/test_point_query.groovy index f27c366efbbd0b..f05d0af1305a68 100644 --- a/regression-test/suites/point_query_p0/test_point_query.groovy +++ b/regression-test/suites/point_query_p0/test_point_query.groovy @@ -304,4 +304,31 @@ suite("test_point_query", "nonConcurrent") { sql """set global enable_nereids_planner=true""" sql "set global enable_fallback_to_original_planner = true" } + + // test partial update/delete + sql "DROP TABLE IF EXISTS table_3821461" + sql """ + CREATE TABLE `table_3821461` ( + `col1` smallint NOT NULL, + `col2` int NOT NULL, + `loc3` char(10) NOT NULL, + `value` char(10) NOT NULL, + INDEX col3 (`loc3`) USING INVERTED, + INDEX col2 (`col2`) USING INVERTED ) + ENGINE=OLAP UNIQUE KEY(`col1`, `col2`, `loc3`) + DISTRIBUTED BY HASH(`col1`, `col2`, `loc3`) BUCKETS 1 + PROPERTIES ( "replication_allocation" = "tag.location.default: 1", "bloom_filter_columns" = "col1", "store_row_column" = "true" ); + """ + sql "insert into table_3821461 values (-10, 20, 'aabc', 'value')" + sql "insert into table_3821461 values (10, 20, 'aabc', 'value');" + sql "insert into table_3821461 values (20, 30, 'aabc', 'value');" + explain { + sql("select * from table_3821461 where col1 = -10 and col2 = 20 and loc3 = 'aabc'") + contains "SHORT-CIRCUIT" + } + qt_sql "select * from table_3821461 where col1 = 10 and col2 = 20 and loc3 = 'aabc';" + sql "delete from table_3821461 where col1 = 10 and col2 = 20 and loc3 = 'aabc';" + qt_sql "select * from table_3821461 where col1 = 10 and col2 = 20 and loc3 = 'aabc';" + sql "update table_3821461 set value = 'update value' where col1 = -10 or col1 = 20;" + qt_sql """select * from table_3821461 where col1 = -10 and col2 = 20 and loc3 = 'aabc'""" } \ No newline at end of file