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

liaoxin01 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 38df92bc209 [fix](scan) Avoid misleading "storage reader" wrapper for 
data/expression errors (#64755)
38df92bc209 is described below

commit 38df92bc209e4bed9492509791ca3ae1bd7c94c3
Author: Xin Liao <[email protected]>
AuthorDate: Thu Jun 25 16:03:45 2026 +0800

    [fix](scan) Avoid misleading "storage reader" wrapper for data/expression 
errors (#64755)
    
    ## Proposed changes
    
    ### Problem
    
    When an `INSERT`/`CTAS` (or any query) hits a data-conversion error
    during scan — e.g. a strict `CAST(... AS BIGINT)` on an empty string
    produced by `regexp_extract`, which returns `INVALID_ARGUMENT parse
    number fail, string: ''` — the user-facing error reads:
    
    ```
    [INVALID_ARGUMENT]parse number fail, string: ''failed to initialize storage 
reader. tablet=421411554, backend=10.228.1.18
    ```
    
    The `failed to initialize storage reader. tablet=...` suffix makes it
    look like the tablet/segment is corrupted or missing, when the real
    cause is a data/expression error.
    
    ### Root cause
    
    `OlapScanner::_open_impl` appended `failed to initialize storage reader.
    tablet=...` to **any** non-OK status returned by `TabletReader::init()`.
    But `init()` does not merely set up objects — the merge reader eagerly
    reads the first block of each rowset (`BlockReader::_init_collect_iter`
    → `VCollectIterator::build_heap` → `Level0Iterator::refresh_current_row`
    → `RowsetReader::next_batch`) to seed the merge heap. Pushed-down
    expressions (`common_expr_ctxs`) are evaluated during that first-block
    read, so a strict-cast failure surfaces inside `init()` and gets wrapped
    with the storage-reader message.
    
    ### Fix
    
    Branch on the error code: only genuine storage-level failures keep the
    `failed to initialize storage reader` wording. For `INVALID_ARGUMENT`
    (data/expression errors) the message stays neutral and explicitly notes
    it is a data/expression error rather than a storage failure, while still
    reporting tablet/backend for locating the node.
    
    This is purely a message/diagnostics change; control flow and the
    returned error code are unchanged. The underlying strict-cast semantics
    issue is tracked separately (see apache/doris#64266).
    
    ## Further comments
    
    No behavior change other than the error text; no new tests added.
---
 be/src/exec/scan/olap_scanner.cpp                                   | 6 ++++--
 .../test_index_compound_directory_fault_injection.groovy            | 5 ++++-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/be/src/exec/scan/olap_scanner.cpp 
b/be/src/exec/scan/olap_scanner.cpp
index 8da4483ea3a..32097681467 100644
--- a/be/src/exec/scan/olap_scanner.cpp
+++ b/be/src/exec/scan/olap_scanner.cpp
@@ -301,8 +301,10 @@ Status OlapScanner::_open_impl(RuntimeState* state) {
 
     auto res = _tablet_reader->init(_tablet_reader_params);
     if (!res.ok()) {
-        res.append("failed to initialize storage reader. tablet=" +
-                   std::to_string(_tablet_reader_params.tablet->tablet_id()) +
+        // init() also runs the eager first-row read that evaluates 
pushed-down expressions,
+        // so res may be a data/expression error rather than a storage 
failure. Keep its own
+        // message and only append the tablet/backend, without a misleading 
storage wording.
+        res.append(". tablet=" + 
std::to_string(_tablet_reader_params.tablet->tablet_id()) +
                    ", backend=" + BackendOptions::get_localhost());
         return res;
     }
diff --git 
a/regression-test/suites/fault_injection_p0/test_index_compound_directory_fault_injection.groovy
 
b/regression-test/suites/fault_injection_p0/test_index_compound_directory_fault_injection.groovy
index ca25f47c88d..a3c90a0a9ae 100644
--- 
a/regression-test/suites/fault_injection_p0/test_index_compound_directory_fault_injection.groovy
+++ 
b/regression-test/suites/fault_injection_p0/test_index_compound_directory_fault_injection.groovy
@@ -178,7 +178,10 @@ suite("test_index_compound_directory_fault_injection", 
"nonConcurrent") {
                 res = sql "select COUNT() from 
${test_index_compound_directory} where request match 'gif'"
                 try_sql("DROP TABLE IF EXISTS 
${test_index_compound_directory}")
             } catch(Exception ex) {
-                assertTrue(ex.toString().contains("failed to initialize 
storage reader"))
+                // _tablet_reader->init() now returns the underlying error 
verbatim and only
+                // appends the tablet/backend context (no longer the misleading
+                // "failed to initialize storage reader" wording).
+                assertTrue(ex.toString().contains("tablet=") && 
ex.toString().contains("backend="))
                 
logger.info("_mock_append_data_error_in_fsindexoutput_flushBuffer,  result: " + 
ex)
             } finally {
                 
GetDebugPoint().disableDebugPointForAllBEs("DorisFSDirectory::FSIndexOutput._mock_append_data_error_in_fsindexoutput_flushBuffer")


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

Reply via email to