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 0f73bd6df2d [refactor](be) Use column check helper for type casts 
(#63946)
0f73bd6df2d is described below

commit 0f73bd6df2d74e23acf1f5a980d239c102ec07a1
Author: Mryange <[email protected]>
AuthorDate: Wed Jun 3 12:02:46 2026 +0800

    [refactor](be) Use column check helper for type casts (#63946)
    
    ### What problem does this PR solve?
    
    Problem Summary: Replace direct typeid_cast usage for Doris column type
    checks with the column-specific check_and_get_column helper. This keeps
    column downcast checks consistent across core column code, expression
    evaluation, storage segment code, and related table reader tests without
    changing behavior.
    
    ### Release note
    
    None
    
    ### Check List (For Author)
    
    - Test <!-- At least one of them must be included. -->
        - [ ] Regression test
        - [ ] Unit Test
        - [ ] Manual test (add detailed scripts or steps below)
        - [ ] No need to test or manual test. Explain why:
    - [ ] This is a refactor/code format and no logic has been changed.
            - [ ] Previous test can cover this change.
            - [ ] No code files have been changed.
            - [ ] Other reason <!-- Add your reason?  -->
    
    - Behavior changed:
        - [ ] No.
        - [ ] Yes. <!-- Explain the behavior change -->
    
    - Does this need documentation?
        - [ ] No.
    - [ ] Yes. <!-- Add document PR link here. eg:
    https://github.com/apache/doris-website/pull/1214 -->
    
    ### Check List (For Reviewer who merge this PR)
    
    - [ ] Confirm the release note
    - [ ] Confirm test cases
    - [ ] Confirm document
    - [ ] Add branch pick label <!-- Add branch pick label that this PR
    should merge into -->
---
 be/src/core/column/column_array.cpp                | 63 +++++++++++-----------
 be/src/core/column/column_const.cpp                |  2 +-
 be/src/core/column/column_const.h                  |  2 +-
 be/src/core/column/column_decimal.h                |  2 +-
 be/src/core/column/column_nullable.h               |  2 +-
 be/src/core/column/column_struct.cpp               |  2 +-
 be/src/exprs/function/if.cpp                       |  2 +-
 be/src/exprs/vcondition_expr.cpp                   |  4 +-
 .../storage/segment/row_binlog_segment_writer.cpp  |  4 +-
 be/src/storage/segment/segment_iterator.cpp        |  6 +--
 be/test/format/table/hive/hive_reader_test.cpp     |  8 +--
 .../format/table/iceberg/iceberg_reader_test.cpp   |  8 +--
 12 files changed, 55 insertions(+), 50 deletions(-)

diff --git a/be/src/core/column/column_array.cpp 
b/be/src/core/column/column_array.cpp
index 534bdf8e4d6..604c4694853 100644
--- a/be/src/core/column/column_array.cpp
+++ b/be/src/core/column/column_array.cpp
@@ -50,7 +50,8 @@ namespace doris {
 namespace {
 
 const ColumnArray::ColumnOffsets& check_array_offsets_column(const IColumn& 
offsets_column) {
-    const auto* offsets_concrete = typeid_cast<const 
ColumnArray::ColumnOffsets*>(&offsets_column);
+    const auto* offsets_concrete =
+            check_and_get_column<ColumnArray::ColumnOffsets>(&offsets_column);
     if (!offsets_concrete) {
         throw doris::Exception(ErrorCode::INTERNAL_ERROR, "offsets_column must 
be a ColumnUInt64");
         __builtin_unreachable();
@@ -851,35 +852,35 @@ size_t filter_generic_inplace(const Filter& filter, 
IColumn& src_data, ColumnOff
 ColumnArrayDataOffsets filter_return_new_dispatch(const Filter& filt, ssize_t 
result_size_hint,
                                                   const ColumnPtr& data,
                                                   const ColumnOffsets* 
offsets) {
-    if (typeid_cast<const ColumnUInt8*>(data.get()))
+    if (check_and_get_column<ColumnUInt8>(data.get()))
         return filter_number_return_new<TYPE_BOOLEAN>(filt, result_size_hint, 
data, offsets);
-    if (typeid_cast<const ColumnInt8*>(data.get()))
+    if (check_and_get_column<ColumnInt8>(data.get()))
         return filter_number_return_new<TYPE_TINYINT>(filt, result_size_hint, 
data, offsets);
-    if (typeid_cast<const ColumnInt16*>(data.get()))
+    if (check_and_get_column<ColumnInt16>(data.get()))
         return filter_number_return_new<TYPE_SMALLINT>(filt, result_size_hint, 
data, offsets);
-    if (typeid_cast<const ColumnInt32*>(data.get()))
+    if (check_and_get_column<ColumnInt32>(data.get()))
         return filter_number_return_new<TYPE_INT>(filt, result_size_hint, 
data, offsets);
-    if (typeid_cast<const ColumnInt64*>(data.get()))
+    if (check_and_get_column<ColumnInt64>(data.get()))
         return filter_number_return_new<TYPE_BIGINT>(filt, result_size_hint, 
data, offsets);
-    if (typeid_cast<const ColumnFloat32*>(data.get()))
+    if (check_and_get_column<ColumnFloat32>(data.get()))
         return filter_number_return_new<TYPE_FLOAT>(filt, result_size_hint, 
data, offsets);
-    if (typeid_cast<const ColumnFloat64*>(data.get()))
+    if (check_and_get_column<ColumnFloat64>(data.get()))
         return filter_number_return_new<TYPE_DOUBLE>(filt, result_size_hint, 
data, offsets);
-    if (typeid_cast<const ColumnDate*>(data.get()))
+    if (check_and_get_column<ColumnDate>(data.get()))
         return filter_number_return_new<TYPE_DATE>(filt, result_size_hint, 
data, offsets);
-    if (typeid_cast<const ColumnDateV2*>(data.get()))
+    if (check_and_get_column<ColumnDateV2>(data.get()))
         return filter_number_return_new<TYPE_DATEV2>(filt, result_size_hint, 
data, offsets);
-    if (typeid_cast<const ColumnDateTime*>(data.get()))
+    if (check_and_get_column<ColumnDateTime>(data.get()))
         return filter_number_return_new<TYPE_DATETIME>(filt, result_size_hint, 
data, offsets);
-    if (typeid_cast<const ColumnDateTimeV2*>(data.get()))
+    if (check_and_get_column<ColumnDateTimeV2>(data.get()))
         return filter_number_return_new<TYPE_DATETIMEV2>(filt, 
result_size_hint, data, offsets);
-    if (typeid_cast<const ColumnTimeStampTz*>(data.get()))
+    if (check_and_get_column<ColumnTimeStampTz>(data.get()))
         return filter_number_return_new<TYPE_TIMESTAMPTZ>(filt, 
result_size_hint, data, offsets);
-    if (typeid_cast<const ColumnTimeV2*>(data.get()))
+    if (check_and_get_column<ColumnTimeV2>(data.get()))
         return filter_number_return_new<TYPE_TIMEV2>(filt, result_size_hint, 
data, offsets);
-    if (typeid_cast<const ColumnIPv4*>(data.get()))
+    if (check_and_get_column<ColumnIPv4>(data.get()))
         return filter_number_return_new<TYPE_IPV4>(filt, result_size_hint, 
data, offsets);
-    if (typeid_cast<const ColumnString*>(data.get()))
+    if (check_and_get_column<ColumnString>(data.get()))
         return filter_string_return_new(filt, result_size_hint, data, offsets);
     return filter_generic_return_new(filt, result_size_hint, data, offsets);
 }
@@ -917,33 +918,33 @@ ColumnPtr ColumnArray::filter(const Filter& filt, ssize_t 
result_size_hint) cons
 // In order not to destroy the original logic, the original logic is still 
retained here.
 size_t filter_inplace_dispatch(const Filter& filter, IColumn& src_data,
                                ColumnOffsets& src_offsets) {
-    if (typeid_cast<ColumnUInt8*>(&src_data))
+    if (check_and_get_column<ColumnUInt8>(&src_data))
         return filter_number_inplace<TYPE_BOOLEAN>(filter, src_data, 
src_offsets);
-    if (typeid_cast<ColumnInt8*>(&src_data))
+    if (check_and_get_column<ColumnInt8>(&src_data))
         return filter_number_inplace<TYPE_TINYINT>(filter, src_data, 
src_offsets);
-    if (typeid_cast<ColumnInt16*>(&src_data))
+    if (check_and_get_column<ColumnInt16>(&src_data))
         return filter_number_inplace<TYPE_SMALLINT>(filter, src_data, 
src_offsets);
-    if (typeid_cast<ColumnInt32*>(&src_data))
+    if (check_and_get_column<ColumnInt32>(&src_data))
         return filter_number_inplace<TYPE_INT>(filter, src_data, src_offsets);
-    if (typeid_cast<ColumnInt64*>(&src_data))
+    if (check_and_get_column<ColumnInt64>(&src_data))
         return filter_number_inplace<TYPE_BIGINT>(filter, src_data, 
src_offsets);
-    if (typeid_cast<ColumnFloat32*>(&src_data))
+    if (check_and_get_column<ColumnFloat32>(&src_data))
         return filter_number_inplace<TYPE_FLOAT>(filter, src_data, 
src_offsets);
-    if (typeid_cast<ColumnFloat64*>(&src_data))
+    if (check_and_get_column<ColumnFloat64>(&src_data))
         return filter_number_inplace<TYPE_DOUBLE>(filter, src_data, 
src_offsets);
-    if (typeid_cast<ColumnDate*>(&src_data))
+    if (check_and_get_column<ColumnDate>(&src_data))
         return filter_number_inplace<TYPE_DATE>(filter, src_data, src_offsets);
-    if (typeid_cast<ColumnDateV2*>(&src_data))
+    if (check_and_get_column<ColumnDateV2>(&src_data))
         return filter_number_inplace<TYPE_DATEV2>(filter, src_data, 
src_offsets);
-    if (typeid_cast<ColumnDateTime*>(&src_data))
+    if (check_and_get_column<ColumnDateTime>(&src_data))
         return filter_number_inplace<TYPE_DATETIME>(filter, src_data, 
src_offsets);
-    if (typeid_cast<ColumnDateTimeV2*>(&src_data))
+    if (check_and_get_column<ColumnDateTimeV2>(&src_data))
         return filter_number_inplace<TYPE_DATETIMEV2>(filter, src_data, 
src_offsets);
-    if (typeid_cast<ColumnTimeStampTz*>(&src_data))
+    if (check_and_get_column<ColumnTimeStampTz>(&src_data))
         return filter_number_inplace<TYPE_TIMESTAMPTZ>(filter, src_data, 
src_offsets);
-    if (typeid_cast<ColumnTimeV2*>(&src_data))
+    if (check_and_get_column<ColumnTimeV2>(&src_data))
         return filter_number_inplace<TYPE_TIMEV2>(filter, src_data, 
src_offsets);
-    if (typeid_cast<ColumnIPv4*>(&src_data))
+    if (check_and_get_column<ColumnIPv4>(&src_data))
         return filter_number_inplace<TYPE_IPV4>(filter, src_data, src_offsets);
     return filter_generic_inplace(filter, src_data, src_offsets);
 }
@@ -953,7 +954,7 @@ size_t ColumnArray::filter(const Filter& filter) {
         return 0;
     }
 
-    if (auto* nullable_data_column = typeid_cast<ColumnNullable*>(data.get())) 
{
+    if (auto* nullable_data_column = 
check_and_get_column<ColumnNullable>(data.get())) {
         const auto result_size = filter_arrays_impl_only_data(
                 nullable_data_column->get_null_map_data(), get_offsets(), 
filter);
 
diff --git a/be/src/core/column/column_const.cpp 
b/be/src/core/column/column_const.cpp
index 7688f5c7a72..be719ef7350 100644
--- a/be/src/core/column/column_const.cpp
+++ b/be/src/core/column/column_const.cpp
@@ -35,7 +35,7 @@ namespace doris {
 
 ColumnPtr squash_const(const ColumnPtr& col) {
     ColumnPtr res = col;
-    while (const auto* c = typeid_cast<const ColumnConst*>(res.get())) {
+    while (const auto* c = check_and_get_column<ColumnConst>(res.get())) {
         res = c->get_data_column_ptr();
     }
     return res;
diff --git a/be/src/core/column/column_const.h 
b/be/src/core/column/column_const.h
index b213aeda0ff..bda7ea13fb1 100644
--- a/be/src/core/column/column_const.h
+++ b/be/src/core/column/column_const.h
@@ -264,7 +264,7 @@ public:
     void for_each_subcolumn(ColumnCallback callback) override { 
callback(data); }
 
     bool structure_equals(const IColumn& rhs) const override {
-        if (const auto* rhs_concrete = typeid_cast<const ColumnConst*>(&rhs)) {
+        if (const auto* rhs_concrete = 
check_and_get_column<ColumnConst>(&rhs)) {
             return data->structure_equals(*rhs_concrete->data);
         }
         return false;
diff --git a/be/src/core/column/column_decimal.h 
b/be/src/core/column/column_decimal.h
index 29f44a55f07..3c89bd3d77b 100644
--- a/be/src/core/column/column_decimal.h
+++ b/be/src/core/column/column_decimal.h
@@ -204,7 +204,7 @@ public:
     MutableColumnPtr permute(const IColumn::Permutation& perm, size_t limit) 
const override;
 
     bool structure_equals(const IColumn& rhs) const override {
-        if (auto rhs_concrete = typeid_cast<const ColumnDecimal<T>*>(&rhs))
+        if (auto rhs_concrete = check_and_get_column<ColumnDecimal<T>>(&rhs))
             return scale == rhs_concrete->scale;
         return false;
     }
diff --git a/be/src/core/column/column_nullable.h 
b/be/src/core/column/column_nullable.h
index 73bab4ff156..bf924fcb2ec 100644
--- a/be/src/core/column/column_nullable.h
+++ b/be/src/core/column/column_nullable.h
@@ -261,7 +261,7 @@ public:
     }
 
     bool structure_equals(const IColumn& rhs) const override {
-        if (const auto* rhs_nullable = typeid_cast<const 
ColumnNullable*>(&rhs)) {
+        if (const auto* rhs_nullable = 
check_and_get_column<ColumnNullable>(&rhs)) {
             return 
_nested_column->structure_equals(*rhs_nullable->_nested_column);
         }
         return false;
diff --git a/be/src/core/column/column_struct.cpp 
b/be/src/core/column/column_struct.cpp
index 57463f6c435..e2a90432c56 100644
--- a/be/src/core/column/column_struct.cpp
+++ b/be/src/core/column/column_struct.cpp
@@ -386,7 +386,7 @@ void ColumnStruct::for_each_subcolumn(ColumnCallback 
callback) {
 }
 
 bool ColumnStruct::structure_equals(const IColumn& rhs) const {
-    if (const auto* rhs_tuple = typeid_cast<const ColumnStruct*>(&rhs)) {
+    if (const auto* rhs_tuple = check_and_get_column<ColumnStruct>(&rhs)) {
         const size_t tuple_size = columns.size();
         if (tuple_size != rhs_tuple->columns.size()) {
             return false;
diff --git a/be/src/exprs/function/if.cpp b/be/src/exprs/function/if.cpp
index d571eae5a91..7e543499ada 100644
--- a/be/src/exprs/function/if.cpp
+++ b/be/src/exprs/function/if.cpp
@@ -240,7 +240,7 @@ public:
             return Status::OK();
         }
 
-        const auto* cond_col = typeid_cast<const 
ColumnUInt8*>(arg_cond.column.get());
+        const auto* cond_col = 
check_and_get_column<ColumnUInt8>(arg_cond.column.get());
         const ColumnConst* cond_const_col =
                 check_and_get_column_const<ColumnUInt8>(arg_cond.column.get());
 
diff --git a/be/src/exprs/vcondition_expr.cpp b/be/src/exprs/vcondition_expr.cpp
index 13e196a5e0b..7ef8ae98ae2 100644
--- a/be/src/exprs/vcondition_expr.cpp
+++ b/be/src/exprs/vcondition_expr.cpp
@@ -194,7 +194,7 @@ Status VectorizedIfExpr::execute_for_null_then_else(Block& 
block,
         return Status::OK();
     }
 
-    const auto* cond_col = typeid_cast<const 
ColumnUInt8*>(arg_cond.column.get());
+    const auto* cond_col = 
check_and_get_column<ColumnUInt8>(arg_cond.column.get());
     const ColumnConst* cond_const_col =
             check_and_get_column_const<ColumnUInt8>(arg_cond.column.get());
 
@@ -781,4 +781,4 @@ Status 
VectorizedCoalesceExpr::execute_column_impl(VExprContext* context, const
     return Status::OK();
 }
 
-} // namespace doris
\ No newline at end of file
+} // namespace doris
diff --git a/be/src/storage/segment/row_binlog_segment_writer.cpp 
b/be/src/storage/segment/row_binlog_segment_writer.cpp
index ccfc53d9fe9..2cc23fc884b 100644
--- a/be/src/storage/segment/row_binlog_segment_writer.cpp
+++ b/be/src/storage/segment/row_binlog_segment_writer.cpp
@@ -312,7 +312,7 @@ Status RowBinlogSegmentWriter::_fill_binlog_columns(size_t 
num_rows,
         // wrong op only happens when partial-update, it will be fixed by 
delete bitmap when publish
         const FieldType op_col_type = 
_tablet_schema->column(binlog_cids[1]).type();
         IColumn* op_col_ptr = binlog_prefix_columns[1].get();
-        auto* op_nullable_column = typeid_cast<ColumnNullable*>(op_col_ptr);
+        auto* op_nullable_column = 
check_and_get_column<ColumnNullable>(op_col_ptr);
         IColumn* op_nested_column = op_nullable_column != nullptr
                                             ? 
&op_nullable_column->get_nested_column()
                                             : op_col_ptr;
@@ -329,7 +329,7 @@ Status RowBinlogSegmentWriter::_fill_binlog_columns(size_t 
num_rows,
         // we can't get correct timestamp when commit
         IColumn* ts_col_ptr = binlog_prefix_columns[2].get();
         auto timestamp = UnixMillis();
-        auto* ts_nullable_column = typeid_cast<ColumnNullable*>(ts_col_ptr);
+        auto* ts_nullable_column = 
check_and_get_column<ColumnNullable>(ts_col_ptr);
         if (ts_nullable_column != nullptr) {
             assert_cast<ColumnInt64*>(&ts_nullable_column->get_nested_column())
                     ->insert_many_vals(timestamp, num_rows);
diff --git a/be/src/storage/segment/segment_iterator.cpp 
b/be/src/storage/segment/segment_iterator.cpp
index e81b523a94c..dc6930777f5 100644
--- a/be/src/storage/segment/segment_iterator.cpp
+++ b/be/src/storage/segment/segment_iterator.cpp
@@ -2566,8 +2566,8 @@ void SegmentIterator::_update_tso_col_if_needed(const 
std::vector<ColumnId>& col
 
     if (_is_pred_column[tso_col_idx]) {
         // Nullable predicate column is represented as 
ColumnNullable(predicate_col)
-        if (auto* tso_nullable =
-                    
typeid_cast<ColumnNullable*>(_current_return_columns[tso_col_idx].get())) {
+        if (auto* tso_nullable = check_and_get_column<ColumnNullable>(
+                    _current_return_columns[tso_col_idx].get())) {
             _current_return_columns[tso_col_idx]->clear();
             auto value = commit_time;
             for (size_t j = 0; j < num_rows; j++) {
@@ -2592,7 +2592,7 @@ void SegmentIterator::_update_tso_col_if_needed(const 
std::vector<ColumnId>& col
     auto column = Schema::get_data_type_ptr(*column_desc)->create_column();
     DCHECK(column_desc->type() == FieldType::OLAP_FIELD_TYPE_BIGINT);
 
-    if (auto* tso_nullable = typeid_cast<ColumnNullable*>(column.get())) {
+    if (auto* tso_nullable = 
check_and_get_column<ColumnNullable>(column.get())) {
         auto* col_ptr = 
assert_cast<ColumnInt64*>(&tso_nullable->get_nested_column());
         for (size_t j = 0; j < num_rows; j++) {
             col_ptr->insert_value(commit_time);
diff --git a/be/test/format/table/hive/hive_reader_test.cpp 
b/be/test/format/table/hive/hive_reader_test.cpp
index 7746cbffa60..31932c2e9c2 100644
--- a/be/test/format/table/hive/hive_reader_test.cpp
+++ b/be/test/format/table/hive/hive_reader_test.cpp
@@ -413,7 +413,8 @@ protected:
                     EXPECT_GT(col->size(), 0) << name << " column/subcolumn 
size should be > 0";
 
                     // Check if it's a nullable column
-                    if (const auto* nullable_col = typeid_cast<const 
ColumnNullable*>(col.get())) {
+                    if (const auto* nullable_col =
+                                
check_and_get_column<ColumnNullable>(col.get())) {
                         auto nested_type =
                                 assert_cast<const 
DataTypeNullable*>(type.get())->get_nested_type();
 
@@ -430,7 +431,8 @@ protected:
                                           nested_name, depth + 
(is_complex_type ? 1 : 0));
                     }
                     // Check if it's a struct column
-                    else if (const auto* struct_col = typeid_cast<const 
ColumnStruct*>(col.get())) {
+                    else if (const auto* struct_col =
+                                     
check_and_get_column<ColumnStruct>(col.get())) {
                         auto struct_type = assert_cast<const 
DataTypeStruct*>(type.get());
                         for (size_t i = 0; i < struct_col->tuple_size(); ++i) {
                             std::string field_name = 
struct_type->get_element_name(i);
@@ -440,7 +442,7 @@ protected:
                         }
                     }
                     // Check if it's an array column
-                    else if (const auto* array_col = typeid_cast<const 
ColumnArray*>(col.get())) {
+                    else if (const auto* array_col = 
check_and_get_column<ColumnArray>(col.get())) {
                         auto array_type = assert_cast<const 
DataTypeArray*>(type.get());
                         auto element_type = array_type->get_nested_type();
                         print_column_rows(array_col->get_data_ptr(), 
element_type, name + ".data",
diff --git a/be/test/format/table/iceberg/iceberg_reader_test.cpp 
b/be/test/format/table/iceberg/iceberg_reader_test.cpp
index fb35b78c617..c2618597312 100644
--- a/be/test/format/table/iceberg/iceberg_reader_test.cpp
+++ b/be/test/format/table/iceberg/iceberg_reader_test.cpp
@@ -473,7 +473,8 @@ protected:
                     EXPECT_GT(col->size(), 0) << name << " column/subcolumn 
size should be > 0";
 
                     // Check if it's a nullable column
-                    if (const auto* nullable_col = typeid_cast<const 
ColumnNullable*>(col.get())) {
+                    if (const auto* nullable_col =
+                                
check_and_get_column<ColumnNullable>(col.get())) {
                         auto nested_type =
                                 assert_cast<const 
DataTypeNullable*>(type.get())->get_nested_type();
 
@@ -490,7 +491,8 @@ protected:
                                           nested_name, depth + 
(is_complex_type ? 1 : 0));
                     }
                     // Check if it's a struct column
-                    else if (const auto* struct_col = typeid_cast<const 
ColumnStruct*>(col.get())) {
+                    else if (const auto* struct_col =
+                                     
check_and_get_column<ColumnStruct>(col.get())) {
                         auto struct_type = assert_cast<const 
DataTypeStruct*>(type.get());
                         for (size_t i = 0; i < struct_col->tuple_size(); ++i) {
                             std::string field_name = 
struct_type->get_element_name(i);
@@ -500,7 +502,7 @@ protected:
                         }
                     }
                     // Check if it's an array column
-                    else if (const auto* array_col = typeid_cast<const 
ColumnArray*>(col.get())) {
+                    else if (const auto* array_col = 
check_and_get_column<ColumnArray>(col.get())) {
                         auto array_type = assert_cast<const 
DataTypeArray*>(type.get());
                         auto element_type = array_type->get_nested_type();
                         print_column_rows(array_col->get_data_ptr(), 
element_type, name + ".data",


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

Reply via email to