This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.1 by this push:
new 367b8dfa750 branch-4.1: [fix](orc) handle cancellation during
condition cache seek #67141 (#67321)
367b8dfa750 is described below
commit 367b8dfa75024371da036d7cf61442798967bd40
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Mon Aug 31 19:03:11 2026 +0800
branch-4.1: [fix](orc) handle cancellation during condition cache seek
#67141 (#67321)
Cherry-picked from #67141
Co-authored-by: Gabriel <[email protected]>
---
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 8154f22266a..868f451963f 100644
--- a/be/src/format_v2/orc/orc_reader.cpp
+++ b/be/src/format_v2/orc/orc_reader.cpp
@@ -1865,6 +1865,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;
@@ -2053,11 +2055,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 e98d0dec74d..1884afaf73c 100644
--- a/be/test/format_v2/orc/orc_reader_test.cpp
+++ b/be/test/format_v2/orc/orc_reader_test.cpp
@@ -6113,6 +6113,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]