This is an automated email from the ASF dual-hosted git repository.
panxiaolei 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 ab18110bb14 [refine](Agg)Reduce max_by min_by binary size (#54443)
ab18110bb14 is described below
commit ab18110bb144019cd4e03c2a2922d0da143fc7a0
Author: Mryange <[email protected]>
AuthorDate: Fri Aug 15 14:53:54 2025 +0800
[refine](Agg)Reduce max_by min_by binary size (#54443)
Previously, max/(min)_by(exprV, exprK) would expand both the types of
exprV and exprK, instantiating n * n templates.
Here, we only instantiate exprK, and the operations related to exprV are
wrapped using virtual functions. In this way, only n templates are
instantiated.
Previous binary size:
```
361.99 MB
./vec/CMakeFiles/Vec.dir/aggregate_functions/aggregate_function_max_by.cpp.o
361.98 MB
./vec/CMakeFiles/Vec.dir/aggregate_functions/aggregate_function_min_by.cpp.o
```
Now:
```
22.33 MB
./vec/CMakeFiles/Vec.dir/aggregate_functions/aggregate_function_max_by.cpp.o
22.33 MB
./vec/CMakeFiles/Vec.dir/aggregate_functions/aggregate_function_min_by.cpp.o
```
---
.../aggregate_function_min_max_by.cpp | 74 ++++++
.../aggregate_function_min_max_by.h | 259 ++++++++++-----------
.../aggregate/aggregate_max_min_by_test.out | Bin 0 -> 482 bytes
.../aggregate/aggregate_max_min_by_test.groovy | 99 ++++++++
4 files changed, 297 insertions(+), 135 deletions(-)
diff --git a/be/src/vec/aggregate_functions/aggregate_function_min_max_by.cpp
b/be/src/vec/aggregate_functions/aggregate_function_min_max_by.cpp
new file mode 100644
index 00000000000..bc77a327527
--- /dev/null
+++ b/be/src/vec/aggregate_functions/aggregate_function_min_max_by.cpp
@@ -0,0 +1,74 @@
+// 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/aggregate_functions/aggregate_function_min_max_by.h"
+
+namespace doris::vectorized {
+#include "common/compile_check_begin.h"
+std::unique_ptr<MaxMinValueBase> create_max_min_value(const DataTypePtr& type)
{
+ switch (type->get_primitive_type()) {
+ case PrimitiveType::TYPE_BOOLEAN:
+ return
std::make_unique<MaxMinValue<SingleValueDataFixed<TYPE_BOOLEAN>>>();
+ case PrimitiveType::TYPE_TINYINT:
+ return
std::make_unique<MaxMinValue<SingleValueDataFixed<TYPE_TINYINT>>>();
+ case PrimitiveType::TYPE_SMALLINT:
+ return
std::make_unique<MaxMinValue<SingleValueDataFixed<TYPE_SMALLINT>>>();
+ case PrimitiveType::TYPE_INT:
+ return std::make_unique<MaxMinValue<SingleValueDataFixed<TYPE_INT>>>();
+ case PrimitiveType::TYPE_BIGINT:
+ return
std::make_unique<MaxMinValue<SingleValueDataFixed<TYPE_BIGINT>>>();
+ case PrimitiveType::TYPE_LARGEINT:
+ return
std::make_unique<MaxMinValue<SingleValueDataFixed<TYPE_LARGEINT>>>();
+ case PrimitiveType::TYPE_FLOAT:
+ return
std::make_unique<MaxMinValue<SingleValueDataFixed<TYPE_FLOAT>>>();
+ case PrimitiveType::TYPE_DOUBLE:
+ return
std::make_unique<MaxMinValue<SingleValueDataFixed<TYPE_DOUBLE>>>();
+ case PrimitiveType::TYPE_DECIMAL32:
+ return
std::make_unique<MaxMinValue<SingleValueDataDecimal<TYPE_DECIMAL32>>>();
+ case PrimitiveType::TYPE_DECIMAL64:
+ return
std::make_unique<MaxMinValue<SingleValueDataDecimal<TYPE_DECIMAL64>>>();
+ case PrimitiveType::TYPE_DECIMAL128I:
+ return
std::make_unique<MaxMinValue<SingleValueDataDecimal<TYPE_DECIMAL128I>>>();
+ case PrimitiveType::TYPE_DECIMALV2:
+ return
std::make_unique<MaxMinValue<SingleValueDataDecimal<TYPE_DECIMALV2>>>();
+ case PrimitiveType::TYPE_DECIMAL256:
+ return
std::make_unique<MaxMinValue<SingleValueDataDecimal<TYPE_DECIMAL256>>>();
+ case PrimitiveType::TYPE_STRING:
+ case PrimitiveType::TYPE_CHAR:
+ case PrimitiveType::TYPE_VARCHAR:
+ return std::make_unique<MaxMinValue<SingleValueDataString>>();
+ case PrimitiveType::TYPE_DATE:
+ return
std::make_unique<MaxMinValue<SingleValueDataFixed<TYPE_DATE>>>();
+ case PrimitiveType::TYPE_DATETIME:
+ return
std::make_unique<MaxMinValue<SingleValueDataFixed<TYPE_DATETIME>>>();
+ case PrimitiveType::TYPE_DATEV2:
+ return
std::make_unique<MaxMinValue<SingleValueDataFixed<TYPE_DATEV2>>>();
+ case PrimitiveType::TYPE_DATETIMEV2:
+ return
std::make_unique<MaxMinValue<SingleValueDataFixed<TYPE_DATETIMEV2>>>();
+ case PrimitiveType::TYPE_BITMAP:
+ return std::make_unique<MaxMinValue<BitmapValueData>>();
+ default:
+ throw doris::Exception(ErrorCode::INTERNAL_ERROR,
+ "Illegal type {} of argument of aggregate
function min/max_by",
+ type->get_name());
+ return nullptr;
+ }
+}
+
+} // namespace doris::vectorized
+
+#include "common/compile_check_end.h"
diff --git a/be/src/vec/aggregate_functions/aggregate_function_min_max_by.h
b/be/src/vec/aggregate_functions/aggregate_function_min_max_by.h
index 01943186300..78a898e3b20 100644
--- a/be/src/vec/aggregate_functions/aggregate_function_min_max_by.h
+++ b/be/src/vec/aggregate_functions/aggregate_function_min_max_by.h
@@ -31,6 +31,44 @@
namespace doris::vectorized {
#include "common/compile_check_begin.h"
+struct MaxMinValueBase {
+ virtual ~MaxMinValueBase() = default;
+ virtual void write(BufferWritable& buf) const = 0;
+ virtual void read(BufferReadable& buf, Arena& arena) = 0;
+ virtual void insert_result_into(IColumn& to) const = 0;
+ virtual void reset() = 0;
+ virtual void change(const IColumn& column, size_t row_num, Arena& arena) =
0;
+ virtual void change(const MaxMinValueBase& to, Arena& arena) = 0;
+};
+
+template <typename VT>
+struct MaxMinValue : public MaxMinValueBase {
+ VT value;
+
+ MaxMinValue() = default;
+
+ ~MaxMinValue() override = default;
+
+ void write(BufferWritable& buf) const override { value.write(buf); }
+
+ void read(BufferReadable& buf, Arena& arena) override { value.read(buf,
arena); }
+
+ void insert_result_into(IColumn& to) const override {
value.insert_result_into(to); }
+
+ void reset() override { value.reset(); }
+
+ void change(const IColumn& column, size_t row_num, Arena& arena) override {
+ value.change(column, row_num, arena);
+ }
+
+ void change(const MaxMinValueBase& to, Arena& arena) override {
+ const auto& derived = assert_cast<const MaxMinValue&>(to);
+ value.change(derived.value, arena);
+ }
+};
+
+std::unique_ptr<MaxMinValueBase> create_max_min_value(const DataTypePtr& type);
+
/// For bitmap value
struct BitmapValueData {
private:
@@ -40,7 +78,6 @@ private:
public:
BitmapValueData() = default;
- BitmapValueData(bool has_value_, BitmapValue value_) :
has_value(has_value_), value(value_) {}
[[nodiscard]] bool has() const { return has_value; }
void insert_result_into(IColumn& to) const {
@@ -83,62 +120,99 @@ public:
}
};
-template <typename VT, typename KT>
+template <typename KT>
struct AggregateFunctionMinMaxByBaseData {
protected:
- VT value;
+ std::unique_ptr<MaxMinValueBase> value;
KT key;
public:
- void insert_result_into(IColumn& to) const { value.insert_result_into(to);
}
+ AggregateFunctionMinMaxByBaseData(const DataTypes argument_types) {
+ value = create_max_min_value(argument_types[0]);
+ }
+
+ void insert_result_into(IColumn& to) const {
value->insert_result_into(to); }
void reset() {
- value.reset();
+ value->reset();
key.reset();
}
void write(BufferWritable& buf) const {
- value.write(buf);
+ value->write(buf);
key.write(buf);
}
void read(BufferReadable& buf, Arena& arena) {
- value.read(buf, arena);
+ value->read(buf, arena);
key.read(buf, arena);
}
};
-template <typename VT, typename KT>
-struct AggregateFunctionMaxByData : public
AggregateFunctionMinMaxByBaseData<VT, KT> {
+template <typename KT>
+struct AggregateFunctionMaxByData : public
AggregateFunctionMinMaxByBaseData<KT> {
using Self = AggregateFunctionMaxByData;
+
+ AggregateFunctionMaxByData(const DataTypes argument_types)
+ : AggregateFunctionMinMaxByBaseData<KT>(argument_types) {}
+
void change_if_better(const IColumn& value_column, const IColumn&
key_column, size_t row_num,
Arena& arena) {
if (this->key.change_if_greater(key_column, row_num, arena)) {
- this->value.change(value_column, row_num, arena);
+ this->value->change(value_column, row_num, arena);
+ }
+ }
+
+ void change_if_better_batch(const IColumn& value_column, const IColumn&
key_column,
+ size_t batch_size, Arena& arena) {
+ size_t max_pos = -1;
+ for (size_t i = 0; i < batch_size; ++i) {
+ if (this->key.change_if_greater(key_column, i, arena)) {
+ max_pos = i;
+ }
+ }
+ if (max_pos != static_cast<size_t>(-1)) {
+ this->value->change(value_column, max_pos, arena);
}
}
void change_if_better(const Self& to, Arena& arena) {
if (this->key.change_if_greater(to.key, arena)) {
- this->value.change(to.value, arena);
+ this->value->change(*to.value, arena);
}
}
static const char* name() { return "max_by"; }
};
-template <typename VT, typename KT>
-struct AggregateFunctionMinByData : public
AggregateFunctionMinMaxByBaseData<VT, KT> {
+template <typename KT>
+struct AggregateFunctionMinByData : public
AggregateFunctionMinMaxByBaseData<KT> {
using Self = AggregateFunctionMinByData;
+
+ AggregateFunctionMinByData(const DataTypes argument_types)
+ : AggregateFunctionMinMaxByBaseData<KT>(argument_types) {}
void change_if_better(const IColumn& value_column, const IColumn&
key_column, size_t row_num,
Arena& arena) {
if (this->key.change_if_less(key_column, row_num, arena)) {
- this->value.change(value_column, row_num, arena);
+ this->value->change(value_column, row_num, arena);
+ }
+ }
+
+ void change_if_better_batch(const IColumn& value_column, const IColumn&
key_column,
+ size_t batch_size, Arena& arena) {
+ size_t min_pos = -1;
+ for (size_t i = 0; i < batch_size; ++i) {
+ if (this->key.change_if_less(key_column, i, arena)) {
+ min_pos = i;
+ }
+ }
+ if (min_pos != static_cast<size_t>(-1)) {
+ this->value->change(value_column, min_pos, arena);
}
}
void change_if_better(const Self& to, Arena& arena) {
if (this->key.change_if_less(to.key, arena)) {
- this->value.change(to.value, arena);
+ this->value->change(*to.value, arena);
}
}
@@ -147,7 +221,7 @@ struct AggregateFunctionMinByData : public
AggregateFunctionMinMaxByBaseData<VT,
template <typename Data>
class AggregateFunctionsMinMaxBy final
- : public IAggregateFunctionDataHelper<Data,
AggregateFunctionsMinMaxBy<Data>>,
+ : public IAggregateFunctionDataHelper<Data,
AggregateFunctionsMinMaxBy<Data>, true>,
MultiExpression,
NullableAggregateFunction {
private:
@@ -156,7 +230,7 @@ private:
public:
AggregateFunctionsMinMaxBy(const DataTypes& arguments)
- : IAggregateFunctionDataHelper<Data,
AggregateFunctionsMinMaxBy<Data>>(
+ : IAggregateFunctionDataHelper<Data,
AggregateFunctionsMinMaxBy<Data>, true>(
{arguments[0], arguments[1]}),
value_type(this->argument_types[0]),
key_type(this->argument_types[1]) {
@@ -175,6 +249,11 @@ public:
this->data(place).change_if_better(*columns[0], *columns[1], row_num,
arena);
}
+ void add_batch_single_place(size_t batch_size, AggregateDataPtr place,
const IColumn** columns,
+ Arena& arena) const override {
+ this->data(place).change_if_better_batch(*columns[0], *columns[1],
batch_size, arena);
+ }
+
void reset(AggregateDataPtr place) const override {
this->data(place).reset(); }
void merge(AggregateDataPtr __restrict place, ConstAggregateDataPtr rhs,
@@ -196,180 +275,90 @@ public:
}
};
-template <template <typename> class AggregateFunctionTemplate,
- template <typename, typename> class Data, typename VT>
-AggregateFunctionPtr create_aggregate_function_min_max_by_impl(const
DataTypes& argument_types,
- const bool
result_is_nullable,
- const
AggregateFunctionAttr& attr) {
+template <template <typename> class AggregateFunctionTemplate, template
<typename> class Data>
+AggregateFunctionPtr create_aggregate_function_min_max_by(const String& name,
+ const DataTypes&
argument_types,
+ const bool
result_is_nullable,
+ const
AggregateFunctionAttr& attr) {
+ if (argument_types.size() != 2) {
+ return nullptr;
+ }
+
switch (argument_types[1]->get_primitive_type()) {
case PrimitiveType::TYPE_BOOLEAN:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT,
SingleValueDataFixed<TYPE_BOOLEAN>>>>(
+
AggregateFunctionTemplate<Data<SingleValueDataFixed<TYPE_BOOLEAN>>>>(
argument_types, result_is_nullable, attr);
case PrimitiveType::TYPE_TINYINT:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT,
SingleValueDataFixed<TYPE_TINYINT>>>>(
+
AggregateFunctionTemplate<Data<SingleValueDataFixed<TYPE_TINYINT>>>>(
argument_types, result_is_nullable, attr);
case PrimitiveType::TYPE_SMALLINT:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT,
SingleValueDataFixed<TYPE_SMALLINT>>>>(
+
AggregateFunctionTemplate<Data<SingleValueDataFixed<TYPE_SMALLINT>>>>(
argument_types, result_is_nullable, attr);
case PrimitiveType::TYPE_INT:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT,
SingleValueDataFixed<TYPE_INT>>>>(
+
AggregateFunctionTemplate<Data<SingleValueDataFixed<TYPE_INT>>>>(
argument_types, result_is_nullable, attr);
case PrimitiveType::TYPE_BIGINT:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT,
SingleValueDataFixed<TYPE_BIGINT>>>>(
+
AggregateFunctionTemplate<Data<SingleValueDataFixed<TYPE_BIGINT>>>>(
argument_types, result_is_nullable, attr);
case PrimitiveType::TYPE_LARGEINT:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT,
SingleValueDataFixed<TYPE_LARGEINT>>>>(
+
AggregateFunctionTemplate<Data<SingleValueDataFixed<TYPE_LARGEINT>>>>(
argument_types, result_is_nullable, attr);
case PrimitiveType::TYPE_FLOAT:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT,
SingleValueDataFixed<TYPE_FLOAT>>>>(
+
AggregateFunctionTemplate<Data<SingleValueDataFixed<TYPE_FLOAT>>>>(
argument_types, result_is_nullable, attr);
case PrimitiveType::TYPE_DOUBLE:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT,
SingleValueDataFixed<TYPE_DOUBLE>>>>(
+
AggregateFunctionTemplate<Data<SingleValueDataFixed<TYPE_DOUBLE>>>>(
argument_types, result_is_nullable, attr);
case PrimitiveType::TYPE_DECIMAL32:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT,
SingleValueDataDecimal<TYPE_DECIMAL32>>>>(
+
AggregateFunctionTemplate<Data<SingleValueDataDecimal<TYPE_DECIMAL32>>>>(
argument_types, result_is_nullable, attr);
case PrimitiveType::TYPE_DECIMAL64:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT,
SingleValueDataDecimal<TYPE_DECIMAL64>>>>(
+
AggregateFunctionTemplate<Data<SingleValueDataDecimal<TYPE_DECIMAL64>>>>(
argument_types, result_is_nullable, attr);
case PrimitiveType::TYPE_DECIMAL128I:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT,
SingleValueDataDecimal<TYPE_DECIMAL128I>>>>(
+
AggregateFunctionTemplate<Data<SingleValueDataDecimal<TYPE_DECIMAL128I>>>>(
argument_types, result_is_nullable, attr);
case PrimitiveType::TYPE_DECIMALV2:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT,
SingleValueDataDecimal<TYPE_DECIMALV2>>>>(
+
AggregateFunctionTemplate<Data<SingleValueDataDecimal<TYPE_DECIMALV2>>>>(
argument_types, result_is_nullable, attr);
case PrimitiveType::TYPE_DECIMAL256:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT,
SingleValueDataDecimal<TYPE_DECIMAL256>>>>(
+
AggregateFunctionTemplate<Data<SingleValueDataDecimal<TYPE_DECIMAL256>>>>(
argument_types, result_is_nullable, attr);
case PrimitiveType::TYPE_CHAR:
case PrimitiveType::TYPE_VARCHAR:
case PrimitiveType::TYPE_STRING:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT, SingleValueDataString>>>(
- argument_types, result_is_nullable, attr);
+
AggregateFunctionTemplate<Data<SingleValueDataString>>>(argument_types,
+
result_is_nullable, attr);
case PrimitiveType::TYPE_DATE:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT,
SingleValueDataFixed<TYPE_DATE>>>>(
+
AggregateFunctionTemplate<Data<SingleValueDataFixed<TYPE_DATE>>>>(
argument_types, result_is_nullable, attr);
case PrimitiveType::TYPE_DATETIME:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT,
SingleValueDataFixed<TYPE_DATETIME>>>>(
+
AggregateFunctionTemplate<Data<SingleValueDataFixed<TYPE_DATETIME>>>>(
argument_types, result_is_nullable, attr);
case PrimitiveType::TYPE_DATEV2:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT,
SingleValueDataFixed<TYPE_DATEV2>>>>(
+
AggregateFunctionTemplate<Data<SingleValueDataFixed<TYPE_DATEV2>>>>(
argument_types, result_is_nullable, attr);
case PrimitiveType::TYPE_DATETIMEV2:
return creator_without_type::create_multi_arguments<
- AggregateFunctionTemplate<Data<VT,
SingleValueDataFixed<TYPE_DATETIMEV2>>>>(
- argument_types, result_is_nullable, attr);
- default:
- return nullptr;
- }
-}
-
-template <template <typename> class AggregateFunctionTemplate,
- template <typename, typename> class Data>
-AggregateFunctionPtr create_aggregate_function_min_max_by(const String& name,
- const DataTypes&
argument_types,
- const bool
result_is_nullable,
- const
AggregateFunctionAttr& attr) {
- if (argument_types.size() != 2) {
- return nullptr;
- }
-
- switch (argument_types[0]->get_primitive_type()) {
- case PrimitiveType::TYPE_BOOLEAN:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataFixed<TYPE_BOOLEAN>>(
- argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_TINYINT:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataFixed<TYPE_TINYINT>>(
- argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_SMALLINT:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataFixed<TYPE_SMALLINT>>(
- argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_INT:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataFixed<TYPE_INT>>(
- argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_BIGINT:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataFixed<TYPE_BIGINT>>(
- argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_LARGEINT:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataFixed<TYPE_LARGEINT>>(
- argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_FLOAT:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataFixed<TYPE_FLOAT>>(
- argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_DOUBLE:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataFixed<TYPE_DOUBLE>>(
- argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_DECIMAL32:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataDecimal<TYPE_DECIMAL32>>(
- argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_DECIMAL64:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataDecimal<TYPE_DECIMAL64>>(
- argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_DECIMAL128I:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataDecimal<TYPE_DECIMAL128I>>(
- argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_DECIMALV2:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataDecimal<TYPE_DECIMALV2>>(
- argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_DECIMAL256:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataDecimal<TYPE_DECIMAL256>>(
- argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_STRING:
- case PrimitiveType::TYPE_CHAR:
- case PrimitiveType::TYPE_VARCHAR:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataString>(
- argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_DATE:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataFixed<TYPE_DATE>>(
- argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_DATETIME:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataFixed<TYPE_DATETIME>>(
- argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_DATEV2:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataFixed<TYPE_DATEV2>>(
- argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_DATETIMEV2:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
SingleValueDataFixed<TYPE_DATETIMEV2>>(
+
AggregateFunctionTemplate<Data<SingleValueDataFixed<TYPE_DATETIMEV2>>>>(
argument_types, result_is_nullable, attr);
- case PrimitiveType::TYPE_BITMAP:
- return
create_aggregate_function_min_max_by_impl<AggregateFunctionTemplate, Data,
-
BitmapValueData>(argument_types,
-
result_is_nullable, attr);
default:
return nullptr;
}
diff --git
a/regression-test/data/query_p0/aggregate/aggregate_max_min_by_test.out
b/regression-test/data/query_p0/aggregate/aggregate_max_min_by_test.out
new file mode 100644
index 00000000000..2b8599bfe9f
Binary files /dev/null and
b/regression-test/data/query_p0/aggregate/aggregate_max_min_by_test.out differ
diff --git
a/regression-test/suites/query_p0/aggregate/aggregate_max_min_by_test.groovy
b/regression-test/suites/query_p0/aggregate/aggregate_max_min_by_test.groovy
new file mode 100644
index 00000000000..4adb4060132
--- /dev/null
+++ b/regression-test/suites/query_p0/aggregate/aggregate_max_min_by_test.groovy
@@ -0,0 +1,99 @@
+/*
+ * 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("aggregate_max_min_by_test") {
+
+ sql """ set ENABLE_DECIMAL256 = true; """
+ sql """DROP TABLE IF EXISTS aggregate_max_min_by_test;"""
+ sql"""
+ CREATE TABLE IF NOT EXISTS aggregate_max_min_by_test (
+ `k0` INT,
+ `k1` BOOLEAN,
+ `k2` TINYINT,
+ `k3` SMALLINT,
+ `k4` INT,
+ `k5` BIGINT,
+ `k6` LARGEINT,
+ `k7` FLOAT,
+ `k8` DOUBLE,
+ `k9` DECIMAL(8,3),
+ `k10` DECIMAL(16,3),
+ `k11` DECIMAL(32,3),
+ `k12` DECIMAL(64,3),
+ `k13` DATE,
+ `k14` DATETIME,
+ `k15` STRING,
+ ) ENGINE=OLAP
+ DUPLICATE KEY(`k0`)
+ DISTRIBUTED BY HASH(`k0`) BUCKETS 1
+ PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1",
+ "storage_format" = "V2"
+ );
+ """
+
+ sql """
+INSERT INTO aggregate_max_min_by_test
+(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15)
+VALUES
+(8, TRUE, 80, 8008, 80008, 800080008, 8000800080008, 8.08,
8.008, 8.008, 8008.008, 8008008.008, 8008008008.008, '2025-08-08',
'2025-08-08 08:08:08', 'text_8'),
+(3, FALSE, 30, 3003, 30003, 300030003, 3000300030003, 3.03,
3.003, 3.003, 3003.003, 3003003.003, 3003003003.003, '2025-03-03',
'2025-03-03 03:03:03', 'text_3'),
+(15, TRUE, 150, 15015, 150015, 1500150015, 15001500150015, 15.15,
15.015, 15.015, 15015.015, 15015015.015, 15015015015.015, '2025-05-15',
'2025-05-15 15:15:15', 'text_15'),
+(1, TRUE, 10, 1001, 10001, 100010001, 1000100010001, 1.01,
1.001, 1.001, 1001.001, 1001001.001, 1001001001.001, '2025-01-01',
'2025-01-01 01:01:01', 'text_1'),
+(12, FALSE, 120, 12012, 120012, 1200120012, 12001200120012, 12.12,
12.012, 12.012, 12012.012, 12012012.012, 12012012012.012, '2025-12-12',
'2025-12-12 12:12:12', 'text_12'),
+(5, TRUE, 50, 5005, 50005, 500050005, 5000500050005, 5.05,
5.005, 5.005, 5005.005, 5005005.005, 5005005005.005, '2025-05-05',
'2025-05-05 05:05:05', 'text_5'),
+(10, FALSE, 100, 10010, 100010, 1000100010, 10001000100010,10.10,
10.010, 10.010, 10010.010, 10010010.010, 10010010010.010, '2025-10-10',
'2025-10-10 10:10:10', 'text_10'),
+(7, TRUE, 70, 7007, 70007, 700070007, 7000700070007, 7.07,
7.007, 7.007, 7007.007, 7007007.007, 7007007007.007, '2025-07-07',
'2025-07-07 07:07:07', 'text_7'),
+(2, FALSE, 20, 2002, 20002, 200020002, 2000200020002, 2.02,
2.002, 2.002, 2002.002, 2002002.002, 2002002002.002, '2025-02-02',
'2025-02-02 02:02:02', 'text_2'),
+(14, TRUE, 140, 14014, 140014, 1400140014, 14001400140014,14.14,
14.014, 14.014, 14014.014, 14014014.014, 14014014014.014, '2025-06-14',
'2025-06-14 14:14:14', 'text_14'),
+(9, FALSE, 90, 9009, 90009, 900090009, 9000900090009, 9.09,
9.009, 9.009, 9009.009, 9009009.009, 9009009009.009, '2025-09-09',
'2025-09-09 09:09:09', 'text_9'),
+(6, TRUE, 60, 6006, 60006, 600060006, 6000600060006, 6.06,
6.006, 6.006, 6006.006, 6006006.006, 6006006006.006, '2025-06-06',
'2025-06-06 06:06:06', 'text_6');
+ """
+
+ qt_sql """
+ SELECT max_by(k0,k2), max_by(k0,k3), max_by(k0,k4), max_by(k0,k5),
max_by(k0,k6),
+ max_by(k0,k7), max_by(k0,k8), max_by(k0,k9), max_by(k0,k10),
max_by(k0,k11),
+ max_by(k0,k12), max_by(k0,k13), max_by(k0,k14), max_by(k0,k15)
+FROM aggregate_max_min_by_test;
+ """
+
+ qt_sql """
+SELECT min_by(k0,k2), min_by(k0,k3), min_by(k0,k4), min_by(k0,k5),
min_by(k0,k6),
+ min_by(k0,k7), min_by(k0,k8), min_by(k0,k9), min_by(k0,k10),
min_by(k0,k11),
+ min_by(k0,k12), min_by(k0,k13), min_by(k0,k14), min_by(k0,k15)
+FROM aggregate_max_min_by_test;
+ """
+
+
+ qt_sql """
+SELECT max_by(k2 , k0), max_by(k3 , k0), max_by(k4 , k0), max_by(k5 , k0),
max_by(k6 , k0),
+ max_by(k7 , k0), max_by(k8 , k0), max_by(k9 , k0), max_by(k10, k0),
max_by(k11, k0),
+ max_by(k12, k0), max_by(k13, k0), max_by(k14, k0), max_by(k15, k0)
+FROM aggregate_max_min_by_test;
+ """
+
+
+ qt_sql """
+SELECT min_by(k2 , k0), min_by(k3 , k0), min_by(k4 , k0), min_by(k5 , k0),
min_by(k6 , k0),
+ min_by(k7 , k0), min_by(k8 , k0), min_by(k9 , k0), min_by(k10, k0),
min_by(k11, k0),
+ min_by(k12, k0), min_by(k13, k0), min_by(k14, k0), min_by(k15, k0)
+FROM aggregate_max_min_by_test;
+ """
+
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]