You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by mo...@apache.org on 2022/07/02 15:33:15 UTC
[doris] branch dev-1.0.1 updated: [hotfix][feature](dev-1.0.1) support `max_by` and `min_by` on row-based engine (#10555)
This is an automated email from the ASF dual-hosted git repository.
morningman pushed a commit to branch dev-1.0.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/dev-1.0.1 by this push:
new c89166ffd4 [hotfix][feature](dev-1.0.1) support `max_by` and `min_by` on row-based engine (#10555)
c89166ffd4 is described below
commit c89166ffd4ee2fa5b6cbbea0ed909741eb2a39af
Author: Gabriel <ga...@gmail.com>
AuthorDate: Sat Jul 2 23:33:11 2022 +0800
[hotfix][feature](dev-1.0.1) support `max_by` and `min_by` on row-based engine (#10555)
This is because in previous, we only implement `max/min_by` function in vec engine.
But the vec is not working well will outer join operation for now, so use can not use
`max/min_by` with outer join in vec engine.
So I implement the `max/min_by` in non-vec engine so that user can use it in non-vec.
This is just a compromise way and I just push it to dev-1.0.1 branch.
We are still working on supporting outer join in vec engine in master branch.
So maybe I will not push this implement to master branch.
---
be/src/exprs/aggregate_functions.cpp | 441 ++++++++++++++++++++-
be/src/exprs/aggregate_functions.h | 14 +
.../org/apache/doris/analysis/AggregateInfo.java | 5 +-
.../java/org/apache/doris/catalog/FunctionSet.java | 167 +++++++-
4 files changed, 608 insertions(+), 19 deletions(-)
diff --git a/be/src/exprs/aggregate_functions.cpp b/be/src/exprs/aggregate_functions.cpp
index 3e2f4b3fe5..885c52d5fe 100644
--- a/be/src/exprs/aggregate_functions.cpp
+++ b/be/src/exprs/aggregate_functions.cpp
@@ -363,6 +363,295 @@ struct DecimalV2AvgState {
int64_t count = 0;
};
+template <typename T, typename KT>
+struct MaxMinByState {
+ T val1;
+ KT val2;
+ bool flag = false;
+};
+
+template <typename T, typename KT>
+struct MaxMinByStateWithString {
+ T val1;
+ KT val2;
+ bool flag = false;
+
+ static const int STRING_LENGTH_RECORD_LENGTH = 4;
+ StringVal serialize(FunctionContext* ctx) {
+ // calculate total serialize buffer length
+ int total_serialized_set_length = 1;
+ if constexpr (std::is_same_v<StringVal, T>) {
+ total_serialized_set_length += STRING_LENGTH_RECORD_LENGTH + ((StringVal)val1).len;
+ } else {
+ total_serialized_set_length += STRING_LENGTH_RECORD_LENGTH + sizeof(T);
+ }
+
+ if constexpr (std::is_same_v<StringVal, KT>) {
+ total_serialized_set_length += STRING_LENGTH_RECORD_LENGTH + ((StringVal)val2).len;
+ } else {
+ total_serialized_set_length += STRING_LENGTH_RECORD_LENGTH + sizeof(KT);
+ }
+
+ StringVal result(ctx, total_serialized_set_length);
+ uint8_t* writer = result.ptr;
+ // type
+ *writer = flag;
+ writer++;
+
+ if constexpr (std::is_same_v<StringVal, T>) {
+ *(int*)writer = ((StringVal)val1).len;
+ writer += STRING_LENGTH_RECORD_LENGTH;
+ memcpy(writer, ((StringVal)val1).ptr, ((StringVal)val1).len);
+ writer += ((StringVal)val1).len;
+ } else {
+ *(int*)writer = sizeof(T);
+ writer += STRING_LENGTH_RECORD_LENGTH;
+ *(T*)writer = val1;
+ writer += sizeof(T);
+ }
+
+ if constexpr (std::is_same_v<StringVal, KT>) {
+ *(int*)writer = ((StringVal)val2).len;
+ writer += STRING_LENGTH_RECORD_LENGTH;
+ memcpy(writer, ((StringVal)val2).ptr, ((StringVal)val2).len);
+ } else {
+ *(int*)writer = sizeof(KT);
+ writer += STRING_LENGTH_RECORD_LENGTH;
+ *(KT*)writer = val2;
+ }
+ return result;
+ }
+
+ void deserialize(const StringVal& src) {
+ uint8_t* reader = src.ptr;
+ // skip type ,no used now
+ flag = (bool)*reader;
+ reader++;
+ const uint8_t* end = src.ptr + src.len;
+
+ const int val1_length = *(int*)reader;
+ reader += STRING_LENGTH_RECORD_LENGTH;
+
+ if constexpr (std::is_same_v<StringVal, T>) {
+ StringVal value((uint8_t*)reader, val1_length);
+ val1 = value;
+ } else {
+ val1 = *(T*)reader;
+ }
+ reader += val1_length;
+
+ const int val2_length = *(int*)reader;
+ reader += STRING_LENGTH_RECORD_LENGTH;
+ if constexpr (std::is_same_v<StringVal, KT>) {
+ StringVal value((uint8_t*)reader, val2_length);
+ val2 = value;
+ } else {
+ val2 = *(KT*)reader;
+ }
+ reader += val2_length;
+ DCHECK(reader == end);
+ }
+};
+
+template <typename T, typename KT>
+void AggregateFunctions::maxminby_init(FunctionContext* ctx, StringVal* dst) {
+ dst->is_null = false;
+ int len;
+ if constexpr (std::is_same_v<T, StringVal> || std::is_same_v<KT, StringVal>) {
+ len = sizeof(MaxMinByStateWithString<T, KT>);
+ dst->ptr = (uint8_t*)new MaxMinByStateWithString<T, KT>;
+ } else {
+ len = sizeof(MaxMinByState<T, KT>);
+ dst->ptr = (uint8_t*)new MaxMinByState<T, KT>;
+ }
+ dst->len = len;
+}
+
+template <typename T, bool max_by_fn>
+constexpr bool maxminby_compare(T x, T y) {
+ if constexpr (max_by_fn) {
+ if constexpr (std::is_same_v<T, StringVal>) {
+ return x.to_string() > y.to_string();
+ } else if constexpr (std::is_same_v<T, DateTimeVal>) {
+ return x.packed_time > y.packed_time;
+ } else {
+ return x.val > y.val;
+ }
+ } else {
+ if constexpr (std::is_same_v<T, StringVal>) {
+ return x.to_string() < y.to_string();
+ } else if constexpr (std::is_same_v<T, DateTimeVal>) {
+ return x.packed_time < y.packed_time;
+ } else {
+ return x.val < y.val;
+ }
+ }
+}
+
+template <typename T, typename KT, bool max_by_fn>
+void AggregateFunctions::maxminby_update(FunctionContext* ctx, const T& slot1, const KT& slot2,
+ StringVal* dst) {
+ if (slot1.is_null) {
+ return;
+ }
+ DCHECK(dst->ptr != nullptr);
+ if constexpr (std::is_same_v<T, StringVal> || std::is_same_v<KT, StringVal>) {
+ DCHECK_EQ(sizeof(MaxMinByStateWithString<T, KT>), dst->len);
+ auto max_by = reinterpret_cast<MaxMinByStateWithString<T, KT>*>(dst->ptr);
+
+ bool condition = !max_by->flag || maxminby_compare<KT, max_by_fn>(slot2, max_by->val2);
+ if (condition) {
+ if constexpr (std::is_same_v<T, StringVal>) {
+ max_by->val1 = StringVal::copy_from(ctx, slot1.ptr, slot1.len);
+ } else {
+ max_by->val1 = slot1;
+ }
+ if constexpr (std::is_same_v<KT, StringVal>) {
+ max_by->val2 = StringVal::copy_from(ctx, slot2.ptr, slot2.len);
+ } else {
+ max_by->val2 = slot2;
+ }
+ if (!max_by->flag) {
+ max_by->flag = true;
+ }
+ }
+ } else {
+ DCHECK_EQ(sizeof(MaxMinByState<T, KT>), dst->len);
+ auto max_by = reinterpret_cast<MaxMinByState<T, KT>*>(dst->ptr);
+
+ bool condition = !max_by->flag || maxminby_compare<KT, max_by_fn>(slot2, max_by->val2);
+ ;
+ if (condition) {
+ max_by->val1 = slot1;
+ max_by->val2 = slot2;
+ if (!max_by->flag) {
+ max_by->flag = true;
+ }
+ }
+ }
+}
+
+template <typename T, typename KT>
+StringVal AggregateFunctions::maxminby_serialize(FunctionContext* ctx, const StringVal& src) {
+ DCHECK(!src.is_null);
+ if constexpr (std::is_same_v<T, StringVal> || std::is_same_v<KT, StringVal>) {
+ auto state = reinterpret_cast<MaxMinByStateWithString<T, KT>*>(src.ptr);
+ StringVal result = state->serialize(ctx);
+ delete (MaxMinByStateWithString<T, KT>*)src.ptr;
+ return result;
+ } else {
+ StringVal result(ctx, src.len);
+ memcpy(result.ptr, src.ptr, src.len);
+ delete (MaxMinByState<T, KT>*)src.ptr;
+ return result;
+ }
+}
+
+template <typename T, typename KT, bool max_by_fn>
+void AggregateFunctions::maxminby_merge(FunctionContext* ctx, const StringVal& src,
+ StringVal* dst) {
+ if (src.is_null || src.ptr == nullptr) {
+ return;
+ }
+ DCHECK(dst->ptr != nullptr);
+
+ if constexpr (std::is_same_v<T, StringVal> || std::is_same_v<KT, StringVal>) {
+ DCHECK_EQ(sizeof(MaxMinByStateWithString<T, KT>), dst->len);
+
+ // deserialize src
+ StringVal src_state_val;
+ int len = sizeof(MaxMinByStateWithString<T, KT>);
+ src_state_val.is_null = false;
+ src_state_val.len = len;
+ src_state_val.ptr = (uint8_t*)new MaxMinByStateWithString<T, KT>;
+ auto src_state = reinterpret_cast<MaxMinByStateWithString<T, KT>*>(src_state_val.ptr);
+ src_state->deserialize(src);
+
+ auto max_by2 = reinterpret_cast<MaxMinByStateWithString<T, KT>*>(dst->ptr);
+ if (!src_state->flag) {
+ return;
+ }
+ bool condition = max_by2->flag == 0 ||
+ maxminby_compare<KT, max_by_fn>(src_state->val2, max_by2->val2);
+ if (condition) {
+ if constexpr (std::is_same_v<T, StringVal>) {
+ max_by2->val1 = StringVal::copy_from(ctx, src_state->val1.ptr, src_state->val1.len);
+ } else {
+ max_by2->val1 = src_state->val1;
+ }
+ if constexpr (std::is_same_v<KT, StringVal>) {
+ max_by2->val2 = StringVal::copy_from(ctx, src_state->val2.ptr, src_state->val2.len);
+ } else {
+ max_by2->val2 = src_state->val2;
+ }
+ if (!max_by2->flag) {
+ max_by2->flag = true;
+ }
+ }
+ } else {
+ DCHECK_EQ(sizeof(MaxMinByState<T, KT>), dst->len);
+ auto max_by1 = reinterpret_cast<MaxMinByState<T, KT>*>(src.ptr);
+ auto max_by2 = reinterpret_cast<MaxMinByState<T, KT>*>(dst->ptr);
+ if (!max_by1->flag) {
+ return;
+ }
+ bool condition =
+ max_by2->flag == 0 || maxminby_compare<KT, max_by_fn>(max_by1->val2, max_by2->val2);
+ ;
+ if (condition) {
+ max_by2->val2 = max_by1->val2;
+ max_by2->val1 = max_by1->val1;
+ if (!max_by2->flag) {
+ max_by2->flag = true;
+ }
+ }
+ }
+}
+
+template <typename T, typename KT>
+T AggregateFunctions::maxminby_get_value(FunctionContext* ctx, const StringVal& src) {
+ if (src.ptr == nullptr) {
+ return T::null();
+ }
+
+ if constexpr (std::is_same_v<T, StringVal> || std::is_same_v<KT, StringVal>) {
+ auto state = reinterpret_cast<MaxMinByStateWithString<T, KT>*>(src.ptr);
+ if (!state->flag) {
+ return T::null();
+ }
+ if constexpr (std::is_same_v<T, StringVal>) {
+ return StringVal::copy_from(ctx, state->val1.ptr, state->val1.len);
+ } else {
+ return state->val1;
+ }
+ } else {
+ auto state = reinterpret_cast<MaxMinByState<T, KT>*>(src.ptr);
+ if (!state->flag) {
+ return T::null();
+ }
+ return state->val1;
+ }
+}
+
+template <typename T, typename KT>
+T AggregateFunctions::maxminby_finalize(doris_udf::FunctionContext* ctx,
+ const doris_udf::StringVal& src) {
+ if (src.ptr == nullptr) {
+ return T::null();
+ }
+ if (src.is_null) {
+ return T::null();
+ }
+ T result = maxminby_get_value<T, KT>(ctx, src);
+
+ if constexpr (std::is_same_v<T, StringVal> || std::is_same_v<KT, StringVal>) {
+ delete (MaxMinByStateWithString<T, KT>*)src.ptr;
+ } else {
+ delete (MaxMinByState<T, KT>*)src.ptr;
+ }
+ return result;
+}
+
void AggregateFunctions::avg_init(FunctionContext* ctx, StringVal* dst) {
dst->is_null = false;
dst->len = sizeof(AvgState);
@@ -1077,7 +1366,7 @@ void AggregateFunctions::hll_merge(FunctionContext* ctx, const StringVal& src, S
DCHECK(!src.is_null);
DCHECK_EQ(dst->len, std::pow(2, HLL_COLUMN_PRECISION));
DCHECK_EQ(src.len, std::pow(2, HLL_COLUMN_PRECISION));
-
+
for (int i = 0; i < src.len; ++i) {
dst->ptr[i] = (dst->ptr[i] < src.ptr[i] ? src.ptr[i] : dst->ptr[i]);
}
@@ -2670,6 +2959,156 @@ template void AggregateFunctions::avg_remove<doris_udf::SmallIntVal>(doris_udf::
doris_udf::SmallIntVal const&,
doris_udf::StringVal*);
+#define MAXMINBY_FUNCTION(TYPE_T, TYPE_KT) \
+ template void AggregateFunctions::maxminby_merge<TYPE_T, TYPE_KT, true>( \
+ FunctionContext * ctx, const StringVal& src, StringVal* dst); \
+ template void AggregateFunctions::maxminby_merge<TYPE_T, TYPE_KT, false>( \
+ FunctionContext * ctx, const StringVal& src, StringVal* dst); \
+ template StringVal AggregateFunctions::maxminby_serialize<TYPE_T, TYPE_KT>( \
+ FunctionContext * ctx, const StringVal& src); \
+ template TYPE_T AggregateFunctions::maxminby_get_value<TYPE_T, TYPE_KT>(FunctionContext * ctx, \
+ const StringVal& src); \
+ template TYPE_T AggregateFunctions::maxminby_finalize<TYPE_T, TYPE_KT>(FunctionContext * ctx, \
+ const StringVal& src); \
+ template void AggregateFunctions::maxminby_init<TYPE_T, TYPE_KT>( \
+ doris_udf::FunctionContext * ctx, doris_udf::StringVal * dst); \
+ template void AggregateFunctions::maxminby_update<TYPE_T, TYPE_KT, false>( \
+ doris_udf::FunctionContext*, TYPE_T const&, TYPE_KT const&, doris_udf::StringVal*); \
+ template void AggregateFunctions::maxminby_update<TYPE_T, TYPE_KT, true>( \
+ doris_udf::FunctionContext*, TYPE_T const&, TYPE_KT const&, doris_udf::StringVal*);
+
+MAXMINBY_FUNCTION(doris_udf::TinyIntVal, doris_udf::TinyIntVal)
+MAXMINBY_FUNCTION(doris_udf::TinyIntVal, doris_udf::IntVal)
+MAXMINBY_FUNCTION(doris_udf::TinyIntVal, doris_udf::SmallIntVal)
+MAXMINBY_FUNCTION(doris_udf::TinyIntVal, doris_udf::BigIntVal)
+MAXMINBY_FUNCTION(doris_udf::TinyIntVal, doris_udf::LargeIntVal)
+MAXMINBY_FUNCTION(doris_udf::TinyIntVal, doris_udf::FloatVal)
+MAXMINBY_FUNCTION(doris_udf::TinyIntVal, doris_udf::DoubleVal)
+MAXMINBY_FUNCTION(doris_udf::TinyIntVal, doris_udf::DecimalV2Val)
+MAXMINBY_FUNCTION(doris_udf::TinyIntVal, doris_udf::BooleanVal)
+MAXMINBY_FUNCTION(doris_udf::TinyIntVal, doris_udf::DateTimeVal)
+MAXMINBY_FUNCTION(doris_udf::TinyIntVal, doris_udf::StringVal)
+
+MAXMINBY_FUNCTION(doris_udf::SmallIntVal, doris_udf::TinyIntVal)
+MAXMINBY_FUNCTION(doris_udf::SmallIntVal, doris_udf::IntVal)
+MAXMINBY_FUNCTION(doris_udf::SmallIntVal, doris_udf::SmallIntVal)
+MAXMINBY_FUNCTION(doris_udf::SmallIntVal, doris_udf::BigIntVal)
+MAXMINBY_FUNCTION(doris_udf::SmallIntVal, doris_udf::LargeIntVal)
+MAXMINBY_FUNCTION(doris_udf::SmallIntVal, doris_udf::FloatVal)
+MAXMINBY_FUNCTION(doris_udf::SmallIntVal, doris_udf::DoubleVal)
+MAXMINBY_FUNCTION(doris_udf::SmallIntVal, doris_udf::DecimalV2Val)
+MAXMINBY_FUNCTION(doris_udf::SmallIntVal, doris_udf::BooleanVal)
+MAXMINBY_FUNCTION(doris_udf::SmallIntVal, doris_udf::DateTimeVal)
+MAXMINBY_FUNCTION(doris_udf::SmallIntVal, doris_udf::StringVal)
+
+MAXMINBY_FUNCTION(doris_udf::IntVal, doris_udf::TinyIntVal)
+MAXMINBY_FUNCTION(doris_udf::IntVal, doris_udf::IntVal)
+MAXMINBY_FUNCTION(doris_udf::IntVal, doris_udf::SmallIntVal)
+MAXMINBY_FUNCTION(doris_udf::IntVal, doris_udf::BigIntVal)
+MAXMINBY_FUNCTION(doris_udf::IntVal, doris_udf::LargeIntVal)
+MAXMINBY_FUNCTION(doris_udf::IntVal, doris_udf::FloatVal)
+MAXMINBY_FUNCTION(doris_udf::IntVal, doris_udf::DoubleVal)
+MAXMINBY_FUNCTION(doris_udf::IntVal, doris_udf::DecimalV2Val)
+MAXMINBY_FUNCTION(doris_udf::IntVal, doris_udf::BooleanVal)
+MAXMINBY_FUNCTION(doris_udf::IntVal, doris_udf::DateTimeVal)
+MAXMINBY_FUNCTION(doris_udf::IntVal, doris_udf::StringVal)
+
+MAXMINBY_FUNCTION(doris_udf::BigIntVal, doris_udf::TinyIntVal)
+MAXMINBY_FUNCTION(doris_udf::BigIntVal, doris_udf::IntVal)
+MAXMINBY_FUNCTION(doris_udf::BigIntVal, doris_udf::SmallIntVal)
+MAXMINBY_FUNCTION(doris_udf::BigIntVal, doris_udf::BigIntVal)
+MAXMINBY_FUNCTION(doris_udf::BigIntVal, doris_udf::LargeIntVal)
+MAXMINBY_FUNCTION(doris_udf::BigIntVal, doris_udf::FloatVal)
+MAXMINBY_FUNCTION(doris_udf::BigIntVal, doris_udf::DoubleVal)
+MAXMINBY_FUNCTION(doris_udf::BigIntVal, doris_udf::DecimalV2Val)
+MAXMINBY_FUNCTION(doris_udf::BigIntVal, doris_udf::BooleanVal)
+MAXMINBY_FUNCTION(doris_udf::BigIntVal, doris_udf::DateTimeVal)
+MAXMINBY_FUNCTION(doris_udf::BigIntVal, doris_udf::StringVal)
+
+MAXMINBY_FUNCTION(doris_udf::LargeIntVal, doris_udf::TinyIntVal)
+MAXMINBY_FUNCTION(doris_udf::LargeIntVal, doris_udf::IntVal)
+MAXMINBY_FUNCTION(doris_udf::LargeIntVal, doris_udf::SmallIntVal)
+MAXMINBY_FUNCTION(doris_udf::LargeIntVal, doris_udf::BigIntVal)
+MAXMINBY_FUNCTION(doris_udf::LargeIntVal, doris_udf::LargeIntVal)
+MAXMINBY_FUNCTION(doris_udf::LargeIntVal, doris_udf::FloatVal)
+MAXMINBY_FUNCTION(doris_udf::LargeIntVal, doris_udf::DoubleVal)
+MAXMINBY_FUNCTION(doris_udf::LargeIntVal, doris_udf::DecimalV2Val)
+MAXMINBY_FUNCTION(doris_udf::LargeIntVal, doris_udf::BooleanVal)
+MAXMINBY_FUNCTION(doris_udf::LargeIntVal, doris_udf::DateTimeVal)
+MAXMINBY_FUNCTION(doris_udf::LargeIntVal, doris_udf::StringVal)
+
+MAXMINBY_FUNCTION(doris_udf::FloatVal, doris_udf::TinyIntVal)
+MAXMINBY_FUNCTION(doris_udf::FloatVal, doris_udf::IntVal)
+MAXMINBY_FUNCTION(doris_udf::FloatVal, doris_udf::SmallIntVal)
+MAXMINBY_FUNCTION(doris_udf::FloatVal, doris_udf::BigIntVal)
+MAXMINBY_FUNCTION(doris_udf::FloatVal, doris_udf::LargeIntVal)
+MAXMINBY_FUNCTION(doris_udf::FloatVal, doris_udf::FloatVal)
+MAXMINBY_FUNCTION(doris_udf::FloatVal, doris_udf::DoubleVal)
+MAXMINBY_FUNCTION(doris_udf::FloatVal, doris_udf::DecimalV2Val)
+MAXMINBY_FUNCTION(doris_udf::FloatVal, doris_udf::BooleanVal)
+MAXMINBY_FUNCTION(doris_udf::FloatVal, doris_udf::DateTimeVal)
+MAXMINBY_FUNCTION(doris_udf::FloatVal, doris_udf::StringVal)
+
+MAXMINBY_FUNCTION(doris_udf::DoubleVal, doris_udf::TinyIntVal)
+MAXMINBY_FUNCTION(doris_udf::DoubleVal, doris_udf::IntVal)
+MAXMINBY_FUNCTION(doris_udf::DoubleVal, doris_udf::SmallIntVal)
+MAXMINBY_FUNCTION(doris_udf::DoubleVal, doris_udf::BigIntVal)
+MAXMINBY_FUNCTION(doris_udf::DoubleVal, doris_udf::LargeIntVal)
+MAXMINBY_FUNCTION(doris_udf::DoubleVal, doris_udf::FloatVal)
+MAXMINBY_FUNCTION(doris_udf::DoubleVal, doris_udf::DoubleVal)
+MAXMINBY_FUNCTION(doris_udf::DoubleVal, doris_udf::DecimalV2Val)
+MAXMINBY_FUNCTION(doris_udf::DoubleVal, doris_udf::BooleanVal)
+MAXMINBY_FUNCTION(doris_udf::DoubleVal, doris_udf::DateTimeVal)
+MAXMINBY_FUNCTION(doris_udf::DoubleVal, doris_udf::StringVal)
+
+MAXMINBY_FUNCTION(doris_udf::DecimalV2Val, doris_udf::TinyIntVal)
+MAXMINBY_FUNCTION(doris_udf::DecimalV2Val, doris_udf::IntVal)
+MAXMINBY_FUNCTION(doris_udf::DecimalV2Val, doris_udf::SmallIntVal)
+MAXMINBY_FUNCTION(doris_udf::DecimalV2Val, doris_udf::BigIntVal)
+MAXMINBY_FUNCTION(doris_udf::DecimalV2Val, doris_udf::LargeIntVal)
+MAXMINBY_FUNCTION(doris_udf::DecimalV2Val, doris_udf::FloatVal)
+MAXMINBY_FUNCTION(doris_udf::DecimalV2Val, doris_udf::DoubleVal)
+MAXMINBY_FUNCTION(doris_udf::DecimalV2Val, doris_udf::DecimalV2Val)
+MAXMINBY_FUNCTION(doris_udf::DecimalV2Val, doris_udf::BooleanVal)
+MAXMINBY_FUNCTION(doris_udf::DecimalV2Val, doris_udf::DateTimeVal)
+MAXMINBY_FUNCTION(doris_udf::DecimalV2Val, doris_udf::StringVal)
+
+MAXMINBY_FUNCTION(doris_udf::BooleanVal, doris_udf::TinyIntVal)
+MAXMINBY_FUNCTION(doris_udf::BooleanVal, doris_udf::IntVal)
+MAXMINBY_FUNCTION(doris_udf::BooleanVal, doris_udf::SmallIntVal)
+MAXMINBY_FUNCTION(doris_udf::BooleanVal, doris_udf::BigIntVal)
+MAXMINBY_FUNCTION(doris_udf::BooleanVal, doris_udf::LargeIntVal)
+MAXMINBY_FUNCTION(doris_udf::BooleanVal, doris_udf::FloatVal)
+MAXMINBY_FUNCTION(doris_udf::BooleanVal, doris_udf::DoubleVal)
+MAXMINBY_FUNCTION(doris_udf::BooleanVal, doris_udf::DecimalV2Val)
+MAXMINBY_FUNCTION(doris_udf::BooleanVal, doris_udf::BooleanVal)
+MAXMINBY_FUNCTION(doris_udf::BooleanVal, doris_udf::DateTimeVal)
+MAXMINBY_FUNCTION(doris_udf::BooleanVal, doris_udf::StringVal)
+
+MAXMINBY_FUNCTION(doris_udf::DateTimeVal, doris_udf::TinyIntVal)
+MAXMINBY_FUNCTION(doris_udf::DateTimeVal, doris_udf::IntVal)
+MAXMINBY_FUNCTION(doris_udf::DateTimeVal, doris_udf::SmallIntVal)
+MAXMINBY_FUNCTION(doris_udf::DateTimeVal, doris_udf::BigIntVal)
+MAXMINBY_FUNCTION(doris_udf::DateTimeVal, doris_udf::LargeIntVal)
+MAXMINBY_FUNCTION(doris_udf::DateTimeVal, doris_udf::FloatVal)
+MAXMINBY_FUNCTION(doris_udf::DateTimeVal, doris_udf::DoubleVal)
+MAXMINBY_FUNCTION(doris_udf::DateTimeVal, doris_udf::DecimalV2Val)
+MAXMINBY_FUNCTION(doris_udf::DateTimeVal, doris_udf::BooleanVal)
+MAXMINBY_FUNCTION(doris_udf::DateTimeVal, doris_udf::DateTimeVal)
+MAXMINBY_FUNCTION(doris_udf::DateTimeVal, doris_udf::StringVal)
+
+MAXMINBY_FUNCTION(doris_udf::StringVal, doris_udf::TinyIntVal)
+MAXMINBY_FUNCTION(doris_udf::StringVal, doris_udf::IntVal)
+MAXMINBY_FUNCTION(doris_udf::StringVal, doris_udf::SmallIntVal)
+MAXMINBY_FUNCTION(doris_udf::StringVal, doris_udf::BigIntVal)
+MAXMINBY_FUNCTION(doris_udf::StringVal, doris_udf::LargeIntVal)
+MAXMINBY_FUNCTION(doris_udf::StringVal, doris_udf::FloatVal)
+MAXMINBY_FUNCTION(doris_udf::StringVal, doris_udf::DoubleVal)
+MAXMINBY_FUNCTION(doris_udf::StringVal, doris_udf::DecimalV2Val)
+MAXMINBY_FUNCTION(doris_udf::StringVal, doris_udf::BooleanVal)
+MAXMINBY_FUNCTION(doris_udf::StringVal, doris_udf::DateTimeVal)
+MAXMINBY_FUNCTION(doris_udf::StringVal, doris_udf::StringVal)
+
template void AggregateFunctions::max_init<BooleanVal>(doris_udf::FunctionContext*,
BooleanVal* dst);
template void AggregateFunctions::max_init<TinyIntVal>(doris_udf::FunctionContext*,
diff --git a/be/src/exprs/aggregate_functions.h b/be/src/exprs/aggregate_functions.h
index de96cccf10..b0cda34e60 100644
--- a/be/src/exprs/aggregate_functions.h
+++ b/be/src/exprs/aggregate_functions.h
@@ -104,6 +104,20 @@ public:
static StringVal percentile_approx_serialize(FunctionContext* ctx, const StringVal& state_sv);
+ template <typename T, typename KT>
+ static void maxminby_init(doris_udf::FunctionContext* ctx, doris_udf::StringVal* dst);
+ template <typename T, typename KT, bool max_by_fn>
+ static void maxminby_update(doris_udf::FunctionContext* ctx, const T& slot1, const KT& slot2,
+ doris_udf::StringVal* dst);
+ template <typename T, typename KT>
+ static StringVal maxminby_serialize(FunctionContext* ctx, const StringVal& src);
+ template <typename T, typename KT, bool max_by_fn>
+ static void maxminby_merge(FunctionContext* ctx, const StringVal& src, StringVal* dst);
+ template <typename T, typename KT>
+ static T maxminby_get_value(doris_udf::FunctionContext* ctx, const doris_udf::StringVal& val);
+ template <typename T, typename KT>
+ static T maxminby_finalize(doris_udf::FunctionContext* ctx, const doris_udf::StringVal& val);
+
// Implementation of Avg.
// TODO: Change this to use a fixed-sized BufferVal as intermediate type.
static void avg_init(doris_udf::FunctionContext* ctx, doris_udf::StringVal* dst);
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/AggregateInfo.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/AggregateInfo.java
index f02d15c7b9..74facd0a55 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/AggregateInfo.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/AggregateInfo.java
@@ -19,6 +19,7 @@ package org.apache.doris.analysis;
import org.apache.doris.catalog.FunctionSet;
import org.apache.doris.common.AnalysisException;
+import org.apache.doris.common.util.VectorizedUtil;
import org.apache.doris.planner.DataPartition;
import org.apache.doris.thrift.TPartitionType;
@@ -455,8 +456,8 @@ public final class AggregateInfo extends AggregateInfoBase {
List<Expr> paramExprs = new ArrayList<>();
// TODO(zhannngchen), change intermediate argument to a list, and remove this
// ad-hoc logic
- if (inputExpr.fn.functionName().equals("max_by") ||
- inputExpr.fn.functionName().equals("min_by")) {
+ if ((inputExpr.fn.functionName().equals("max_by") ||
+ inputExpr.fn.functionName().equals("min_by")) && VectorizedUtil.isVectorized()) {
paramExprs.addAll(inputExpr.getFnParams().exprs());
} else {
paramExprs.add(new SlotRef(inputDesc.getSlots().get(i + getGroupingExprs().size())));
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
index 8096d14631..d0ff5711f3 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
@@ -402,8 +402,8 @@ public class FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo
.put(Type.DECIMALV2,
"16knuth_var_updateEPN9doris_udf15FunctionContextERKNS1_12DecimalV2ValEPNS1_9StringValE")
.build();
-
-
+
+
private static final Map<Type, String> STDDEV_REMOVE_SYMBOL =
ImmutableMap.<Type, String>builder()
.put(Type.TINYINT,
@@ -420,7 +420,7 @@ public class FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo
"16knuth_var_removeIN9doris_udf9DoubleValEEEvPNS2_15FunctionContextERKT_PNS2_9StringValE")
.put(Type.DECIMALV2,
"16knuth_var_removeEPN9doris_udf15FunctionContextERKNS1_12DecimalV2ValEPNS1_9StringValE")
- .build();
+ .build();
private static final Map<Type, String> STDDEV_MERGE_SYMBOL =
ImmutableMap.<Type, String>builder()
.put(Type.TINYINT,
@@ -509,8 +509,8 @@ public class FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo
"26knuth_stddev_pop_get_valueEPN9doris_udf15FunctionContextERKNS1_9StringValE")
.put(Type.DECIMALV2,
"36decimalv2_knuth_stddev_pop_get_valueEPN9doris_udf15FunctionContextERKNS1_9StringValE")
- .build();
-
+ .build();
+
private static final Map<Type, String> VAR_FINALIZE_SYMBOL =
ImmutableMap.<Type, String>builder()
.put(Type.TINYINT,
@@ -545,8 +545,8 @@ public class FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo
"19knuth_var_get_valueEPN9doris_udf15FunctionContextERKNS1_9StringValE")
.put(Type.DECIMALV2,
"29decimalv2_knuth_var_get_valueEPN9doris_udf15FunctionContextERKNS1_9StringValE")
- .build();
-
+ .build();
+
private static final Map<Type, String> VAR_POP_FINALIZE_SYMBOL =
ImmutableMap.<Type, String>builder()
.put(Type.TINYINT,
@@ -581,7 +581,7 @@ public class FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo
"23knuth_var_pop_get_valueEPN9doris_udf15FunctionContextERKNS1_9StringValE")
.put(Type.DECIMALV2,
"33decimalv2_knuth_var_pop_get_valueEPN9doris_udf15FunctionContextERKNS1_9StringValE")
- .build();
+ .build();
public static final String HLL_HASH = "hll_hash";
public static final String HLL_UNION = "hll_union";
@@ -1334,6 +1334,141 @@ public class FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo
prefix + "17count_star_removeEPN9doris_udf15FunctionContextEPNS1_9BigIntValE",
null, false, true, true, true));
+ Map<ScalarType, String> symbolsMap = new HashMap<>();
+ symbolsMap.put(Type.INT, "6IntVal");
+ symbolsMap.put(Type.BOOLEAN, "10BooleanVal");
+ symbolsMap.put(Type.FLOAT, "8FloatVal");
+ symbolsMap.put(Type.TINYINT, "10TinyIntVal");
+ symbolsMap.put(Type.SMALLINT, "11SmallIntVal");
+ symbolsMap.put(Type.LARGEINT, "11LargeIntVal");
+ symbolsMap.put(Type.BIGINT, "9BigIntVal");
+ symbolsMap.put(Type.DOUBLE, "9DoubleVal");
+ symbolsMap.put(Type.DECIMALV2, "12DecimalV2Val");
+ symbolsMap.put(Type.DATE, "11DateTimeVal");
+ symbolsMap.put(Type.DATETIME, "11DateTimeVal");
+ symbolsMap.put(Type.STRING, "9StringVal");
+ symbolsMap.put(Type.VARCHAR, "9StringVal");
+ symbolsMap.put(Type.CHAR, "9StringVal");
+ for (ScalarType type1: symbolsMap.keySet()) {
+ for (ScalarType type2: symbolsMap.keySet()) {
+ if (symbolsMap.get(type1).equals(symbolsMap.get(type2)) && !type1.isStringType()) {
+ addBuiltin(AggregateFunction.createBuiltin("max_by",
+ Lists.<Type>newArrayList(type1, type2), type1, Type.VARCHAR,
+ prefix + "13maxminby_initIN9doris_udf" + symbolsMap.get(type1) + "ES3_EEvPNS2_15FunctionContextEPNS2_9StringValE",
+ prefix + "15maxminby_updateIN9doris_udf" + symbolsMap.get(type1) + "ES3_Lb1EEEvPNS2_15FunctionContextERKT_RKT0_PNS2_9StringValE",
+ prefix + "14maxminby_mergeIN9doris_udf" + symbolsMap.get(type1) + "ES3_Lb1EEEvPNS2_15FunctionContextERKNS2_9StringValEPS6_",
+ prefix + "18maxminby_serializeIN9doris_udf" + symbolsMap.get(type1) + "ES3_EENS2_9StringValEPNS2_15FunctionContextERKS4_",
+ prefix + "18maxminby_get_valueIN9doris_udf" + symbolsMap.get(type1) + "ES3_EET_PNS2_15FunctionContextERKNS2_9StringValE",
+ null,
+ prefix + "17maxminby_finalizeIN9doris_udf" + symbolsMap.get(type1) + "ES3_EET_PNS2_15FunctionContextERKNS2_9StringValE",
+ false, true, false));
+ } else if (type1.isStringType() && !symbolsMap.get(type1).equals(symbolsMap.get(type2))) {
+ addBuiltin(AggregateFunction.createBuiltin("max_by",
+ Lists.<Type>newArrayList(type1, type2), type1, Type.VARCHAR,
+ prefix + "13maxminby_initIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEEvPNS2_15FunctionContextEPS3_",
+ prefix + "15maxminby_updateIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "ELb1EEEvPNS2_15FunctionContextERKT_RKT0_PS3_",
+ prefix + "14maxminby_mergeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "ELb1EEEvPNS2_15FunctionContextERKS3_PS3_",
+ prefix + "18maxminby_serializeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEES3_PNS2_15FunctionContextERKS3_",
+ prefix + "18maxminby_get_valueIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEET_PNS2_15FunctionContextERKS3_",
+ null,
+ prefix + "17maxminby_finalizeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEET_PNS2_15FunctionContextERKS3_",
+ false, true, false));
+ } else if (type2.isStringType() && !symbolsMap.get(type1).equals(symbolsMap.get(type2))) {
+ addBuiltin(AggregateFunction.createBuiltin("max_by",
+ Lists.<Type>newArrayList(type1, type2), type1, Type.VARCHAR,
+ prefix + "13maxminby_initIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEEvPNS2_15FunctionContextEPS4_",
+ prefix + "15maxminby_updateIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "ELb1EEEvPNS2_15FunctionContextERKT_RKT0_PS4_",
+ prefix + "14maxminby_mergeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "ELb1EEEvPNS2_15FunctionContextERKS4_PS4_",
+ prefix + "18maxminby_serializeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEES4_PNS2_15FunctionContextERKS4_",
+ prefix + "18maxminby_get_valueIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEET_PNS2_15FunctionContextERKS4_",
+ null,
+ prefix + "17maxminby_finalizeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEET_PNS2_15FunctionContextERKS4_",
+ false, true, false));
+ } else if (type1.isStringType() && symbolsMap.get(type1).equals(symbolsMap.get(type2))) {
+ addBuiltin(AggregateFunction.createBuiltin("max_by",
+ Lists.<Type>newArrayList(type1, type2), type1, Type.VARCHAR,
+ prefix + "13maxminby_initIN9doris_udf" + symbolsMap.get(type1) + "ES3_EEvPNS2_15FunctionContextEPS3_",
+ prefix + "15maxminby_updateIN9doris_udf" + symbolsMap.get(type1) + "ES3_Lb1EEEvPNS2_15FunctionContextERKT_RKT0_PS3_",
+ prefix + "14maxminby_mergeIN9doris_udf" + symbolsMap.get(type1) + "ES3_Lb1EEEvPNS2_15FunctionContextERKS3_PS3_",
+ prefix + "18maxminby_serializeIN9doris_udf" + symbolsMap.get(type1) + "ES3_EES3_PNS2_15FunctionContextERKS3_",
+ prefix + "18maxminby_get_valueIN9doris_udf" + symbolsMap.get(type1) + "ES3_EET_PNS2_15FunctionContextERKS3_",
+ null,
+ prefix + "17maxminby_finalizeIN9doris_udf" + symbolsMap.get(type1) + "ES3_EET_PNS2_15FunctionContextERKS3_",
+ false, true, false));
+ } else {
+ addBuiltin(AggregateFunction.createBuiltin("max_by",
+ Lists.<Type>newArrayList(type1, type2), type1, Type.VARCHAR,
+ prefix + "13maxminby_initIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEEvPNS2_15FunctionContextEPNS2_9StringValE",
+ prefix + "15maxminby_updateIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "ELb1EEEvPNS2_15FunctionContextERKT_RKT0_PNS2_9StringValE",
+ prefix + "14maxminby_mergeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "ELb1EEEvPNS2_15FunctionContextERKNS2_9StringValEPS7_",
+ prefix + "18maxminby_serializeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEENS2_9StringValEPNS2_15FunctionContextERKS5_",
+ prefix + "18maxminby_get_valueIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEET_PNS2_15FunctionContextERKNS2_9StringValE",
+ null,
+ prefix + "17maxminby_finalizeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEET_PNS2_15FunctionContextERKNS2_9StringValE",
+ false, true, false));
+ }
+ }
+ }
+ for (ScalarType type1: symbolsMap.keySet()) {
+ for (ScalarType type2: symbolsMap.keySet()) {
+ if (symbolsMap.get(type1).equals(symbolsMap.get(type2)) && !type1.isStringType()) {
+ addBuiltin(AggregateFunction.createBuiltin("min_by",
+ Lists.<Type>newArrayList(type1, type2), type1, Type.VARCHAR,
+ prefix + "13maxminby_initIN9doris_udf" + symbolsMap.get(type1) + "ES3_EEvPNS2_15FunctionContextEPNS2_9StringValE",
+ prefix + "15maxminby_updateIN9doris_udf" + symbolsMap.get(type1) + "ES3_Lb0EEEvPNS2_15FunctionContextERKT_RKT0_PNS2_9StringValE",
+ prefix + "14maxminby_mergeIN9doris_udf" + symbolsMap.get(type1) + "ES3_Lb0EEEvPNS2_15FunctionContextERKNS2_9StringValEPS6_",
+ prefix + "18maxminby_serializeIN9doris_udf" + symbolsMap.get(type1) + "ES3_EENS2_9StringValEPNS2_15FunctionContextERKS4_",
+ prefix + "18maxminby_get_valueIN9doris_udf" + symbolsMap.get(type1) + "ES3_EET_PNS2_15FunctionContextERKNS2_9StringValE",
+ null,
+ prefix + "17maxminby_finalizeIN9doris_udf" + symbolsMap.get(type1) + "ES3_EET_PNS2_15FunctionContextERKNS2_9StringValE",
+ false, true, false));
+ } else if (type1.isStringType() && !symbolsMap.get(type1).equals(symbolsMap.get(type2))) {
+ addBuiltin(AggregateFunction.createBuiltin("min_by",
+ Lists.<Type>newArrayList(type1, type2), type1, Type.VARCHAR,
+ prefix + "13maxminby_initIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEEvPNS2_15FunctionContextEPS3_",
+ prefix + "15maxminby_updateIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "ELb0EEEvPNS2_15FunctionContextERKT_RKT0_PS3_",
+ prefix + "14maxminby_mergeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "ELb0EEEvPNS2_15FunctionContextERKS3_PS3_",
+ prefix + "18maxminby_serializeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEES3_PNS2_15FunctionContextERKS3_",
+ prefix + "18maxminby_get_valueIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEET_PNS2_15FunctionContextERKS3_",
+ null,
+ prefix + "17maxminby_finalizeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEET_PNS2_15FunctionContextERKS3_",
+ false, true, false));
+ } else if (type2.isStringType() && !symbolsMap.get(type1).equals(symbolsMap.get(type2))) {
+ addBuiltin(AggregateFunction.createBuiltin("min_by",
+ Lists.<Type>newArrayList(type1, type2), type1, Type.VARCHAR,
+ prefix + "13maxminby_initIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEEvPNS2_15FunctionContextEPS4_",
+ prefix + "15maxminby_updateIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "ELb0EEEvPNS2_15FunctionContextERKT_RKT0_PS4_",
+ prefix + "14maxminby_mergeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "ELb0EEEvPNS2_15FunctionContextERKS4_PS4_",
+ prefix + "18maxminby_serializeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEES4_PNS2_15FunctionContextERKS4_",
+ prefix + "18maxminby_get_valueIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEET_PNS2_15FunctionContextERKS4_",
+ null,
+ prefix + "17maxminby_finalizeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEET_PNS2_15FunctionContextERKS4_",
+ false, true, false));
+ } else if (type1.isStringType() && symbolsMap.get(type1).equals(symbolsMap.get(type2))) {
+ addBuiltin(AggregateFunction.createBuiltin("min_by",
+ Lists.<Type>newArrayList(type1, type2), type1, Type.VARCHAR,
+ prefix + "13maxminby_initIN9doris_udf" + symbolsMap.get(type1) + "ES3_EEvPNS2_15FunctionContextEPS3_",
+ prefix + "15maxminby_updateIN9doris_udf" + symbolsMap.get(type1) + "ES3_Lb0EEEvPNS2_15FunctionContextERKT_RKT0_PS3_",
+ prefix + "14maxminby_mergeIN9doris_udf" + symbolsMap.get(type1) + "ES3_Lb0EEEvPNS2_15FunctionContextERKS3_PS3_",
+ prefix + "18maxminby_serializeIN9doris_udf" + symbolsMap.get(type1) + "ES3_EES3_PNS2_15FunctionContextERKS3_",
+ prefix + "18maxminby_get_valueIN9doris_udf" + symbolsMap.get(type1) + "ES3_EET_PNS2_15FunctionContextERKS3_",
+ null,
+ prefix + "17maxminby_finalizeIN9doris_udf" + symbolsMap.get(type1) + "ES3_EET_PNS2_15FunctionContextERKS3_",
+ false, true, false));
+ } else {
+ addBuiltin(AggregateFunction.createBuiltin("min_by",
+ Lists.<Type>newArrayList(type1, type2), type1, Type.VARCHAR,
+ prefix + "13maxminby_initIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEEvPNS2_15FunctionContextEPNS2_9StringValE",
+ prefix + "15maxminby_updateIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "ELb0EEEvPNS2_15FunctionContextERKT_RKT0_PNS2_9StringValE",
+ prefix + "14maxminby_mergeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "ELb0EEEvPNS2_15FunctionContextERKNS2_9StringValEPS7_",
+ prefix + "18maxminby_serializeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEENS2_9StringValEPNS2_15FunctionContextERKS5_",
+ prefix + "18maxminby_get_valueIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEET_PNS2_15FunctionContextERKNS2_9StringValE",
+ null,
+ prefix + "17maxminby_finalizeIN9doris_udf" + symbolsMap.get(type1) + "ENS2_" + symbolsMap.get(type2) + "EEET_PNS2_15FunctionContextERKNS2_9StringValE",
+ false, true, false));
+ }
+ }
+ }
// windowFunnel
addBuiltin(AggregateFunction.createBuiltin(FunctionSet.WINDOW_FUNNEL,
Lists.newArrayList(Type.BIGINT, Type.STRING, Type.DATETIME, Type.BOOLEAN),
@@ -1465,7 +1600,7 @@ public class FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo
prefix + MULTI_DISTINCT_COUNT_FINALIZE_SYMBOL.get(t),
false, true, true, true));
-
+
} else if (t.equals(Type.DATE) || t.equals(Type.DATETIME)) {
addBuiltin(AggregateFunction.createBuiltin("multi_distinct_count", Lists.newArrayList(t),
Type.BIGINT,
@@ -1785,7 +1920,7 @@ public class FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo
null, prefix + STDDEV_POP_GET_VALUE_SYMBOL.get(t), prefix + STDDEV_REMOVE_SYMBOL.get(t),
prefix + STDDEV_POP_FINALIZE_SYMBOL.get(t),
false, true, false));
-
+
addBuiltin(AggregateFunction.createBuiltin("stddev_samp",
Lists.newArrayList(t), STDDEV_RETTYPE_SYMBOL.get(t), Type.VARCHAR,
prefix + STDDEV_INIT_SYMBOL.get(t),
@@ -1829,7 +1964,7 @@ public class FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo
null, null, null,
prefix + STDDEV_POP_FINALIZE_SYMBOL.get(t),
false, true, false, true));
-
+
//vec: variance variance_samp var_samp variance_pop var_pop
addBuiltin(AggregateFunction.createBuiltin("variance",
Lists.newArrayList(t), STDDEV_RETTYPE_SYMBOL.get(t), t,
@@ -1870,7 +2005,7 @@ public class FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo
prefix + STDDEV_MERGE_SYMBOL.get(t),
null, null, null,
prefix + VAR_FINALIZE_SYMBOL.get(t),
- false, true, false, true));
+ false, true, false, true));
addBuiltin(AggregateFunction.createBuiltin("variance",
Lists.newArrayList(t), STDDEV_RETTYPE_SYMBOL.get(t), Type.VARCHAR,
@@ -2109,7 +2244,7 @@ public class FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo
"",
"",
true, false, true, true));
-
+
//Percentile
addBuiltin(AggregateFunction.createBuiltin("percentile",
Lists.newArrayList(Type.BIGINT, Type.DOUBLE), Type.DOUBLE, Type.VARCHAR,
@@ -2164,7 +2299,7 @@ public class FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo
prefix + "23percentile_approx_mergeEPN9doris_udf15FunctionContextERKNS1_9StringValEPS4_",
prefix + "27percentile_approx_serializeEPN9doris_udf15FunctionContextERKNS1_9StringValE",
prefix + "26percentile_approx_finalizeEPN9doris_udf15FunctionContextERKNS1_9StringValE",
- false, true, false, true));
+ false, true, false, true));
// Avg
// TODO: switch to CHAR(sizeof(AvgIntermediateType) when that becomes available
@@ -2320,7 +2455,7 @@ public class FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo
prefix + "17count_star_updateEPN9doris_udf15FunctionContextEPNS1_9BigIntValE",
prefix + "11count_mergeEPN9doris_udf15FunctionContextERKNS1_9BigIntValEPS4_",
null, null));
-
+
//vec Rank
addBuiltin(AggregateFunction.createAnalyticBuiltin("rank",
Lists.<Type>newArrayList(), Type.BIGINT, Type.VARCHAR,
@@ -2399,7 +2534,7 @@ public class FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo
prefix + OFFSET_FN_INIT_SYMBOL.get(t),
prefix + OFFSET_FN_UPDATE_SYMBOL.get(t),
null, t.isStringType() ? stringValGetValue : null, null));
-
+
addBuiltin(AggregateFunction.createAnalyticBuiltin(
"lead", Lists.newArrayList(t, Type.BIGINT, t), t, t,
prefix + OFFSET_FN_INIT_SYMBOL.get(t),
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org