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 ad269d4dd27 [opt](column) avoid redundant COW column clones (#64735)
ad269d4dd27 is described below
commit ad269d4dd279d0d3658d5d434022dd562f02bf37
Author: Mryange <[email protected]>
AuthorDate: Thu Jun 25 14:46:53 2026 +0800
[opt](column) avoid redundant COW column clones (#64735)
### What problem does this PR solve?
Several expression and writer paths cloned columns even though they only
needed a shared COW view before passing data to existing COW-aware APIs.
Root cause:
array_map copied array offsets for result wrapping, Hive/Iceberg
partition filtering cloned every column before calling
Block::filter_block_internal, the IF null-condition path cloned the
pass-through else column, and get_output_block_after_execute_exprs kept
a legacy do_projection clone path for an old Block::clear_column_data
ownership issue.
This change reuses shared ColumnPtr values in those non-mutating paths,
removes the obsolete do_projection branch, and lets the COW-aware block
helpers detach only when mutation is actually needed.
### Release note
None
---
be/src/core/block/block.cpp | 10 ++----
be/src/core/column/column.cpp | 37 ++++++++++------------
be/src/core/column/column.h | 7 ++--
be/src/core/column/column_array.h | 7 +++-
be/src/core/column/column_const.h | 6 +++-
be/src/core/column/column_map.h | 8 ++++-
be/src/core/column/column_nullable.h | 7 +++-
be/src/core/column/column_struct.cpp | 8 ++++-
be/src/core/column/column_struct.h | 3 +-
be/src/core/column/column_variant.cpp | 17 ++++++++--
be/src/core/column/column_variant.h | 3 +-
.../operator/multi_cast_data_stream_source.cpp | 2 +-
.../sink/writer/iceberg/viceberg_table_writer.cpp | 21 ++----------
.../sink/writer/maxcompute/vmc_table_writer.cpp | 2 +-
be/src/exec/sink/writer/vhive_table_writer.cpp | 22 ++-----------
.../exprs/lambda_function/varray_map_function.cpp | 18 +++++------
be/src/exprs/vcondition_expr.cpp | 3 +-
be/src/exprs/vexpr_context.cpp | 16 ++--------
be/src/exprs/vexpr_context.h | 3 +-
19 files changed, 93 insertions(+), 107 deletions(-)
diff --git a/be/src/core/block/block.cpp b/be/src/core/block/block.cpp
index d94f6b3a186..726e3b2c3a5 100644
--- a/be/src/core/block/block.cpp
+++ b/be/src/core/block/block.cpp
@@ -89,17 +89,13 @@ bool is_recursively_exclusive(const IColumn& column) {
}
bool exclusive = true;
- IColumn::ColumnCallback callback = [&](IColumn::WrappedPtr& subcolumn) {
+ IColumn::ColumnCallback callback = [&](const IColumn& subcolumn) {
if (!exclusive) {
return;
}
- const ColumnPtr& subcolumn_ptr = const_cast<const
IColumn::WrappedPtr&>(subcolumn);
- DCHECK(subcolumn_ptr);
- exclusive = is_recursively_exclusive(*subcolumn_ptr);
+ exclusive = is_recursively_exclusive(subcolumn);
};
- // `for_each_subcolumn` only exposes a mutable callback type. This callback
- // only reads the wrapped pointers and never calls the non-const accessors.
- const_cast<IColumn&>(column).for_each_subcolumn(callback);
+ column.for_each_subcolumn(callback);
return exclusive;
}
diff --git a/be/src/core/column/column.cpp b/be/src/core/column/column.cpp
index 3fea47f9388..68048b10053 100644
--- a/be/src/core/column/column.cpp
+++ b/be/src/core/column/column.cpp
@@ -32,12 +32,11 @@ std::string IColumn::dump_structure() const {
std::stringstream res;
res << get_name() << "(size = " << size();
- ColumnCallback callback = [&](ColumnPtr& subcolumn) {
- res << ", " << subcolumn->dump_structure();
+ ColumnCallback callback = [&](const IColumn& subcolumn) {
+ res << ", " << subcolumn.dump_structure();
};
- // simply read using for_each_subcolumn without modification; const_cast
can be used.
- const_cast<IColumn*>(this)->for_each_subcolumn(callback);
+ for_each_subcolumn(callback);
res << ")";
return res.str();
@@ -45,11 +44,10 @@ std::string IColumn::dump_structure() const {
int IColumn::count_const_column() const {
int count = is_column_const(*this) ? 1 : 0;
- ColumnCallback callback = [&](ColumnPtr& subcolumn) {
- count += subcolumn->count_const_column();
+ ColumnCallback callback = [&](const IColumn& subcolumn) {
+ count += subcolumn.count_const_column();
};
- // simply read using for_each_subcolumn without modification; const_cast
can be used.
- const_cast<IColumn*>(this)->for_each_subcolumn(callback);
+ for_each_subcolumn(callback);
return count;
}
@@ -95,13 +93,12 @@ bool IColumn::column_boolean_check() const {
};
bool is_valid = check_boolean_is_zero_or_one(*this);
- ColumnCallback callback = [&](ColumnPtr& subcolumn) {
- if (!subcolumn->column_boolean_check()) {
+ ColumnCallback callback = [&](const IColumn& subcolumn) {
+ if (!subcolumn.column_boolean_check()) {
is_valid = false;
}
};
- // simply read using for_each_subcolumn without modification; const_cast
can be used.
- const_cast<IColumn*>(this)->for_each_subcolumn(callback);
+ for_each_subcolumn(callback);
return is_valid;
}
@@ -122,13 +119,12 @@ bool IColumn::null_map_check() const {
};
bool is_valid = check_null_map_is_zero_or_one(*this);
- ColumnCallback callback = [&](ColumnPtr& subcolumn) {
- if (!subcolumn->null_map_check()) {
+ ColumnCallback callback = [&](const IColumn& subcolumn) {
+ if (!subcolumn.null_map_check()) {
is_valid = false;
}
};
- // simply read using for_each_subcolumn without modification; const_cast
can be used.
- const_cast<IColumn*>(this)->for_each_subcolumn(callback);
+ for_each_subcolumn(callback);
return is_valid;
}
@@ -231,15 +227,14 @@ bool is_column_const(const IColumn& column) {
}
void IColumn::check_const_only_in_top_level() const {
- ColumnCallback throw_if_const = [&](WrappedPtr& column) {
- const ColumnPtr& col = const_cast<const WrappedPtr&>(column);
- if (is_column_const(*col)) {
+ ColumnCallback throw_if_const = [&](const IColumn& column) {
+ if (is_column_const(column)) {
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
"const column is not allowed to be nested,
but got {}",
- col->get_name());
+ column.get_name());
}
};
- const_cast<IColumn*>(this)->for_each_subcolumn(throw_if_const);
+ for_each_subcolumn(throw_if_const);
}
} // namespace doris
diff --git a/be/src/core/column/column.h b/be/src/core/column/column.h
index ecd0245d718..6e5b69d9077 100644
--- a/be/src/core/column/column.h
+++ b/be/src/core/column/column.h
@@ -563,9 +563,10 @@ public:
/// If the column contains subcolumns (such as Array, Nullable, etc), do
callback on them.
/// Shallow: doesn't do recursive calls; don't do call for itself.
- using ColumnCallback = std::function<void(WrappedPtr&)>;
- using ImutableColumnCallback = std::function<void(const IColumn&)>;
- virtual void for_each_subcolumn(ColumnCallback) {}
+ using MutableColumnCallback = std::function<void(WrappedPtr&)>;
+ using ColumnCallback = std::function<void(const IColumn&)>;
+ virtual void for_each_subcolumn(MutableColumnCallback) {}
+ virtual void for_each_subcolumn(ColumnCallback) const {}
/// Columns have equal structure.
/// If true - you can use "compare_at", "insert_from", etc. methods.
diff --git a/be/src/core/column/column_array.h
b/be/src/core/column/column_array.h
index 9c4e37ed794..0f2ef78a26c 100644
--- a/be/src/core/column/column_array.h
+++ b/be/src/core/column/column_array.h
@@ -216,7 +216,7 @@ public:
return get_offsets()[i] - get_offsets()[i - 1];
}
- void for_each_subcolumn(ColumnCallback callback) override {
+ void for_each_subcolumn(MutableColumnCallback callback) override {
IColumn::WrappedPtr
offsets_column(std::move(static_cast<ColumnOffsets::Ptr&>(offsets)));
Defer defer([&] {
static_cast<ColumnOffsets::Ptr&>(offsets) =
@@ -226,6 +226,11 @@ public:
callback(data);
}
+ void for_each_subcolumn(ColumnCallback callback) const override {
+ callback(*static_cast<const ColumnOffsets::Ptr&>(offsets));
+ callback(*static_cast<const IColumn::Ptr&>(data));
+ }
+
ColumnPtr convert_column_if_overflow() override {
data = data->convert_column_if_overflow();
return IColumn::convert_column_if_overflow();
diff --git a/be/src/core/column/column_const.h
b/be/src/core/column/column_const.h
index 238d0f971b5..fa647aca466 100644
--- a/be/src/core/column/column_const.h
+++ b/be/src/core/column/column_const.h
@@ -261,7 +261,11 @@ public:
}
}
- void for_each_subcolumn(ColumnCallback callback) override {
callback(data); }
+ void for_each_subcolumn(MutableColumnCallback callback) override {
callback(data); }
+
+ void for_each_subcolumn(ColumnCallback callback) const override {
+ callback(*static_cast<const IColumn::Ptr&>(data));
+ }
bool structure_equals(const IColumn& rhs) const override {
if (const auto* rhs_concrete =
check_and_get_column<ColumnConst>(&rhs)) {
diff --git a/be/src/core/column/column_map.h b/be/src/core/column/column_map.h
index f5bb29d8be5..d8f40a8fa98 100644
--- a/be/src/core/column/column_map.h
+++ b/be/src/core/column/column_map.h
@@ -74,7 +74,7 @@ public:
std::string get_name() const override;
- void for_each_subcolumn(ColumnCallback callback) override {
+ void for_each_subcolumn(MutableColumnCallback callback) override {
IColumn::WrappedPtr
offsets(std::move(static_cast<COffsets::Ptr&>(offsets_column)));
Defer defer([&] {
static_cast<COffsets::Ptr&>(offsets_column) =
@@ -85,6 +85,12 @@ public:
callback(offsets);
}
+ void for_each_subcolumn(ColumnCallback callback) const override {
+ callback(*static_cast<const IColumn::Ptr&>(keys_column));
+ callback(*static_cast<const IColumn::Ptr&>(values_column));
+ callback(*static_cast<const COffsets::Ptr&>(offsets_column));
+ }
+
void sanity_check() const override {
keys_column->sanity_check();
values_column->sanity_check();
diff --git a/be/src/core/column/column_nullable.h
b/be/src/core/column/column_nullable.h
index 563d5e7011d..2161260bf9f 100644
--- a/be/src/core/column/column_nullable.h
+++ b/be/src/core/column/column_nullable.h
@@ -250,7 +250,7 @@ public:
return get_ptr();
}
- void for_each_subcolumn(ColumnCallback callback) override {
+ void for_each_subcolumn(MutableColumnCallback callback) override {
callback(_nested_column);
IColumn::WrappedPtr
null_map(std::move(static_cast<ColumnUInt8::Ptr&>(_null_map)));
@@ -260,6 +260,11 @@ public:
callback(null_map);
}
+ void for_each_subcolumn(ColumnCallback callback) const override {
+ callback(*static_cast<const IColumn::Ptr&>(_nested_column));
+ callback(*static_cast<const ColumnUInt8::Ptr&>(_null_map));
+ }
+
bool structure_equals(const IColumn& rhs) const override {
if (const auto* rhs_nullable =
check_and_get_column<ColumnNullable>(&rhs)) {
return
_nested_column->structure_equals(*rhs_nullable->_nested_column);
diff --git a/be/src/core/column/column_struct.cpp
b/be/src/core/column/column_struct.cpp
index e2a90432c56..9b0c5d2d27a 100644
--- a/be/src/core/column/column_struct.cpp
+++ b/be/src/core/column/column_struct.cpp
@@ -379,12 +379,18 @@ bool ColumnStruct::has_enough_capacity(const IColumn&
src) const {
return true;
}
-void ColumnStruct::for_each_subcolumn(ColumnCallback callback) {
+void ColumnStruct::for_each_subcolumn(MutableColumnCallback callback) {
for (auto& column : columns) {
callback(column);
}
}
+void ColumnStruct::for_each_subcolumn(ColumnCallback callback) const {
+ for (const auto& column : columns) {
+ callback(*static_cast<const IColumn::Ptr&>(column));
+ }
+}
+
bool ColumnStruct::structure_equals(const IColumn& rhs) const {
if (const auto* rhs_tuple = check_and_get_column<ColumnStruct>(&rhs)) {
const size_t tuple_size = columns.size();
diff --git a/be/src/core/column/column_struct.h
b/be/src/core/column/column_struct.h
index e1f81950ddc..19b5259ee50 100644
--- a/be/src/core/column/column_struct.h
+++ b/be/src/core/column/column_struct.h
@@ -155,7 +155,8 @@ public:
size_t byte_size() const override;
size_t allocated_bytes() const override;
bool has_enough_capacity(const IColumn& src) const override;
- void for_each_subcolumn(ColumnCallback callback) override;
+ void for_each_subcolumn(MutableColumnCallback callback) override;
+ void for_each_subcolumn(ColumnCallback callback) const override;
bool structure_equals(const IColumn& rhs) const override;
size_t tuple_size() const { return columns.size(); }
diff --git a/be/src/core/column/column_variant.cpp
b/be/src/core/column/column_variant.cpp
index 723d52d46b9..d4f1cb1e4bd 100644
--- a/be/src/core/column/column_variant.cpp
+++ b/be/src/core/column/column_variant.cpp
@@ -826,7 +826,7 @@ size_t ColumnVariant::allocated_bytes() const {
return res;
}
-void ColumnVariant::for_each_subcolumn(ColumnCallback callback) {
+void ColumnVariant::for_each_subcolumn(MutableColumnCallback callback) {
for (auto& entry : subcolumns) {
for (auto& part : entry->data.data) {
callback(part);
@@ -839,6 +839,16 @@ void ColumnVariant::for_each_subcolumn(ColumnCallback
callback) {
ENABLE_CHECK_CONSISTENCY(this);
}
+void ColumnVariant::for_each_subcolumn(ColumnCallback callback) const {
+ for (const auto& entry : subcolumns) {
+ for (const auto& part : entry->data.data) {
+ callback(*static_cast<const IColumn::Ptr&>(part));
+ }
+ }
+ callback(*static_cast<const IColumn::Ptr&>(serialized_sparse_column));
+ callback(*static_cast<const IColumn::Ptr&>(serialized_doc_value_column));
+}
+
void ColumnVariant::insert_from(const IColumn& src, size_t n) {
const auto* src_v = assert_cast<const ColumnVariant*>(&src);
ENABLE_CHECK_CONSISTENCY(src_v);
@@ -2375,7 +2385,7 @@ size_t ColumnVariant::filter(const Filter& filter) {
for (auto& subcolumn : subcolumns) {
subcolumn->data.num_rows = count;
}
- for_each_subcolumn([&](auto& part) {
+ MutableColumnCallback callback = [&](IColumn::WrappedPtr& part) {
if (part->size() != count) {
if (part->is_exclusive()) {
const auto result_size = part->filter(filter);
@@ -2390,7 +2400,8 @@ size_t ColumnVariant::filter(const Filter& filter) {
part = part->filter(filter, count);
}
}
- });
+ };
+ for_each_subcolumn(callback);
}
num_rows = count;
ENABLE_CHECK_CONSISTENCY(this);
diff --git a/be/src/core/column/column_variant.h
b/be/src/core/column/column_variant.h
index 1d5c4eed137..cccf4d4031d 100644
--- a/be/src/core/column/column_variant.h
+++ b/be/src/core/column/column_variant.h
@@ -469,7 +469,8 @@ public:
bool has_enough_capacity(const IColumn& src) const override { return
false; }
- void for_each_subcolumn(ColumnCallback callback) override;
+ void for_each_subcolumn(MutableColumnCallback callback) override;
+ void for_each_subcolumn(ColumnCallback callback) const override;
// Do nothing, call try_insert instead
void insert(const Field& field) override { try_insert(field); }
diff --git a/be/src/exec/operator/multi_cast_data_stream_source.cpp
b/be/src/exec/operator/multi_cast_data_stream_source.cpp
index 2b9e663ce07..04aa6a18dcf 100644
--- a/be/src/exec/operator/multi_cast_data_stream_source.cpp
+++ b/be/src/exec/operator/multi_cast_data_stream_source.cpp
@@ -110,7 +110,7 @@ Status
MultiCastDataStreamerSourceOperatorX::get_block_impl(RuntimeState* state,
if (!local_state._output_expr_contexts.empty() && output_block->rows() >
0) {
SCOPED_TIMER(local_state._materialize_data_timer);
RETURN_IF_ERROR(VExprContext::get_output_block_after_execute_exprs(
- local_state._output_expr_contexts, *output_block, block,
true));
+ local_state._output_expr_contexts, *output_block, block));
materialize_block_inplace(*block);
}
return Status::OK();
diff --git a/be/src/exec/sink/writer/iceberg/viceberg_table_writer.cpp
b/be/src/exec/sink/writer/iceberg/viceberg_table_writer.cpp
index 0a3b0843115..9e0f6821380 100644
--- a/be/src/exec/sink/writer/iceberg/viceberg_table_writer.cpp
+++ b/be/src/exec/sink/writer/iceberg/viceberg_table_writer.cpp
@@ -206,7 +206,7 @@ Status VIcebergTableWriter::write(RuntimeState* state,
Block& block) {
}
Block output_block;
RETURN_IF_ERROR(VExprContext::get_output_block_after_execute_exprs(_vec_output_expr_ctxs,
block,
-
&output_block, false));
+
&output_block));
materialize_block_inplace(output_block);
return _write_prepared_block(output_block);
}
@@ -436,23 +436,8 @@ Status VIcebergTableWriter::_write_prepared_block(Block&
output_block) {
Status VIcebergTableWriter::_filter_block(doris::Block& block, const
IColumn::Filter* filter,
doris::Block* output_block) {
- const ColumnsWithTypeAndName& columns_with_type_and_name =
- block.get_columns_with_type_and_name();
- ColumnsWithTypeAndName result_columns;
- for (const auto& col : columns_with_type_and_name) {
-
result_columns.emplace_back(col.column->clone_resized(col.column->size()),
col.type,
- col.name);
- }
- *output_block = {std::move(result_columns)};
-
- std::vector<uint32_t> columns_to_filter;
- int column_to_keep = output_block->columns();
- columns_to_filter.resize(column_to_keep);
- for (uint32_t i = 0; i < column_to_keep; ++i) {
- columns_to_filter[i] = i;
- }
-
- Block::filter_block_internal(output_block, columns_to_filter, *filter);
+ *output_block = block;
+ Block::filter_block_internal(output_block, *filter);
return Status::OK();
}
diff --git a/be/src/exec/sink/writer/maxcompute/vmc_table_writer.cpp
b/be/src/exec/sink/writer/maxcompute/vmc_table_writer.cpp
index a7818ea01d2..a35eb325fd4 100644
--- a/be/src/exec/sink/writer/maxcompute/vmc_table_writer.cpp
+++ b/be/src/exec/sink/writer/maxcompute/vmc_table_writer.cpp
@@ -145,7 +145,7 @@ Status VMCTableWriter::write(RuntimeState* state, Block&
block) {
Block output_block;
RETURN_IF_ERROR(VExprContext::get_output_block_after_execute_exprs(_vec_output_expr_ctxs,
block,
-
&output_block, false));
+
&output_block));
materialize_block_inplace(output_block);
_row_count += output_block.rows();
diff --git a/be/src/exec/sink/writer/vhive_table_writer.cpp
b/be/src/exec/sink/writer/vhive_table_writer.cpp
index 04a0c04c1dd..ee8e2a88bbb 100644
--- a/be/src/exec/sink/writer/vhive_table_writer.cpp
+++ b/be/src/exec/sink/writer/vhive_table_writer.cpp
@@ -92,7 +92,7 @@ Status VHiveTableWriter::write(RuntimeState* state, Block&
block) {
}
Block output_block;
RETURN_IF_ERROR(VExprContext::get_output_block_after_execute_exprs(_vec_output_expr_ctxs,
block,
-
&output_block, false));
+
&output_block));
materialize_block_inplace(output_block);
std::unordered_map<std::shared_ptr<VHivePartitionWriter>, IColumn::Filter>
writer_positions;
@@ -220,24 +220,8 @@ Status VHiveTableWriter::write(RuntimeState* state, Block&
block) {
Status VHiveTableWriter::_filter_block(doris::Block& block, const
IColumn::Filter* filter,
doris::Block* output_block) {
- const ColumnsWithTypeAndName& columns_with_type_and_name =
- block.get_columns_with_type_and_name();
- ColumnsWithTypeAndName result_columns;
- for (int i = 0; i < columns_with_type_and_name.size(); ++i) {
- const auto& col = columns_with_type_and_name[i];
-
result_columns.emplace_back(col.column->clone_resized(col.column->size()),
col.type,
- col.name);
- }
- *output_block = {std::move(result_columns)};
-
- std::vector<uint32_t> columns_to_filter;
- int column_to_keep = output_block->columns();
- columns_to_filter.resize(column_to_keep);
- for (uint32_t i = 0; i < column_to_keep; ++i) {
- columns_to_filter[i] = i;
- }
-
- Block::filter_block_internal(output_block, columns_to_filter, *filter);
+ *output_block = block;
+ Block::filter_block_internal(output_block, *filter);
return Status::OK();
}
diff --git a/be/src/exprs/lambda_function/varray_map_function.cpp
b/be/src/exprs/lambda_function/varray_map_function.cpp
index db82c465000..9dc63c98b6a 100644
--- a/be/src/exprs/lambda_function/varray_map_function.cpp
+++ b/be/src/exprs/lambda_function/varray_map_function.cpp
@@ -121,7 +121,7 @@ public:
auto outside_null_map = ColumnUInt8::create(
arguments[0].column->convert_to_full_column_if_const()->size(), 0);
// offset column
- MutableColumnPtr array_column_offset;
+ ColumnPtr array_column_offset;
size_t nested_array_column_rows = 0;
ColumnPtr first_array_offsets = nullptr;
//2. get the result column from executed expr, and the needed is
nested column of array
@@ -158,8 +158,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 = col_array.get_offsets_column();
- array_column_offset =
off_data.clone_resized(col_array.get_offsets_column().size());
+ array_column_offset = first_array_offsets;
args_info.offsets_ptr = &col_array.get_offsets();
} else {
// select array_map((x,y)->x+y,c_array1,[0,1,2,3]) from
array_test2;
@@ -200,8 +199,8 @@ public:
auto empty_nested_column = assert_cast<const
DataTypeArray*>(nested_type.get())
->get_nested_type()
->create_column();
- auto result_array_column =
ColumnArray::create(std::move(empty_nested_column),
-
std::move(array_column_offset));
+ auto result_array_column =
+ ColumnArray::create(std::move(empty_nested_column),
array_column_offset);
if (is_nullable) {
result_column =
ColumnNullable::create(std::move(result_array_column),
@@ -300,7 +299,7 @@ public:
if (result_type->is_nullable()) {
if (res_type->is_nullable()) {
result_column = ColumnNullable::create(
- ColumnArray::create(std::move(result_col),
std::move(array_column_offset)),
+ ColumnArray::create(std::move(result_col),
array_column_offset),
std::move(outside_null_map));
} else {
// deal with eg: select array_map(x -> x is null, [null, 1,
2]);
@@ -310,19 +309,18 @@ public:
result_column = ColumnNullable::create(
ColumnArray::create(ColumnNullable::create(std::move(result_col),
std::move(nested_null_map)),
- std::move(array_column_offset)),
+ array_column_offset),
std::move(outside_null_map));
}
} else {
if (res_type->is_nullable()) {
- result_column =
- ColumnArray::create(std::move(result_col),
std::move(array_column_offset));
+ result_column = ColumnArray::create(std::move(result_col),
array_column_offset);
} else {
auto nested_null_map = ColumnUInt8::create(result_col->size(),
0);
result_column = ColumnArray::create(
ColumnNullable::create(std::move(result_col),
std::move(nested_null_map)),
- std::move(array_column_offset));
+ array_column_offset);
}
}
return Status::OK();
diff --git a/be/src/exprs/vcondition_expr.cpp b/be/src/exprs/vcondition_expr.cpp
index ab8f694c2c5..61d1b561165 100644
--- a/be/src/exprs/vcondition_expr.cpp
+++ b/be/src/exprs/vcondition_expr.cpp
@@ -369,7 +369,8 @@ Status VectorizedIfExpr::execute_for_null_condition(Block&
block, const ColumnNu
handled = false;
if (cond_is_null) {
- block.replace_by_position(result,
arg_else.column->clone_resized(arg_cond.column->size()));
+ DCHECK_EQ(arg_else.column->size(), arg_cond.column->size());
+ block.replace_by_position(result, arg_else.column);
handled = true;
return Status::OK();
}
diff --git a/be/src/exprs/vexpr_context.cpp b/be/src/exprs/vexpr_context.cpp
index b9abce25588..29cff202ab9 100644
--- a/be/src/exprs/vexpr_context.cpp
+++ b/be/src/exprs/vexpr_context.cpp
@@ -386,15 +386,8 @@ Status
VExprContext::execute_conjuncts_and_filter_block(const VExprContextSPtrs&
return Status::OK();
}
-// do_projection: for some query(e.g. in
MultiCastDataStreamerSourceOperator::get_block()),
-// output_vexpr_ctxs will output the same column more than once, and if the
output_block
-// is mem-reused later, it will trigger DCHECK_EQ(d.column->use_count(), 1)
failure when
-// doing Block::clear_column_data, set do_projection to true to copy the
column data to
-// avoid this problem.
Status VExprContext::get_output_block_after_execute_exprs(
- const VExprContextSPtrs& output_vexpr_ctxs, const Block& input_block,
Block* output_block,
- bool do_projection) {
- auto rows = input_block.rows();
+ const VExprContextSPtrs& output_vexpr_ctxs, const Block& input_block,
Block* output_block) {
ColumnsWithTypeAndName result_columns;
_reset_memory_usage(output_vexpr_ctxs);
@@ -406,12 +399,7 @@ Status VExprContext::get_output_block_after_execute_exprs(
const auto& name = vexpr_ctx->expr_name();
vexpr_ctx->_memory_usage += result_column->allocated_bytes();
- if (do_projection) {
- result_columns.emplace_back(result_column->clone_resized(rows),
type, name);
-
- } else {
- result_columns.emplace_back(result_column, type, name);
- }
+ result_columns.emplace_back(result_column, type, name);
}
*output_block = {result_columns};
return Status::OK();
diff --git a/be/src/exprs/vexpr_context.h b/be/src/exprs/vexpr_context.h
index 72398c71d05..3b9f08d6474 100644
--- a/be/src/exprs/vexpr_context.h
+++ b/be/src/exprs/vexpr_context.h
@@ -319,8 +319,7 @@ public:
int column_to_keep,
IColumn::Filter& filter);
[[nodiscard]] static Status get_output_block_after_execute_exprs(const
VExprContextSPtrs&,
- const
Block&, Block*,
- bool
do_projection = false);
+ const
Block&, Block*);
int get_last_result_column_id() const {
DCHECK(_last_result_column_id != -1);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]