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 09258e4f275 Revert "[opt](column) avoid redundant COW column clones"
(#64920)
09258e4f275 is described below
commit 09258e4f2751911d52a59e00f0a61b428626bdea
Author: Mryange <[email protected]>
AuthorDate: Mon Jun 29 16:45:44 2026 +0800
Revert "[opt](column) avoid redundant COW column clones" (#64920)
Reverts apache/doris#64735
---
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, 107 insertions(+), 93 deletions(-)
diff --git a/be/src/core/block/block.cpp b/be/src/core/block/block.cpp
index 726e3b2c3a5..d94f6b3a186 100644
--- a/be/src/core/block/block.cpp
+++ b/be/src/core/block/block.cpp
@@ -89,13 +89,17 @@ bool is_recursively_exclusive(const IColumn& column) {
}
bool exclusive = true;
- IColumn::ColumnCallback callback = [&](const IColumn& subcolumn) {
+ IColumn::ColumnCallback callback = [&](IColumn::WrappedPtr& subcolumn) {
if (!exclusive) {
return;
}
- exclusive = is_recursively_exclusive(subcolumn);
+ const ColumnPtr& subcolumn_ptr = const_cast<const
IColumn::WrappedPtr&>(subcolumn);
+ DCHECK(subcolumn_ptr);
+ exclusive = is_recursively_exclusive(*subcolumn_ptr);
};
- column.for_each_subcolumn(callback);
+ // `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);
return exclusive;
}
diff --git a/be/src/core/column/column.cpp b/be/src/core/column/column.cpp
index 68048b10053..3fea47f9388 100644
--- a/be/src/core/column/column.cpp
+++ b/be/src/core/column/column.cpp
@@ -32,11 +32,12 @@ std::string IColumn::dump_structure() const {
std::stringstream res;
res << get_name() << "(size = " << size();
- ColumnCallback callback = [&](const IColumn& subcolumn) {
- res << ", " << subcolumn.dump_structure();
+ ColumnCallback callback = [&](ColumnPtr& subcolumn) {
+ res << ", " << subcolumn->dump_structure();
};
- for_each_subcolumn(callback);
+ // simply read using for_each_subcolumn without modification; const_cast
can be used.
+ const_cast<IColumn*>(this)->for_each_subcolumn(callback);
res << ")";
return res.str();
@@ -44,10 +45,11 @@ std::string IColumn::dump_structure() const {
int IColumn::count_const_column() const {
int count = is_column_const(*this) ? 1 : 0;
- ColumnCallback callback = [&](const IColumn& subcolumn) {
- count += subcolumn.count_const_column();
+ ColumnCallback callback = [&](ColumnPtr& subcolumn) {
+ count += subcolumn->count_const_column();
};
- for_each_subcolumn(callback);
+ // simply read using for_each_subcolumn without modification; const_cast
can be used.
+ const_cast<IColumn*>(this)->for_each_subcolumn(callback);
return count;
}
@@ -93,12 +95,13 @@ bool IColumn::column_boolean_check() const {
};
bool is_valid = check_boolean_is_zero_or_one(*this);
- ColumnCallback callback = [&](const IColumn& subcolumn) {
- if (!subcolumn.column_boolean_check()) {
+ ColumnCallback callback = [&](ColumnPtr& subcolumn) {
+ if (!subcolumn->column_boolean_check()) {
is_valid = false;
}
};
- for_each_subcolumn(callback);
+ // simply read using for_each_subcolumn without modification; const_cast
can be used.
+ const_cast<IColumn*>(this)->for_each_subcolumn(callback);
return is_valid;
}
@@ -119,12 +122,13 @@ bool IColumn::null_map_check() const {
};
bool is_valid = check_null_map_is_zero_or_one(*this);
- ColumnCallback callback = [&](const IColumn& subcolumn) {
- if (!subcolumn.null_map_check()) {
+ ColumnCallback callback = [&](ColumnPtr& subcolumn) {
+ if (!subcolumn->null_map_check()) {
is_valid = false;
}
};
- for_each_subcolumn(callback);
+ // simply read using for_each_subcolumn without modification; const_cast
can be used.
+ const_cast<IColumn*>(this)->for_each_subcolumn(callback);
return is_valid;
}
@@ -227,14 +231,15 @@ bool is_column_const(const IColumn& column) {
}
void IColumn::check_const_only_in_top_level() const {
- ColumnCallback throw_if_const = [&](const IColumn& column) {
- if (is_column_const(column)) {
+ ColumnCallback throw_if_const = [&](WrappedPtr& column) {
+ const ColumnPtr& col = const_cast<const WrappedPtr&>(column);
+ if (is_column_const(*col)) {
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
"const column is not allowed to be nested,
but got {}",
- column.get_name());
+ col->get_name());
}
};
- for_each_subcolumn(throw_if_const);
+ const_cast<IColumn*>(this)->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 6e5b69d9077..ecd0245d718 100644
--- a/be/src/core/column/column.h
+++ b/be/src/core/column/column.h
@@ -563,10 +563,9 @@ 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 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 {}
+ using ColumnCallback = std::function<void(WrappedPtr&)>;
+ using ImutableColumnCallback = std::function<void(const IColumn&)>;
+ virtual void for_each_subcolumn(ColumnCallback) {}
/// 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 0f2ef78a26c..9c4e37ed794 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(MutableColumnCallback callback) override {
+ void for_each_subcolumn(ColumnCallback callback) override {
IColumn::WrappedPtr
offsets_column(std::move(static_cast<ColumnOffsets::Ptr&>(offsets)));
Defer defer([&] {
static_cast<ColumnOffsets::Ptr&>(offsets) =
@@ -226,11 +226,6 @@ 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 fa647aca466..238d0f971b5 100644
--- a/be/src/core/column/column_const.h
+++ b/be/src/core/column/column_const.h
@@ -261,11 +261,7 @@ public:
}
}
- void for_each_subcolumn(MutableColumnCallback callback) override {
callback(data); }
-
- void for_each_subcolumn(ColumnCallback callback) const override {
- callback(*static_cast<const IColumn::Ptr&>(data));
- }
+ void for_each_subcolumn(ColumnCallback callback) override {
callback(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 d8f40a8fa98..f5bb29d8be5 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(MutableColumnCallback callback) 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) =
@@ -85,12 +85,6 @@ 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 2161260bf9f..563d5e7011d 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(MutableColumnCallback callback) override {
+ void for_each_subcolumn(ColumnCallback callback) override {
callback(_nested_column);
IColumn::WrappedPtr
null_map(std::move(static_cast<ColumnUInt8::Ptr&>(_null_map)));
@@ -260,11 +260,6 @@ 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 9b0c5d2d27a..e2a90432c56 100644
--- a/be/src/core/column/column_struct.cpp
+++ b/be/src/core/column/column_struct.cpp
@@ -379,18 +379,12 @@ bool ColumnStruct::has_enough_capacity(const IColumn&
src) const {
return true;
}
-void ColumnStruct::for_each_subcolumn(MutableColumnCallback callback) {
+void ColumnStruct::for_each_subcolumn(ColumnCallback 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 19b5259ee50..e1f81950ddc 100644
--- a/be/src/core/column/column_struct.h
+++ b/be/src/core/column/column_struct.h
@@ -155,8 +155,7 @@ 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(MutableColumnCallback callback) override;
- void for_each_subcolumn(ColumnCallback callback) const override;
+ void for_each_subcolumn(ColumnCallback callback) 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 d4f1cb1e4bd..723d52d46b9 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(MutableColumnCallback callback) {
+void ColumnVariant::for_each_subcolumn(ColumnCallback callback) {
for (auto& entry : subcolumns) {
for (auto& part : entry->data.data) {
callback(part);
@@ -839,16 +839,6 @@ void
ColumnVariant::for_each_subcolumn(MutableColumnCallback 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);
@@ -2385,7 +2375,7 @@ size_t ColumnVariant::filter(const Filter& filter) {
for (auto& subcolumn : subcolumns) {
subcolumn->data.num_rows = count;
}
- MutableColumnCallback callback = [&](IColumn::WrappedPtr& part) {
+ for_each_subcolumn([&](auto& part) {
if (part->size() != count) {
if (part->is_exclusive()) {
const auto result_size = part->filter(filter);
@@ -2400,8 +2390,7 @@ 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 cccf4d4031d..1d5c4eed137 100644
--- a/be/src/core/column/column_variant.h
+++ b/be/src/core/column/column_variant.h
@@ -469,8 +469,7 @@ public:
bool has_enough_capacity(const IColumn& src) const override { return
false; }
- void for_each_subcolumn(MutableColumnCallback callback) override;
- void for_each_subcolumn(ColumnCallback callback) const override;
+ void for_each_subcolumn(ColumnCallback callback) 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 04aa6a18dcf..2b9e663ce07 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));
+ local_state._output_expr_contexts, *output_block, block,
true));
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 9e0f6821380..0a3b0843115 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));
+
&output_block, false));
materialize_block_inplace(output_block);
return _write_prepared_block(output_block);
}
@@ -436,8 +436,23 @@ Status VIcebergTableWriter::_write_prepared_block(Block&
output_block) {
Status VIcebergTableWriter::_filter_block(doris::Block& block, const
IColumn::Filter* filter,
doris::Block* output_block) {
- *output_block = block;
- Block::filter_block_internal(output_block, *filter);
+ 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);
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 a35eb325fd4..a7818ea01d2 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));
+
&output_block, false));
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 ee8e2a88bbb..04a0c04c1dd 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));
+
&output_block, false));
materialize_block_inplace(output_block);
std::unordered_map<std::shared_ptr<VHivePartitionWriter>, IColumn::Filter>
writer_positions;
@@ -220,8 +220,24 @@ Status VHiveTableWriter::write(RuntimeState* state, Block&
block) {
Status VHiveTableWriter::_filter_block(doris::Block& block, const
IColumn::Filter* filter,
doris::Block* output_block) {
- *output_block = block;
- Block::filter_block_internal(output_block, *filter);
+ 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);
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 9dc63c98b6a..db82c465000 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
- ColumnPtr array_column_offset;
+ MutableColumnPtr 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,7 +158,8 @@ public:
if (i == 0) {
nested_array_column_rows = col_array.get_data_ptr()->size();
first_array_offsets = col_array.get_offsets_ptr();
- array_column_offset = first_array_offsets;
+ 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 {
// select array_map((x,y)->x+y,c_array1,[0,1,2,3]) from
array_test2;
@@ -199,8 +200,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),
array_column_offset);
+ auto result_array_column =
ColumnArray::create(std::move(empty_nested_column),
+
std::move(array_column_offset));
if (is_nullable) {
result_column =
ColumnNullable::create(std::move(result_array_column),
@@ -299,7 +300,7 @@ public:
if (result_type->is_nullable()) {
if (res_type->is_nullable()) {
result_column = ColumnNullable::create(
- ColumnArray::create(std::move(result_col),
array_column_offset),
+ ColumnArray::create(std::move(result_col),
std::move(array_column_offset)),
std::move(outside_null_map));
} else {
// deal with eg: select array_map(x -> x is null, [null, 1,
2]);
@@ -309,18 +310,19 @@ public:
result_column = ColumnNullable::create(
ColumnArray::create(ColumnNullable::create(std::move(result_col),
std::move(nested_null_map)),
- array_column_offset),
+ std::move(array_column_offset)),
std::move(outside_null_map));
}
} else {
if (res_type->is_nullable()) {
- result_column = ColumnArray::create(std::move(result_col),
array_column_offset);
+ result_column =
+ ColumnArray::create(std::move(result_col),
std::move(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)),
- array_column_offset);
+ std::move(array_column_offset));
}
}
return Status::OK();
diff --git a/be/src/exprs/vcondition_expr.cpp b/be/src/exprs/vcondition_expr.cpp
index 61d1b561165..ab8f694c2c5 100644
--- a/be/src/exprs/vcondition_expr.cpp
+++ b/be/src/exprs/vcondition_expr.cpp
@@ -369,8 +369,7 @@ Status VectorizedIfExpr::execute_for_null_condition(Block&
block, const ColumnNu
handled = false;
if (cond_is_null) {
- DCHECK_EQ(arg_else.column->size(), arg_cond.column->size());
- block.replace_by_position(result, arg_else.column);
+ block.replace_by_position(result,
arg_else.column->clone_resized(arg_cond.column->size()));
handled = true;
return Status::OK();
}
diff --git a/be/src/exprs/vexpr_context.cpp b/be/src/exprs/vexpr_context.cpp
index 29cff202ab9..b9abce25588 100644
--- a/be/src/exprs/vexpr_context.cpp
+++ b/be/src/exprs/vexpr_context.cpp
@@ -386,8 +386,15 @@ 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) {
+ const VExprContextSPtrs& output_vexpr_ctxs, const Block& input_block,
Block* output_block,
+ bool do_projection) {
+ auto rows = input_block.rows();
ColumnsWithTypeAndName result_columns;
_reset_memory_usage(output_vexpr_ctxs);
@@ -399,7 +406,12 @@ Status VExprContext::get_output_block_after_execute_exprs(
const auto& name = vexpr_ctx->expr_name();
vexpr_ctx->_memory_usage += result_column->allocated_bytes();
- result_columns.emplace_back(result_column, type, name);
+ if (do_projection) {
+ result_columns.emplace_back(result_column->clone_resized(rows),
type, name);
+
+ } else {
+ 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 3b9f08d6474..72398c71d05 100644
--- a/be/src/exprs/vexpr_context.h
+++ b/be/src/exprs/vexpr_context.h
@@ -319,7 +319,8 @@ public:
int column_to_keep,
IColumn::Filter& filter);
[[nodiscard]] static Status get_output_block_after_execute_exprs(const
VExprContextSPtrs&,
- const
Block&, Block*);
+ const
Block&, Block*,
+ bool
do_projection = false);
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]