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

Gabriel39 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 ebb13c31799 [fix](be) Avoid abort on absent schema tree columns 
(#67164)
ebb13c31799 is described below

commit ebb13c31799de7c764681ced6288d690c5962790
Author: Socrates <[email protected]>
AuthorDate: Thu Aug 27 15:23:36 2026 +0800

    [fix](be) Avoid abort on absent schema tree columns (#67164)
    
    ### What problem does this PR solve?
    
    Issue Number: None
    
    Related PR: #66835
    
    Problem Summary:
    
    Table-format predicate probes can reference a column that is not
    registered in the schema tree. `StructNode::children_column_exists()`
    assumed every probe had an entry, so an absent key triggered a DCHECK in
    debug builds or `std::out_of_range` in release builds and terminated the
    BE process.
    
    This change treats an unregistered child as unavailable for file-level
    processing while preserving `has_children_column()` for callers that
    need to distinguish an FE/BE schema-contract mismatch from a
    file-missing column. The unit test covers present, known-missing, and
    unregistered children.
    
    ### Release note
    
    Prevent a BE abort when table-format processing probes a column absent
    from the schema tree.
    
    ### Check List (For Author)
    
    - Test:
    - No local BE build or unit test was run per the requested validation
    boundary.
      - `build-support/clang-format.sh` passed with clang-format 16.
      - `build-support/check-format.sh` passed with clang-format 16.
      - `build-support/check-build-hygiene.sh` passed.
      - `git diff --check` passed.
    - Behavior changed: Yes. An unregistered schema-tree child now reports
    unavailable instead of terminating the BE process.
    - Does this need documentation: No
---
 be/src/format/table/table_schema_change_helper.h         | 13 ++++++-------
 be/test/format/table/table_schema_change_helper_test.cpp | 11 +++++++++++
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/be/src/format/table/table_schema_change_helper.h 
b/be/src/format/table/table_schema_change_helper.h
index 24cd989c7f3..8d800044cbd 100644
--- a/be/src/format/table/table_schema_change_helper.h
+++ b/be/src/format/table/table_schema_change_helper.h
@@ -77,11 +77,10 @@ public:
             return nullptr;
         }
 
-        // Presence-only check (does NOT DCHECK). Distinct from 
children_column_exists, which asserts
-        // the key exists and then reports the file-side exists flag. Callers 
use this to reject a
-        // projected column that is absent from the table-side schema tree (an 
FE/BE schema-contract
-        // mismatch) BEFORE calling children_column_exists, turning a would-be 
process abort into a
-        // graceful per-query error.
+        // Presence-only check. Distinct from children_column_exists, which 
reports the file-side
+        // exists flag and also returns false for an unregistered key. Callers 
use this to distinguish
+        // a projected column absent from the table-side schema tree (an FE/BE 
schema-contract mismatch)
+        // from a registered column that is absent from the data file.
         virtual bool has_children_column(std::string table_column_name) const {
             throw std::logic_error(
                     "has_children_column should not be called on base 
TableInfoNode");
@@ -188,8 +187,8 @@ public:
         }
 
         bool children_column_exists(std::string table_column_name) const 
override {
-            DCHECK(children.contains(table_column_name));
-            return children.at(table_column_name).exists;
+            auto child = children.find(table_column_name);
+            return child != children.end() && child->second.exists;
         }
 
         const schema::external::TField* get_missing_column_field(
diff --git a/be/test/format/table/table_schema_change_helper_test.cpp 
b/be/test/format/table/table_schema_change_helper_test.cpp
index 9d42a49c1eb..68cfcf43358 100644
--- a/be/test/format/table/table_schema_change_helper_test.cpp
+++ b/be/test/format/table/table_schema_change_helper_test.cpp
@@ -117,6 +117,17 @@ TEST(PartitionColumnFillerTest, 
FillNullableIntPartitionValue) {
     }
 }
 
+TEST(MockTableSchemaChangeHelper, UnknownStructChildDoesNotExist) {
+    TableSchemaChangeHelper::StructNode root;
+    root.add_children("file_column", "file_column",
+                      std::make_shared<TableSchemaChangeHelper::ScalarNode>());
+    root.add_not_exist_children("missing_file_column");
+
+    EXPECT_TRUE(root.children_column_exists("file_column"));
+    EXPECT_FALSE(root.children_column_exists("missing_file_column"));
+    EXPECT_FALSE(root.children_column_exists("partition_column"));
+}
+
 TEST(MockTableSchemaChangeHelper, OrcNameNoSchemaChange) {
     std::vector<DataTypePtr> data_types;
     std::vector<std::string> column_names;


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

Reply via email to