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 d0536c04c51 [refine](column) use strong-typed ColumnUInt8 for null_map
in ColumnNullable (#63491)
d0536c04c51 is described below
commit d0536c04c510100372be455785866d7daa028c5b
Author: Mryange <[email protected]>
AuthorDate: Tue May 26 15:52:54 2026 +0800
[refine](column) use strong-typed ColumnUInt8 for null_map in
ColumnNullable (#63491)
### What problem does this PR solve?
The null_map column in `ColumnNullable` was stored as a generic
`IColumn::WrappedPtr`, requiring `assert_cast<ColumnUInt8>` at every
call site that accessed it. This had two problems:
1. **Redundant runtime casts**: Every access to `get_null_map_column()`
or `get_null_map_column_ptr()` performed an `assert_cast`, adding
unnecessary overhead on hot paths (filter evaluation, null propagation,
etc.).
2. **Type safety**: The generic `WrappedPtr` type provided no
compile-time guarantee that the null map is always a `ColumnUInt8`,
making it possible to accidentally store a wrong column type.
Root cause: The `_null_map` member was typed as a generic
`IColumn::WrappedPtr` instead of the concrete `ColumnUInt8::WrappedPtr`.
Fix: Change `_null_map` to `ColumnUInt8::WrappedPtr` so the type is
fixed at the member level. The constructor now validates and converts to
`ColumnUInt8::MutablePtr` on entry via a helper
`assert_mutable_null_map()`. All call sites that previously did
`assert_cast<ColumnUInt8>` now get the correct type directly.
### 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.h | 4 +-
be/src/core/column/column_const.h | 2 +-
be/src/core/column/column_map.h | 6 +-
be/src/core/column/column_nullable.cpp | 64 ++++++++++++++--------
be/src/core/column/column_nullable.h | 33 +++++++----
be/src/core/column/column_struct.h | 2 +-
be/src/core/column/column_variant.cpp | 2 +-
be/src/core/column/column_variant.h | 6 +-
be/src/core/cow.h | 5 +-
be/src/exec/operator/table_function_operator.cpp | 9 +--
.../exprs/function/function_always_not_nullable.h | 3 +-
be/src/exprs/function/function_hll.cpp | 3 +-
be/src/exprs/function/function_quantile_state.cpp | 3 +-
be/src/exprs/function/if.cpp | 24 ++++----
.../exprs/lambda_function/varray_map_function.cpp | 5 +-
.../exprs/table_function/python_udtf_function.cpp | 7 +--
be/src/exprs/table_function/udf_table_function.cpp | 7 +--
be/src/exprs/table_function/vexplode.cpp | 7 +--
be/src/exprs/table_function/vexplode_bitmap.cpp | 8 +--
.../exprs/table_function/vexplode_json_object.cpp | 7 +--
be/src/exprs/table_function/vexplode_map.cpp | 7 +--
be/src/exprs/table_function/vexplode_numbers.cpp | 4 +-
be/src/exprs/table_function/vexplode_numbers.h | 13 ++---
be/src/exprs/table_function/vexplode_v2.cpp | 12 ++--
be/src/exprs/table_function/vjson_each.cpp | 6 +-
be/src/exprs/vcase_expr.h | 5 +-
be/src/exprs/vcompound_pred.h | 5 +-
be/src/exprs/vcondition_expr.cpp | 22 +++++---
be/src/storage/segment/column_reader.cpp | 52 +++++++++---------
.../exec/operator/table_function_operator_test.cpp | 3 +-
be/test/exprs/function/function_test_util.cpp | 6 +-
31 files changed, 178 insertions(+), 164 deletions(-)
diff --git a/be/src/core/column/column_array.h
b/be/src/core/column/column_array.h
index 06eb3d2123e..27dfbdc893f 100644
--- a/be/src/core/column/column_array.h
+++ b/be/src/core/column/column_array.h
@@ -266,8 +266,8 @@ public:
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
- WrappedPtr data;
- WrappedPtr offsets;
+ IColumn::WrappedPtr data;
+ IColumn::WrappedPtr offsets;
};
} // namespace doris
diff --git a/be/src/core/column/column_const.h
b/be/src/core/column/column_const.h
index 7f648ece468..cc8b94ff234 100644
--- a/be/src/core/column/column_const.h
+++ b/be/src/core/column/column_const.h
@@ -103,7 +103,7 @@ class ColumnConst final : public COWHelper<IColumn,
ColumnConst> {
private:
friend class COWHelper<IColumn, ColumnConst>;
using Self = ColumnConst;
- WrappedPtr data;
+ IColumn::WrappedPtr data;
size_t s;
ColumnConst(const ColumnPtr& data, size_t s_, bool create_with_empty =
false,
diff --git a/be/src/core/column/column_map.h b/be/src/core/column/column_map.h
index fa67caa654e..3566ab8759d 100644
--- a/be/src/core/column/column_map.h
+++ b/be/src/core/column/column_map.h
@@ -240,9 +240,9 @@ public:
private:
friend class COWHelper<IColumn, ColumnMap>;
- WrappedPtr keys_column; // nullable
- WrappedPtr values_column; // nullable
- WrappedPtr offsets_column; // offset
+ IColumn::WrappedPtr keys_column; // nullable
+ IColumn::WrappedPtr values_column; // nullable
+ IColumn::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/column/column_nullable.cpp
b/be/src/core/column/column_nullable.cpp
index 03674fb0917..119c165c136 100644
--- a/be/src/core/column/column_nullable.cpp
+++ b/be/src/core/column/column_nullable.cpp
@@ -41,6 +41,10 @@ const ColumnUInt8& check_nullable_null_map_column(const
IColumn& null_map) {
return *concrete;
}
+ColumnUInt8::Ptr check_nullable_null_map_column_ptr(const ColumnPtr& null_map)
{
+ return
ColumnUInt8::cast_to_column_ptr(&check_nullable_null_map_column(*null_map));
+}
+
void check_nullable_sizes(const IColumn& nested_column, const IColumn&
null_map) {
const auto& null_map_concrete = check_nullable_null_map_column(null_map);
if (nested_column.size() != null_map_concrete.size()) {
@@ -53,24 +57,36 @@ void check_nullable_sizes(const IColumn& nested_column,
const IColumn& null_map)
} // namespace
+namespace {
+ColumnUInt8::MutablePtr assert_mutable_null_map(MutableColumnPtr&& null_map) {
+ if (is_column_const(*null_map)) [[unlikely]] {
+ throw doris::Exception(ErrorCode::INTERNAL_ERROR,
+ "ColumnNullable cannot have constant null map");
+ }
+ auto mutable_null_map = ColumnUInt8::cast_to_column_mutptr(
+ assert_cast<ColumnUInt8*,
TypeCheckOnRelease::DISABLE>(null_map.get()));
+ null_map = nullptr;
+ return mutable_null_map;
+}
+} // namespace
+
ColumnNullable::ColumnNullable(MutableColumnPtr&& nested_column_,
MutableColumnPtr&& null_map_)
+ : ColumnNullable(std::move(nested_column_),
assert_mutable_null_map(std::move(null_map_))) {
+}
+
+ColumnNullable::ColumnNullable(MutableColumnPtr&& nested_column_,
+ ColumnUInt8::MutablePtr&& null_map_)
: _nested_column(std::move(nested_column_)),
_null_map(std::move(null_map_)) {
check_const_only_in_top_level();
// after convert const column to full column, it may be a nullable column
if (_nested_column->is_nullable()) {
- assert_cast<ColumnNullable&>(*_nested_column)
- .apply_null_map(static_cast<const
ColumnUInt8&>(get_null_map_column()));
- _null_map =
assert_cast<ColumnNullable&>(*_nested_column).get_null_map_column_ptr();
- _nested_column =
assert_cast<ColumnNullable&>(*_nested_column).get_nested_column_ptr();
- }
-
- if (is_column_const(get_null_map_column())) [[unlikely]] {
- throw doris::Exception(ErrorCode::INTERNAL_ERROR,
- "ColumnNullable cannot have constant null map");
- __builtin_unreachable();
+ auto& nested_nullable = assert_cast<ColumnNullable&>(*_nested_column);
+ nested_nullable.apply_null_map(get_null_map_column());
+ _null_map = nested_nullable._null_map;
+ _nested_column = nested_nullable.get_nested_column_ptr();
}
check_nullable_sizes(*static_cast<const IColumn::Ptr&>(_nested_column),
- *static_cast<const IColumn::Ptr&>(_null_map));
+ *static_cast<const ColumnUInt8::Ptr&>(_null_map));
}
ColumnNullable::ColumnNullable(SharedTag, ColumnPtr nested_column_, ColumnPtr
null_map_) {
@@ -78,8 +94,9 @@ ColumnNullable::ColumnNullable(SharedTag, ColumnPtr
nested_column_, ColumnPtr nu
if (const auto* nullable_nested =
check_and_get_column<ColumnNullable>(nested_column_.get())) {
auto merged_null_map = null_map_->clone_empty();
- merged_null_map->insert_range_from(*null_map_, 0, null_map_->size());
- auto& merged_null_map_data =
assert_cast<ColumnUInt8&>(*merged_null_map).get_data();
+ auto merged_null_map_ptr =
assert_mutable_null_map(std::move(merged_null_map));
+ merged_null_map_ptr->insert_range_from(*null_map_, 0,
null_map_->size());
+ auto& merged_null_map_data = merged_null_map_ptr->get_data();
const auto& nested_null_map_data =
nullable_nested->get_null_map_data();
DCHECK_EQ(merged_null_map_data.size(), nested_null_map_data.size());
for (size_t i = 0; i != merged_null_map_data.size(); ++i) {
@@ -87,21 +104,21 @@ ColumnNullable::ColumnNullable(SharedTag, ColumnPtr
nested_column_, ColumnPtr nu
}
static_cast<IColumn::Ptr&>(_nested_column) =
nullable_nested->get_nested_column_ptr();
- static_cast<IColumn::Ptr&>(_null_map) = std::move(merged_null_map);
+ static_cast<ColumnUInt8::Ptr&>(_null_map) =
std::move(merged_null_map_ptr);
} else {
static_cast<IColumn::Ptr&>(_nested_column) = std::move(nested_column_);
- static_cast<IColumn::Ptr&>(_null_map) = std::move(null_map_);
+ static_cast<ColumnUInt8::Ptr&>(_null_map) =
check_nullable_null_map_column_ptr(null_map_);
}
check_const_only_in_top_level();
check_nullable_sizes(*static_cast<const IColumn::Ptr&>(_nested_column),
- *static_cast<const IColumn::Ptr&>(_null_map));
+ *static_cast<const ColumnUInt8::Ptr&>(_null_map));
}
void ColumnNullable::replace_columns(ColumnPtr nested_column, ColumnPtr
null_map) {
check_nullable_sizes(*nested_column, *null_map);
static_cast<IColumn::Ptr&>(_nested_column) = std::move(nested_column);
- static_cast<IColumn::Ptr&>(_null_map) = std::move(null_map);
+ static_cast<ColumnUInt8::Ptr&>(_null_map) =
check_nullable_null_map_column_ptr(null_map);
check_const_only_in_top_level();
}
@@ -178,7 +195,8 @@ void ColumnNullable::update_crc32c_batch(uint32_t*
__restrict hashes,
// before this normalized nested column is written back.
auto nested_mut = std::move(*static_cast<const
IColumn::Ptr&>(_nested_column)).mutate();
nested_mut->replace_column_null_data(real_null_data);
- static_cast<IColumn::Ptr&>(const_cast<WrappedPtr&>(_nested_column)) =
std::move(nested_mut);
+
static_cast<IColumn::Ptr&>(const_cast<IColumn::WrappedPtr&>(_nested_column)) =
+ std::move(nested_mut);
_nested_column->update_crc32c_batch(hashes, nullptr);
} else {
auto s = size();
@@ -412,10 +430,10 @@ void
ColumnNullable::append_data_by_selector(IColumn::MutablePtr& res,
const IColumn::Selector&
selector, size_t begin,
size_t end) const {
auto& res_column = assert_cast<ColumnNullable&>(*res);
- auto res_nested_column = res_column.get_nested_column_ptr();
+ MutableColumnPtr res_nested_column = res_column.get_nested_column_ptr();
get_nested_column().append_data_by_selector(res_nested_column, selector,
begin, end);
- auto res_null_map = res_column.get_null_map_column_ptr();
- get_null_map_column().append_data_by_selector(res_null_map, selector,
begin, end);
+ IColumn::MutablePtr res_null_map_column =
res_column.get_null_map_column_ptr();
+ get_null_map_column().append_data_by_selector(res_null_map_column,
selector, begin, end);
}
void ColumnNullable::pop_back(size_t n) {
@@ -440,8 +458,8 @@ Status ColumnNullable::filter_by_selector(const uint16_t*
sel, size_t sel_size,
auto* nullable_col_ptr = assert_cast<ColumnNullable*>(col_ptr);
// Access the nested column via const path to avoid assert_mutable_ref
(which requires
// exclusive ownership). The output col_ptr was just created, so its
nested column is exclusive.
- IColumn* nest_col_raw = const_cast<IColumn*>(
- static_cast<const
WrappedPtr&>(nullable_col_ptr->_nested_column).get());
+ auto nest_col_raw = const_cast<IColumn*>(
+ static_cast<const
IColumn::WrappedPtr&>(nullable_col_ptr->_nested_column).get());
/// `get_null_map_data` will set `_need_update_has_null` to true
auto& res_nullmap = nullable_col_ptr->get_null_map_data();
diff --git a/be/src/core/column/column_nullable.h
b/be/src/core/column/column_nullable.h
index 769c0a0a05f..371edf8fc63 100644
--- a/be/src/core/column/column_nullable.h
+++ b/be/src/core/column/column_nullable.h
@@ -26,11 +26,13 @@
#include "core/column/column_vector.h"
#include "core/cow.h"
#include "core/data_type/define_primitive_type.h"
+#include "core/data_type/primitive_type.h"
#include "core/field.h"
#include "core/string_ref.h"
#include "core/typeid_cast.h"
#include "core/types.h"
#include "storage/olap_common.h"
+#include "util/defer_op.h"
class SipHash;
@@ -57,6 +59,7 @@ private:
ColumnNullable(MutableColumnPtr&& nested_column_, MutableColumnPtr&&
null_map_);
struct SharedTag {};
ColumnNullable(SharedTag, ColumnPtr nested_column_, ColumnPtr null_map_);
+ ColumnNullable(MutableColumnPtr&& nested_column_,
ColumnUInt8::MutablePtr&& null_map_);
ColumnNullable(const ColumnNullable&) = default;
public:
@@ -68,6 +71,11 @@ public:
return Base::create(SharedTag {}, nested_column_, null_map_);
}
+ static MutablePtr create(MutableColumnPtr&& nested_column_,
+ ColumnUInt8::MutablePtr&& null_map_) {
+ return Base::create(std::move(nested_column_), std::move(null_map_));
+ }
+
template <typename... Args>
static MutablePtr create(Args&&... args)
requires IsMutableColumns<Args...>::value
@@ -246,7 +254,12 @@ public:
void for_each_subcolumn(ColumnCallback callback) override {
callback(_nested_column);
- callback(_null_map);
+
+ IColumn::WrappedPtr
null_map(std::move(static_cast<ColumnUInt8::Ptr&>(_null_map)));
+ Defer defer([&] {
+ _null_map = cast_to_column<ColumnUInt8>(static_cast<const
IColumn::Ptr&>(null_map));
+ });
+ callback(null_map);
}
bool structure_equals(const IColumn& rhs) const override {
@@ -380,16 +393,16 @@ public:
}
// return the column that represents the byte map. if want use null_map,
just call this.
- const ColumnPtr& get_null_map_column_ptr() const { return _null_map; }
- const ColumnUInt8& get_null_map_column() const {
- return assert_cast<const ColumnUInt8&,
TypeCheckOnRelease::DISABLE>(*_null_map);
- }
+ const ColumnUInt8::Ptr& get_null_map_column_ptr() const { return
_null_map; }
+ const ColumnUInt8& get_null_map_column() const { return *_null_map; }
const NullMap& get_null_map_data() const { return
get_null_map_column().get_data(); }
- MutableColumnPtr get_null_map_column_ptr() { return
_null_map->assert_mutable(); }
- ColumnUInt8& get_null_map_column() {
- return assert_cast<ColumnUInt8&,
TypeCheckOnRelease::DISABLE>(*_null_map);
+ ColumnUInt8::MutablePtr get_null_map_column_ptr() {
+ auto null_map = _null_map->assert_mutable();
+ return ColumnUInt8::cast_to_column_mutptr(
+ assert_cast<ColumnUInt8*,
TypeCheckOnRelease::DISABLE>(null_map.get()));
}
+ ColumnUInt8& get_null_map_column() { return *_null_map; }
NullMap& get_null_map_data() { return get_null_map_column().get_data(); }
// push not null value wouldn't change the nullity. no need to update
_has_null
@@ -403,8 +416,8 @@ private:
template <bool negative>
void apply_null_map_impl(const ColumnUInt8& map);
- WrappedPtr _nested_column;
- WrappedPtr _null_map;
+ IColumn::WrappedPtr _nested_column;
+ ColumnUInt8::WrappedPtr _null_map;
};
ColumnPtr make_nullable(const ColumnPtr& column, bool is_nullable = false);
diff --git a/be/src/core/column/column_struct.h
b/be/src/core/column/column_struct.h
index ca77868d056..bee55370b85 100644
--- a/be/src/core/column/column_struct.h
+++ b/be/src/core/column/column_struct.h
@@ -51,7 +51,7 @@ class ColumnStruct final : public COWHelper<IColumn,
ColumnStruct> {
private:
friend class COWHelper<IColumn, ColumnStruct>;
- using TupleColumns = std::vector<WrappedPtr>;
+ using TupleColumns = std::vector<IColumn::WrappedPtr>;
TupleColumns columns;
template <bool positive>
diff --git a/be/src/core/column/column_variant.cpp
b/be/src/core/column/column_variant.cpp
index 37921e26989..88cd501acb3 100644
--- a/be/src/core/column/column_variant.cpp
+++ b/be/src/core/column/column_variant.cpp
@@ -2118,7 +2118,7 @@ void ColumnVariant::clear_sparse_column() {
}
void ColumnVariant::ensure_binary_columns_rows() {
- auto resize_if_empty = [this](WrappedPtr& column) {
+ auto resize_if_empty = [this](IColumn::WrappedPtr& column) {
const auto& const_column = static_cast<const IColumn::Ptr&>(column);
if (const_column->size() == num_rows) {
return;
diff --git a/be/src/core/column/column_variant.h
b/be/src/core/column/column_variant.h
index 1ae92afd54c..1d5c4eed137 100644
--- a/be/src/core/column/column_variant.h
+++ b/be/src/core/column/column_variant.h
@@ -247,7 +247,7 @@ public:
/// Parts of column. Parts should be in increasing order in terms of
subtypes/supertypes.
/// That means that the least common type for i-th prefix is the type
of i-th part
/// and it's the supertype for all type of column from 0 to i-1.
- std::vector<WrappedPtr> data;
+ std::vector<IColumn::WrappedPtr> data;
std::vector<DataTypePtr> data_types;
std::vector<DataTypeSerDeSPtr> data_serdes;
/// Until we insert any non-default field we don't know further
@@ -275,10 +275,10 @@ private:
// It's filled when the number of subcolumns reaches the limit.
// It has type Map(String, String) and stores a map (path, binary
serialized subcolumn value) for each row.
- WrappedPtr serialized_sparse_column = ColumnMap::create(
+ IColumn::WrappedPtr serialized_sparse_column = ColumnMap::create(
ColumnString::create(), ColumnString::create(),
ColumnArray::ColumnOffsets::create());
- WrappedPtr serialized_doc_value_column = ColumnMap::create(
+ IColumn::WrappedPtr serialized_doc_value_column = ColumnMap::create(
ColumnString::create(), ColumnString::create(),
ColumnArray::ColumnOffsets::create());
// if `_max_subcolumns_count == 0`, all subcolumns are materialized.
diff --git a/be/src/core/cow.h b/be/src/core/cow.h
index afa0cab3d5b..7fb4cb4f754 100644
--- a/be/src/core/cow.h
+++ b/be/src/core/cow.h
@@ -351,13 +351,13 @@ protected:
: value(std::forward<std::initializer_list<U>>(arg)) {}
const T* get() const { return value.get(); }
- T* get() { return &value->assert_mutable_ref(); }
+ T* get() { return &static_cast<T&>(value->assert_mutable_ref()); }
const T* operator->() const { return get(); }
T* operator->() { return get(); }
const T& operator*() const { return *value; }
- T& operator*() { return value->assert_mutable_ref(); }
+ T& operator*() { return static_cast<T&>(value->assert_mutable_ref()); }
operator const immutable_ptr<T>&() const { return value; }
operator immutable_ptr<T>&() { return value; }
@@ -419,6 +419,7 @@ public:
static_assert(std::is_base_of_v<doris::IColumn, Base>, "COWHelper only use
in IColumn");
using Ptr = typename Base::template immutable_ptr<Derived>;
using MutablePtr = typename Base::template mutable_ptr<Derived>;
+ using WrappedPtr = typename Base::template chameleon_ptr<Derived>;
#include "common/compile_check_avoid_begin.h"
diff --git a/be/src/exec/operator/table_function_operator.cpp
b/be/src/exec/operator/table_function_operator.cpp
index 397a9754620..bb4f8945359 100644
--- a/be/src/exec/operator/table_function_operator.cpp
+++ b/be/src/exec/operator/table_function_operator.cpp
@@ -282,8 +282,7 @@ Status
TableFunctionLocalState::_get_expanded_block_block_fast_path(
if (out_col->is_nullable()) {
auto* nullable = assert_cast<ColumnNullable*>(out_col.get());
struct_col_ptr =
assert_cast<ColumnStruct*>(nullable->get_nested_column_ptr().get());
- outer_struct_nullmap_ptr =
-
assert_cast<ColumnUInt8*>(nullable->get_null_map_column_ptr().get());
+ outer_struct_nullmap_ptr =
nullable->get_null_map_column_ptr().get();
} else {
struct_col_ptr = assert_cast<ColumnStruct*>(out_col.get());
}
@@ -343,8 +342,7 @@ Status
TableFunctionLocalState::_get_expanded_block_block_fast_path(
val_nullable->get_nested_column_ptr()->insert_range_from(
*_block_fast_path_ctx.nested_col,
segment_ctx.seg_nested_start,
segment_ctx.seg_nested_count);
- auto* val_nullmap =
-
assert_cast<ColumnUInt8*>(val_nullable->get_null_map_column_ptr().get());
+ auto* val_nullmap = val_nullable->get_null_map_column_ptr().get();
auto& val_nullmap_data = val_nullmap->get_data();
const size_t old_size = val_nullmap_data.size();
val_nullmap_data.resize(old_size + segment_ctx.seg_nested_count);
@@ -365,8 +363,7 @@ Status
TableFunctionLocalState::_get_expanded_block_block_fast_path(
out_nullable->get_nested_column_ptr()->insert_range_from(
*_block_fast_path_ctx.nested_col,
segment_ctx.seg_nested_start,
segment_ctx.seg_nested_count);
- auto* nullmap_column =
-
assert_cast<ColumnUInt8*>(out_nullable->get_null_map_column_ptr().get());
+ auto* nullmap_column =
out_nullable->get_null_map_column_ptr().get();
auto& nullmap_data = nullmap_column->get_data();
const size_t old_size = nullmap_data.size();
nullmap_data.resize(old_size + segment_ctx.seg_nested_count);
diff --git a/be/src/exprs/function/function_always_not_nullable.h
b/be/src/exprs/function/function_always_not_nullable.h
index dc9b1eb3073..0f9790fb135 100644
--- a/be/src/exprs/function/function_always_not_nullable.h
+++ b/be/src/exprs/function/function_always_not_nullable.h
@@ -51,8 +51,7 @@ public:
const ColumnNullable* col_nullable = assert_cast<const
ColumnNullable*>(column.get());
const ColumnType* col =
check_and_get_column<ColumnType>(col_nullable->get_nested_column_ptr().get());
- const ColumnUInt8* col_nullmap =
- assert_cast<const
ColumnUInt8*>(col_nullable->get_null_map_column_ptr().get());
+ const ColumnUInt8* col_nullmap =
col_nullable->get_null_map_column_ptr().get();
if (col != nullptr) {
if constexpr (WithReturn) {
diff --git a/be/src/exprs/function/function_hll.cpp
b/be/src/exprs/function/function_hll.cpp
index ec47b07744b..a3e10bdc433 100644
--- a/be/src/exprs/function/function_hll.cpp
+++ b/be/src/exprs/function/function_hll.cpp
@@ -99,8 +99,7 @@ public:
check_and_get_column<ColumnNullable>(column.get())) {
const ColumnHLL* col =
check_and_get_column<ColumnHLL>(col_nullable->get_nested_column_ptr().get());
- const ColumnUInt8* col_nullmap =
- assert_cast<const
ColumnUInt8*>(col_nullable->get_null_map_column_ptr().get());
+ const ColumnUInt8* col_nullmap =
col_nullable->get_null_map_column_ptr().get();
if (col != nullptr) {
Function::vector_nullable(col->get_data(),
col_nullmap->get_data(), column_result);
diff --git a/be/src/exprs/function/function_quantile_state.cpp
b/be/src/exprs/function/function_quantile_state.cpp
index eed78b97da9..4019e84e65e 100644
--- a/be/src/exprs/function/function_quantile_state.cpp
+++ b/be/src/exprs/function/function_quantile_state.cpp
@@ -91,8 +91,7 @@ public:
const NullMap* nullmap = nullptr;
if constexpr (is_nullable) {
col_nullable = assert_cast<const ColumnNullable*>(column.get());
- col_nullmap =
- assert_cast<const
ColumnUInt8*>(col_nullable->get_null_map_column_ptr().get());
+ col_nullmap = col_nullable->get_null_map_column_ptr().get();
col = assert_cast<const
ColumnFloat64*>(col_nullable->get_nested_column_ptr().get());
nullmap = &col_nullmap->get_data();
diff --git a/be/src/exprs/function/if.cpp b/be/src/exprs/function/if.cpp
index d00b0f3edbb..d571eae5a91 100644
--- a/be/src/exprs/function/if.cpp
+++ b/be/src/exprs/function/if.cpp
@@ -361,19 +361,23 @@ public:
// b. create a const_nullmap_column: it's a not nullable column or
a const nullable column, contain a const value
Block temporary_block;
temporary_block.insert(arg_cond);
- auto then_nested_null_map =
- (then_type_is_nullable && !then_column_is_const_nullable)
- ? then_is_nullable->get_null_map_column_ptr()
- :
DataTypeUInt8().create_column_const_with_default_value(
- input_rows_count);
+ ColumnPtr then_nested_null_map;
+ if (then_type_is_nullable && !then_column_is_const_nullable) {
+ then_nested_null_map =
then_is_nullable->get_null_map_column_ptr();
+ } else {
+ then_nested_null_map =
+
DataTypeUInt8().create_column_const_with_default_value(input_rows_count);
+ }
temporary_block.insert({then_nested_null_map,
std::make_shared<DataTypeUInt8>(),
"then_column_null_map"});
- auto else_nested_null_map =
- (else_type_is_nullable && !else_column_is_const_nullable)
- ? else_is_nullable->get_null_map_column_ptr()
- :
DataTypeUInt8().create_column_const_with_default_value(
- input_rows_count);
+ ColumnPtr else_nested_null_map;
+ if (else_type_is_nullable && !else_column_is_const_nullable) {
+ else_nested_null_map =
else_is_nullable->get_null_map_column_ptr();
+ } else {
+ else_nested_null_map =
+
DataTypeUInt8().create_column_const_with_default_value(input_rows_count);
+ }
temporary_block.insert({else_nested_null_map,
std::make_shared<DataTypeUInt8>(),
"else_column_null_map"});
temporary_block.insert(
diff --git a/be/src/exprs/lambda_function/varray_map_function.cpp
b/be/src/exprs/lambda_function/varray_map_function.cpp
index 79fbb5f5dfd..b669830c5bb 100644
--- a/be/src/exprs/lambda_function/varray_map_function.cpp
+++ b/be/src/exprs/lambda_function/varray_map_function.cpp
@@ -146,9 +146,8 @@ public:
->get_nested_type();
// need to union nullmap from all columns
- VectorizedUtils::update_null_map(
- outside_null_map->get_data(),
- assert_cast<const
ColumnUInt8&>(*column_array_nullmap).get_data());
+ VectorizedUtils::update_null_map(outside_null_map->get_data(),
+
column_array_nullmap->get_data());
}
// here is the array column
diff --git a/be/src/exprs/table_function/python_udtf_function.cpp
b/be/src/exprs/table_function/python_udtf_function.cpp
index 4bcd8ae4636..eaaf4d5227a 100644
--- a/be/src/exprs/table_function/python_udtf_function.cpp
+++ b/be/src/exprs/table_function/python_udtf_function.cpp
@@ -195,9 +195,9 @@ void
PythonUDTFFunction::get_same_many_values(MutableColumnPtr& column, int leng
if (_is_nullable) {
auto* nullable_column = assert_cast<ColumnNullable*>(column.get());
auto nested_column = nullable_column->get_nested_column_ptr();
- auto nullmap_column = nullable_column->get_null_map_column_ptr();
+ auto* nullmap_column =
nullable_column->get_null_map_column_ptr().get();
nested_column->insert_many_from(*_array_column_detail.nested_col,
pos, length);
-
assert_cast<ColumnUInt8*>(nullmap_column.get())->insert_many_defaults(length);
+ nullmap_column->insert_many_defaults(length);
} else {
column->insert_many_from(*_array_column_detail.nested_col, pos,
length);
}
@@ -215,8 +215,7 @@ int PythonUDTFFunction::get_value(MutableColumnPtr& column,
int max_step) {
if (_is_nullable) {
auto* nullable_column = assert_cast<ColumnNullable*>(column.get());
auto nested_column = nullable_column->get_nested_column_ptr();
- auto* nullmap_column =
-
assert_cast<ColumnUInt8*>(nullable_column->get_null_map_column_ptr().get());
+ auto* nullmap_column =
nullable_column->get_null_map_column_ptr().get();
nested_column->insert_range_from(*_array_column_detail.nested_col,
pos, max_step);
size_t old_size = nullmap_column->size();
diff --git a/be/src/exprs/table_function/udf_table_function.cpp
b/be/src/exprs/table_function/udf_table_function.cpp
index 414766ef915..67f727ec297 100644
--- a/be/src/exprs/table_function/udf_table_function.cpp
+++ b/be/src/exprs/table_function/udf_table_function.cpp
@@ -161,9 +161,9 @@ void
UDFTableFunction::get_same_many_values(MutableColumnPtr& column, int length
if (_is_nullable) {
auto* nullable_column = assert_cast<ColumnNullable*>(column.get());
auto nested_column = nullable_column->get_nested_column_ptr();
- auto nullmap_column = nullable_column->get_null_map_column_ptr();
+ auto* nullmap_column =
nullable_column->get_null_map_column_ptr().get();
nested_column->insert_many_from(*_array_column_detail.nested_col,
pos, length);
-
assert_cast<ColumnUInt8*>(nullmap_column.get())->insert_many_defaults(length);
+ nullmap_column->insert_many_defaults(length);
} else {
column->insert_many_from(*_array_column_detail.nested_col, pos,
length);
}
@@ -180,8 +180,7 @@ int UDFTableFunction::get_value(MutableColumnPtr& column,
int max_step) {
if (_is_nullable) {
auto* nullable_column = assert_cast<ColumnNullable*>(column.get());
auto nested_column = nullable_column->get_nested_column_ptr();
- auto* nullmap_column =
-
assert_cast<ColumnUInt8*>(nullable_column->get_null_map_column_ptr().get());
+ auto* nullmap_column =
nullable_column->get_null_map_column_ptr().get();
nested_column->insert_range_from(*_array_column_detail.nested_col,
pos, max_step);
size_t old_size = nullmap_column->size();
nullmap_column->resize(old_size + max_step);
diff --git a/be/src/exprs/table_function/vexplode.cpp
b/be/src/exprs/table_function/vexplode.cpp
index 0b8556229a4..efbfdb335fc 100644
--- a/be/src/exprs/table_function/vexplode.cpp
+++ b/be/src/exprs/table_function/vexplode.cpp
@@ -138,8 +138,8 @@ void
VExplodeTableFunction::get_same_many_values(MutableColumnPtr& column, int l
assert_cast<ColumnNullable*>(column.get())
->get_nested_column_ptr()
->insert_many_from(*_detail.nested_col, pos, length);
- assert_cast<ColumnUInt8*>(
-
assert_cast<ColumnNullable*>(column.get())->get_null_map_column_ptr().get())
+ assert_cast<ColumnNullable*>(column.get())
+ ->get_null_map_column_ptr()
->insert_many_defaults(length);
} else {
column->insert_many_from(*_detail.nested_col, pos, length);
@@ -157,8 +157,7 @@ int VExplodeTableFunction::get_value(MutableColumnPtr&
column, int max_step) {
if (_is_nullable) {
auto* nullable_column = assert_cast<ColumnNullable*>(column.get());
auto nested_column = nullable_column->get_nested_column_ptr();
- auto* nullmap_column =
-
assert_cast<ColumnUInt8*>(nullable_column->get_null_map_column_ptr().get());
+ auto* nullmap_column =
nullable_column->get_null_map_column_ptr().get();
nested_column->insert_range_from(*_detail.nested_col, pos,
max_step);
size_t old_size = nullmap_column->size();
nullmap_column->resize(old_size + max_step);
diff --git a/be/src/exprs/table_function/vexplode_bitmap.cpp
b/be/src/exprs/table_function/vexplode_bitmap.cpp
index 80ba79ce9d2..b21f099dde7 100644
--- a/be/src/exprs/table_function/vexplode_bitmap.cpp
+++ b/be/src/exprs/table_function/vexplode_bitmap.cpp
@@ -75,8 +75,8 @@ void
VExplodeBitmapTableFunction::get_same_many_values(MutableColumnPtr& column,
assert_cast<ColumnInt64*>(
assert_cast<ColumnNullable*>(column.get())->get_nested_column_ptr().get())
->insert_many_vals(**_cur_iter, length);
- assert_cast<ColumnUInt8*>(
-
assert_cast<ColumnNullable*>(column.get())->get_null_map_column_ptr().get())
+ assert_cast<ColumnNullable*>(column.get())
+ ->get_null_map_column_ptr()
->insert_many_defaults(length);
} else {
assert_cast<ColumnInt64*>(column.get())->insert_many_vals(**_cur_iter, length);
@@ -114,8 +114,8 @@ int
VExplodeBitmapTableFunction::get_value(MutableColumnPtr& column, int max_ste
if (_is_nullable) {
target = assert_cast<ColumnInt64*>(
assert_cast<ColumnNullable*>(column.get())->get_nested_column_ptr().get());
- assert_cast<ColumnUInt8*>(
-
assert_cast<ColumnNullable*>(column.get())->get_null_map_column_ptr().get())
+ assert_cast<ColumnNullable*>(column.get())
+ ->get_null_map_column_ptr()
->insert_many_defaults(max_step);
} else {
target = assert_cast<ColumnInt64*>(column.get());
diff --git a/be/src/exprs/table_function/vexplode_json_object.cpp
b/be/src/exprs/table_function/vexplode_json_object.cpp
index 0e33c503e38..4611034f082 100644
--- a/be/src/exprs/table_function/vexplode_json_object.cpp
+++ b/be/src/exprs/table_function/vexplode_json_object.cpp
@@ -107,8 +107,8 @@ void
VExplodeJsonObjectTableFunction::get_same_many_values(MutableColumnPtr& col
// make map kv value into struct
ret = assert_cast<ColumnStruct*>(
assert_cast<ColumnNullable*>(column.get())->get_nested_column_ptr().get());
- assert_cast<ColumnUInt8*>(
-
assert_cast<ColumnNullable*>(column.get())->get_null_map_column_ptr().get())
+ assert_cast<ColumnNullable*>(column.get())
+ ->get_null_map_column_ptr()
->insert_many_defaults(length);
} else if (is_column<ColumnStruct>(column.get())) {
ret = assert_cast<ColumnStruct*>(column.get());
@@ -137,8 +137,7 @@ int
VExplodeJsonObjectTableFunction::get_value(MutableColumnPtr& column, int max
auto* nullable_column = assert_cast<ColumnNullable*>(column.get());
struct_column =
assert_cast<ColumnStruct*>(nullable_column->get_nested_column_ptr().get());
- auto* nullmap_column =
-
assert_cast<ColumnUInt8*>(nullable_column->get_null_map_column_ptr().get());
+ auto* nullmap_column =
nullable_column->get_null_map_column_ptr().get();
// here nullmap_column insert max_step many defaults as if
MAP[row_idx] is NULL
// will be not update value, _cur_size = 0, means current_empty;
// so here could insert directly
diff --git a/be/src/exprs/table_function/vexplode_map.cpp
b/be/src/exprs/table_function/vexplode_map.cpp
index 0245eee3156..cff60eaa3d5 100644
--- a/be/src/exprs/table_function/vexplode_map.cpp
+++ b/be/src/exprs/table_function/vexplode_map.cpp
@@ -101,8 +101,8 @@ void
VExplodeMapTableFunction::get_same_many_values(MutableColumnPtr& column, in
// make map kv value into struct
ret = assert_cast<ColumnStruct*>(
assert_cast<ColumnNullable*>(column.get())->get_nested_column_ptr().get());
- assert_cast<ColumnUInt8*>(
-
assert_cast<ColumnNullable*>(column.get())->get_null_map_column_ptr().get())
+ assert_cast<ColumnNullable*>(column.get())
+ ->get_null_map_column_ptr()
->insert_many_defaults(length);
} else if (is_column<ColumnStruct>(column.get())) {
ret = assert_cast<ColumnStruct*>(column.get());
@@ -131,8 +131,7 @@ int VExplodeMapTableFunction::get_value(MutableColumnPtr&
column, int max_step)
auto* nullable_column = assert_cast<ColumnNullable*>(column.get());
struct_column =
assert_cast<ColumnStruct*>(nullable_column->get_nested_column_ptr().get());
- auto* nullmap_column =
-
assert_cast<ColumnUInt8*>(nullable_column->get_null_map_column_ptr().get());
+ auto* nullmap_column =
nullable_column->get_null_map_column_ptr().get();
// here nullmap_column insert max_step many defaults as if
MAP[row_idx] is NULL
// will be not update value, _cur_size = 0, means current_empty;
// so here could insert directly
diff --git a/be/src/exprs/table_function/vexplode_numbers.cpp
b/be/src/exprs/table_function/vexplode_numbers.cpp
index 3746cabd0bb..0f93dec02f1 100644
--- a/be/src/exprs/table_function/vexplode_numbers.cpp
+++ b/be/src/exprs/table_function/vexplode_numbers.cpp
@@ -103,8 +103,8 @@ void
VExplodeNumbersTableFunction::get_same_many_values(MutableColumnPtr& column
assert_cast<ColumnInt32*>(
assert_cast<ColumnNullable*>(column.get())->get_nested_column_ptr().get())
->insert_many_vals(static_cast<int32_t>(_cur_offset),
length);
- assert_cast<ColumnUInt8*>(
-
assert_cast<ColumnNullable*>(column.get())->get_null_map_column_ptr().get())
+ assert_cast<ColumnNullable*>(column.get())
+ ->get_null_map_column_ptr()
->insert_many_defaults(length);
} else {
assert_cast<ColumnInt32*>(column.get())
diff --git a/be/src/exprs/table_function/vexplode_numbers.h
b/be/src/exprs/table_function/vexplode_numbers.h
index 1b715a67d10..9a862b666bb 100644
--- a/be/src/exprs/table_function/vexplode_numbers.h
+++ b/be/src/exprs/table_function/vexplode_numbers.h
@@ -45,11 +45,11 @@ public:
max_step = std::min(max_step, (int)(_cur_size - _cur_offset));
if (_is_const) {
if (_is_nullable) {
- static_cast<ColumnInt32*>(
-
static_cast<ColumnNullable*>(column.get())->get_nested_column_ptr().get())
+ assert_cast<ColumnInt32*>(
+
assert_cast<ColumnNullable*>(column.get())->get_nested_column_ptr().get())
->insert_range_from(*_elements_column, _cur_offset,
max_step);
- static_cast<ColumnUInt8*>(
-
static_cast<ColumnNullable*>(column.get())->get_null_map_column_ptr().get())
+ assert_cast<ColumnNullable*>(column.get())
+ ->get_null_map_column_ptr()
->insert_many_defaults(max_step);
} else {
static_cast<ColumnInt32*>(column.get())
@@ -66,9 +66,8 @@ public:
target =
assert_cast<ColumnInt32*>(assert_cast<ColumnNullable*>(column.get())
->get_nested_column_ptr()
.get());
-
assert_cast<ColumnUInt8*>(assert_cast<ColumnNullable*>(column.get())
-
->get_null_map_column_ptr()
- .get())
+ assert_cast<ColumnNullable*>(column.get())
+ ->get_null_map_column_ptr()
->insert_many_defaults(max_step);
} else {
target = assert_cast<ColumnInt32*>(column.get());
diff --git a/be/src/exprs/table_function/vexplode_v2.cpp
b/be/src/exprs/table_function/vexplode_v2.cpp
index 62a4ab1d66a..e256c2aaa82 100644
--- a/be/src/exprs/table_function/vexplode_v2.cpp
+++ b/be/src/exprs/table_function/vexplode_v2.cpp
@@ -163,8 +163,7 @@ void
VExplodeV2TableFunction::get_same_many_values(MutableColumnPtr& column, int
auto* nullable_column = assert_cast<ColumnNullable*>(column.get());
struct_column =
assert_cast<ColumnStruct*>(nullable_column->get_nested_column_ptr().get());
- auto* nullmap_column =
-
assert_cast<ColumnUInt8*>(nullable_column->get_null_map_column_ptr().get());
+ auto* nullmap_column =
nullable_column->get_null_map_column_ptr().get();
nullmap_column->insert_many_defaults(length);
} else {
@@ -192,8 +191,7 @@ void
VExplodeV2TableFunction::get_same_many_values(MutableColumnPtr& column, int
struct_field.insert_many_defaults(length);
} else {
auto* nullable_column =
assert_cast<ColumnNullable*>(struct_field.get_ptr().get());
- auto* nullmap_column =
-
assert_cast<ColumnUInt8*>(nullable_column->get_null_map_column_ptr().get());
+ auto* nullmap_column =
nullable_column->get_null_map_column_ptr().get();
// only need to check if the value at position pos is null
if (element_size < _cur_offset ||
(detail.nested_nullmap_data &&
detail.nested_nullmap_data[pos])) {
@@ -223,8 +221,7 @@ int VExplodeV2TableFunction::get_value(MutableColumnPtr&
column, int max_step) {
auto* nullable_column =
assert_cast<ColumnNullable*>(column.get());
struct_column =
assert_cast<ColumnStruct*>(nullable_column->get_nested_column_ptr().get());
- auto* nullmap_column =
-
assert_cast<ColumnUInt8*>(nullable_column->get_null_map_column_ptr().get());
+ auto* nullmap_column =
nullable_column->get_null_map_column_ptr().get();
nullmap_column->insert_many_defaults(max_step);
} else {
@@ -253,8 +250,7 @@ int VExplodeV2TableFunction::get_value(MutableColumnPtr&
column, int max_step) {
struct_field.insert_many_defaults(max_step);
} else {
auto* nullable_column =
assert_cast<ColumnNullable*>(struct_field.get_ptr().get());
- auto* nullmap_column =
-
assert_cast<ColumnUInt8*>(nullable_column->get_null_map_column_ptr().get());
+ auto* nullmap_column =
nullable_column->get_null_map_column_ptr().get();
if (element_size >= _cur_offset + max_step) {
nullable_column->get_nested_column_ptr()->insert_range_from(*detail.nested_col,
pos, max_step);
diff --git a/be/src/exprs/table_function/vjson_each.cpp
b/be/src/exprs/table_function/vjson_each.cpp
index 4b233ae9f85..aa978f75e7c 100644
--- a/be/src/exprs/table_function/vjson_each.cpp
+++ b/be/src/exprs/table_function/vjson_each.cpp
@@ -162,8 +162,7 @@ void
VJsonEachTableFunction<TEXT_MODE>::get_same_many_values(MutableColumnPtr& c
if (_is_nullable) {
auto* nullable = assert_cast<ColumnNullable*>(column.get());
ret =
assert_cast<ColumnStruct*>(nullable->get_nested_column_ptr().get());
- assert_cast<ColumnUInt8*>(nullable->get_null_map_column_ptr().get())
- ->insert_many_defaults(length);
+ nullable->get_null_map_column_ptr()->insert_many_defaults(length);
} else {
ret = assert_cast<ColumnStruct*>(column.get());
}
@@ -184,8 +183,7 @@ int
VJsonEachTableFunction<TEXT_MODE>::get_value(MutableColumnPtr& column, int m
if (_is_nullable) {
auto* nullable_col = assert_cast<ColumnNullable*>(column.get());
struct_col =
assert_cast<ColumnStruct*>(nullable_col->get_nested_column_ptr().get());
-
assert_cast<ColumnUInt8*>(nullable_col->get_null_map_column_ptr().get())
- ->insert_many_defaults(max_step);
+
nullable_col->get_null_map_column_ptr()->insert_many_defaults(max_step);
} else {
struct_col = assert_cast<ColumnStruct*>(column.get());
}
diff --git a/be/src/exprs/vcase_expr.h b/be/src/exprs/vcase_expr.h
index b8e274be82a..fef3a3462f9 100644
--- a/be/src/exprs/vcase_expr.h
+++ b/be/src/exprs/vcase_expr.h
@@ -277,10 +277,7 @@ private:
continue;
}
const auto* __restrict cond_raw_nullmap =
- assert_cast<const ColumnUInt8*,
TypeCheckOnRelease::DISABLE>(
-
column_nullable_ptr->get_null_map_column_ptr().get())
- ->get_data()
- .data();
+
column_nullable_ptr->get_null_map_column_ptr()->get_data().data();
for (int row_idx = 0; row_idx < rows_count; row_idx++) {
then_idx_ptr[row_idx] |= (!then_idx_ptr[row_idx] *
cond_raw_data[row_idx] *
!cond_raw_nullmap[row_idx]) *
diff --git a/be/src/exprs/vcompound_pred.h b/be/src/exprs/vcompound_pred.h
index e82fa04ba8e..0c8fd46d8bd 100644
--- a/be/src/exprs/vcompound_pred.h
+++ b/be/src/exprs/vcompound_pred.h
@@ -406,10 +406,7 @@ private:
assert_cast<const
ColumnUInt8*>(nullable_column->get_nested_column_ptr().get())
->get_data()
.data();
- auto* null_map = assert_cast<const ColumnUInt8*>(
-
nullable_column->get_null_map_column_ptr().get())
- ->get_data()
- .data();
+ auto* null_map =
nullable_column->get_null_map_column_ptr()->get_data().data();
return std::make_pair(data_column, null_map);
} else {
auto* data_column = assert_cast<const
ColumnUInt8*>(column.get())->get_data().data();
diff --git a/be/src/exprs/vcondition_expr.cpp b/be/src/exprs/vcondition_expr.cpp
index ef462f4cde9..2f2ffddebe5 100644
--- a/be/src/exprs/vcondition_expr.cpp
+++ b/be/src/exprs/vcondition_expr.cpp
@@ -311,17 +311,23 @@ Status
VectorizedIfExpr::execute_for_nullable_then_else(Block& block,
// b. create a const_nullmap_column: it's a not nullable column or a
const nullable column, contain a const value
Block temporary_block;
temporary_block.insert(arg_cond);
- auto then_nested_null_map =
- (then_type_is_nullable && !then_column_is_const_nullable)
- ? then_is_nullable->get_null_map_column_ptr()
- :
DataTypeUInt8().create_column_const_with_default_value(input_rows_count);
+ ColumnPtr then_nested_null_map;
+ if (then_type_is_nullable && !then_column_is_const_nullable) {
+ then_nested_null_map = then_is_nullable->get_null_map_column_ptr();
+ } else {
+ then_nested_null_map =
+
DataTypeUInt8().create_column_const_with_default_value(input_rows_count);
+ }
temporary_block.insert(
{then_nested_null_map, std::make_shared<DataTypeUInt8>(),
"then_column_null_map"});
- auto else_nested_null_map =
- (else_type_is_nullable && !else_column_is_const_nullable)
- ? else_is_nullable->get_null_map_column_ptr()
- :
DataTypeUInt8().create_column_const_with_default_value(input_rows_count);
+ ColumnPtr else_nested_null_map;
+ if (else_type_is_nullable && !else_column_is_const_nullable) {
+ else_nested_null_map = else_is_nullable->get_null_map_column_ptr();
+ } else {
+ else_nested_null_map =
+
DataTypeUInt8().create_column_const_with_default_value(input_rows_count);
+ }
temporary_block.insert(
{else_nested_null_map, std::make_shared<DataTypeUInt8>(),
"else_column_null_map"});
temporary_block.insert(
diff --git a/be/src/storage/segment/column_reader.cpp
b/be/src/storage/segment/column_reader.cpp
index 02c59ce6cb6..7fc5d5e1466 100644
--- a/be/src/storage/segment/column_reader.cpp
+++ b/be/src/storage/segment/column_reader.cpp
@@ -979,12 +979,12 @@ Status MapFileColumnIterator::next_batch(size_t* n,
MutableColumnPtr& dst, bool*
size_t num_read = *n;
if (_null_iterator) {
bool null_signs_has_null = false;
+ MutableColumnPtr null_map_column = std::move(null_map_ptr);
RETURN_IF_ERROR(
- _null_iterator->next_batch(&num_read, null_map_ptr,
&null_signs_has_null));
+ _null_iterator->next_batch(&num_read, null_map_column,
&null_signs_has_null));
} else {
// schema-change: column became nullable but old segment has no
null data
- auto& null_map = assert_cast<ColumnUInt8&,
TypeCheckOnRelease::DISABLE>(*null_map_ptr);
- null_map.insert_many_vals(0, num_read);
+ null_map_ptr->insert_many_vals(0, num_read);
}
DCHECK(num_read == *n);
// fill nested ColumnMap with empty (zero-element) maps
@@ -1039,11 +1039,11 @@ Status MapFileColumnIterator::next_batch(size_t* n,
MutableColumnPtr& dst, bool*
// if so, we should set null_map to all null by default
if (_null_iterator) {
bool null_signs_has_null = false;
+ MutableColumnPtr null_map_column = std::move(null_map_ptr);
RETURN_IF_ERROR(
- _null_iterator->next_batch(&num_read, null_map_ptr,
&null_signs_has_null));
+ _null_iterator->next_batch(&num_read, null_map_column,
&null_signs_has_null));
} else {
- auto& null_map = assert_cast<ColumnUInt8&,
TypeCheckOnRelease::DISABLE>(*null_map_ptr);
- null_map.insert_many_vals(0, num_read);
+ null_map_ptr->insert_many_vals(0, num_read);
}
DCHECK(num_read == *n);
}
@@ -1064,12 +1064,12 @@ Status MapFileColumnIterator::read_by_rowids(const
rowid_t* rowids, const size_t
auto& nullable_col = assert_cast<ColumnNullable&>(*dst);
if (_null_iterator) {
auto null_map_ptr = nullable_col.get_null_map_column_ptr();
- RETURN_IF_ERROR(_null_iterator->read_by_rowids(rowids, count,
null_map_ptr));
+ MutableColumnPtr null_map_column = std::move(null_map_ptr);
+ RETURN_IF_ERROR(_null_iterator->read_by_rowids(rowids, count,
null_map_column));
} else {
// schema-change: column became nullable but old segment has no
null data
auto null_map_ptr = nullable_col.get_null_map_column_ptr();
- auto& null_map = assert_cast<ColumnUInt8&,
TypeCheckOnRelease::DISABLE>(*null_map_ptr);
- null_map.insert_many_vals(0, count);
+ null_map_ptr->insert_many_vals(0, count);
}
// fill nested ColumnMap with empty (zero-element) maps
auto& column_map = assert_cast<ColumnMap&,
TypeCheckOnRelease::DISABLE>(
@@ -1099,12 +1099,13 @@ Status MapFileColumnIterator::read_by_rowids(const
rowid_t* rowids, const size_t
}
auto null_map_ptr =
static_cast<ColumnNullable&>(*dst).get_null_map_column_ptr();
size_t null_before = null_map_ptr->size();
- RETURN_IF_ERROR(_null_iterator->read_by_rowids(rowids, count,
null_map_ptr));
+ auto* null_map_col = null_map_ptr.get();
+ MutableColumnPtr null_map_column = std::move(null_map_ptr);
+ RETURN_IF_ERROR(_null_iterator->read_by_rowids(rowids, count,
null_map_column));
// extract a light-weight view to decide element reads
- auto& null_map_col = assert_cast<ColumnUInt8&>(*null_map_ptr);
null_mask.reserve(count);
for (size_t i = 0; i < count; ++i) {
- null_mask.push_back(null_map_col.get_element(null_before + i));
+ null_mask.push_back(null_map_col->get_element(null_before + i));
}
} else if (dst->is_nullable()) {
// in not-null to null linked-schemachange mode,
@@ -1112,8 +1113,7 @@ Status MapFileColumnIterator::read_by_rowids(const
rowid_t* rowids, const size_t
// so may dst from changed meta which is nullable but old data is not
nullable,
// if so, we should set null_map to all null by default
auto null_map_ptr =
static_cast<ColumnNullable&>(*dst).get_null_map_column_ptr();
- auto& null_map = assert_cast<ColumnUInt8&>(*null_map_ptr);
- null_map.insert_many_vals(0, count);
+ null_map_ptr->insert_many_vals(0, count);
}
// 2. bulk read start ordinals for requested rows
@@ -1397,12 +1397,12 @@ Status StructFileColumnIterator::next_batch(size_t* n,
MutableColumnPtr& dst, bo
size_t num_read = *n;
if (_null_iterator) {
bool null_signs_has_null = false;
+ MutableColumnPtr null_map_column = std::move(null_map_ptr);
RETURN_IF_ERROR(
- _null_iterator->next_batch(&num_read, null_map_ptr,
&null_signs_has_null));
+ _null_iterator->next_batch(&num_read, null_map_column,
&null_signs_has_null));
} else {
// schema-change: column became nullable but old segment has no
null data
- auto& null_map = assert_cast<ColumnUInt8&,
TypeCheckOnRelease::DISABLE>(*null_map_ptr);
- null_map.insert_many_vals(0, num_read);
+ null_map_ptr->insert_many_vals(0, num_read);
}
DCHECK(num_read == *n);
// fill nested ColumnStruct with defaults to maintain consistent
column sizes
@@ -1435,11 +1435,11 @@ Status StructFileColumnIterator::next_batch(size_t* n,
MutableColumnPtr& dst, bo
// if so, we should set null_map to all null by default
if (_null_iterator) {
bool null_signs_has_null = false;
+ MutableColumnPtr null_map_column = std::move(null_map_ptr);
RETURN_IF_ERROR(
- _null_iterator->next_batch(&num_read, null_map_ptr,
&null_signs_has_null));
+ _null_iterator->next_batch(&num_read, null_map_column,
&null_signs_has_null));
} else {
- auto& null_map = assert_cast<ColumnUInt8&,
TypeCheckOnRelease::DISABLE>(*null_map_ptr);
- null_map.insert_many_vals(0, num_read);
+ null_map_ptr->insert_many_vals(0, num_read);
}
DCHECK(num_read == *n);
}
@@ -1762,12 +1762,12 @@ Status ArrayFileColumnIterator::next_batch(size_t* n,
MutableColumnPtr& dst, boo
size_t num_read = *n;
if (_null_iterator) {
bool null_signs_has_null = false;
+ MutableColumnPtr null_map_column = std::move(null_map_ptr);
RETURN_IF_ERROR(
- _null_iterator->next_batch(&num_read, null_map_ptr,
&null_signs_has_null));
+ _null_iterator->next_batch(&num_read, null_map_column,
&null_signs_has_null));
} else {
// schema-change: column became nullable but old segment has no
null data
- auto& null_map = assert_cast<ColumnUInt8&,
TypeCheckOnRelease::DISABLE>(*null_map_ptr);
- null_map.insert_many_vals(0, num_read);
+ null_map_ptr->insert_many_vals(0, num_read);
}
DCHECK(num_read == *n);
// fill nested ColumnArray with empty (zero-length) arrays
@@ -1817,11 +1817,11 @@ Status ArrayFileColumnIterator::next_batch(size_t* n,
MutableColumnPtr& dst, boo
// if so, we should set null_map to all null by default
if (_null_iterator) {
bool null_signs_has_null = false;
+ MutableColumnPtr null_map_column = std::move(null_map_ptr);
RETURN_IF_ERROR(
- _null_iterator->next_batch(&num_read, null_map_ptr,
&null_signs_has_null));
+ _null_iterator->next_batch(&num_read, null_map_column,
&null_signs_has_null));
} else {
- auto& null_map = assert_cast<ColumnUInt8&,
TypeCheckOnRelease::DISABLE>(*null_map_ptr);
- null_map.insert_many_vals(0, num_read);
+ null_map_ptr->insert_many_vals(0, num_read);
}
DCHECK(num_read == *n);
}
diff --git a/be/test/exec/operator/table_function_operator_test.cpp
b/be/test/exec/operator/table_function_operator_test.cpp
index b6057ede0f5..913687414be 100644
--- a/be/test/exec/operator/table_function_operator_test.cpp
+++ b/be/test/exec/operator/table_function_operator_test.cpp
@@ -145,8 +145,7 @@ public:
auto* nullable_column = assert_cast<ColumnNullable*>(column.get());
nullable_column->get_nested_column_ptr()->insert_range_from(*_detail.nested_col,
pos,
max_step);
- auto* nullmap_column =
-
assert_cast<ColumnUInt8*>(nullable_column->get_null_map_column_ptr().get());
+ auto* nullmap_column =
nullable_column->get_null_map_column_ptr().get();
const size_t old_size = nullmap_column->size();
nullmap_column->resize(old_size + max_step);
if (_detail.nested_nullmap_data != nullptr) {
diff --git a/be/test/exprs/function/function_test_util.cpp
b/be/test/exprs/function/function_test_util.cpp
index d0e6092fed6..b37e452b69a 100644
--- a/be/test/exprs/function/function_test_util.cpp
+++ b/be/test/exprs/function/function_test_util.cpp
@@ -390,8 +390,7 @@ bool insert_cell(MutableColumnPtr& column, DataTypePtr
type_ptr, const AnyType&
auto* nullable_column = assert_cast<ColumnNullable*>(column.get());
auto col_type = remove_nullable(type_ptr);
auto col = nullable_column->get_nested_column_ptr();
- auto* nullmap_column =
-
assert_cast<ColumnUInt8*>(nullable_column->get_null_map_column_ptr().get());
+ auto* nullmap_column =
nullable_column->get_null_map_column_ptr().get();
bool ok = insert_cell(col, col_type, cell, datetime_is_string_format);
nullmap_column->insert_value(ok ? 0 : 1);
} else {
@@ -553,8 +552,7 @@ bool insert_cell(MutableColumnPtr& column, DataTypePtr
type_ptr, const AnyType&
auto* nullable_column = assert_cast<ColumnNullable*>(column.get());
auto* struct_column =
assert_cast<ColumnStruct*>(nullable_column->get_nested_column_ptr().get());
- auto* nullmap_column =
-
assert_cast<ColumnUInt8*>(nullable_column->get_null_map_column_ptr().get());
+ auto* nullmap_column =
nullable_column->get_null_map_column_ptr().get();
nullmap_column->insert_default();
for (size_t i = 0; i < v.size(); ++i) {
auto& field = v[i];
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]