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 <yanxuech...@selectdb.com>
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: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to