This is an automated email from the ASF dual-hosted git repository.
airborne12 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 0dcd2a31a7b [fix](be) Restore segment index expression unit tests
(#68695)
0dcd2a31a7b is described below
commit 0dcd2a31a7bb00ba9a817c2600f64e770efea54d
Author: Jack <[email protected]>
AuthorDate: Fri Oct 2 21:26:32 2026 +0800
[fix](be) Restore segment index expression unit tests (#68695)
### What problem does this PR solve?
Related PR: #61092
Problem Summary:
`SegmentIteratorApplyIndexExprTest` has been excluded from the BE unit
test build since it was introduced. Its fixture creates a 100-row
segment but leaves the candidate row bitmap empty. `_apply_index_expr()`
skips virtual column index expressions when no rows remain, so seven
cases never exercise their downgrade and error-propagation assertions.
This PR initializes the fixture bitmap with all segment rows and removes
the test file from the CMake exclusion list. It sets the mock expression
node type to `MATCH_PRED` so the now-reachable `is_virtual_slot_ref()`
check reads initialized state. The tests also verify that a null index
context skips evaluation, that evaluation continues after a handled
downgrade, and that a missing index error propagates when fallback is
disabled.
With only the CMake change, 7 of the original 11 cases failed locally.
With the fixture and mock changes, all 12 cases pass.
---
be/test/CMakeLists.txt | 1 -
.../segment_iterator_apply_index_expr_test.cpp | 31 +++++++++++++++++++---
2 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/be/test/CMakeLists.txt b/be/test/CMakeLists.txt
index f76ef151d0f..2bd2ff51d5f 100644
--- a/be/test/CMakeLists.txt
+++ b/be/test/CMakeLists.txt
@@ -100,7 +100,6 @@ list(REMOVE_ITEM UT_FILES
${CMAKE_CURRENT_SOURCE_DIR}/storage/segment/frame_of_reference_page_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/storage/segment/plain_page_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/storage/segment/rle_page_test.cpp
-
${CMAKE_CURRENT_SOURCE_DIR}/storage/segment/segment_iterator_apply_index_expr_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/runtime/decimal_value_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/util/decompress_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/io/fs/remote_file_system_test.cpp
diff --git a/be/test/storage/segment/segment_iterator_apply_index_expr_test.cpp
b/be/test/storage/segment/segment_iterator_apply_index_expr_test.cpp
index eedab965926..dae24c34265 100644
--- a/be/test/storage/segment/segment_iterator_apply_index_expr_test.cpp
+++ b/be/test/storage/segment/segment_iterator_apply_index_expr_test.cpp
@@ -45,9 +45,13 @@ namespace {
// A test VExpr that returns a configurable Status from
evaluate_inverted_index.
class MockEvalExpr : public VExpr {
public:
- MockEvalExpr() { _data_type = std::make_shared<DataTypeUInt8>(); }
+ MockEvalExpr() {
+ _data_type = std::make_shared<DataTypeUInt8>();
+ set_node_type(TExprNodeType::MATCH_PRED);
+ }
void set_evaluate_status(Status st) { _eval_status = std::move(st); }
+ int evaluate_count() const { return _evaluate_count; }
const std::string& expr_name() const override {
static const std::string kName = "MockEvalExpr";
@@ -62,11 +66,13 @@ public:
}
Status evaluate_inverted_index(VExprContext* context, uint32_t
segment_num_rows) override {
+ ++_evaluate_count;
return _eval_status;
}
private:
Status _eval_status = Status::OK();
+ int _evaluate_count = 0;
};
TabletSchemaSPtr make_tablet_schema() {
@@ -119,6 +125,7 @@ protected:
// Read schema covers all tablet columns in order, so ordinal ==
tablet cid.
_read_schema = std::make_shared<ReadSchema>(_tablet_schema->columns());
_iter = std::make_unique<SegmentIterator>(_segment, _read_schema);
+ _iter->_row_bitmap.addRange(0, _segment->num_rows());
// Set up RuntimeState with fallback enabled so
_downgrade_without_index works
TQueryOptions query_options;
@@ -145,8 +152,11 @@ TEST_F(SegmentIteratorApplyIndexExprTest,
virtual_column_evaluate_ok) {
// When the index context is null, the expr should be skipped (continue).
TEST_F(SegmentIteratorApplyIndexExprTest,
virtual_column_null_index_context_skipped) {
- _iter->_virtual_column_exprs[0] = make_mock_ctx(Status::OK(),
/*with_index_context=*/false);
+ auto ctx =
make_mock_ctx(Status::Error<ErrorCode::INTERNAL_ERROR>("unexpected evaluation"),
+ /*with_index_context=*/false);
+ _iter->_virtual_column_exprs[0] = ctx;
EXPECT_TRUE(_iter->_apply_index_expr().ok());
+
EXPECT_EQ(std::static_pointer_cast<MockEvalExpr>(ctx->root())->evaluate_count(),
0);
}
// When evaluate_inverted_index returns INVERTED_INDEX_BYPASS (a downgrade
error),
@@ -169,6 +179,19 @@ TEST_F(SegmentIteratorApplyIndexExprTest,
virtual_column_downgrade_file_not_foun
EXPECT_EQ(_stats.inverted_index_downgrade_count, 1);
}
+TEST_F(SegmentIteratorApplyIndexExprTest,
virtual_column_file_not_found_without_fallback_fails) {
+ TQueryOptions query_options = _runtime_state.query_options();
+ query_options.__set_enable_fallback_on_missing_inverted_index(false);
+ _runtime_state.set_query_options(query_options);
+ _iter->_virtual_column_exprs[0] =
+
make_mock_ctx(Status::Error<ErrorCode::INVERTED_INDEX_FILE_NOT_FOUND>("not
found"));
+
+ Status st = _iter->_apply_index_expr();
+ EXPECT_FALSE(st.ok());
+ EXPECT_EQ(st.code(), ErrorCode::INVERTED_INDEX_FILE_NOT_FOUND);
+ EXPECT_EQ(_stats.inverted_index_downgrade_count, 0);
+}
+
// When evaluate_inverted_index returns INVERTED_INDEX_EVALUATE_SKIPPED,
// _apply_index_expr should downgrade and continue.
TEST_F(SegmentIteratorApplyIndexExprTest,
virtual_column_downgrade_evaluate_skipped_continues) {
@@ -215,10 +238,12 @@ TEST_F(SegmentIteratorApplyIndexExprTest,
multiple_virtual_columns_mixed_results
_iter->_virtual_column_exprs[0] = make_mock_ctx(Status::OK());
_iter->_virtual_column_exprs[1] =
make_mock_ctx(Status::Error<ErrorCode::INVERTED_INDEX_BYPASS>("bypass"));
- _iter->_virtual_column_exprs[2] = make_mock_ctx(Status::OK());
+ auto final_ctx = make_mock_ctx(Status::OK());
+ _iter->_virtual_column_exprs[2] = final_ctx;
Status st = _iter->_apply_index_expr();
EXPECT_TRUE(st.ok()) << st.to_string();
EXPECT_EQ(_stats.inverted_index_downgrade_count, 1);
+
EXPECT_EQ(std::static_pointer_cast<MockEvalExpr>(final_ctx->root())->evaluate_count(),
1);
}
// Multiple virtual column exprs: second one returns unhandled error, should
stop and propagate.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]