This is an automated email from the ASF dual-hosted git repository.
zclll 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 17a81a419a4 [check](column)const is only allowed at the top level.
(#60578)
17a81a419a4 is described below
commit 17a81a419a469e4b9ccae0dafc94d962d70d6797
Author: Mryange <[email protected]>
AuthorDate: Mon Mar 2 19:14:45 2026 +0800
[check](column)const is only allowed at the top level. (#60578)
check nested const occurrences; const is only allowed at the top level.
e.g. const(nullable(...)) is allowed.
const(array(const(...))) is not allowed.
---
be/src/vec/columns/column.cpp | 11 +
be/src/vec/columns/column.h | 5 +
be/src/vec/columns/column_array.cpp | 4 +-
be/src/vec/columns/column_map.cpp | 1 +
be/src/vec/columns/column_nullable.cpp | 4 +-
be/src/vec/columns/column_struct.cpp | 1 +
be/test/vec/columns/column_array_test.cpp | 73 +++--
.../column_check_const_only_in_top_level_test.cpp | 311 +++++++++++++++++++++
8 files changed, 366 insertions(+), 44 deletions(-)
diff --git a/be/src/vec/columns/column.cpp b/be/src/vec/columns/column.cpp
index b206fc17034..68777b37240 100644
--- a/be/src/vec/columns/column.cpp
+++ b/be/src/vec/columns/column.cpp
@@ -230,4 +230,15 @@ bool is_column_const(const IColumn& column) {
return is_column<ColumnConst>(column);
}
+void IColumn::check_const_only_in_top_level() const {
+ ColumnCallback throw_if_const = [&](WrappedPtr& column) {
+ if (is_column_const(*column)) {
+ throw doris::Exception(ErrorCode::INTERNAL_ERROR,
+ "const column is not allowed to be nested,
but got {}",
+ column->get_name());
+ }
+ };
+ const_cast<IColumn*>(this)->for_each_subcolumn(throw_if_const);
+}
+
} // namespace doris::vectorized
diff --git a/be/src/vec/columns/column.h b/be/src/vec/columns/column.h
index d0aa6970af5..3e89aec134a 100644
--- a/be/src/vec/columns/column.h
+++ b/be/src/vec/columns/column.h
@@ -750,6 +750,11 @@ protected:
static_cast<Derived&>(*this).insert_from(*srcs[i], positions[i]);
}
}
+
+ // Used to check nested const occurrences; const is only allowed at the
top level.
+ // e.g. const(nullable(...)) is allowed.
+ // const(array(const(...))) is not allowed.
+ void check_const_only_in_top_level() const;
};
using ColumnPtr = IColumn::Ptr;
diff --git a/be/src/vec/columns/column_array.cpp
b/be/src/vec/columns/column_array.cpp
index 58457ca406f..a3e6ebe3a6b 100644
--- a/be/src/vec/columns/column_array.cpp
+++ b/be/src/vec/columns/column_array.cpp
@@ -62,9 +62,7 @@ ColumnArray::ColumnArray(MutableColumnPtr&& nested_column,
MutableColumnPtr&& of
// "nested_column must be nullable, but got
{}", data->get_name());
// }
// #endif
-
- data = data->convert_to_full_column_if_const();
- offsets = offsets->convert_to_full_column_if_const();
+ check_const_only_in_top_level();
const auto* offsets_concrete = typeid_cast<const
ColumnOffsets*>(offsets.get());
if (!offsets_concrete) {
diff --git a/be/src/vec/columns/column_map.cpp
b/be/src/vec/columns/column_map.cpp
index 3e93a6185bc..88f811dffcb 100644
--- a/be/src/vec/columns/column_map.cpp
+++ b/be/src/vec/columns/column_map.cpp
@@ -52,6 +52,7 @@ ColumnMap::ColumnMap(MutableColumnPtr&& keys,
MutableColumnPtr&& values, Mutable
: keys_column(std::move(keys)),
values_column(std::move(values)),
offsets_column(std::move(offsets)) {
+ check_const_only_in_top_level();
const auto* offsets_concrete = assert_cast<const
COffsets*>(offsets_column.get());
if (!offsets_concrete->empty() && keys_column && values_column) {
diff --git a/be/src/vec/columns/column_nullable.cpp
b/be/src/vec/columns/column_nullable.cpp
index f0cf6943c09..bb9e7914ff9 100644
--- a/be/src/vec/columns/column_nullable.cpp
+++ b/be/src/vec/columns/column_nullable.cpp
@@ -32,9 +32,7 @@ namespace doris::vectorized {
ColumnNullable::ColumnNullable(MutableColumnPtr&& nested_column_,
MutableColumnPtr&& null_map_)
: _nested_column(std::move(nested_column_)),
_null_map(std::move(null_map_)) {
- /// ColumnNullable cannot have constant nested column. But constant
argument could be passed. Materialize it.
- _nested_column = get_nested_column().convert_to_full_column_if_const();
-
+ 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)
diff --git a/be/src/vec/columns/column_struct.cpp
b/be/src/vec/columns/column_struct.cpp
index 1d0cb9302e0..ca908fc9605 100644
--- a/be/src/vec/columns/column_struct.cpp
+++ b/be/src/vec/columns/column_struct.cpp
@@ -62,6 +62,7 @@ ColumnStruct::ColumnStruct(MutableColumns&& mutable_columns) {
}
columns.push_back(std::move(column));
}
+ check_const_only_in_top_level();
}
ColumnStruct::MutablePtr ColumnStruct::create(const Columns& columns) {
diff --git a/be/test/vec/columns/column_array_test.cpp
b/be/test/vec/columns/column_array_test.cpp
index bbac856bd88..08224b55d6e 100644
--- a/be/test/vec/columns/column_array_test.cpp
+++ b/be/test/vec/columns/column_array_test.cpp
@@ -612,60 +612,57 @@ TEST_F(ColumnArrayTest, ShrinkPaddingCharsTest) {
//////////////////////// special function from column_array.h
////////////////////////
TEST_F(ColumnArrayTest, CreateArrayTest) {
- // test create_array : nested_column && offsets_column should not be
const, and convert_to_full_column_if_const should not impl in array
- // in some situation,
- // like join_probe_operator.cpp::_build_output_block,
- // we call column.convert_to_full_column_if_const,
- // then we may call clear_column_data() to clear the column (eg. in
HashJoinProbeOperatorX::pull() which call
local_state._probe_block.clear_column_data after filter_data_and_build_output())
- // in clear_column_data() if use_count() == 1, we will call
column->clear() to clear the column data
- //
- // however in array impl for convert_to_full_column_if_const: ```
ColumnArray::create(data->convert_to_full_column_if_const(), offsets);```
- // may make the nested_column use_count() more than 1 which means it is
shared with other block, but return ColumnArray is new which use_count() is 1,
- // then in clear_column_data() if we will call array_column->use_count()
== 1 will be true to clear the column with nested_column, and shared
nested_column block will meet undefined behavior cause maybe core
- //
- // so actually according to the semantics of the function, it should not
impl in array,
- // but we should make sure in creation of array, the nested_column &&
offsets_column should not be const
+ // Test ColumnArray constructor constraints: nested_column and
offsets_column must not be ColumnConst.
+ // The constructor enforces this via check_const_only_in_top_level(),
preventing COW-related issues:
+ // - ColumnConst is immutable and meant for repeated values across rows
+ // - ColumnArray requires mutable nested data for operations like
insert/filter/clear
+ // - Wrapping shared ColumnConst in ColumnArray violates use_count()
assumptions in clear_column_data()
for (auto& array_column : array_columns) {
const auto* column = check_and_get_column<ColumnArray>(
remove_nullable(array_column->assume_mutable()).get());
auto column_size = column->size();
LOG(INFO) << "column_type: " << column->get_name();
- // test create_array
- // test create expect exception case
- // 1.offsets is not ColumnOffset64
- auto tmp_data_col = column->get_data_ptr()->clone_resized(1);
- MutableColumnPtr tmp_offsets_col =
- assert_cast<const
ColumnArray::ColumnOffsets&>(column->get_offsets_column())
- .clone_resized(1);
- // 2.offsets size is not equal to data size
+
+ // Test expected exception cases
+ // 1. nested_column is ColumnConst (violates
check_const_only_in_top_level)
+ auto tmp_data_col = column->get_data_ptr()->clone_empty();
+ tmp_data_col->insert_default(); // ColumnConst requires nested column
size = 1
+ auto const_data = ColumnConst::create(std::move(tmp_data_col),
column_size);
+ EXPECT_ANY_THROW({
+ auto new_array_column =
+ ColumnArray::create(const_data->assume_mutable(),
column->get_offsets_ptr());
+ });
+
+ // 2. offsets_column is ColumnConst (violates
check_const_only_in_top_level)
+ auto tmp_offsets_col = column->get_offsets_ptr()->clone_empty();
+ tmp_offsets_col->insert_default(); // ColumnConst requires nested
column size = 1
+ auto const_offsets = ColumnConst::create(std::move(tmp_offsets_col),
column_size);
+ EXPECT_ANY_THROW({
+ auto new_array_column =
+ ColumnArray::create(column->get_data_ptr(),
const_offsets->assume_mutable());
+ });
+
+ // 3. offsets size does not match data size
auto tmp_data_col1 = column->get_data_ptr()->clone_resized(2);
EXPECT_ANY_THROW({
auto new_array_column = ColumnArray::create(
tmp_data_col1->assume_mutable(),
column->get_offsets_column().clone_resized(1)->assume_mutable());
});
- // 3.data is const
- auto last_offset = column->get_offsets().back();
- EXPECT_ANY_THROW(
- { auto const_col = ColumnConst::create(column->get_data_ptr(),
last_offset); });
- Field assert_field;
- column->get(0, assert_field);
- auto const_col = ColumnConst::create(tmp_data_col->assume_mutable(),
last_offset);
- EXPECT_ANY_THROW({
- // const_col is not empty
- auto new_array_column =
ColumnArray::create(const_col->assume_mutable());
- });
+
+ // Test successful creation with normal columns
auto new_array_column =
- ColumnArray::create(const_col->assume_mutable(),
column->get_offsets_ptr());
- EXPECT_EQ(new_array_column->size(), column_size)
- << "array_column size is not equal to column size";
+ ColumnArray::create(column->get_data_ptr(),
column->get_offsets_ptr());
+ EXPECT_EQ(new_array_column->size(), column_size);
EXPECT_EQ(new_array_column->get_data_ptr()->size(),
column->get_data_ptr()->size());
EXPECT_EQ(new_array_column->get_offsets_ptr()->size(),
column->get_offsets_ptr()->size());
- // check column data
+
+ // Verify data integrity
for (size_t j = 0; j < column_size; j++) {
- Field f1;
+ Field f1, f2;
new_array_column->get(j, f1);
- EXPECT_EQ(f1, assert_field) << "array_column data is not equal to
column data";
+ column->get(j, f2);
+ EXPECT_EQ(f1, f2);
}
}
}
diff --git a/be/test/vec/columns/column_check_const_only_in_top_level_test.cpp
b/be/test/vec/columns/column_check_const_only_in_top_level_test.cpp
new file mode 100644
index 00000000000..6a52f6fadcc
--- /dev/null
+++ b/be/test/vec/columns/column_check_const_only_in_top_level_test.cpp
@@ -0,0 +1,311 @@
+// 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 <gtest/gtest.h>
+
+#include "testutil/column_helper.h"
+#include "vec/columns/column.h"
+#include "vec/columns/column_array.h"
+#include "vec/columns/column_const.h"
+#include "vec/columns/column_map.h"
+#include "vec/columns/column_nullable.h"
+#include "vec/columns/column_struct.h"
+#include "vec/columns/column_vector.h"
+#include "vec/data_types/data_type_array.h"
+#include "vec/data_types/data_type_map.h"
+#include "vec/data_types/data_type_nullable.h"
+#include "vec/data_types/data_type_number.h"
+#include "vec/data_types/data_type_struct.h"
+
+namespace doris::vectorized {
+
+class ColumnCheckConstOnlyInTopLevelTest : public ::testing::Test {
+protected:
+ void SetUp() override {}
+ void TearDown() override {}
+};
+
+// Test ColumnNullable: nested column should not be const
+TEST_F(ColumnCheckConstOnlyInTopLevelTest, ColumnNullableWithConstNested) {
+ // Create a const column (nested column size must be 1 when
create_with_empty=false)
+ auto int_col = ColumnHelper::create_column<DataTypeInt32>({1});
+ auto const_col = ColumnConst::create(int_col, 3, false, false);
+
+ // Create a null map
+ auto null_map = ColumnUInt8::create();
+ null_map->insert_value(0);
+ null_map->insert_value(0);
+ null_map->insert_value(0);
+
+ // Try to create ColumnNullable with const nested column - should throw
+ EXPECT_THROW({ ColumnNullable::create(std::move(const_col),
std::move(null_map)); },
+ doris::Exception);
+}
+
+// Test ColumnNullable: normal case (non-const nested column) should not throw
+TEST_F(ColumnCheckConstOnlyInTopLevelTest, ColumnNullableWithNonConstNested) {
+ auto int_col = ColumnHelper::create_column<DataTypeInt32>({1, 2, 3});
+ auto null_map = ColumnUInt8::create();
+ null_map->insert_value(0);
+ null_map->insert_value(0);
+ null_map->insert_value(0);
+
+ // Should not throw
+ EXPECT_NO_THROW({
+ auto nullable_col = ColumnNullable::create(std::move(int_col),
std::move(null_map));
+ EXPECT_EQ(nullable_col->size(), 3);
+ });
+}
+
+// Test ColumnArray: nested data column should not be const
+TEST_F(ColumnCheckConstOnlyInTopLevelTest, ColumnArrayWithConstData) {
+ // Create a const column (nested column size must be 1 when
create_with_empty=false)
+ auto int_col = ColumnHelper::create_column<DataTypeInt32>({1});
+ auto const_col = ColumnConst::create(int_col, 3, false, false);
+
+ // Create offsets
+ auto offsets = ColumnArray::ColumnOffsets::create();
+ offsets->insert_value(3);
+
+ // Try to create ColumnArray with const data column - should throw
+ EXPECT_THROW({ ColumnArray::create(std::move(const_col),
std::move(offsets)); },
+ doris::Exception);
+}
+
+// Test ColumnArray: normal case should not throw
+TEST_F(ColumnCheckConstOnlyInTopLevelTest, ColumnArrayWithNonConstData) {
+ auto int_col = ColumnHelper::create_column<DataTypeInt32>({1, 2, 3});
+ auto offsets = ColumnArray::ColumnOffsets::create();
+ offsets->insert_value(3);
+
+ // Should not throw
+ EXPECT_NO_THROW({
+ auto array_col = ColumnArray::create(std::move(int_col),
std::move(offsets));
+ EXPECT_EQ(array_col->size(), 1);
+ });
+}
+
+// Test ColumnStruct: nested columns should not be const
+TEST_F(ColumnCheckConstOnlyInTopLevelTest, ColumnStructWithConstElement) {
+ // Create a const column (nested column size must be 1 when
create_with_empty=false)
+ auto int_col = ColumnHelper::create_column<DataTypeInt32>({1});
+ auto const_col = ColumnConst::create(int_col, 3, false, false);
+
+ MutableColumns columns;
+ columns.push_back(std::move(const_col));
+
+ // Try to create ColumnStruct with const element - should throw
+ EXPECT_THROW({ ColumnStruct::create(std::move(columns)); },
doris::Exception);
+}
+
+// Test ColumnStruct: normal case should not throw
+TEST_F(ColumnCheckConstOnlyInTopLevelTest, ColumnStructWithNonConstElements) {
+ auto int_col1 = ColumnHelper::create_column<DataTypeInt32>({1, 2, 3});
+ auto int_col2 = ColumnHelper::create_column<DataTypeInt32>({4, 5, 6});
+
+ MutableColumns columns;
+ columns.push_back(int_col1->assume_mutable());
+ columns.push_back(int_col2->assume_mutable());
+
+ // Should not throw
+ EXPECT_NO_THROW({
+ auto struct_col = ColumnStruct::create(std::move(columns));
+ EXPECT_EQ(struct_col->size(), 3);
+ });
+}
+
+// Test ColumnMap: keys column should not be const
+TEST_F(ColumnCheckConstOnlyInTopLevelTest, ColumnMapWithConstKeys) {
+ // Create a const keys column (nested column size must be 1 when
create_with_empty=false)
+ auto keys_col = ColumnHelper::create_column<DataTypeInt32>({1});
+ auto const_keys = ColumnConst::create(keys_col, 3, false, false);
+
+ // Create normal values column
+ auto values_col = ColumnHelper::create_column<DataTypeInt32>({10, 20, 30});
+
+ // Create offsets
+ auto offsets = ColumnArray::ColumnOffsets::create();
+ offsets->insert_value(3);
+
+ // Try to create ColumnMap with const keys - should throw
+ EXPECT_THROW(
+ {
+ ColumnMap::create(std::move(const_keys),
std::move(values_col), std::move(offsets));
+ },
+ doris::Exception);
+}
+
+// Test ColumnMap: values column should not be const
+TEST_F(ColumnCheckConstOnlyInTopLevelTest, ColumnMapWithConstValues) {
+ // Create normal keys column
+ auto keys_col = ColumnHelper::create_column<DataTypeInt32>({1, 2, 3});
+
+ // Create a const values column (nested column size must be 1 when
create_with_empty=false)
+ auto values_col = ColumnHelper::create_column<DataTypeInt32>({10});
+ auto const_values = ColumnConst::create(values_col, 3, false, false);
+
+ // Create offsets
+ auto offsets = ColumnArray::ColumnOffsets::create();
+ offsets->insert_value(3);
+
+ // Try to create ColumnMap with const values - should throw
+ EXPECT_THROW(
+ {
+ ColumnMap::create(std::move(keys_col),
std::move(const_values), std::move(offsets));
+ },
+ doris::Exception);
+}
+
+// Test ColumnMap: offsets column should not be const
+TEST_F(ColumnCheckConstOnlyInTopLevelTest, ColumnMapWithConstOffsets) {
+ // Create normal keys and values columns
+ auto keys_col = ColumnHelper::create_column<DataTypeInt32>({1, 2, 3});
+ auto values_col = ColumnHelper::create_column<DataTypeInt32>({10, 20, 30});
+
+ // Create a const offsets column (nested column size must be 1 when
create_with_empty=false)
+ auto offsets = ColumnArray::ColumnOffsets::create();
+ offsets->insert_value(3);
+ auto const_offsets = ColumnConst::create(std::move(offsets), 1, false,
false);
+
+ // Try to create ColumnMap with const offsets - should throw
+ EXPECT_THROW(
+ {
+ ColumnMap::create(std::move(keys_col), std::move(values_col),
+ std::move(const_offsets));
+ },
+ doris::Exception);
+}
+
+// Test ColumnMap: normal case should not throw
+TEST_F(ColumnCheckConstOnlyInTopLevelTest, ColumnMapWithNonConstColumns) {
+ auto keys_col = ColumnHelper::create_column<DataTypeInt32>({1, 2, 3});
+ auto values_col = ColumnHelper::create_column<DataTypeInt32>({10, 20, 30});
+ auto offsets = ColumnArray::ColumnOffsets::create();
+ offsets->insert_value(3);
+
+ // Should not throw
+ EXPECT_NO_THROW({
+ auto map_col =
+ ColumnMap::create(std::move(keys_col), std::move(values_col),
std::move(offsets));
+ EXPECT_EQ(map_col->size(), 1);
+ });
+}
+
+// Test deeply nested const column - Array<Array<Int32>> with inner array
being const
+TEST_F(ColumnCheckConstOnlyInTopLevelTest, NestedArrayWithConstInnerArray) {
+ // Create an inner array column (size 1 for const creation)
+ auto inner_data = ColumnHelper::create_column<DataTypeInt32>({1, 2, 3});
+ auto inner_offsets = ColumnArray::ColumnOffsets::create();
+ inner_offsets->insert_value(3);
+ auto inner_array = ColumnArray::create(std::move(inner_data),
std::move(inner_offsets));
+
+ // Make the inner array const (nested column size must be 1 when
create_with_empty=false)
+ auto const_inner_array = ColumnConst::create(std::move(inner_array), 2,
false, false);
+
+ // Try to create outer array with const inner array - should throw
+ auto outer_offsets = ColumnArray::ColumnOffsets::create();
+ outer_offsets->insert_value(2);
+
+ EXPECT_THROW({ ColumnArray::create(std::move(const_inner_array),
std::move(outer_offsets)); },
+ doris::Exception);
+}
+
+// Test Nullable<Array<Int32>> with const array nested
+TEST_F(ColumnCheckConstOnlyInTopLevelTest, NullableWithConstArray) {
+ // Create an array column (size 1 for const creation)
+ auto data = ColumnHelper::create_column<DataTypeInt32>({1, 2, 3});
+ auto offsets = ColumnArray::ColumnOffsets::create();
+ offsets->insert_value(3);
+ auto array_col = ColumnArray::create(std::move(data), std::move(offsets));
+
+ // Make the array const (nested column size must be 1 when
create_with_empty=false)
+ auto const_array = ColumnConst::create(std::move(array_col), 3, false,
false);
+
+ // Create null map
+ auto null_map = ColumnUInt8::create();
+ null_map->insert_value(0);
+ null_map->insert_value(0);
+ null_map->insert_value(0);
+
+ // Try to create ColumnNullable with const array nested - should throw
+ EXPECT_THROW({ ColumnNullable::create(std::move(const_array),
std::move(null_map)); },
+ doris::Exception);
+}
+
+// Test Struct<Array<Int32>> with const array element
+TEST_F(ColumnCheckConstOnlyInTopLevelTest, StructWithConstArrayElement) {
+ // Create an array column (size 1 for const creation)
+ auto data = ColumnHelper::create_column<DataTypeInt32>({1, 2, 3});
+ auto offsets = ColumnArray::ColumnOffsets::create();
+ offsets->insert_value(3);
+ auto array_col = ColumnArray::create(std::move(data), std::move(offsets));
+
+ // Make the array const (nested column size must be 1 when
create_with_empty=false)
+ auto const_array = ColumnConst::create(std::move(array_col), 3, false,
false);
+
+ MutableColumns columns;
+ columns.push_back(std::move(const_array));
+
+ // Try to create ColumnStruct with const array element - should throw
+ EXPECT_THROW({ ColumnStruct::create(std::move(columns)); },
doris::Exception);
+}
+
+// Test check_const_only_in_top_level directly
+TEST_F(ColumnCheckConstOnlyInTopLevelTest, DirectCheckConstOnlyInTopLevel) {
+ // Normal column should not throw
+ {
+ auto int_col = ColumnHelper::create_column<DataTypeInt32>({1, 2, 3});
+ EXPECT_NO_THROW({ int_col->check_const_only_in_top_level(); });
+ }
+
+ // Normal nullable column should not throw
+ {
+ auto nullable_col =
+ ColumnHelper::create_nullable_column<DataTypeInt32>({1, 2, 3},
{0, 0, 0});
+ EXPECT_NO_THROW({ nullable_col->check_const_only_in_top_level(); });
+ }
+
+ // Normal array column should not throw
+ {
+ auto data = ColumnHelper::create_column<DataTypeInt32>({1, 2, 3});
+ auto offsets = ColumnArray::ColumnOffsets::create();
+ offsets->insert_value(3);
+ auto array_col = ColumnArray::create(std::move(data),
std::move(offsets));
+ EXPECT_NO_THROW({ array_col->check_const_only_in_top_level(); });
+ }
+}
+
+// Test empty columns
+TEST_F(ColumnCheckConstOnlyInTopLevelTest, EmptyColumnsNoThrow) {
+ // Empty array should not throw
+ {
+ auto data = ColumnHelper::create_column<DataTypeInt32>({});
+ auto array_col = ColumnArray::create(std::move(data));
+ EXPECT_NO_THROW({ array_col->check_const_only_in_top_level(); });
+ }
+
+ // Empty map should not throw
+ {
+ auto keys = ColumnHelper::create_column<DataTypeInt32>({});
+ auto values = ColumnHelper::create_column<DataTypeInt32>({});
+ auto offsets = ColumnArray::ColumnOffsets::create();
+ auto map_col = ColumnMap::create(std::move(keys), std::move(values),
std::move(offsets));
+ EXPECT_NO_THROW({ map_col->check_const_only_in_top_level(); });
+ }
+}
+
+} // namespace doris::vectorized
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]