diff --git a/be/src/exec/common/hash_table/hash_key_type.h b/be/src/exec/common/hash_table/hash_key_type.h index 4ce690596d82df..8ce7882f3a6bde 100644 --- a/be/src/exec/common/hash_table/hash_key_type.h +++ b/be/src/exec/common/hash_table/hash_key_type.h @@ -87,7 +87,8 @@ inline HashKeyType get_hash_key_type_fixed(const std::vector& data_ size_t key_byte_size = 0; for (const auto& data_type : data_types) { - if (!data_type->have_maximum_size_of_value()) { + if (is_complex_type(data_type->get_primitive_type()) || + !data_type->have_maximum_size_of_value()) { return HashKeyType::serialized; } key_byte_size += data_type->get_size_of_value_in_memory(); diff --git a/be/test/exec/common/hash_table/hash_key_type_test.cpp b/be/test/exec/common/hash_table/hash_key_type_test.cpp new file mode 100644 index 00000000000000..4d68ff70801ee5 --- /dev/null +++ b/be/test/exec/common/hash_table/hash_key_type_test.cpp @@ -0,0 +1,60 @@ +// 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 "exec/common/hash_table/hash_key_type.h" + +#include + +#include + +#include "core/data_type/data_type_nullable.h" +#include "core/data_type/data_type_number.h" +#include "core/data_type/data_type_struct.h" + +namespace doris { + +TEST(HashKeyTypeTest, FixedWidthStructUsesSerializedKey) { + const auto group_key = make_nullable(std::make_shared()); + + for (const auto& field_type : DataTypes {make_nullable(std::make_shared()), + make_nullable(std::make_shared())}) { + SCOPED_TRACE(field_type->get_name()); + const auto struct_type = + make_nullable(std::make_shared(DataTypes {field_type})); + + ASSERT_TRUE(struct_type->have_maximum_size_of_value()); + EXPECT_EQ(HashKeyType::serialized, get_hash_key_type({group_key, struct_type})); + EXPECT_EQ(HashKeyType::serialized, get_hash_key_type_fixed({group_key, struct_type})); + } +} + +TEST(HashKeyTypeTest, SingleStructUsesSerializedKey) { + const auto struct_type = make_nullable(std::make_shared( + DataTypes {make_nullable(std::make_shared())})); + + EXPECT_EQ(HashKeyType::serialized, get_hash_key_type({struct_type})); +} + +TEST(HashKeyTypeTest, NumericKeysUseFixedKey) { + const DataTypes data_types {std::make_shared(), + std::make_shared()}; + + EXPECT_EQ(HashKeyType::fixed64, get_hash_key_type(data_types)); + EXPECT_EQ(HashKeyType::fixed64, get_hash_key_type_fixed(data_types)); +} + +} // namespace doris diff --git a/regression-test/data/datatype_p0/complex_types/test_group_by_fixed_width_struct.out b/regression-test/data/datatype_p0/complex_types/test_group_by_fixed_width_struct.out new file mode 100644 index 00000000000000..5b8edf516fece7 --- /dev/null +++ b/regression-test/data/datatype_p0/complex_types/test_group_by_fixed_width_struct.out @@ -0,0 +1,23 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !group_by_tiny_struct -- +1 {"v":1} 2 +1 {"v":2} 1 +2 {"v":1} 2 + +-- !group_by_int_struct -- +1 {"v":10} 2 +1 {"v":20} 1 +2 {"v":10} 2 + +-- !array_agg_distinct_struct -- +1 2 +2 1 + +-- !collect_list_distinct_struct -- +1 2 +2 1 + +-- !group_array_distinct_struct -- +1 2 +2 1 + diff --git a/regression-test/suites/datatype_p0/complex_types/test_group_by_fixed_width_struct.groovy b/regression-test/suites/datatype_p0/complex_types/test_group_by_fixed_width_struct.groovy new file mode 100644 index 00000000000000..36be8f79c03095 --- /dev/null +++ b/regression-test/suites/datatype_p0/complex_types/test_group_by_fixed_width_struct.groovy @@ -0,0 +1,76 @@ +// 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. + +suite("test_group_by_fixed_width_struct") { + sql "DROP TABLE IF EXISTS test_group_by_fixed_width_struct" + + sql """ + CREATE TABLE test_group_by_fixed_width_struct ( + id INT, + grp INT, + st_tiny STRUCT, + st_int STRUCT + ) + DUPLICATE KEY(id) + DISTRIBUTED BY HASH(id) BUCKETS 1 + PROPERTIES ("replication_num" = "1") + """ + + sql """ + INSERT INTO test_group_by_fixed_width_struct VALUES + (1, 1, NAMED_STRUCT('v', 1), NAMED_STRUCT('v', 10)), + (2, 1, NAMED_STRUCT('v', 1), NAMED_STRUCT('v', 10)), + (3, 1, NAMED_STRUCT('v', 2), NAMED_STRUCT('v', 20)), + (4, 2, NAMED_STRUCT('v', 1), NAMED_STRUCT('v', 10)), + (5, 2, NAMED_STRUCT('v', 1), NAMED_STRUCT('v', 10)) + """ + + order_qt_group_by_tiny_struct """ + SELECT grp, st_tiny, COUNT(*) + FROM test_group_by_fixed_width_struct + GROUP BY grp, st_tiny + ORDER BY grp, st_tiny + """ + + order_qt_group_by_int_struct """ + SELECT grp, st_int, COUNT(*) + FROM test_group_by_fixed_width_struct + GROUP BY grp, st_int + ORDER BY grp, st_int + """ + + order_qt_array_agg_distinct_struct """ + SELECT grp, SIZE(array_agg(DISTINCT st_int)) + FROM test_group_by_fixed_width_struct + GROUP BY grp + ORDER BY grp + """ + + order_qt_collect_list_distinct_struct """ + SELECT grp, SIZE(collect_list(DISTINCT st_int)) + FROM test_group_by_fixed_width_struct + GROUP BY grp + ORDER BY grp + """ + + order_qt_group_array_distinct_struct """ + SELECT grp, SIZE(group_array(DISTINCT st_int)) + FROM test_group_by_fixed_width_struct + GROUP BY grp + ORDER BY grp + """ +}