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]

Reply via email to