This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.1 by this push:
new f771a422a94 branch-2.1: [fix](column) fix
ColumnWithTypeAndName::get_nested use-after-free when input Const(Nullable)
column #48288 (#49258)
f771a422a94 is described below
commit f771a422a94f0fc2f8dd14f65f1e520fff5a7911
Author: Mryange <[email protected]>
AuthorDate: Thu Mar 20 09:53:20 2025 +0800
branch-2.1: [fix](column) fix ColumnWithTypeAndName::get_nested
use-after-free when input Const(Nullable) column #48288 (#49258)
---
be/src/vec/core/column_with_type_and_name.cpp | 5 +-
be/test/testutil/column_helper.cpp | 39 +++++++
be/test/testutil/column_helper.h | 116 +++++++++++++++++++++
.../vec/core/column_with_type_and_name_test.cpp | 40 +++++++
4 files changed, 198 insertions(+), 2 deletions(-)
diff --git a/be/src/vec/core/column_with_type_and_name.cpp
b/be/src/vec/core/column_with_type_and_name.cpp
index cd0f7194004..efd887b194b 100644
--- a/be/src/vec/core/column_with_type_and_name.cpp
+++ b/be/src/vec/core/column_with_type_and_name.cpp
@@ -93,8 +93,9 @@ ColumnWithTypeAndName ColumnWithTypeAndName::get_nested(bool
replace_null_data_t
auto nested_type = assert_cast<const
DataTypeNullable*>(type.get())->get_nested_type();
ColumnPtr nested_column = column;
if (column) {
- nested_column = nested_column->convert_to_full_column_if_const();
- const auto* source_column = assert_cast<const
ColumnNullable*>(nested_column.get());
+ // A column_ptr is needed here to ensure that the column in
convert_to_full_column_if_const is not released.
+ auto column_ptr = nested_column->convert_to_full_column_if_const();
+ const auto* source_column = assert_cast<const
ColumnNullable*>(column_ptr.get());
nested_column = source_column->get_nested_column_ptr();
if (replace_null_data_to_default) {
diff --git a/be/test/testutil/column_helper.cpp
b/be/test/testutil/column_helper.cpp
new file mode 100644
index 00000000000..b00a681ec72
--- /dev/null
+++ b/be/test/testutil/column_helper.cpp
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+#include "column_helper.h"
+
+#include <gtest/gtest.h>
+
+#include "vec/data_types/data_type_number.h"
+
+namespace doris::vectorized {
+
+TEST(ColumnHelperTest, test) {
+ EXPECT_TRUE(ColumnHelper::column_equal(
+ ColumnHelper::create_column<DataTypeInt32>({1, 2, 3, 4, 5}),
+ ColumnHelper::create_column<DataTypeInt32>({1, 2, 3, 4, 5})));
+
+ EXPECT_FALSE(ColumnHelper::column_equal(
+ ColumnHelper::create_column<DataTypeInt32>({1, 2, 3, 4, 5}),
+ ColumnHelper::create_column<DataTypeInt32>({1, 2, 3, 4, 5, 6})));
+
+ EXPECT_FALSE(ColumnHelper::column_equal(
+ ColumnHelper::create_column<DataTypeInt32>({1, 1, 3, 4, 5}),
+ ColumnHelper::create_column<DataTypeInt32>({1, 2, 3, 4, 5})));
+}
+
+} // namespace doris::vectorized
diff --git a/be/test/testutil/column_helper.h b/be/test/testutil/column_helper.h
new file mode 100644
index 00000000000..a9cf58bb880
--- /dev/null
+++ b/be/test/testutil/column_helper.h
@@ -0,0 +1,116 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+#include <memory>
+#include <type_traits>
+#include <vector>
+
+#include "vec/columns/column_nullable.h"
+#include "vec/core/block.h"
+#include "vec/data_types/data_type_string.h"
+
+namespace doris::vectorized {
+struct ColumnHelper {
+public:
+ template <typename DataType>
+ static ColumnPtr create_column(const std::vector<typename
DataType::FieldType>& data) {
+ auto column = DataType::ColumnType::create();
+ if constexpr (std::is_same_v<DataTypeString, DataType>) {
+ for (const auto& datum : data) {
+ column->insert_data(datum.data(), datum.size());
+ }
+ } else {
+ for (const auto& datum : data) {
+ column->insert_value(datum);
+ }
+ }
+ return std::move(column);
+ }
+
+ template <typename DataType>
+ static ColumnPtr create_nullable_column(
+ const std::vector<typename DataType::FieldType>& data,
+ const std::vector<typename NullMap::value_type>& null_map) {
+ auto null_col = ColumnUInt8::create();
+ for (const auto& datum : null_map) {
+ null_col->insert_value(datum);
+ }
+ auto ptr = create_column<DataType>(data);
+ return ColumnNullable::create(std::move(ptr), std::move(null_col));
+ }
+
+ static bool column_equal(const ColumnPtr& column1, const ColumnPtr&
column2) {
+ if (column1->size() != column2->size()) {
+ return false;
+ }
+ for (size_t i = 0; i < column1->size(); i++) {
+ if (column1->compare_at(i, i, *column2, 1) != 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ static bool block_equal(const Block& block1, const Block& block2) {
+ if (block1.columns() != block2.columns()) {
+ return false;
+ }
+ for (size_t i = 0; i < block1.columns(); i++) {
+ if (!column_equal(block1.get_by_position(i).column,
block2.get_by_position(i).column)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ template <typename DataType>
+ static Block create_block(const std::vector<typename DataType::FieldType>&
data) {
+ auto column = create_column<DataType>(data);
+ auto data_type = std::make_shared<DataType>();
+ Block block({ColumnWithTypeAndName(column, data_type, "column")});
+ return block;
+ }
+
+ template <typename DataType>
+ static Block create_nullable_block(const std::vector<typename
DataType::FieldType>& data,
+ const std::vector<typename
NullMap::value_type>& null_map) {
+ auto column = create_nullable_column<DataType>(data, null_map);
+ auto data_type =
std::make_shared<DataTypeNullable>(std::make_shared<DataType>());
+ Block block({ColumnWithTypeAndName(column, data_type, "column")});
+ return block;
+ }
+
+ template <typename DataType>
+ static ColumnWithTypeAndName create_column_with_name(
+ const std::vector<typename DataType::FieldType>& datas) {
+ auto column = create_column<DataType>(datas);
+ auto data_type = std::make_shared<DataType>();
+ return ColumnWithTypeAndName(column, data_type, "column");
+ }
+
+ template <typename DataType>
+ static ColumnWithTypeAndName create_nullable_column_with_name(
+ const std::vector<typename DataType::FieldType>& datas,
+ const std::vector<typename NullMap::value_type>& null_map) {
+ auto column = create_nullable_column<DataType>(datas, null_map);
+ auto data_type =
std::make_shared<DataTypeNullable>(std::make_shared<DataType>());
+ return ColumnWithTypeAndName(column, data_type, "column");
+ }
+};
+} // namespace doris::vectorized
diff --git a/be/test/vec/core/column_with_type_and_name_test.cpp
b/be/test/vec/core/column_with_type_and_name_test.cpp
new file mode 100644
index 00000000000..1cdda959a82
--- /dev/null
+++ b/be/test/vec/core/column_with_type_and_name_test.cpp
@@ -0,0 +1,40 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "vec/core/column_with_type_and_name.h"
+
+#include <gtest/gtest.h>
+
+#include "testutil/column_helper.h"
+#include "vec/core/types.h"
+#include "vec/data_types/data_type_nullable.h"
+#include "vec/data_types/data_type_number.h"
+
+namespace doris::vectorized {
+
+TEST(ColumnWithTypeAndNameTest, get_nested_test) {
+ ColumnWithTypeAndName column_with_type_and_name;
+ auto null_column =
ColumnNullable::create(ColumnHelper::create_column<DataTypeInt32>({1}),
+
ColumnHelper::create_column<DataTypeUInt8>({true}));
+ column_with_type_and_name.column = ColumnConst::create(null_column, 3);
+ column_with_type_and_name.type =
+
std::make_shared<DataTypeNullable>(std::make_shared<DataTypeInt32>());
+ column_with_type_and_name.name = "column_with_type_and_name";
+ column_with_type_and_name.get_nested(true);
+}
+
+} // namespace doris::vectorized
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]