This is an automated email from the ASF dual-hosted git repository.

yiguolei 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 2b7475fa06a [fix](orc) handle cancellation during condition cache seek 
(#67141)
2b7475fa06a is described below

commit 2b7475fa06a27437ae0384c9cf86d24fefd6407b
Author: Gabriel <[email protected]>
AuthorDate: Mon Aug 31 10:44:12 2026 +0800

    [fix](orc) handle cancellation during condition cache seek (#67141)
    
    ### What problem does this PR solve?
    
    Issue Number: DORIS-28199
    
    Problem Summary:
    
    Condition-cache granule skipping can call ORC seekToRow before the
    existing nextBatch exception boundary. When a query is cancelled during
    that I/O, the ORC input stream throws a stop exception that escapes
    get_block and may terminate the BE process.
    
    ### Release note
    
    Fix BE process termination when an ORC scan is cancelled during
    condition-cache seeking.
    
    ### Check List (For Author)
    
    - Test
        - [x] Regression test
        - [x] Unit Test
        - [ ] Manual test
        - [ ] No need to test or manual test.
    
    Verification: NewOrcReaderTest.* passed 163/163 under ASAN_UT.
    Clang-format 16 passed for both affected C++ files.
    
    - Behavior changed:
        - [ ] No.
    - [x] Yes. Cancellation during a condition-cache seek now returns clean
    EOF instead of allowing the ORC stop exception to escape.
    
    - Does this need documentation?
        - [x] No.
        - [ ] Yes.
    
    ### Check List (For Reviewer who merge this PR)
    
    - [ ] Confirm the release note
    - [ ] Confirm test cases
    - [ ] Confirm document
    - [ ] Add branch pick label
---
 be/src/format_v2/orc/orc_reader.cpp       | 12 +++++---
 be/test/format_v2/orc/orc_reader_test.cpp | 48 +++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/be/src/format_v2/orc/orc_reader.cpp 
b/be/src/format_v2/orc/orc_reader.cpp
index e7509ebd078..83cb929e18b 100644
--- a/be/src/format_v2/orc/orc_reader.cpp
+++ b/be/src/format_v2/orc/orc_reader.cpp
@@ -1751,6 +1751,8 @@ void 
OrcReader::_skip_condition_cache_false_granules(size_t* rows, bool* eof) {
     }
     if (target_row > _state->condition_cache_next_row) {
         DORIS_CHECK(target_row <= file_total_rows);
+        
DBUG_EXECUTE_IF("OrcReader._skip_condition_cache_false_granules.before_seek_to_row",
+                        DBUG_RUN_CALLBACK());
         _state->row_reader->seekToRow(target_row);
         if (_io_ctx != nullptr) {
             _io_ctx->condition_cache_filtered_rows += target_row - 
_state->condition_cache_next_row;
@@ -1939,11 +1941,13 @@ Status OrcReader::get_block(Block* file_block, size_t* 
rows, bool* eof) {
 
     bool has_next = false;
     while (true) {
-        _skip_condition_cache_false_granules(rows, eof);
-        if (*eof) {
-            return Status::OK();
-        }
         try {
+            // Condition-cache seeks can perform I/O, so keep them in the same 
cancellation
+            // boundary as next().
+            _skip_condition_cache_false_granules(rows, eof);
+            if (*eof) {
+                return Status::OK();
+            }
             _state->orc_lazy_selection_valid = false;
             _state->orc_lazy_selected_rows.clear();
             _state->orc_lazy_input_rows = 0;
diff --git a/be/test/format_v2/orc/orc_reader_test.cpp 
b/be/test/format_v2/orc/orc_reader_test.cpp
index 2663f3fea07..1058d774d44 100644
--- a/be/test/format_v2/orc/orc_reader_test.cpp
+++ b/be/test/format_v2/orc/orc_reader_test.cpp
@@ -6133,6 +6133,54 @@ TEST_F(NewOrcReaderTest, 
ConditionCacheHitSkipsFalseGranulesBeforeColumnRead) {
     EXPECT_EQ(rows, 0);
 }
 
+TEST_F(NewOrcReaderTest, ConditionCacheSeekReturnsCleanEofWhenCancelled) {
+    constexpr int64_t row_count = ConditionCacheContext::GRANULE_SIZE * 2;
+    const auto file_path = (_test_dir / 
"condition_cache_cancelled_seek.orc").string();
+    write_large_orc_int_file(file_path, row_count);
+
+    auto io_ctx = std::make_shared<io::IOContext>();
+    auto reader = create_reader_for_path(file_path, nullptr, io_ctx);
+    RuntimeState state {TQueryOptions(), TQueryGlobals()};
+    ASSERT_TRUE(reader->init(&state).ok());
+
+    std::vector<format::ColumnDefinition> schema;
+    ASSERT_TRUE(reader->get_schema(&schema).ok());
+    ASSERT_EQ(schema.size(), 1);
+
+    auto request = std::make_shared<format::FileScanRequest>();
+    request->predicate_columns = {field_projection(0)};
+    request->non_predicate_columns = {field_projection(0)};
+    request->local_positions.emplace(format::LocalColumnId(0), 
format::LocalIndex(0));
+    request->conjuncts.push_back(
+            
VExprContext::create_shared(std::make_shared<NullableInt32GreaterThanExpr>(
+                    0, ConditionCacheContext::GRANULE_SIZE)));
+    ASSERT_TRUE(reader->open(request).ok());
+
+    auto ctx = std::make_shared<ConditionCacheContext>();
+    ctx->is_hit = true;
+    ctx->filter_result =
+            std::make_shared<std::vector<bool>>(std::vector<bool> {false, 
true, false});
+    reader->set_condition_cache_context(ctx);
+
+    int injection_count = 0;
+    ScopedDebugPoint debug_point(
+            
"OrcReader._skip_condition_cache_false_granules.before_seek_to_row", [&]() {
+                ++injection_count;
+                io_ctx->should_stop = true;
+                throw ::orc::ParseError("stop");
+            });
+
+    Block block = build_file_block(schema);
+    size_t rows = 123;
+    bool eof = false;
+    auto status = reader->get_block(&block, &rows, &eof);
+    EXPECT_EQ(injection_count, 1);
+    ASSERT_TRUE(status.ok()) << status;
+    EXPECT_TRUE(eof);
+    EXPECT_EQ(rows, 0);
+    EXPECT_EQ(block.rows(), 0);
+}
+
 TEST_F(NewOrcReaderTest, ConditionCacheHitHandlesSplitWithoutSelectedStripe) {
     const auto multi_stripe_file_path = (_test_dir / 
"condition_cache_empty_split.orc").string();
     write_multi_stripe_orc_int_file(multi_stripe_file_path);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to