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

Mryange 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 2ad56a85edb [refine](column) strong type array and map offsets (#63678)
2ad56a85edb is described below

commit 2ad56a85edb9678b1b033fa3ce2d845bfda834ba
Author: Mryange <[email protected]>
AuthorDate: Mon Jun 1 14:42:32 2026 +0800

    [refine](column) strong type array and map offsets (#63678)
    
    ### What problem does this PR solve?
    
    Array and map offset subcolumns were still stored and exposed through
    generic IColumn pointers, so callers had to repeatedly downcast them
    back to their concrete offset column types. Root cause: the ownership,
    COW mutation, deserialization, and segment reader write-back paths still
    treated these offsets as generic subcolumns, which left the
    strong-typing change incomplete and kept redundant same-type assert_cast
    usage in affected callers and tests. This change promotes ColumnArray
    offsets and ColumnMap offsets_column to typed wrapped pointers, updates
    the typed accessors and generic write-back paths to preserve the
    concrete offset column type, and removes the now-redundant casts in
    array functions, lambda functions, and unit tests. It also cleans up one
    redundant nullable null-map cast uncovered during the BE UT compile.
    ### Release note
    
    None
---
 be/src/core/column/column_array.cpp                | 35 +++++++++++-----
 be/src/core/column/column_array.h                  | 28 +++++++------
 be/src/core/column/column_map.cpp                  | 44 ++++++++++++--------
 be/src/core/column/column_map.h                    | 47 ++++++++++++++--------
 be/src/core/data_type/data_type_array.cpp          |  6 ++-
 be/src/core/data_type/data_type_map.cpp            |  5 ++-
 .../exprs/function/array/function_array_exists.cpp |  3 +-
 .../exprs/function/array/function_array_filter.cpp |  8 +---
 .../function/array/function_array_flatten.cpp      |  4 +-
 .../lambda_function/varray_filter_function.cpp     |  8 +---
 .../exprs/lambda_function/varray_map_function.cpp  |  3 +-
 .../exprs/lambda_function/varray_sort_function.cpp |  4 +-
 be/src/storage/segment/column_reader.cpp           | 25 ++++++++++--
 be/test/core/column/column_array_test.cpp          |  8 ++--
 be/test/core/column/column_map_test.cpp            |  8 ++--
 15 files changed, 145 insertions(+), 91 deletions(-)

diff --git a/be/src/core/column/column_array.cpp 
b/be/src/core/column/column_array.cpp
index 70b219012b6..534bdf8e4d6 100644
--- a/be/src/core/column/column_array.cpp
+++ b/be/src/core/column/column_array.cpp
@@ -58,6 +58,21 @@ const ColumnArray::ColumnOffsets& 
check_array_offsets_column(const IColumn& offs
     return *offsets_concrete;
 }
 
+ColumnArray::ColumnOffsets::Ptr check_array_offsets_column_ptr(const 
ColumnPtr& offsets_column) {
+    return ColumnArray::ColumnOffsets::cast_to_column_ptr(
+            &check_array_offsets_column(*offsets_column));
+}
+
+ColumnArray::ColumnOffsets::MutablePtr assert_mutable_array_offsets(
+        MutableColumnPtr&& offsets_column) {
+    check_array_offsets_column(*offsets_column);
+    auto mutable_offsets = ColumnArray::ColumnOffsets::cast_to_column_mutptr(
+            assert_cast<ColumnArray::ColumnOffsets*, 
TypeCheckOnRelease::DISABLE>(
+                    offsets_column.get()));
+    offsets_column = nullptr;
+    return mutable_offsets;
+}
+
 void validate_array_offsets(const IColumn& nested_column, const IColumn& 
offsets_column) {
     const auto& offsets_concrete = check_array_offsets_column(offsets_column);
     if (!offsets_concrete.empty()) {
@@ -84,7 +99,9 @@ void check_empty_array_data_without_offsets(const IColumn& 
nested_column) {
 } // namespace
 
 ColumnArray::ColumnArray(MutableColumnPtr&& nested_column, MutableColumnPtr&& 
offsets_column)
-        : data(std::move(nested_column)), offsets(std::move(offsets_column)) {
+        : data(std::move(nested_column)) {
+    static_cast<ColumnOffsets::Ptr&>(offsets) =
+            assert_mutable_array_offsets(std::move(offsets_column));
     // TODO(lihangyu) : we need to check the nullable attribute of array's 
data column.
     // but currently ColumnMap<ColumnString, ColumnString> is used to store 
sparse data of variant type,
     // so I temporarily disable this check.
@@ -99,7 +116,7 @@ ColumnArray::ColumnArray(MutableColumnPtr&& nested_column, 
MutableColumnPtr&& of
     // #endif
     check_const_only_in_top_level();
     validate_array_offsets(*static_cast<const IColumn::Ptr&>(data),
-                           *static_cast<const IColumn::Ptr&>(offsets));
+                           *static_cast<const ColumnOffsets::Ptr&>(offsets));
 
     /** NOTE
       * Arrays with constant value are possible and used in implementation of 
higher order functions (see FunctionReplicate).
@@ -110,15 +127,15 @@ ColumnArray::ColumnArray(MutableColumnPtr&& 
nested_column, MutableColumnPtr&& of
 ColumnArray::ColumnArray(MutableColumnPtr&& nested_column) : 
data(std::move(nested_column)) {
     data = data->convert_to_full_column_if_const();
     check_empty_array_data_without_offsets(*data);
-    offsets = ColumnOffsets::create();
+    static_cast<ColumnOffsets::Ptr&>(offsets) = ColumnOffsets::create();
 }
 
 ColumnArray::ColumnArray(SharedTag, ColumnPtr nested_column, ColumnPtr 
offsets_column) {
     static_cast<IColumn::Ptr&>(data) = std::move(nested_column);
-    static_cast<IColumn::Ptr&>(offsets) = std::move(offsets_column);
+    static_cast<ColumnOffsets::Ptr&>(offsets) = 
check_array_offsets_column_ptr(offsets_column);
     check_const_only_in_top_level();
     validate_array_offsets(*static_cast<const IColumn::Ptr&>(data),
-                           *static_cast<const IColumn::Ptr&>(offsets));
+                           *static_cast<const ColumnOffsets::Ptr&>(offsets));
 }
 
 std::string ColumnArray::get_name() const {
@@ -880,7 +897,7 @@ ColumnPtr ColumnArray::filter(const Filter& filt, ssize_t 
result_size_hint) cons
                                      res_null_map->get_data(), filt, 
result_size_hint);
 
         auto src_data = nullable_data_column->get_nested_column_ptr();
-        const auto* src_offsets = assert_cast<const 
ColumnOffsets*>(offsets.get());
+        const auto* src_offsets = offsets.get();
         auto array_of_nested =
                 filter_return_new_dispatch(filt, result_size_hint, src_data, 
src_offsets);
 
@@ -889,7 +906,7 @@ ColumnPtr ColumnArray::filter(const Filter& filt, ssize_t 
result_size_hint) cons
                 array_of_nested.offsets);
     } else {
         // filter offsets
-        const auto* src_offsets = assert_cast<const 
ColumnOffsets*>(offsets.get());
+        const auto* src_offsets = offsets.get();
         auto array_of_nested =
                 filter_return_new_dispatch(filt, result_size_hint, data, 
src_offsets);
         return ColumnArray::create(array_of_nested.data, 
std::move(array_of_nested.offsets));
@@ -941,12 +958,12 @@ size_t ColumnArray::filter(const Filter& filter) {
                 nullable_data_column->get_null_map_data(), get_offsets(), 
filter);
 
         auto& src_data = nullable_data_column->get_nested_column();
-        auto& src_offsets = assert_cast<ColumnOffsets&>(*offsets);
+        auto& src_offsets = *offsets;
         filter_inplace_dispatch(filter, src_data, src_offsets);
         return result_size;
     } else {
         auto& src_data = get_data();
-        auto& src_offsets = assert_cast<ColumnOffsets&>(*offsets);
+        auto& src_offsets = *offsets;
 
         return filter_inplace_dispatch(filter, src_data, src_offsets);
     }
diff --git a/be/src/core/column/column_array.h 
b/be/src/core/column/column_array.h
index 24afb744d19..9c4e37ed794 100644
--- a/be/src/core/column/column_array.h
+++ b/be/src/core/column/column_array.h
@@ -37,6 +37,7 @@
 #include "core/field.h"
 #include "core/string_ref.h"
 #include "core/types.h"
+#include "util/defer_op.h"
 
 class SipHash;
 
@@ -193,24 +194,22 @@ public:
     IColumn& get_data() { return *data; }
     const IColumn& get_data() const { return *data; }
 
-    IColumn& get_offsets_column() { return *offsets; }
-    const IColumn& get_offsets_column() const { return *offsets; }
+    ColumnOffsets& get_offsets_column() { return *offsets; }
+    const ColumnOffsets& get_offsets_column() const { return *offsets; }
 
-    Offsets64& ALWAYS_INLINE get_offsets() {
-        return assert_cast<ColumnOffsets&, 
TypeCheckOnRelease::DISABLE>(*offsets).get_data();
-    }
+    Offsets64& ALWAYS_INLINE get_offsets() { return offsets->get_data(); }
 
-    const Offsets64& ALWAYS_INLINE get_offsets() const {
-        return assert_cast<const ColumnOffsets&, 
TypeCheckOnRelease::DISABLE>(*offsets).get_data();
-    }
+    const Offsets64& ALWAYS_INLINE get_offsets() const { return 
offsets->get_data(); }
 
     bool has_equal_offsets(const ColumnArray& other) const;
 
     const ColumnPtr& get_data_ptr() const { return data; }
     ColumnPtr& get_data_ptr() { return data; }
 
-    const ColumnPtr& get_offsets_ptr() const { return offsets; }
-    ColumnPtr& get_offsets_ptr() { return offsets; }
+    const ColumnOffsets::Ptr& get_offsets_ptr() const {
+        return static_cast<const ColumnOffsets::Ptr&>(offsets);
+    }
+    ColumnOffsets::Ptr& get_offsets_ptr() { return 
static_cast<ColumnOffsets::Ptr&>(offsets); }
 
     size_t ALWAYS_INLINE offset_at(ssize_t i) const { return get_offsets()[i - 
1]; }
     size_t ALWAYS_INLINE size_at(ssize_t i) const {
@@ -218,7 +217,12 @@ public:
     }
 
     void for_each_subcolumn(ColumnCallback callback) override {
-        callback(offsets);
+        IColumn::WrappedPtr 
offsets_column(std::move(static_cast<ColumnOffsets::Ptr&>(offsets)));
+        Defer defer([&] {
+            static_cast<ColumnOffsets::Ptr&>(offsets) =
+                    cast_to_column<ColumnOffsets>(static_cast<const 
IColumn::Ptr&>(offsets_column));
+        });
+        callback(offsets_column);
         callback(data);
     }
 
@@ -265,7 +269,7 @@ private:
     // [2,1,5,9,1]\n[1,2,4] --> data column [2,1,5,9,1,1,2,4], offset[-1] = 0, 
offset[0] = 5, offset[1] = 8
     // [[2,1,5],[9,1]]\n[[1,2]] --> data column [3 column array], offset[-1] = 
0, offset[0] = 2, offset[1] = 3
     IColumn::WrappedPtr data;
-    IColumn::WrappedPtr offsets;
+    ColumnOffsets::WrappedPtr offsets;
 };
 
 } // namespace doris
diff --git a/be/src/core/column/column_map.cpp 
b/be/src/core/column/column_map.cpp
index be984c15727..2d9c266e73a 100644
--- a/be/src/core/column/column_map.cpp
+++ b/be/src/core/column/column_map.cpp
@@ -52,6 +52,18 @@ const ColumnMap::COffsets& check_map_offsets_column(const 
IColumn& offsets_colum
     return *offsets_concrete;
 }
 
+ColumnMap::COffsets::Ptr check_map_offsets_column_ptr(const ColumnPtr& 
offsets_column) {
+    return 
ColumnMap::COffsets::cast_to_column_ptr(&check_map_offsets_column(*offsets_column));
+}
+
+ColumnMap::COffsets::MutablePtr assert_mutable_map_offsets(MutableColumnPtr&& 
offsets_column) {
+    check_map_offsets_column(*offsets_column);
+    auto mutable_offsets = ColumnMap::COffsets::cast_to_column_mutptr(
+            assert_cast<ColumnMap::COffsets*, 
TypeCheckOnRelease::DISABLE>(offsets_column.get()));
+    offsets_column = nullptr;
+    return mutable_offsets;
+}
+
 void validate_map_columns(const IColumn& keys, const IColumn& values, const 
IColumn& offsets) {
     const auto& offsets_concrete = check_map_offsets_column(offsets);
 
@@ -86,21 +98,21 @@ std::string ColumnMap::get_name() const {
 ColumnMap::ColumnMap(MutableColumnPtr&& keys, MutableColumnPtr&& values, 
MutableColumnPtr&& offsets)
         : keys_column(std::move(keys)),
           values_column(std::move(values)),
-          offsets_column(std::move(offsets)) {
+          offsets_column(assert_mutable_map_offsets(std::move(offsets))) {
     check_const_only_in_top_level();
     validate_map_columns(*static_cast<const IColumn::Ptr&>(keys_column),
                          *static_cast<const IColumn::Ptr&>(values_column),
-                         *static_cast<const IColumn::Ptr&>(offsets_column));
+                         *static_cast<const COffsets::Ptr&>(offsets_column));
 }
 
 ColumnMap::ColumnMap(SharedTag, ColumnPtr keys, ColumnPtr values, ColumnPtr 
offsets) {
     static_cast<IColumn::Ptr&>(keys_column) = std::move(keys);
     static_cast<IColumn::Ptr&>(values_column) = std::move(values);
-    static_cast<IColumn::Ptr&>(offsets_column) = std::move(offsets);
+    static_cast<COffsets::Ptr&>(offsets_column) = 
check_map_offsets_column_ptr(offsets);
     check_const_only_in_top_level();
     validate_map_columns(*static_cast<const IColumn::Ptr&>(keys_column),
                          *static_cast<const IColumn::Ptr&>(values_column),
-                         *static_cast<const IColumn::Ptr&>(offsets_column));
+                         *static_cast<const COffsets::Ptr&>(offsets_column));
 }
 
 // todo. here to resize every row map
@@ -547,10 +559,10 @@ void ColumnMap::insert_range_from_ignore_overflow(const 
IColumn& src, size_t sta
 
 ColumnPtr ColumnMap::filter(const Filter& filt, ssize_t result_size_hint) 
const {
     auto k_arr = ColumnArray::create(static_cast<const 
IColumn::Ptr&>(keys_column),
-                                     static_cast<const 
IColumn::Ptr&>(offsets_column))
+                                     static_cast<const 
IColumn::Ptr&>(get_offsets_ptr()))
                          ->filter(filt, result_size_hint);
     auto v_arr = ColumnArray::create(static_cast<const 
IColumn::Ptr&>(values_column),
-                                     static_cast<const 
IColumn::Ptr&>(offsets_column))
+                                     static_cast<const 
IColumn::Ptr&>(get_offsets_ptr()))
                          ->filter(filt, result_size_hint);
     return ColumnMap::create(assert_cast<const 
ColumnArray&>(*k_arr).get_data_ptr(),
                              assert_cast<const 
ColumnArray&>(*v_arr).get_data_ptr(),
@@ -560,7 +572,7 @@ ColumnPtr ColumnMap::filter(const Filter& filt, ssize_t 
result_size_hint) const
 size_t ColumnMap::filter(const Filter& filter) {
     // Move subcolumns out of this ColumnMap to get exclusive ownership, then 
write back.
     auto keys_mut = 
IColumn::mutate(std::move(static_cast<IColumn::Ptr&>(keys_column)));
-    auto offsets_mut = 
IColumn::mutate(std::move(static_cast<IColumn::Ptr&>(offsets_column)));
+    auto offsets_mut = IColumn::mutate(std::move(get_offsets_ptr()));
     auto values_mut = 
IColumn::mutate(std::move(static_cast<IColumn::Ptr&>(values_column)));
     // Clone offsets for values (both keys and values share the same offsets 
structure)
     MutableColumnPtr copied_off = offsets_mut->clone_empty();
@@ -571,19 +583,19 @@ size_t ColumnMap::filter(const Filter& filter) {
     v_arr->filter(filter);
     // Put filtered subcolumns back
     static_cast<IColumn::Ptr&>(keys_column) = k_arr->get_data_ptr();
-    static_cast<IColumn::Ptr&>(offsets_column) = k_arr->get_offsets_ptr();
+    offsets_column = k_arr->get_offsets_ptr();
     static_cast<IColumn::Ptr&>(values_column) = v_arr->get_data_ptr();
-    // Use const access to avoid assert_mutable_ref() on the just-written-back 
offsets_column
-    // (k_arr still holds a ref, so use_count > 1 until k_arr goes out of 
scope)
-    return static_cast<const IColumn::Ptr&>(offsets_column)->size();
+    // Read through a const view because k_arr still shares the 
just-written-back offsets
+    // until it goes out of scope, so mutable WrappedPtr access would hit 
assert_mutable_ref().
+    return static_cast<const COffsets::Ptr&>(offsets_column)->size();
 }
 
 MutableColumnPtr ColumnMap::permute(const Permutation& perm, size_t limit) 
const {
     auto k_arr = ColumnArray::create(static_cast<const 
IColumn::Ptr&>(keys_column),
-                                     static_cast<const 
IColumn::Ptr&>(offsets_column))
+                                     static_cast<const 
IColumn::Ptr&>(get_offsets_ptr()))
                          ->permute(perm, limit);
     auto v_arr = ColumnArray::create(static_cast<const 
IColumn::Ptr&>(values_column),
-                                     static_cast<const 
IColumn::Ptr&>(offsets_column))
+                                     static_cast<const 
IColumn::Ptr&>(get_offsets_ptr()))
                          ->permute(perm, limit);
 
     return ColumnMap::create(assert_cast<const 
ColumnArray&>(*k_arr).get_data_ptr(),
@@ -593,9 +605,9 @@ MutableColumnPtr ColumnMap::permute(const Permutation& 
perm, size_t limit) const
 
 Status ColumnMap::deduplicate_keys(bool recursive) {
     const IColumn& ck = *static_cast<const IColumn::Ptr&>(keys_column);
-    const IColumn& co = *static_cast<const IColumn::Ptr&>(offsets_column);
+    const auto& offsets = static_cast<const ColumnMap*>(this)->get_offsets();
     const auto inner_rows = ck.size();
-    const auto rows = co.size();
+    const auto rows = offsets.size();
 
     if (recursive) {
         const auto& values_ptr = static_cast<const 
IColumn::Ptr&>(values_column);
@@ -651,8 +663,6 @@ Status ColumnMap::deduplicate_keys(bool recursive) {
     auto& new_offsets_data = new_offsets->get_data();
 
     IColumn::Filter filter(inner_rows, 1);
-    const auto& offsets = static_cast<const ColumnMap*>(this)->get_offsets();
-
     Offset64 offset = 0;
     bool has_duplicated_key = false;
 
diff --git a/be/src/core/column/column_map.h b/be/src/core/column/column_map.h
index 1747d9ef17c..f5bb29d8be5 100644
--- a/be/src/core/column/column_map.h
+++ b/be/src/core/column/column_map.h
@@ -43,6 +43,7 @@
 #include "core/string_ref.h"
 #include "core/types.h"
 #include "exec/common/sip_hash.h"
+#include "util/defer_op.h"
 
 class SipHash;
 
@@ -74,9 +75,14 @@ public:
     std::string get_name() const override;
 
     void for_each_subcolumn(ColumnCallback callback) override {
+        IColumn::WrappedPtr 
offsets(std::move(static_cast<COffsets::Ptr&>(offsets_column)));
+        Defer defer([&] {
+            static_cast<COffsets::Ptr&>(offsets_column) =
+                    cast_to_column<COffsets>(static_cast<const 
IColumn::Ptr&>(offsets));
+        });
         callback(keys_column);
         callback(values_column);
-        callback(offsets_column);
+        callback(offsets);
     }
 
     void sanity_check() const override {
@@ -131,18 +137,17 @@ public:
                                "Method replace_column_data is not supported 
for " + get_name());
     }
 
-    ColumnArray::Offsets64& ALWAYS_INLINE get_offsets() {
-        return assert_cast<COffsets&, 
TypeCheckOnRelease::DISABLE>(*offsets_column).get_data();
-    }
+    ColumnArray::Offsets64& ALWAYS_INLINE get_offsets() { return 
offsets_column->get_data(); }
     const ColumnArray::Offsets64& ALWAYS_INLINE get_offsets() const {
-        return assert_cast<const COffsets&, 
TypeCheckOnRelease::DISABLE>(*offsets_column)
-                .get_data();
+        return offsets_column->get_data();
     }
-    IColumn& get_offsets_column() { return *offsets_column; }
-    const IColumn& get_offsets_column() const { return *offsets_column; }
+    COffsets& get_offsets_column() { return *offsets_column; }
+    const COffsets& get_offsets_column() const { return *offsets_column; }
 
-    const ColumnPtr& get_offsets_ptr() const { return offsets_column; }
-    ColumnPtr& get_offsets_ptr() { return offsets_column; }
+    const COffsets::Ptr& get_offsets_ptr() const {
+        return static_cast<const COffsets::Ptr&>(offsets_column);
+    }
+    COffsets::Ptr& get_offsets_ptr() { return 
static_cast<COffsets::Ptr&>(offsets_column); }
 
     size_t ALWAYS_INLINE offset_at(ssize_t i) const { return get_offsets()[i - 
1]; }
 
@@ -179,9 +184,13 @@ public:
     IColumn& get_keys() { return *keys_column; }
 
     const ColumnPtr get_keys_array_ptr() const {
-        return ColumnArray::create(keys_column, offsets_column);
+        return ColumnArray::create(keys_column,
+                                   static_cast<const 
IColumn::Ptr&>(get_offsets_ptr()));
+    }
+    ColumnPtr get_keys_array_ptr() {
+        return ColumnArray::create(keys_column,
+                                   static_cast<const 
IColumn::Ptr&>(get_offsets_ptr()));
     }
-    ColumnPtr get_keys_array_ptr() { return ColumnArray::create(keys_column, 
offsets_column); }
 
     const ColumnPtr& get_values_ptr() const { return values_column; }
     ColumnPtr& get_values_ptr() { return values_column; }
@@ -190,9 +199,13 @@ public:
     IColumn& get_values() { return *values_column; }
 
     const ColumnPtr get_values_array_ptr() const {
-        return ColumnArray::create(values_column, offsets_column);
+        return ColumnArray::create(values_column,
+                                   static_cast<const 
IColumn::Ptr&>(get_offsets_ptr()));
+    }
+    ColumnPtr get_values_array_ptr() {
+        return ColumnArray::create(values_column,
+                                   static_cast<const 
IColumn::Ptr&>(get_offsets_ptr()));
     }
-    ColumnPtr get_values_array_ptr() { return 
ColumnArray::create(values_column, offsets_column); }
 
     size_t ALWAYS_INLINE size_at(ssize_t i) const {
         return get_offsets()[i] - get_offsets()[i - 1];
@@ -239,9 +252,9 @@ public:
 private:
     friend class COWHelper<IColumn, ColumnMap>;
 
-    IColumn::WrappedPtr keys_column;    // nullable
-    IColumn::WrappedPtr values_column;  // nullable
-    IColumn::WrappedPtr offsets_column; // offset
+    IColumn::WrappedPtr keys_column;     // nullable
+    IColumn::WrappedPtr values_column;   // nullable
+    COffsets::WrappedPtr offsets_column; // offset
 
     ColumnMap(MutableColumnPtr&& keys, MutableColumnPtr&& values, 
MutableColumnPtr&& offsets);
     ColumnMap(SharedTag, ColumnPtr keys, ColumnPtr values, ColumnPtr offsets);
diff --git a/be/src/core/data_type/data_type_array.cpp 
b/be/src/core/data_type/data_type_array.cpp
index 38bb9711347..1cd003e4289 100644
--- a/be/src/core/data_type/data_type_array.cpp
+++ b/be/src/core/data_type/data_type_array.cpp
@@ -130,7 +130,11 @@ const char* DataTypeArray::deserialize(const char* buf, 
MutableColumnPtr* column
     // children
     auto nested_column = std::move(*data_column->get_data_ptr()).mutate();
     buf = get_nested_type()->deserialize(buf, &nested_column, be_exec_version);
-    data_column->get_offsets_ptr() = std::move(offsets_column);
+    auto typed_offsets_column = 
ColumnArray::ColumnOffsets::cast_to_column_mutptr(
+            assert_cast<ColumnArray::ColumnOffsets*, 
TypeCheckOnRelease::DISABLE>(
+                    offsets_column.get()));
+    offsets_column = nullptr;
+    data_column->get_offsets_ptr() = std::move(typed_offsets_column);
     data_column->get_data_ptr() = std::move(nested_column);
     return buf;
 }
diff --git a/be/src/core/data_type/data_type_map.cpp 
b/be/src/core/data_type/data_type_map.cpp
index c0292526701..e57950c5ad5 100644
--- a/be/src/core/data_type/data_type_map.cpp
+++ b/be/src/core/data_type/data_type_map.cpp
@@ -140,7 +140,10 @@ const char* DataTypeMap::deserialize(const char* buf, 
MutableColumnPtr* column,
     auto nested_values_column = 
std::move(*map_column->get_values_ptr()).mutate();
     buf = get_key_type()->deserialize(buf, &nested_keys_column, 
be_exec_version);
     buf = get_value_type()->deserialize(buf, &nested_values_column, 
be_exec_version);
-    map_column->get_offsets_ptr() = std::move(offsets_column);
+    auto typed_offsets_column = ColumnMap::COffsets::cast_to_column_mutptr(
+            assert_cast<ColumnMap::COffsets*, 
TypeCheckOnRelease::DISABLE>(offsets_column.get()));
+    offsets_column = nullptr;
+    map_column->get_offsets_ptr() = std::move(typed_offsets_column);
     map_column->get_keys_ptr() = std::move(nested_keys_column);
     map_column->get_values_ptr() = std::move(nested_values_column);
     return buf;
diff --git a/be/src/exprs/function/array/function_array_exists.cpp 
b/be/src/exprs/function/array/function_array_exists.cpp
index a3d5f36e344..9009ba2f755 100644
--- a/be/src/exprs/function/array/function_array_exists.cpp
+++ b/be/src/exprs/function/array/function_array_exists.cpp
@@ -68,8 +68,7 @@ public:
         const auto first_column =
                 
block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
         const ColumnArray& first_col_array = assert_cast<const 
ColumnArray&>(*first_column);
-        const auto& first_off_data = assert_cast<const 
ColumnArray::ColumnOffsets&>(
-                first_col_array.get_offsets_column());
+        const auto& first_off_data = first_col_array.get_offsets_column();
 
         const auto& nested_nullable_column =
                 assert_cast<const 
ColumnNullable&>(*first_col_array.get_data_ptr());
diff --git a/be/src/exprs/function/array/function_array_filter.cpp 
b/be/src/exprs/function/array/function_array_filter.cpp
index 71a1a9a1bf8..9d9329fa010 100644
--- a/be/src/exprs/function/array/function_array_filter.cpp
+++ b/be/src/exprs/function/array/function_array_filter.cpp
@@ -70,16 +70,12 @@ public:
                 
block.get_by_position(arguments[1]).column->convert_to_full_column_if_const();
 
         const ColumnArray& first_col_array = assert_cast<const 
ColumnArray&>(*first_column);
-        const auto& first_off_data =
-                assert_cast<const 
ColumnArray::ColumnOffsets&>(first_col_array.get_offsets_column())
-                        .get_data();
+        const auto& first_off_data = 
first_col_array.get_offsets_column().get_data();
         const auto& first_nested_nullable_column =
                 assert_cast<const 
ColumnNullable&>(*first_col_array.get_data_ptr());
 
         const ColumnArray& second_col_array = assert_cast<const 
ColumnArray&>(*second_column);
-        const auto& second_off_data = assert_cast<const 
ColumnArray::ColumnOffsets&>(
-                                              
second_col_array.get_offsets_column())
-                                              .get_data();
+        const auto& second_off_data = 
second_col_array.get_offsets_column().get_data();
         const auto& second_nested_null_map_data =
                 assert_cast<const 
ColumnNullable&>(*second_col_array.get_data_ptr())
                         .get_null_map_column()
diff --git a/be/src/exprs/function/array/function_array_flatten.cpp 
b/be/src/exprs/function/array/function_array_flatten.cpp
index 3f76bcfb015..83b68b2d648 100644
--- a/be/src/exprs/function/array/function_array_flatten.cpp
+++ b/be/src/exprs/function/array/function_array_flatten.cpp
@@ -62,9 +62,7 @@ public:
         auto* src_data_type_array =
                 assert_cast<const 
DataTypeArray*>(remove_nullable(src_data_type).get());
 
-        auto result_column_offsets = assert_cast<const 
ColumnArray::ColumnOffsets&>(
-                                             
src_column_array_ptr->get_offsets_column())
-                                             .clone();
+        auto result_column_offsets = 
src_column_array_ptr->get_offsets_column().clone();
         auto* offsets = 
assert_cast<ColumnArray::ColumnOffsets*>(result_column_offsets.get())
                                 ->get_data()
                                 .data();
diff --git a/be/src/exprs/lambda_function/varray_filter_function.cpp 
b/be/src/exprs/lambda_function/varray_filter_function.cpp
index 85d45c131de..f8fa7d0f8a8 100644
--- a/be/src/exprs/lambda_function/varray_filter_function.cpp
+++ b/be/src/exprs/lambda_function/varray_filter_function.cpp
@@ -84,9 +84,7 @@ public:
                                              column_array_nullmap.get_data());
         }
         const auto& first_col_array = assert_cast<const 
ColumnArray&>(*first_arg_column);
-        const auto& first_off_data =
-                assert_cast<const 
ColumnArray::ColumnOffsets&>(first_col_array.get_offsets_column())
-                        .get_data();
+        const auto& first_off_data = 
first_col_array.get_offsets_column().get_data();
         const auto& first_nested_nullable_column =
                 assert_cast<const 
ColumnNullable&>(*first_col_array.get_data_ptr());
 
@@ -108,9 +106,7 @@ public:
                                              column_array_nullmap.get_data());
         }
         const auto& second_col_array = assert_cast<const 
ColumnArray&>(*second_arg_column);
-        const auto& second_off_data = assert_cast<const 
ColumnArray::ColumnOffsets&>(
-                                              
second_col_array.get_offsets_column())
-                                              .get_data();
+        const auto& second_off_data = 
second_col_array.get_offsets_column().get_data();
         const auto& second_nested_null_map_data =
                 assert_cast<const 
ColumnNullable&>(*second_col_array.get_data_ptr())
                         .get_null_map_column()
diff --git a/be/src/exprs/lambda_function/varray_map_function.cpp 
b/be/src/exprs/lambda_function/varray_map_function.cpp
index b669830c5bb..c21da9d09d8 100644
--- a/be/src/exprs/lambda_function/varray_map_function.cpp
+++ b/be/src/exprs/lambda_function/varray_map_function.cpp
@@ -157,8 +157,7 @@ public:
             if (i == 0) {
                 nested_array_column_rows = col_array.get_data_ptr()->size();
                 first_array_offsets = col_array.get_offsets_ptr();
-                const auto& off_data = assert_cast<const 
ColumnArray::ColumnOffsets&>(
-                        col_array.get_offsets_column());
+                const auto& off_data = col_array.get_offsets_column();
                 array_column_offset = 
off_data.clone_resized(col_array.get_offsets_column().size());
                 args_info.offsets_ptr = &col_array.get_offsets();
             } else {
diff --git a/be/src/exprs/lambda_function/varray_sort_function.cpp 
b/be/src/exprs/lambda_function/varray_sort_function.cpp
index 29fe56b0476..9a78617625f 100644
--- a/be/src/exprs/lambda_function/varray_sort_function.cpp
+++ b/be/src/exprs/lambda_function/varray_sort_function.cpp
@@ -96,9 +96,7 @@ public:
         }
 
         const auto& col_array = assert_cast<const ColumnArray&>(*arg_column);
-        const auto& off_data =
-                assert_cast<const 
ColumnArray::ColumnOffsets&>(col_array.get_offsets_column())
-                        .get_data();
+        const auto& off_data = col_array.get_offsets_column().get_data();
 
         const auto& nested_nullable_column =
                 assert_cast<const ColumnNullable&>(*col_array.get_data_ptr());
diff --git a/be/src/storage/segment/column_reader.cpp 
b/be/src/storage/segment/column_reader.cpp
index ea6fffe5bc6..de526a432b8 100644
--- a/be/src/storage/segment/column_reader.cpp
+++ b/be/src/storage/segment/column_reader.cpp
@@ -997,7 +997,13 @@ Status MapFileColumnIterator::next_batch(size_t* n, 
MutableColumnPtr& dst, bool*
     auto& column_map = assert_cast<ColumnMap&, TypeCheckOnRelease::DISABLE>(
             dst->is_nullable() ? 
static_cast<ColumnNullable&>(*dst).get_nested_column() : *dst);
     auto column_offsets_ptr = 
IColumn::mutate(std::move(column_map.get_offsets_ptr()));
-    Defer defer_offsets {[&] { column_map.get_offsets_ptr() = 
std::move(column_offsets_ptr); }};
+    Defer defer_offsets {[&] {
+        auto typed_column_offsets_ptr = 
ColumnMap::COffsets::cast_to_column_mutptr(
+                assert_cast<ColumnMap::COffsets*, TypeCheckOnRelease::DISABLE>(
+                        column_offsets_ptr.get()));
+        column_offsets_ptr = nullptr;
+        column_map.get_offsets_ptr() = std::move(typed_column_offsets_ptr);
+    }};
     bool offsets_has_null = false;
     ssize_t start = column_offsets_ptr->size();
     RETURN_IF_ERROR(_offsets_iterator->next_batch(n, column_offsets_ptr, 
&offsets_has_null));
@@ -1084,7 +1090,12 @@ Status MapFileColumnIterator::read_by_rowids(const 
rowid_t* rowids, const size_t
     auto& column_map = assert_cast<ColumnMap&, TypeCheckOnRelease::DISABLE>(
             dst->is_nullable() ? 
static_cast<ColumnNullable&>(*dst).get_nested_column() : *dst);
     auto offsets_ptr = 
IColumn::mutate(std::move(column_map.get_offsets_ptr()));
-    Defer defer_offsets {[&] { column_map.get_offsets_ptr() = 
std::move(offsets_ptr); }};
+    Defer defer_offsets {[&] {
+        auto typed_offsets_ptr = ColumnMap::COffsets::cast_to_column_mutptr(
+                assert_cast<ColumnMap::COffsets*, 
TypeCheckOnRelease::DISABLE>(offsets_ptr.get()));
+        offsets_ptr = nullptr;
+        column_map.get_offsets_ptr() = std::move(typed_offsets_ptr);
+    }};
     auto& offsets = static_cast<ColumnArray::ColumnOffsets&>(*offsets_ptr);
     size_t base = offsets.get_data().empty() ? 0 : offsets.get_data().back();
 
@@ -1781,8 +1792,14 @@ Status ArrayFileColumnIterator::next_batch(size_t* n, 
MutableColumnPtr& dst, boo
             dst->is_nullable() ? 
static_cast<ColumnNullable&>(*dst).get_nested_column() : *dst);
 
     bool offsets_has_null = false;
-    auto column_offsets_ptr = 
IColumn::mutate(std::move(column_array.get_offsets_ptr()));
-    Defer defer_offsets {[&] { column_array.get_offsets_ptr() = 
std::move(column_offsets_ptr); }};
+    auto column_offsets_ptr = 
std::move(*column_array.get_offsets_ptr()).mutate();
+    Defer defer_offsets {[&] {
+        auto typed_column_offsets_ptr = 
ColumnArray::ColumnOffsets::cast_to_column_mutptr(
+                assert_cast<ColumnArray::ColumnOffsets*, 
TypeCheckOnRelease::DISABLE>(
+                        column_offsets_ptr.get()));
+        column_offsets_ptr = nullptr;
+        column_array.get_offsets_ptr() = std::move(typed_column_offsets_ptr);
+    }};
     ssize_t start = column_offsets_ptr->size();
     RETURN_IF_ERROR(_offset_iterator->next_batch(n, column_offsets_ptr, 
&offsets_has_null));
     if (*n == 0) {
diff --git a/be/test/core/column/column_array_test.cpp 
b/be/test/core/column/column_array_test.cpp
index 3af184caccf..bef1cbdca36 100644
--- a/be/test/core/column/column_array_test.cpp
+++ b/be/test/core/column/column_array_test.cpp
@@ -995,8 +995,8 @@ TEST_F(ColumnArrayTest, ArrayTypeTesterase) {
     // std::cout << tmp2.dump_data(0, tmp2.rows());
     auto* column_result = assert_cast<ColumnArray*>(column_res.get());
     auto& column_offsets_res = column_result->get_offsets_column();
-    auto& offset_data_res = assert_cast<ColumnOffset64&>(column_offsets_res);
-    auto& offset_data = assert_cast<ColumnOffset64&>(column_offsets);
+    auto& offset_data_res = column_offsets_res;
+    auto& offset_data = column_offsets;
     auto& column_data_res = assert_cast<ColumnInt32&>(
             
assert_cast<ColumnNullable&>(column_result->get_data()).get_nested_column());
     auto& column_data_origin = assert_cast<ColumnInt32&>(
@@ -1060,8 +1060,8 @@ TEST_F(ColumnArrayTest, ArrayTypeTest2erase) {
 
     auto* column_result = assert_cast<ColumnArray*>(column_res.get());
     auto& column_offsets_res = column_result->get_offsets_column();
-    auto& offset_data_res = assert_cast<ColumnOffset64&>(column_offsets_res);
-    auto& offset_data = assert_cast<ColumnOffset64&>(column_offsets);
+    auto& offset_data_res = column_offsets_res;
+    auto& offset_data = column_offsets;
     auto& column_data_res = assert_cast<ColumnInt32&>(
             
assert_cast<ColumnNullable&>(column_result->get_data()).get_nested_column());
     auto& column_data_origin = assert_cast<ColumnInt32&>(
diff --git a/be/test/core/column/column_map_test.cpp 
b/be/test/core/column/column_map_test.cpp
index 4ac21457eff..9e47be872aa 100644
--- a/be/test/core/column/column_map_test.cpp
+++ b/be/test/core/column/column_map_test.cpp
@@ -105,8 +105,8 @@ TEST_F(ColumnMapTest, MapTypeTesterase) {
     EXPECT_EQ(column_map->size(), 2);
     auto* column_result = assert_cast<ColumnMap*>(column_res.get());
     auto& column_offsets_res = column_result->get_offsets_column();
-    auto& offset_data_res = assert_cast<ColumnOffset64&>(column_offsets_res);
-    auto& offset_data = assert_cast<ColumnOffset64&>(column_offsets);
+    auto& offset_data_res = column_offsets_res;
+    auto& offset_data = column_offsets;
 
     auto& column_data_res = assert_cast<ColumnInt64&>(
             
assert_cast<ColumnNullable&>(assert_cast<ColumnMap&>(*column_res).get_values())
@@ -196,8 +196,8 @@ TEST_F(ColumnMapTest, MapTypeTest2erase) {
     EXPECT_EQ(column_map->size(), 3);
     auto* column_result = assert_cast<ColumnMap*>(column_res.get());
     auto& column_offsets_res = column_result->get_offsets_column();
-    auto& offset_data_res = assert_cast<ColumnOffset64&>(column_offsets_res);
-    auto& offset_data = assert_cast<ColumnOffset64&>(column_offsets);
+    auto& offset_data_res = column_offsets_res;
+    auto& offset_data = column_offsets;
 
     auto& column_data_res = assert_cast<ColumnInt64&>(
             
assert_cast<ColumnNullable&>(assert_cast<ColumnMap&>(*column_res).get_values())


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


Reply via email to