This is an automated email from the ASF dual-hosted git repository.
mrhhsg 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 805435f51b0 [fix](agg) Make map_agg_v2 support datev2/timev2 as key
type (#53163)
805435f51b0 is described below
commit 805435f51b026e2c9fe1b656d02da811a2f4a262
Author: Jerry Hu <[email protected]>
AuthorDate: Mon Jul 14 14:35:32 2025 +0800
[fix](agg) Make map_agg_v2 support datev2/timev2 as key type (#53163)
### What problem does this PR solve?
Issue Number: close #xxx
Related PR: #xxx
Problem Summary:
### Release note
None
### Check List (For Author)
- Test <!-- At least one of them must be included. -->
- [ ] Regression test
- [ ] Unit Test
- [ ] Manual test (add detailed scripts or steps below)
- [ ] No need to test or manual test. Explain why:
- [ ] This is a refactor/code format and no logic has been changed.
- [ ] Previous test can cover this change.
- [ ] No code files have been changed.
- [ ] Other reason <!-- Add your reason? -->
- Behavior changed:
- [ ] No.
- [ ] Yes. <!-- Explain the behavior change -->
- Does this need documentation?
- [ ] No.
- [ ] Yes. <!-- Add document PR link here. eg:
https://github.com/apache/doris-website/pull/1214 -->
### Check List (For Reviewer who merge this PR)
- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label <!-- Add branch pick label that this PR
should merge into -->
---
.../aggregate_function_map_v2.cpp | 1 +
.../aggregate_function_map_v2.h | 1 -
be/src/vec/core/field.cpp | 59 +++++++++++++++
be/src/vec/core/field.h | 81 +--------------------
.../data/query_p0/aggregate/map_agg.out | Bin 742 -> 856 bytes
.../suites/query_p0/aggregate/map_agg.groovy | 52 +++++++++++++
6 files changed, 115 insertions(+), 79 deletions(-)
diff --git a/be/src/vec/aggregate_functions/aggregate_function_map_v2.cpp
b/be/src/vec/aggregate_functions/aggregate_function_map_v2.cpp
index cbb028d6aa9..7278e5201c1 100644
--- a/be/src/vec/aggregate_functions/aggregate_function_map_v2.cpp
+++ b/be/src/vec/aggregate_functions/aggregate_function_map_v2.cpp
@@ -54,6 +54,7 @@ AggregateFunctionPtr
create_aggregate_function_map_agg_v2(const std::string& nam
case PrimitiveType::TYPE_DATETIME:
case PrimitiveType::TYPE_DATEV2:
case PrimitiveType::TYPE_DATETIMEV2:
+ case PrimitiveType::TYPE_TIMEV2:
return create_agg_function_map_agg_v2(argument_types,
result_is_nullable);
default:
LOG(WARNING) << fmt::format("unsupported input type {} for aggregate
function {}",
diff --git a/be/src/vec/aggregate_functions/aggregate_function_map_v2.h
b/be/src/vec/aggregate_functions/aggregate_function_map_v2.h
index ae99c4735ef..3daa2631344 100644
--- a/be/src/vec/aggregate_functions/aggregate_function_map_v2.h
+++ b/be/src/vec/aggregate_functions/aggregate_function_map_v2.h
@@ -28,7 +28,6 @@
#include "vec/common/assert_cast.h"
#include "vec/core/field.h"
#include "vec/data_types/data_type_map.h"
-#include "vec/io/io_helper.h"
namespace doris::vectorized {
#include "common/compile_check_begin.h"
diff --git a/be/src/vec/core/field.cpp b/be/src/vec/core/field.cpp
index b1c98ec5018..8b3f4867549 100644
--- a/be/src/vec/core/field.cpp
+++ b/be/src/vec/core/field.cpp
@@ -443,6 +443,65 @@ std::string Field::get_type_name() const {
return type_to_string(type);
}
+#define MATCH_PRIMITIVE_TYPE(primite_type)
\
+ if (type == primite_type) {
\
+ const auto& v = get<typename
PrimitiveTypeTraits<primite_type>::NearestFieldType>(); \
+ return std::string_view(reinterpret_cast<const char*>(&v), sizeof(v));
\
+ }
+
+std::string_view Field::as_string_view() const {
+ if (type == PrimitiveType::TYPE_STRING || type ==
PrimitiveType::TYPE_VARCHAR ||
+ type == PrimitiveType::TYPE_CHAR) {
+ const auto& s = get<String>();
+ return {s.data(), s.size()};
+ }
+ // MATCH_PRIMITIVE_TYPE(INVALID_TYPE);
+ // MATCH_PRIMITIVE_TYPE(TYPE_NULL);
+ MATCH_PRIMITIVE_TYPE(TYPE_BOOLEAN);
+ MATCH_PRIMITIVE_TYPE(TYPE_TINYINT);
+ MATCH_PRIMITIVE_TYPE(TYPE_SMALLINT);
+ MATCH_PRIMITIVE_TYPE(TYPE_INT);
+ MATCH_PRIMITIVE_TYPE(TYPE_BIGINT);
+ MATCH_PRIMITIVE_TYPE(TYPE_LARGEINT);
+ MATCH_PRIMITIVE_TYPE(TYPE_FLOAT)
+ MATCH_PRIMITIVE_TYPE(TYPE_DOUBLE);
+ // MATCH_PRIMITIVE_TYPE(TYPE_VARCHAR);
+ MATCH_PRIMITIVE_TYPE(TYPE_DATE);
+ MATCH_PRIMITIVE_TYPE(TYPE_DATETIME);
+ // MATCH_PRIMITIVE_TYPE(TYPE_BINARY);
+ // MATCH_PRIMITIVE_TYPE(TYPE_DECIMAL);
+ // MATCH_PRIMITIVE_TYPE(TYPE_CHAR);
+ // MATCH_PRIMITIVE_TYPE(TYPE_STRUCT);
+ // MATCH_PRIMITIVE_TYPE(TYPE_ARRAY);
+ // MATCH_PRIMITIVE_TYPE(TYPE_MAP);
+ // MATCH_PRIMITIVE_TYPE(TYPE_HLL);
+ MATCH_PRIMITIVE_TYPE(TYPE_DECIMALV2);
+ MATCH_PRIMITIVE_TYPE(TYPE_TIME);
+ // MATCH_PRIMITIVE_TYPE(TYPE_BITMAP);
+ // MATCH_PRIMITIVE_TYPE(TYPE_STRING);
+ // MATCH_PRIMITIVE_TYPE(TYPE_QUANTILE_STATE);
+ MATCH_PRIMITIVE_TYPE(TYPE_DATEV2);
+ MATCH_PRIMITIVE_TYPE(TYPE_DATETIMEV2);
+ MATCH_PRIMITIVE_TYPE(TYPE_TIMEV2);
+ MATCH_PRIMITIVE_TYPE(TYPE_DECIMAL32);
+ MATCH_PRIMITIVE_TYPE(TYPE_DECIMAL64);
+ MATCH_PRIMITIVE_TYPE(TYPE_DECIMAL128I);
+ // MATCH_PRIMITIVE_TYPE(TYPE_JSONB);
+ // MATCH_PRIMITIVE_TYPE(TYPE_VARIANT);
+ // MATCH_PRIMITIVE_TYPE(TYPE_LAMBDA_FUNCTION);
+ // MATCH_PRIMITIVE_TYPE(TYPE_AGG_STATE);
+ MATCH_PRIMITIVE_TYPE(TYPE_DECIMAL256);
+ MATCH_PRIMITIVE_TYPE(TYPE_IPV4);
+ MATCH_PRIMITIVE_TYPE(TYPE_IPV6);
+ MATCH_PRIMITIVE_TYPE(TYPE_UINT32);
+ MATCH_PRIMITIVE_TYPE(TYPE_UINT64);
+ // MATCH_PRIMITIVE_TYPE(TYPE_FIXED_LENGTH_OBJECT);
+ throw Exception(
+ Status::FatalError("type not supported for as_string_view,
type={}", get_type_name()));
+}
+
+#undef MATCH_PRIMITIVE_TYPE
+
#define DECLARE_FUNCTION(FUNC_NAME)
\
template void Field::FUNC_NAME<TYPE_NULL>(
\
typename PrimitiveTypeTraits<TYPE_NULL>::NearestFieldType && rhs);
\
diff --git a/be/src/vec/core/field.h b/be/src/vec/core/field.h
index bca1273cdc2..b19422c1377 100644
--- a/be/src/vec/core/field.h
+++ b/be/src/vec/core/field.h
@@ -475,82 +475,7 @@ public:
}
}
- std::string to_string() const {
- std::string res;
- switch (type) {
- case PrimitiveType::TYPE_DATETIMEV2: {
- auto v = get<UInt64>();
- res.resize(sizeof(v));
- memcpy(res.data(), &v, sizeof(v));
- break;
- }
- case PrimitiveType::TYPE_DATETIME:
- case PrimitiveType::TYPE_DATE:
- case PrimitiveType::TYPE_BIGINT: {
- auto v = get<Int64>();
- res.resize(sizeof(v));
- memcpy(res.data(), &v, sizeof(v));
- break;
- }
- case PrimitiveType::TYPE_LARGEINT: {
- auto v = get<Int128>();
- res.resize(sizeof(v));
- memcpy(res.data(), &v, sizeof(v));
- break;
- }
- case PrimitiveType::TYPE_IPV6: {
- auto v = get<IPv6>();
- res.resize(sizeof(v));
- memcpy(res.data(), &v, sizeof(v));
- break;
- }
- case PrimitiveType::TYPE_DOUBLE: {
- auto v = get<Float64>();
- res.resize(sizeof(v));
- memcpy(res.data(), &v, sizeof(v));
- break;
- }
- case PrimitiveType::TYPE_STRING:
- case PrimitiveType::TYPE_CHAR:
- case PrimitiveType::TYPE_VARCHAR: {
- res = get<String>();
- break;
- }
- case PrimitiveType::TYPE_DECIMAL32: {
- auto v = get<DecimalField<Decimal32>>();
- res.resize(sizeof(v));
- memcpy(res.data(), &v, sizeof(v));
- break;
- }
- case PrimitiveType::TYPE_DECIMAL64: {
- auto v = get<DecimalField<Decimal64>>();
- res.resize(sizeof(v));
- memcpy(res.data(), &v, sizeof(v));
- break;
- }
- case PrimitiveType::TYPE_DECIMALV2: {
- auto v = get<DecimalField<Decimal128V2>>();
- res.resize(sizeof(v));
- memcpy(res.data(), &v, sizeof(v));
- break;
- }
- case PrimitiveType::TYPE_DECIMAL128I: {
- auto v = get<DecimalField<Decimal128V3>>();
- res.resize(sizeof(v));
- memcpy(res.data(), &v, sizeof(v));
- break;
- }
- case PrimitiveType::TYPE_DECIMAL256: {
- auto v = get<DecimalField<Decimal256>>();
- res.resize(sizeof(v));
- memcpy(res.data(), &v, sizeof(v));
- break;
- }
- default:
- throw Exception(Status::FatalError("type not supported, type={}",
get_type_name()));
- }
- return res;
- }
+ std::string_view as_string_view() const;
private:
std::aligned_union_t<DBMS_MIN_FIELD_SIZE - sizeof(PrimitiveType), Null,
UInt64, UInt128, Int64,
@@ -720,7 +645,7 @@ struct std::hash<doris::vectorized::Field> {
if (field.is_null()) {
return 0;
}
- std::hash<std::string> hasher;
- return hasher(field.to_string());
+ std::hash<std::string_view> hasher;
+ return hasher(field.as_string_view());
}
};
diff --git a/regression-test/data/query_p0/aggregate/map_agg.out
b/regression-test/data/query_p0/aggregate/map_agg.out
index 9af8d0f3784..57c85b2f91c 100644
Binary files a/regression-test/data/query_p0/aggregate/map_agg.out and
b/regression-test/data/query_p0/aggregate/map_agg.out differ
diff --git a/regression-test/suites/query_p0/aggregate/map_agg.groovy
b/regression-test/suites/query_p0/aggregate/map_agg.groovy
index 06a6ce53da8..e98ce3635ee 100644
--- a/regression-test/suites/query_p0/aggregate/map_agg.groovy
+++ b/regression-test/suites/query_p0/aggregate/map_agg.groovy
@@ -357,4 +357,56 @@ suite("map_agg") {
qt_test_dumplicate "select k2, m['b'] from (select k2, map_agg(v1, v2) m
from `test_map_agg_2` group by k2) a order by k2;"
qt_test_null "select k2, m[null] from (select k2, map_agg(v1, v2) m from
`test_map_agg_2` group by k2) a order by k2;"
+
+ sql "DROP TABLE IF EXISTS `test_map_agg_datetime`;"
+ sql """
+ CREATE TABLE `test_map_agg_datetime` (
+ `k1` int NULL,
+ `v1` date NULL,
+ `v2` datetime NULL,
+ `v3` text NULL
+ ) ENGINE=OLAP
+ DUPLICATE KEY(`k1`)
+ DISTRIBUTED BY HASH(`k1`) BUCKETS 1
+ PROPERTIES ( 'replication_num' = '1');
+ """
+
+ sql """
+ insert into `test_map_agg_datetime` values
+ ( 1 , '2012-01-02' , '2012-01-02 01:01:01' , 'j' ),
+ ( 1 , '2012-02-02' , '2012-01-07 22:01:01' , 'a3' ),
+ ( 1 , '2012-03-02' , '2012-03-02 01:01:01' , 'a5' ),
+ ( 2 , '2012-01-02' , '2012-03-02 01:01:01' , 'ee' ),
+ ( 2 , null , null , 'a' ),
+ ( 2 , '2012-01-02' , '2012-01-07 22:01:01' , 'a' ),
+ ( 3 , '2012-07-02' , '2012-01-07 22:01:01' , 'c' ),
+ ( 3 , null , '2012-03-02 01:01:01' , '3' ),
+ ( 3 , '2012-08-02' , null , 'e' ),
+ ( 4 , '2012-01-02' , '2012-01-02 01:01:01' , 'a' ),
+ ( 4 , '2012-04-02' , '2012-03-02 01:01:01' , 'b' ),
+ ( 4 , null , '2012-03-04 01:01:01' , '2' ),
+ ( 4 , null , '2012-01-07 22:01:01' , null );
+ """
+
+ qt_test_datetimev2 """
+ select
+ k1
+ , m1[cast('2012-01-02' as date)] v1
+ , m1[cast('2012-02-02' as date)] v2
+ , m1[cast('2012-04-02' as date)] v3
+ , m2[cast('2012-03-02 01:01:01' as datetime)] v4
+ , m2[cast('2012-03-02 01:01:01' as datetime)] v5
+ , m2[cast('2012-01-07 22:01:01' as datetime)] v6
+ , m3[time(cast('2012-03-02 01:01:01' as datetime))] v7
+ , m3[time(cast('2012-01-07 22:01:01' as datetime))] v8
+ from (
+ select
+ k1
+ , map_agg(`v1`, `v3`) m1
+ , map_agg(`v2`, `v3`) m2
+ , map_agg(time(`v2`), `v3`) m3
+ from `test_map_agg_datetime`
+ group by k1
+ ) a order by k1;
+ """
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]