This is an automated email from the ASF dual-hosted git repository.

airborne 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 5f6c2750f8d [env](compiler) Reduce the compilation time of aggregate 
functions. (#61179)
5f6c2750f8d is described below

commit 5f6c2750f8dd2a601c976c0d55f6957df4e01fc2
Author: Mryange <[email protected]>
AuthorDate: Wed Mar 11 15:49:56 2026 +0800

    [env](compiler) Reduce the compilation time of aggregate functions. (#61179)
    
    ### What problem does this PR solve?
    
    Previously, some of our aggregate functions were implemented in very
    large .cpp files, which made compilation slow.
    For example, be/src/exprs/aggregate/aggregate_function_window.cpp takes
    347.25 seconds to compile. T
    
    his PR splits these files into multiple smaller files so they can be
    compiled in parallel.
    
    before
    ```
     347.25  be/src/exprs/aggregate/aggregate_function_window.cpp
    ```
    
    now
    ```
    [1/7] Compiling: be/src/exprs/aggregate/aggregate_function_window.cpp
      → 25.9s
    
    [2/7] Compiling: be/src/exprs/aggregate/aggregate_function_window_first.cpp
      → 60.5s
    
    [3/7] Compiling: be/src/exprs/aggregate/aggregate_function_window_funnel.cpp
      → 19.6s
    
    [4/7] Compiling: be/src/exprs/aggregate/aggregate_function_window_lag.cpp
      → 60.6s
    
    [5/7] Compiling: be/src/exprs/aggregate/aggregate_function_window_last.cpp
      → 63.9s
    
    [6/7] Compiling: be/src/exprs/aggregate/aggregate_function_window_lead.cpp
      → 69.1s
    
    [7/7] Compiling: 
be/src/exprs/aggregate/aggregate_function_window_nth_value.cpp
      → 74.5s
    ```
---
 .../exprs/aggregate/aggregate_function_collect.cpp |  61 +---
 ...llect.cpp => aggregate_function_collect_impl.h} |  31 +-
 .../aggregate/aggregate_function_collect_limit.cpp |  30 ++
 .../aggregate_function_collect_no_limit.cpp        |  31 ++
 .../aggregate_function_group_array_intersect.cpp   |  44 +++
 .../aggregate_function_group_array_set_op.cpp      | 128 +------
 ...> aggregate_function_group_array_set_op_impl.h} |  48 +--
 .../aggregate_function_group_array_union.cpp       |  43 +++
 .../exprs/aggregate/aggregate_function_min_max.cpp | 131 +-------
 .../aggregate/aggregate_function_min_max_any.cpp   |  27 ++
 ...n_max.cpp => aggregate_function_min_max_impl.h} |  25 +-
 .../aggregate/aggregate_function_min_max_max.cpp   |  27 ++
 .../aggregate/aggregate_function_min_max_min.cpp   |  27 ++
 .../exprs/aggregate/aggregate_function_reader.cpp  |  26 --
 ...r.cpp => aggregate_function_reader_replace.cpp} |  38 +--
 be/src/exprs/aggregate/aggregate_function_topn.cpp |  40 +--
 .../aggregate/aggregate_function_topn_array.cpp    |  52 +++
 .../aggregate/aggregate_function_topn_weighted.cpp |  52 +++
 .../exprs/aggregate/aggregate_function_window.cpp  | 368 ++-------------------
 .../aggregate/aggregate_function_window_first.cpp  |  27 ++
 ...window.cpp => aggregate_function_window_impl.h} |  52 +--
 .../aggregate/aggregate_function_window_lag.cpp    |  27 ++
 .../aggregate/aggregate_function_window_last.cpp   |  27 ++
 .../aggregate/aggregate_function_window_lead.cpp   |  27 ++
 .../aggregate_function_window_nth_value.cpp        |  27 ++
 25 files changed, 544 insertions(+), 872 deletions(-)

diff --git a/be/src/exprs/aggregate/aggregate_function_collect.cpp 
b/be/src/exprs/aggregate/aggregate_function_collect.cpp
index 65e8372d252..4f8d4b83cac 100644
--- a/be/src/exprs/aggregate/aggregate_function_collect.cpp
+++ b/be/src/exprs/aggregate/aggregate_function_collect.cpp
@@ -17,9 +17,6 @@
 
 #include "exprs/aggregate/aggregate_function_collect.h"
 
-#include "common/exception.h"
-#include "common/status.h"
-#include "core/call_on_type_index.h"
 #include "exprs/aggregate/aggregate_function_simple_factory.h"
 #include "exprs/aggregate/factory_helpers.h"
 #include "exprs/aggregate/helpers.h"
@@ -27,50 +24,14 @@
 namespace doris {
 #include "common/compile_check_begin.h"
 
-template <PrimitiveType T, bool HasLimit>
-AggregateFunctionPtr do_create_agg_function_collect(bool distinct, const 
DataTypes& argument_types,
-                                                    const bool 
result_is_nullable,
-
-                                                    const 
AggregateFunctionAttr& attr) {
-    if (distinct) {
-        if constexpr (T == INVALID_TYPE) {
-            throw Exception(ErrorCode::INTERNAL_ERROR,
-                            "unexpected type for collect, please check the 
input");
-        } else {
-            return creator_without_type::create<AggregateFunctionCollect<
-                    AggregateFunctionCollectSetData<T, HasLimit>, HasLimit>>(
-                    argument_types, result_is_nullable, attr);
-        }
-    } else {
-        return creator_without_type::create<
-                AggregateFunctionCollect<AggregateFunctionCollectListData<T, 
HasLimit>, HasLimit>>(
-                argument_types, result_is_nullable, attr);
-    }
-}
-
-template <bool HasLimit>
-AggregateFunctionPtr create_aggregate_function_collect_impl(const std::string& 
name,
-                                                            const DataTypes& 
argument_types,
-                                                            const bool 
result_is_nullable,
-
-                                                            const 
AggregateFunctionAttr& attr) {
-    bool distinct = name == "collect_set";
-
-    AggregateFunctionPtr agg_fn;
-    auto call = [&](const auto& type) -> bool {
-        using DispatcType = std::decay_t<decltype(type)>;
-        agg_fn = do_create_agg_function_collect<DispatcType::PType, HasLimit>(
-                distinct, argument_types, result_is_nullable, attr);
-        return true;
-    };
-
-    if (!dispatch_switch_all(argument_types[0]->get_primitive_type(), call)) {
-        // We do not care what the real type is.
-        agg_fn = do_create_agg_function_collect<INVALID_TYPE, 
HasLimit>(distinct, argument_types,
-                                                                        
result_is_nullable, attr);
-    }
-    return agg_fn;
-}
+// Forward declarations — template instantiations live in separate TUs
+AggregateFunctionPtr create_aggregate_function_collect_no_limit(const 
std::string& name,
+                                                                const 
DataTypes& argument_types,
+                                                                const bool 
result_is_nullable,
+                                                                const 
AggregateFunctionAttr& attr);
+AggregateFunctionPtr create_aggregate_function_collect_with_limit(
+        const std::string& name, const DataTypes& argument_types, const bool 
result_is_nullable,
+        const AggregateFunctionAttr& attr);
 
 AggregateFunctionPtr create_aggregate_function_collect(const std::string& name,
                                                        const DataTypes& 
argument_types,
@@ -79,11 +40,11 @@ AggregateFunctionPtr 
create_aggregate_function_collect(const std::string& name,
                                                        const 
AggregateFunctionAttr& attr) {
     assert_arity_range(name, argument_types, 1, 2);
     if (argument_types.size() == 1) {
-        return create_aggregate_function_collect_impl<false>(name, 
argument_types,
-                                                             
result_is_nullable, attr);
+        return create_aggregate_function_collect_no_limit(name, 
argument_types, result_is_nullable,
+                                                          attr);
     }
     if (argument_types.size() == 2) {
-        return create_aggregate_function_collect_impl<true>(name, 
argument_types,
+        return create_aggregate_function_collect_with_limit(name, 
argument_types,
                                                             
result_is_nullable, attr);
     }
     return nullptr;
diff --git a/be/src/exprs/aggregate/aggregate_function_collect.cpp 
b/be/src/exprs/aggregate/aggregate_function_collect_impl.h
similarity index 67%
copy from be/src/exprs/aggregate/aggregate_function_collect.cpp
copy to be/src/exprs/aggregate/aggregate_function_collect_impl.h
index 65e8372d252..7c52b20b495 100644
--- a/be/src/exprs/aggregate/aggregate_function_collect.cpp
+++ b/be/src/exprs/aggregate/aggregate_function_collect_impl.h
@@ -15,12 +15,12 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#include "exprs/aggregate/aggregate_function_collect.h"
+#pragma once
 
 #include "common/exception.h"
 #include "common/status.h"
 #include "core/call_on_type_index.h"
-#include "exprs/aggregate/aggregate_function_simple_factory.h"
+#include "exprs/aggregate/aggregate_function_collect.h"
 #include "exprs/aggregate/factory_helpers.h"
 #include "exprs/aggregate/helpers.h"
 
@@ -72,28 +72,5 @@ AggregateFunctionPtr 
create_aggregate_function_collect_impl(const std::string& n
     return agg_fn;
 }
 
-AggregateFunctionPtr create_aggregate_function_collect(const std::string& name,
-                                                       const DataTypes& 
argument_types,
-                                                       const DataTypePtr& 
result_type,
-                                                       const bool 
result_is_nullable,
-                                                       const 
AggregateFunctionAttr& attr) {
-    assert_arity_range(name, argument_types, 1, 2);
-    if (argument_types.size() == 1) {
-        return create_aggregate_function_collect_impl<false>(name, 
argument_types,
-                                                             
result_is_nullable, attr);
-    }
-    if (argument_types.size() == 2) {
-        return create_aggregate_function_collect_impl<true>(name, 
argument_types,
-                                                            
result_is_nullable, attr);
-    }
-    return nullptr;
-}
-
-void register_aggregate_function_collect_list(AggregateFunctionSimpleFactory& 
factory) {
-    // notice: array_agg only differs from collect_list in that array_agg will 
show null elements in array
-    factory.register_function_both("collect_list", 
create_aggregate_function_collect);
-    factory.register_function_both("collect_set", 
create_aggregate_function_collect);
-    factory.register_alias("collect_list", "group_array");
-    factory.register_alias("collect_set", "group_uniq_array");
-}
-} // namespace doris
\ No newline at end of file
+} // namespace doris
+#include "common/compile_check_end.h"
diff --git a/be/src/exprs/aggregate/aggregate_function_collect_limit.cpp 
b/be/src/exprs/aggregate/aggregate_function_collect_limit.cpp
new file mode 100644
index 00000000000..318529689dc
--- /dev/null
+++ b/be/src/exprs/aggregate/aggregate_function_collect_limit.cpp
@@ -0,0 +1,30 @@
+// 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 "exprs/aggregate/aggregate_function_collect_impl.h"
+
+namespace doris {
+#include "common/compile_check_begin.h"
+
+AggregateFunctionPtr create_aggregate_function_collect_with_limit(
+        const std::string& name, const DataTypes& argument_types, const bool 
result_is_nullable,
+        const AggregateFunctionAttr& attr) {
+    return create_aggregate_function_collect_impl<true>(name, argument_types, 
result_is_nullable,
+                                                        attr);
+}
+
+} // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_collect_no_limit.cpp 
b/be/src/exprs/aggregate/aggregate_function_collect_no_limit.cpp
new file mode 100644
index 00000000000..ba81be14068
--- /dev/null
+++ b/be/src/exprs/aggregate/aggregate_function_collect_no_limit.cpp
@@ -0,0 +1,31 @@
+// 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 "exprs/aggregate/aggregate_function_collect_impl.h"
+
+namespace doris {
+#include "common/compile_check_begin.h"
+
+AggregateFunctionPtr create_aggregate_function_collect_no_limit(const 
std::string& name,
+                                                                const 
DataTypes& argument_types,
+                                                                const bool 
result_is_nullable,
+                                                                const 
AggregateFunctionAttr& attr) {
+    return create_aggregate_function_collect_impl<false>(name, argument_types, 
result_is_nullable,
+                                                         attr);
+}
+
+} // namespace doris
diff --git 
a/be/src/exprs/aggregate/aggregate_function_group_array_intersect.cpp 
b/be/src/exprs/aggregate/aggregate_function_group_array_intersect.cpp
new file mode 100644
index 00000000000..3210974c1cf
--- /dev/null
+++ b/be/src/exprs/aggregate/aggregate_function_group_array_intersect.cpp
@@ -0,0 +1,44 @@
+// 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 "common/exception.h"
+#include "core/data_type/data_type_array.h"
+#include "core/data_type/data_type_nullable.h"
+#include "exprs/aggregate/aggregate_function_group_array_set_op_impl.h"
+
+namespace doris {
+#include "common/compile_check_begin.h"
+
+AggregateFunctionPtr create_aggregate_function_group_array_intersect(
+        const std::string& name, const DataTypes& argument_types, const 
DataTypePtr& result_type,
+        const bool result_is_nullable, const AggregateFunctionAttr& attr) {
+    assert_arity_range(name, argument_types, 1, 1);
+    const DataTypePtr& argument_type = remove_nullable(argument_types[0]);
+
+    if (argument_type->get_primitive_type() != TYPE_ARRAY) {
+        throw Exception(
+                ErrorCode::INVALID_ARGUMENT,
+                "Aggregate function group_array_intersect accepts only array 
type argument. "
+                "Provided argument type: " +
+                        argument_type->get_name());
+    }
+    return 
create_aggregate_function_group_array_impl<GroupArrayNumericIntersectData,
+                                                      
GroupArrayStringIntersectData>(
+            {argument_type}, result_is_nullable, attr);
+}
+
+} // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_group_array_set_op.cpp 
b/be/src/exprs/aggregate/aggregate_function_group_array_set_op.cpp
index f12c4c62615..f988cba5b48 100644
--- a/be/src/exprs/aggregate/aggregate_function_group_array_set_op.cpp
+++ b/be/src/exprs/aggregate/aggregate_function_group_array_set_op.cpp
@@ -20,134 +20,22 @@
 
 #include "exprs/aggregate/aggregate_function_group_array_set_op.h"
 
-#include <glog/logging.h>
-
-#include "core/data_type/define_primitive_type.h"
-#include "core/data_type/primitive_type.h"
 #include "exprs/aggregate/aggregate_function.h"
-#include "exprs/aggregate/factory_helpers.h"
-#include "exprs/aggregate/helpers.h"
+#include "exprs/aggregate/aggregate_function_simple_factory.h"
 
 namespace doris {
 #include "common/compile_check_begin.h"
 
-template <template <PrimitiveType> class ImplNumericData, typename 
ImplStringData>
-inline AggregateFunctionPtr create_aggregate_function_group_array_impl(
-        const DataTypes& argument_types, const bool result_is_nullable,
-        const AggregateFunctionAttr& attr) {
-    const auto& nested_type = remove_nullable(
-            assert_cast<const 
DataTypeArray&>(*(argument_types[0])).get_nested_type());
-
-    switch (nested_type->get_primitive_type()) {
-    case doris::PrimitiveType::TYPE_BOOLEAN:
-        return creator_without_type::create<
-                
AggregateFunctionGroupArraySetOp<ImplNumericData<TYPE_BOOLEAN>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_TINYINT:
-        return creator_without_type::create<
-                
AggregateFunctionGroupArraySetOp<ImplNumericData<TYPE_TINYINT>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_SMALLINT:
-        return creator_without_type::create<
-                
AggregateFunctionGroupArraySetOp<ImplNumericData<TYPE_SMALLINT>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_INT:
-        return creator_without_type::create<
-                AggregateFunctionGroupArraySetOp<ImplNumericData<TYPE_INT>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_BIGINT:
-        return creator_without_type::create<
-                
AggregateFunctionGroupArraySetOp<ImplNumericData<TYPE_BIGINT>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_LARGEINT:
-        return creator_without_type::create<
-                
AggregateFunctionGroupArraySetOp<ImplNumericData<TYPE_LARGEINT>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_DATEV2:
-        return creator_without_type::create<
-                
AggregateFunctionGroupArraySetOp<ImplNumericData<TYPE_DATEV2>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_DATETIMEV2:
-        return creator_without_type::create<
-                
AggregateFunctionGroupArraySetOp<ImplNumericData<TYPE_DATETIMEV2>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_DOUBLE:
-        return creator_without_type::create<
-                
AggregateFunctionGroupArraySetOp<ImplNumericData<TYPE_DOUBLE>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_FLOAT:
-        return creator_without_type::create<
-                AggregateFunctionGroupArraySetOp<ImplNumericData<TYPE_FLOAT>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_DECIMAL32:
-        return creator_without_type::create<
-                
AggregateFunctionGroupArraySetOp<ImplNumericData<TYPE_DECIMAL32>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_DECIMAL64:
-        return creator_without_type::create<
-                
AggregateFunctionGroupArraySetOp<ImplNumericData<TYPE_DECIMAL64>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_DECIMAL128I:
-        return creator_without_type::create<
-                
AggregateFunctionGroupArraySetOp<ImplNumericData<TYPE_DECIMAL128I>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_DECIMAL256:
-        return creator_without_type::create<
-                
AggregateFunctionGroupArraySetOp<ImplNumericData<TYPE_DECIMAL256>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_IPV4:
-        return creator_without_type::create<
-                AggregateFunctionGroupArraySetOp<ImplNumericData<TYPE_IPV4>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_IPV6:
-        return creator_without_type::create<
-                AggregateFunctionGroupArraySetOp<ImplNumericData<TYPE_IPV6>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_STRING:
-    case PrimitiveType::TYPE_VARCHAR:
-    case PrimitiveType::TYPE_CHAR:
-        return 
creator_without_type::create<AggregateFunctionGroupArraySetOp<ImplStringData>>(
-                argument_types, result_is_nullable, attr);
-    default:
-        LOG(WARNING) << " got invalid of nested type: " << 
nested_type->get_name();
-        return nullptr;
-    }
-}
-
+// Forward declarations — implementations live in separate TUs
 AggregateFunctionPtr create_aggregate_function_group_array_intersect(
         const std::string& name, const DataTypes& argument_types, const 
DataTypePtr& result_type,
-        const bool result_is_nullable, const AggregateFunctionAttr& attr) {
-    assert_arity_range(name, argument_types, 1, 1);
-    const DataTypePtr& argument_type = remove_nullable(argument_types[0]);
+        const bool result_is_nullable, const AggregateFunctionAttr& attr);
 
-    if (argument_type->get_primitive_type() != TYPE_ARRAY) {
-        throw Exception(
-                ErrorCode::INVALID_ARGUMENT,
-                "Aggregate function group_array_intersect accepts only array 
type argument. "
-                "Provided argument type: " +
-                        argument_type->get_name());
-    }
-    return 
create_aggregate_function_group_array_impl<GroupArrayNumericIntersectData,
-                                                      
GroupArrayStringIntersectData>(
-            {argument_type}, result_is_nullable, attr);
-}
-
-AggregateFunctionPtr create_aggregate_function_group_array_union(
-        const std::string& name, const DataTypes& argument_types, const 
DataTypePtr& result_type,
-        const bool result_is_nullable, const AggregateFunctionAttr& attr) {
-    assert_arity_range(name, argument_types, 1, 1);
-    const DataTypePtr& argument_type = remove_nullable(argument_types[0]);
-
-    if (argument_type->get_primitive_type() != TYPE_ARRAY) {
-        throw Exception(ErrorCode::INVALID_ARGUMENT,
-                        "Aggregate function group_array_union accepts only 
array type argument. "
-                        "Provided argument type: " +
-                                argument_type->get_name());
-    }
-    return 
create_aggregate_function_group_array_impl<GroupArrayNumericUnionData,
-                                                      
GroupArrayStringUnionData>(
-            {argument_type}, result_is_nullable, attr);
-}
+AggregateFunctionPtr create_aggregate_function_group_array_union(const 
std::string& name,
+                                                                 const 
DataTypes& argument_types,
+                                                                 const 
DataTypePtr& result_type,
+                                                                 const bool 
result_is_nullable,
+                                                                 const 
AggregateFunctionAttr& attr);
 
 void 
register_aggregate_function_group_array_set_op(AggregateFunctionSimpleFactory& 
factory) {
     factory.register_function_both("group_array_intersect",
diff --git a/be/src/exprs/aggregate/aggregate_function_group_array_set_op.cpp 
b/be/src/exprs/aggregate/aggregate_function_group_array_set_op_impl.h
similarity index 70%
copy from be/src/exprs/aggregate/aggregate_function_group_array_set_op.cpp
copy to be/src/exprs/aggregate/aggregate_function_group_array_set_op_impl.h
index f12c4c62615..b6fc8082538 100644
--- a/be/src/exprs/aggregate/aggregate_function_group_array_set_op.cpp
+++ b/be/src/exprs/aggregate/aggregate_function_group_array_set_op_impl.h
@@ -14,17 +14,15 @@
 // KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
-// This file is copied from
-// 
https://github.com/ClickHouse/ClickHouse/blob/master/src/AggregateFunctions/AggregateFunctionGroupArrayIntersect.cpp
-// and modified by Doris
 
-#include "exprs/aggregate/aggregate_function_group_array_set_op.h"
+#pragma once
 
 #include <glog/logging.h>
 
 #include "core/data_type/define_primitive_type.h"
 #include "core/data_type/primitive_type.h"
 #include "exprs/aggregate/aggregate_function.h"
+#include "exprs/aggregate/aggregate_function_group_array_set_op.h"
 #include "exprs/aggregate/factory_helpers.h"
 #include "exprs/aggregate/helpers.h"
 
@@ -114,45 +112,5 @@ inline AggregateFunctionPtr 
create_aggregate_function_group_array_impl(
     }
 }
 
-AggregateFunctionPtr create_aggregate_function_group_array_intersect(
-        const std::string& name, const DataTypes& argument_types, const 
DataTypePtr& result_type,
-        const bool result_is_nullable, const AggregateFunctionAttr& attr) {
-    assert_arity_range(name, argument_types, 1, 1);
-    const DataTypePtr& argument_type = remove_nullable(argument_types[0]);
-
-    if (argument_type->get_primitive_type() != TYPE_ARRAY) {
-        throw Exception(
-                ErrorCode::INVALID_ARGUMENT,
-                "Aggregate function group_array_intersect accepts only array 
type argument. "
-                "Provided argument type: " +
-                        argument_type->get_name());
-    }
-    return 
create_aggregate_function_group_array_impl<GroupArrayNumericIntersectData,
-                                                      
GroupArrayStringIntersectData>(
-            {argument_type}, result_is_nullable, attr);
-}
-
-AggregateFunctionPtr create_aggregate_function_group_array_union(
-        const std::string& name, const DataTypes& argument_types, const 
DataTypePtr& result_type,
-        const bool result_is_nullable, const AggregateFunctionAttr& attr) {
-    assert_arity_range(name, argument_types, 1, 1);
-    const DataTypePtr& argument_type = remove_nullable(argument_types[0]);
-
-    if (argument_type->get_primitive_type() != TYPE_ARRAY) {
-        throw Exception(ErrorCode::INVALID_ARGUMENT,
-                        "Aggregate function group_array_union accepts only 
array type argument. "
-                        "Provided argument type: " +
-                                argument_type->get_name());
-    }
-    return 
create_aggregate_function_group_array_impl<GroupArrayNumericUnionData,
-                                                      
GroupArrayStringUnionData>(
-            {argument_type}, result_is_nullable, attr);
-}
-
-void 
register_aggregate_function_group_array_set_op(AggregateFunctionSimpleFactory& 
factory) {
-    factory.register_function_both("group_array_intersect",
-                                   
create_aggregate_function_group_array_intersect);
-    factory.register_function_both("group_array_union",
-                                   
create_aggregate_function_group_array_union);
-}
 } // namespace doris
+#include "common/compile_check_end.h"
diff --git a/be/src/exprs/aggregate/aggregate_function_group_array_union.cpp 
b/be/src/exprs/aggregate/aggregate_function_group_array_union.cpp
new file mode 100644
index 00000000000..6180a478b1d
--- /dev/null
+++ b/be/src/exprs/aggregate/aggregate_function_group_array_union.cpp
@@ -0,0 +1,43 @@
+// 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 "common/exception.h"
+#include "core/data_type/data_type_array.h"
+#include "core/data_type/data_type_nullable.h"
+#include "exprs/aggregate/aggregate_function_group_array_set_op_impl.h"
+
+namespace doris {
+#include "common/compile_check_begin.h"
+
+AggregateFunctionPtr create_aggregate_function_group_array_union(
+        const std::string& name, const DataTypes& argument_types, const 
DataTypePtr& result_type,
+        const bool result_is_nullable, const AggregateFunctionAttr& attr) {
+    assert_arity_range(name, argument_types, 1, 1);
+    const DataTypePtr& argument_type = remove_nullable(argument_types[0]);
+
+    if (argument_type->get_primitive_type() != TYPE_ARRAY) {
+        throw Exception(ErrorCode::INVALID_ARGUMENT,
+                        "Aggregate function group_array_union accepts only 
array type argument. "
+                        "Provided argument type: " +
+                                argument_type->get_name());
+    }
+    return 
create_aggregate_function_group_array_impl<GroupArrayNumericUnionData,
+                                                      
GroupArrayStringUnionData>(
+            {argument_type}, result_is_nullable, attr);
+}
+
+} // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_min_max.cpp 
b/be/src/exprs/aggregate/aggregate_function_min_max.cpp
index 5279746b1be..ac953ba9108 100644
--- a/be/src/exprs/aggregate/aggregate_function_min_max.cpp
+++ b/be/src/exprs/aggregate/aggregate_function_min_max.cpp
@@ -20,135 +20,16 @@
 
 #include "exprs/aggregate/aggregate_function_min_max.h"
 
-#include "core/data_type/data_type.h"
-#include "core/data_type/data_type_nullable.h"
-#include "core/data_type/define_primitive_type.h"
-#include "core/types.h"
 #include "exprs/aggregate/aggregate_function_simple_factory.h"
-#include "exprs/aggregate/factory_helpers.h"
-#include "exprs/aggregate/helpers.h"
 
 namespace doris {
 #include "common/compile_check_begin.h"
-/// min, max
-template <template <typename> class Data>
-AggregateFunctionPtr create_aggregate_function_single_value(const String& name,
-                                                            const DataTypes& 
argument_types,
-                                                            const DataTypePtr& 
result_type,
-                                                            const bool 
result_is_nullable,
-                                                            const 
AggregateFunctionAttr& attr) {
-    assert_arity_range(name, argument_types, 1, 1);
-    switch (argument_types[0]->get_primitive_type()) {
-    case PrimitiveType::TYPE_STRING:
-    case PrimitiveType::TYPE_CHAR:
-    case PrimitiveType::TYPE_VARCHAR:
-    case PrimitiveType::TYPE_JSONB:
-        return creator_without_type::create_unary_arguments<
-                AggregateFunctionsSingleValue<Data<SingleValueDataString>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_DATE:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_DATE>>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_DATETIME:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_DATETIME>>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_DATEV2:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_DATEV2>>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_DATETIMEV2:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_DATETIMEV2>>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_TIMESTAMPTZ:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_TIMESTAMPTZ>>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_TIME:
-    case PrimitiveType::TYPE_TIMEV2:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_TIMEV2>>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_IPV4:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_IPV4>>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_IPV6:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_IPV6>>>>(
-                argument_types, result_is_nullable, attr);
-    // For boolean, tinyint, smallint, int, bigint, largeint
-    case PrimitiveType::TYPE_BOOLEAN:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_BOOLEAN>>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_TINYINT:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_TINYINT>>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_SMALLINT:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_SMALLINT>>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_INT:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_INT>>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_BIGINT:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_BIGINT>>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_LARGEINT:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_LARGEINT>>>>(
-                argument_types, result_is_nullable, attr);
-    // For float, double
-    case PrimitiveType::TYPE_FLOAT:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_FLOAT>>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_DOUBLE:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_DOUBLE>>>>(
-                argument_types, result_is_nullable, attr);
-    // For decimal
-    case PrimitiveType::TYPE_DECIMAL32:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataDecimal<TYPE_DECIMAL32>>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_DECIMAL64:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataDecimal<TYPE_DECIMAL64>>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_DECIMALV2:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataDecimal<TYPE_DECIMALV2>>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_DECIMAL128I:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataDecimal<TYPE_DECIMAL128I>>>>(
-                argument_types, result_is_nullable, attr);
-    case PrimitiveType::TYPE_DECIMAL256:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataDecimal<TYPE_DECIMAL256>>>>(
-                argument_types, result_is_nullable, attr);
-    // For Complex type. Currently, only type_array supports min and max.
-    case PrimitiveType::TYPE_ARRAY:
-    case PrimitiveType::TYPE_MAP:
-    case PrimitiveType::TYPE_STRUCT:
-    case PrimitiveType::TYPE_AGG_STATE:
-    case PrimitiveType::TYPE_BITMAP:
-    case PrimitiveType::TYPE_HLL:
-    case PrimitiveType::TYPE_QUANTILE_STATE:
-        return creator_without_type::create_unary_arguments<
-                
AggregateFunctionsSingleValue<Data<SingleValueDataComplexType>>>(
-                argument_types, result_is_nullable, attr);
-    default:
-        return nullptr;
-    }
-}
+
+// Template definition lives in aggregate_function_min_max_impl.h
+// Explicit instantiations provided by:
+//   aggregate_function_min_max_max.cpp  (AggregateFunctionMaxData)
+//   aggregate_function_min_max_min.cpp  (AggregateFunctionMinData)
+//   aggregate_function_min_max_any.cpp  (AggregateFunctionAnyData)
 
 void register_aggregate_function_minmax(AggregateFunctionSimpleFactory& 
factory) {
     factory.register_function_both(
diff --git a/be/src/exprs/aggregate/aggregate_function_min_max_any.cpp 
b/be/src/exprs/aggregate/aggregate_function_min_max_any.cpp
new file mode 100644
index 00000000000..4e83d6f75b4
--- /dev/null
+++ b/be/src/exprs/aggregate/aggregate_function_min_max_any.cpp
@@ -0,0 +1,27 @@
+// 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 "exprs/aggregate/aggregate_function_min_max_impl.h"
+
+namespace doris {
+
+// Explicit instantiation for AggregateFunctionAnyData
+template AggregateFunctionPtr 
create_aggregate_function_single_value<AggregateFunctionAnyData>(
+        const String&, const DataTypes&, const DataTypePtr&, const bool,
+        const AggregateFunctionAttr&);
+
+} // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_min_max.cpp 
b/be/src/exprs/aggregate/aggregate_function_min_max_impl.h
similarity index 89%
copy from be/src/exprs/aggregate/aggregate_function_min_max.cpp
copy to be/src/exprs/aggregate/aggregate_function_min_max_impl.h
index 5279746b1be..48c6db2d67e 100644
--- a/be/src/exprs/aggregate/aggregate_function_min_max.cpp
+++ b/be/src/exprs/aggregate/aggregate_function_min_max_impl.h
@@ -14,23 +14,21 @@
 // KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
-// This file is copied from
-// 
https://github.com/ClickHouse/ClickHouse/blob/master/src/AggregateFunctions/AggregateFunctionMinMaxAny.cpp
-// and modified by Doris
 
-#include "exprs/aggregate/aggregate_function_min_max.h"
+#pragma once
 
 #include "core/data_type/data_type.h"
 #include "core/data_type/data_type_nullable.h"
 #include "core/data_type/define_primitive_type.h"
 #include "core/types.h"
-#include "exprs/aggregate/aggregate_function_simple_factory.h"
+#include "exprs/aggregate/aggregate_function_min_max.h"
 #include "exprs/aggregate/factory_helpers.h"
 #include "exprs/aggregate/helpers.h"
 
 namespace doris {
 #include "common/compile_check_begin.h"
-/// min, max
+
+/// min, max, any — shared template definition
 template <template <typename> class Data>
 AggregateFunctionPtr create_aggregate_function_single_value(const String& name,
                                                             const DataTypes& 
argument_types,
@@ -79,7 +77,6 @@ AggregateFunctionPtr 
create_aggregate_function_single_value(const String& name,
         return creator_without_type::create_unary_arguments<
                 
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_IPV6>>>>(
                 argument_types, result_is_nullable, attr);
-    // For boolean, tinyint, smallint, int, bigint, largeint
     case PrimitiveType::TYPE_BOOLEAN:
         return creator_without_type::create_unary_arguments<
                 
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_BOOLEAN>>>>(
@@ -104,7 +101,6 @@ AggregateFunctionPtr 
create_aggregate_function_single_value(const String& name,
         return creator_without_type::create_unary_arguments<
                 
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_LARGEINT>>>>(
                 argument_types, result_is_nullable, attr);
-    // For float, double
     case PrimitiveType::TYPE_FLOAT:
         return creator_without_type::create_unary_arguments<
                 
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_FLOAT>>>>(
@@ -113,7 +109,6 @@ AggregateFunctionPtr 
create_aggregate_function_single_value(const String& name,
         return creator_without_type::create_unary_arguments<
                 
AggregateFunctionsSingleValue<Data<SingleValueDataFixed<TYPE_DOUBLE>>>>(
                 argument_types, result_is_nullable, attr);
-    // For decimal
     case PrimitiveType::TYPE_DECIMAL32:
         return creator_without_type::create_unary_arguments<
                 
AggregateFunctionsSingleValue<Data<SingleValueDataDecimal<TYPE_DECIMAL32>>>>(
@@ -134,7 +129,6 @@ AggregateFunctionPtr 
create_aggregate_function_single_value(const String& name,
         return creator_without_type::create_unary_arguments<
                 
AggregateFunctionsSingleValue<Data<SingleValueDataDecimal<TYPE_DECIMAL256>>>>(
                 argument_types, result_is_nullable, attr);
-    // For Complex type. Currently, only type_array supports min and max.
     case PrimitiveType::TYPE_ARRAY:
     case PrimitiveType::TYPE_MAP:
     case PrimitiveType::TYPE_STRUCT:
@@ -150,14 +144,5 @@ AggregateFunctionPtr 
create_aggregate_function_single_value(const String& name,
     }
 }
 
-void register_aggregate_function_minmax(AggregateFunctionSimpleFactory& 
factory) {
-    factory.register_function_both(
-            "max", 
create_aggregate_function_single_value<AggregateFunctionMaxData>);
-    factory.register_function_both(
-            "min", 
create_aggregate_function_single_value<AggregateFunctionMinData>);
-    factory.register_function_both(
-            "any", 
create_aggregate_function_single_value<AggregateFunctionAnyData>);
-    factory.register_alias("any", "any_value");
-}
-
 } // namespace doris
+#include "common/compile_check_end.h"
diff --git a/be/src/exprs/aggregate/aggregate_function_min_max_max.cpp 
b/be/src/exprs/aggregate/aggregate_function_min_max_max.cpp
new file mode 100644
index 00000000000..2bb24cc9be1
--- /dev/null
+++ b/be/src/exprs/aggregate/aggregate_function_min_max_max.cpp
@@ -0,0 +1,27 @@
+// 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 "exprs/aggregate/aggregate_function_min_max_impl.h"
+
+namespace doris {
+
+// Explicit instantiation for AggregateFunctionMaxData
+template AggregateFunctionPtr 
create_aggregate_function_single_value<AggregateFunctionMaxData>(
+        const String&, const DataTypes&, const DataTypePtr&, const bool,
+        const AggregateFunctionAttr&);
+
+} // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_min_max_min.cpp 
b/be/src/exprs/aggregate/aggregate_function_min_max_min.cpp
new file mode 100644
index 00000000000..333bbd6cca2
--- /dev/null
+++ b/be/src/exprs/aggregate/aggregate_function_min_max_min.cpp
@@ -0,0 +1,27 @@
+// 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 "exprs/aggregate/aggregate_function_min_max_impl.h"
+
+namespace doris {
+
+// Explicit instantiation for AggregateFunctionMinData
+template AggregateFunctionPtr 
create_aggregate_function_single_value<AggregateFunctionMinData>(
+        const String&, const DataTypes&, const DataTypePtr&, const bool,
+        const AggregateFunctionAttr&);
+
+} // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_reader.cpp 
b/be/src/exprs/aggregate/aggregate_function_reader.cpp
index 18477322ac2..2c978202022 100644
--- a/be/src/exprs/aggregate/aggregate_function_reader.cpp
+++ b/be/src/exprs/aggregate/aggregate_function_reader.cpp
@@ -24,7 +24,6 @@
 #include "exprs/aggregate/aggregate_function_hll_union_agg.h"
 #include "exprs/aggregate/aggregate_function_min_max.h"
 #include "exprs/aggregate/aggregate_function_quantile_state.h"
-#include "exprs/aggregate/aggregate_function_reader_first_last.h"
 #include "exprs/aggregate/aggregate_function_simple_factory.h"
 #include "exprs/aggregate/aggregate_function_sum.h"
 #include "exprs/aggregate/helpers.h"
@@ -58,29 +57,4 @@ void 
register_aggregate_function_reader_load(AggregateFunctionSimpleFactory& fac
     register_function_both("quantile_union", 
create_aggregate_function_quantile_state_union);
 }
 
-// only replace function in load/reader do different agg operation.
-// because Doris can ensure that the data is globally ordered in reader, but 
cannot in load
-// 1. reader, get the first value of input data.
-// 2. load, get the last value of input data.
-void 
register_aggregate_function_replace_reader_load(AggregateFunctionSimpleFactory& 
factory) {
-    auto register_function = [&](const std::string& name, const std::string& 
suffix,
-                                 const AggregateFunctionCreator& creator, bool 
nullable) {
-        factory.register_function(name + suffix, creator, nullable);
-    };
-
-    register_function("replace", AGG_READER_SUFFIX, 
create_aggregate_function_first<true>, false);
-    register_function("replace", AGG_READER_SUFFIX, 
create_aggregate_function_first<true>, true);
-    register_function("replace", AGG_LOAD_SUFFIX, 
create_aggregate_function_last<false>, false);
-    register_function("replace", AGG_LOAD_SUFFIX, 
create_aggregate_function_last<false>, true);
-
-    register_function("replace_if_not_null", AGG_READER_SUFFIX,
-                      create_aggregate_function_first_non_null_value<true>, 
false);
-    register_function("replace_if_not_null", AGG_READER_SUFFIX,
-                      create_aggregate_function_first_non_null_value<true>, 
true);
-    register_function("replace_if_not_null", AGG_LOAD_SUFFIX,
-                      create_aggregate_function_last_non_null_value<false>, 
false);
-    register_function("replace_if_not_null", AGG_LOAD_SUFFIX,
-                      create_aggregate_function_last_non_null_value<false>, 
true);
-}
-
 } // namespace doris
\ No newline at end of file
diff --git a/be/src/exprs/aggregate/aggregate_function_reader.cpp 
b/be/src/exprs/aggregate/aggregate_function_reader_replace.cpp
similarity index 55%
copy from be/src/exprs/aggregate/aggregate_function_reader.cpp
copy to be/src/exprs/aggregate/aggregate_function_reader_replace.cpp
index 18477322ac2..da0c13d2a88 100644
--- a/be/src/exprs/aggregate/aggregate_function_reader.cpp
+++ b/be/src/exprs/aggregate/aggregate_function_reader_replace.cpp
@@ -16,48 +16,12 @@
 // under the License.
 
 #include "exprs/aggregate/aggregate_function_reader.h"
-
-#include <algorithm>
-#include <string>
-
-#include "exprs/aggregate/aggregate_function_bitmap.h"
-#include "exprs/aggregate/aggregate_function_hll_union_agg.h"
-#include "exprs/aggregate/aggregate_function_min_max.h"
-#include "exprs/aggregate/aggregate_function_quantile_state.h"
 #include "exprs/aggregate/aggregate_function_reader_first_last.h"
 #include "exprs/aggregate/aggregate_function_simple_factory.h"
-#include "exprs/aggregate/aggregate_function_sum.h"
-#include "exprs/aggregate/helpers.h"
 
 namespace doris {
 #include "common/compile_check_begin.h"
 
-// auto spread at nullable condition, null value do not participate aggregate
-void register_aggregate_function_reader_load(AggregateFunctionSimpleFactory& 
factory) {
-    // add a suffix to the function name here to distinguish special functions 
of agg reader
-    auto register_function_both = [&](const std::string& name,
-                                      const AggregateFunctionCreator& creator) 
{
-        factory.register_function_both(name + AGG_READER_SUFFIX, creator);
-        factory.register_function_both(name + AGG_LOAD_SUFFIX, creator);
-    };
-
-    register_function_both(
-            "sum",
-            creator_with_type_list<TYPE_TINYINT, TYPE_SMALLINT, TYPE_INT, 
TYPE_BIGINT,
-                                   TYPE_LARGEINT, TYPE_FLOAT, TYPE_DOUBLE, 
TYPE_DECIMAL32,
-                                   TYPE_DECIMAL64, TYPE_DECIMAL128I, 
TYPE_DECIMAL256,
-                                   
TYPE_DECIMALV2>::creator<AggregateFunctionSumSimpleReader>);
-    register_function_both("max", 
create_aggregate_function_single_value<AggregateFunctionMaxData>);
-    register_function_both("min", 
create_aggregate_function_single_value<AggregateFunctionMinData>);
-    register_function_both("bitmap_union",
-                           creator_without_type::creator<
-                                   
AggregateFunctionBitmapOp<AggregateFunctionBitmapUnionOp>>);
-    register_function_both("hll_union",
-                           
creator_without_type::creator<AggregateFunctionHLLUnion<
-                                   
AggregateFunctionHLLUnionImpl<AggregateFunctionHLLData>>>);
-    register_function_both("quantile_union", 
create_aggregate_function_quantile_state_union);
-}
-
 // only replace function in load/reader do different agg operation.
 // because Doris can ensure that the data is globally ordered in reader, but 
cannot in load
 // 1. reader, get the first value of input data.
@@ -83,4 +47,4 @@ void 
register_aggregate_function_replace_reader_load(AggregateFunctionSimpleFact
                       create_aggregate_function_last_non_null_value<false>, 
true);
 }
 
-} // namespace doris
\ No newline at end of file
+} // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_topn.cpp 
b/be/src/exprs/aggregate/aggregate_function_topn.cpp
index 5ce5a1d65f4..2404959b86b 100644
--- a/be/src/exprs/aggregate/aggregate_function_topn.cpp
+++ b/be/src/exprs/aggregate/aggregate_function_topn.cpp
@@ -22,6 +22,7 @@
 
 #include "core/data_type/data_type.h"
 #include "core/data_type/define_primitive_type.h"
+#include "exprs/aggregate/aggregate_function_simple_factory.h"
 #include "exprs/aggregate/helpers.h"
 
 namespace doris {
@@ -42,51 +43,18 @@ AggregateFunctionPtr create_aggregate_function_topn(const 
std::string& name,
     return nullptr;
 }
 
-template <PrimitiveType T>
-using ImplArray = AggregateFunctionTopNImplArray<T, false>;
-template <PrimitiveType T>
-using ImplArrayWithDefault = AggregateFunctionTopNImplArray<T, true>;
-
-using creator =
-        creator_with_type_list<TYPE_TINYINT, TYPE_SMALLINT, TYPE_INT, 
TYPE_BIGINT, TYPE_LARGEINT,
-                               TYPE_FLOAT, TYPE_DOUBLE, TYPE_DECIMAL32, 
TYPE_DECIMAL64,
-                               TYPE_DECIMAL128I, TYPE_DECIMAL256, 
TYPE_VARCHAR, TYPE_DATEV2,
-                               TYPE_DATETIMEV2, TYPE_TIMESTAMPTZ, TYPE_IPV4, 
TYPE_IPV6>;
-
+// Forward declarations — implementations live in separate TUs
 AggregateFunctionPtr create_aggregate_function_topn_array(const std::string& 
name,
                                                           const DataTypes& 
argument_types,
                                                           const DataTypePtr& 
result_type,
                                                           const bool 
result_is_nullable,
-                                                          const 
AggregateFunctionAttr& attr) {
-    bool has_default_param = (argument_types.size() == 3);
-    if (has_default_param) {
-        return creator::create<AggregateFunctionTopNArray, 
ImplArrayWithDefault>(
-                argument_types, result_is_nullable, attr);
-    } else {
-        return creator::create<AggregateFunctionTopNArray, 
ImplArray>(argument_types,
-                                                                      
result_is_nullable, attr);
-    }
-}
-
-template <PrimitiveType T>
-using ImplWeight = AggregateFunctionTopNImplWeight<T, false>;
-template <PrimitiveType T>
-using ImplWeightWithDefault = AggregateFunctionTopNImplWeight<T, true>;
+                                                          const 
AggregateFunctionAttr& attr);
 
 AggregateFunctionPtr create_aggregate_function_topn_weighted(const 
std::string& name,
                                                              const DataTypes& 
argument_types,
                                                              const 
DataTypePtr& result_type,
                                                              const bool 
result_is_nullable,
-                                                             const 
AggregateFunctionAttr& attr) {
-    bool has_default_param = (argument_types.size() == 4);
-    if (has_default_param) {
-        return creator::create<AggregateFunctionTopNArray, 
ImplWeightWithDefault>(
-                argument_types, result_is_nullable, attr);
-    } else {
-        return creator::create<AggregateFunctionTopNArray, 
ImplWeight>(argument_types,
-                                                                       
result_is_nullable, attr);
-    }
-}
+                                                             const 
AggregateFunctionAttr& attr);
 
 void register_aggregate_function_topn(AggregateFunctionSimpleFactory& factory) 
{
     factory.register_function_both("topn", create_aggregate_function_topn);
diff --git a/be/src/exprs/aggregate/aggregate_function_topn_array.cpp 
b/be/src/exprs/aggregate/aggregate_function_topn_array.cpp
new file mode 100644
index 00000000000..a63239e9b2b
--- /dev/null
+++ b/be/src/exprs/aggregate/aggregate_function_topn_array.cpp
@@ -0,0 +1,52 @@
+// 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 "core/data_type/data_type.h"
+#include "core/data_type/define_primitive_type.h"
+#include "exprs/aggregate/aggregate_function_topn.h"
+#include "exprs/aggregate/helpers.h"
+
+namespace doris {
+#include "common/compile_check_begin.h"
+
+template <PrimitiveType T>
+using ImplArray = AggregateFunctionTopNImplArray<T, false>;
+template <PrimitiveType T>
+using ImplArrayWithDefault = AggregateFunctionTopNImplArray<T, true>;
+
+using topn_array_creator =
+        creator_with_type_list<TYPE_TINYINT, TYPE_SMALLINT, TYPE_INT, 
TYPE_BIGINT, TYPE_LARGEINT,
+                               TYPE_FLOAT, TYPE_DOUBLE, TYPE_DECIMAL32, 
TYPE_DECIMAL64,
+                               TYPE_DECIMAL128I, TYPE_DECIMAL256, 
TYPE_VARCHAR, TYPE_DATEV2,
+                               TYPE_DATETIMEV2, TYPE_TIMESTAMPTZ, TYPE_IPV4, 
TYPE_IPV6>;
+
+AggregateFunctionPtr create_aggregate_function_topn_array(const std::string& 
name,
+                                                          const DataTypes& 
argument_types,
+                                                          const DataTypePtr& 
result_type,
+                                                          const bool 
result_is_nullable,
+                                                          const 
AggregateFunctionAttr& attr) {
+    bool has_default_param = (argument_types.size() == 3);
+    if (has_default_param) {
+        return topn_array_creator::create<AggregateFunctionTopNArray, 
ImplArrayWithDefault>(
+                argument_types, result_is_nullable, attr);
+    } else {
+        return topn_array_creator::create<AggregateFunctionTopNArray, 
ImplArray>(
+                argument_types, result_is_nullable, attr);
+    }
+}
+
+} // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_topn_weighted.cpp 
b/be/src/exprs/aggregate/aggregate_function_topn_weighted.cpp
new file mode 100644
index 00000000000..8e93406e6d7
--- /dev/null
+++ b/be/src/exprs/aggregate/aggregate_function_topn_weighted.cpp
@@ -0,0 +1,52 @@
+// 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 "core/data_type/data_type.h"
+#include "core/data_type/define_primitive_type.h"
+#include "exprs/aggregate/aggregate_function_topn.h"
+#include "exprs/aggregate/helpers.h"
+
+namespace doris {
+#include "common/compile_check_begin.h"
+
+template <PrimitiveType T>
+using ImplWeight = AggregateFunctionTopNImplWeight<T, false>;
+template <PrimitiveType T>
+using ImplWeightWithDefault = AggregateFunctionTopNImplWeight<T, true>;
+
+using topn_weighted_creator =
+        creator_with_type_list<TYPE_TINYINT, TYPE_SMALLINT, TYPE_INT, 
TYPE_BIGINT, TYPE_LARGEINT,
+                               TYPE_FLOAT, TYPE_DOUBLE, TYPE_DECIMAL32, 
TYPE_DECIMAL64,
+                               TYPE_DECIMAL128I, TYPE_DECIMAL256, 
TYPE_VARCHAR, TYPE_DATEV2,
+                               TYPE_DATETIMEV2, TYPE_TIMESTAMPTZ, TYPE_IPV4, 
TYPE_IPV6>;
+
+AggregateFunctionPtr create_aggregate_function_topn_weighted(const 
std::string& name,
+                                                             const DataTypes& 
argument_types,
+                                                             const 
DataTypePtr& result_type,
+                                                             const bool 
result_is_nullable,
+                                                             const 
AggregateFunctionAttr& attr) {
+    bool has_default_param = (argument_types.size() == 4);
+    if (has_default_param) {
+        return topn_weighted_creator::create<AggregateFunctionTopNArray, 
ImplWeightWithDefault>(
+                argument_types, result_is_nullable, attr);
+    } else {
+        return topn_weighted_creator::create<AggregateFunctionTopNArray, 
ImplWeight>(
+                argument_types, result_is_nullable, attr);
+    }
+}
+
+} // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_window.cpp 
b/be/src/exprs/aggregate/aggregate_function_window.cpp
index f0ef6284a1a..01e35bb999a 100644
--- a/be/src/exprs/aggregate/aggregate_function_window.cpp
+++ b/be/src/exprs/aggregate/aggregate_function_window.cpp
@@ -21,350 +21,44 @@
 #include "exprs/aggregate/aggregate_function_window.h"
 
 #include <string>
-#include <variant>
 
-#include "core/data_type/data_type.h"
-#include "exec/common/template_helpers.hpp"
 #include "exprs/aggregate/aggregate_function_simple_factory.h"
 #include "exprs/aggregate/helpers.h"
 
 namespace doris {
 #include "common/compile_check_begin.h"
 
-template <template <typename> class AggregateFunctionTemplate,
-          template <typename ColVecType, bool, bool> class Data,
-          template <typename, bool> class Impl, bool result_is_nullable, bool 
arg_is_nullable>
-AggregateFunctionPtr create_function_lead_lag_first_last(const String& name,
-                                                         const DataTypes& 
argument_types) {
-    bool arg_ignore_null_value = false;
-    // FE have rewrite case first_value(k1,false)--->first_value(k1)
-    // so size is 2, must will be arg_ignore_null_value
-    if (argument_types.size() == 2) {
-        DCHECK(name == "first_value" || name == "last_value" || name == 
"nth_value")
-                << "invalid function name: " << name;
-        arg_ignore_null_value = true;
-    }
-    switch (argument_types[0]->get_primitive_type()) {
-    case PrimitiveType::TYPE_BOOLEAN: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnUInt8, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnUInt8, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_TINYINT: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnInt8, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnInt8, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_SMALLINT: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnInt16, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnInt16, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_INT: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnInt32, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnInt32, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_BIGINT: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnInt64, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnInt64, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_LARGEINT: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnInt128, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnInt128, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_FLOAT: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnFloat32, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnFloat32, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_DOUBLE: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnFloat64, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnFloat64, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_DECIMAL32: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnDecimal32, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnDecimal32, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_DECIMAL64: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnDecimal64, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnDecimal64, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_DECIMAL128I: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnDecimal128V3, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnDecimal128V3, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_DECIMALV2: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnDecimal128V2, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnDecimal128V2, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_DECIMAL256: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnDecimal256, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnDecimal256, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_STRING:
-    case PrimitiveType::TYPE_CHAR:
-    case PrimitiveType::TYPE_VARCHAR:
-    case PrimitiveType::TYPE_JSONB: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnString, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnString, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_DATETIMEV2: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnDateTimeV2, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnDateTimeV2, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_DATEV2: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnDateV2, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnDateV2, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_IPV4: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnIPv4, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnIPv4, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_IPV6: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnIPv6, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnIPv6, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_ARRAY: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnArray, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnArray, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_MAP: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnMap, result_is_nullable, arg_is_nullable>, 
true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnMap, result_is_nullable, arg_is_nullable>, 
false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_STRUCT: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnStruct, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnStruct, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_VARIANT: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnVariant, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnVariant, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_BITMAP: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnBitmap, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnBitmap, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_HLL: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnHLL, result_is_nullable, arg_is_nullable>, 
true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnHLL, result_is_nullable, arg_is_nullable>, 
false>>>(
-                    argument_types);
-        }
-    }
-    case PrimitiveType::TYPE_QUANTILE_STATE: {
-        if (arg_ignore_null_value) {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnQuantileState, result_is_nullable, 
arg_is_nullable>, true>>>(
-                    argument_types);
-        } else {
-            return std::make_shared<AggregateFunctionTemplate<
-                    Impl<Data<ColumnQuantileState, result_is_nullable, 
arg_is_nullable>, false>>>(
-                    argument_types);
-        }
-    }
-    default:
-        LOG(WARNING) << "with unknowed type, failed in  
create_aggregate_function_" << name
-                     << " and type is: " << argument_types[0]->get_name();
-        return nullptr;
-    }
-}
-
-#define CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(CREATE_FUNCTION_NAME, 
FUNCTION_DATA,             \
-                                                  FUNCTION_IMPL)               
                    \
-    AggregateFunctionPtr CREATE_FUNCTION_NAME(                                 
                    \
-            const std::string& name, const DataTypes& argument_types,          
                    \
-            const DataTypePtr& result_type, const bool result_is_nullable,     
                    \
-            const AggregateFunctionAttr& attr) {                               
                    \
-        const bool arg_is_nullable = argument_types[0]->is_nullable();         
                    \
-        AggregateFunctionPtr res = nullptr;                                    
                    \
-                                                                               
                    \
-        std::visit(                                                            
                    \
-                [&](auto result_is_nullable, auto arg_is_nullable) {           
                    \
-                    res = AggregateFunctionPtr(                                
                    \
-                            
create_function_lead_lag_first_last<WindowFunctionData, FUNCTION_DATA, \
-                                                                FUNCTION_IMPL, 
result_is_nullable, \
-                                                                
arg_is_nullable>(name,             \
-                                                                               
  argument_types)); \
-                },                                                             
                    \
-                make_bool_variant(result_is_nullable), 
make_bool_variant(arg_is_nullable));        \
-        if (!res) {                                                            
                    \
-            LOG(WARNING) << " failed in  create_aggregate_function_" << name   
                    \
-                         << " and type is: " << argument_types[0]->get_name(); 
                    \
-        }                                                                      
                    \
-        return res;                                                            
                    \
-    }
-
-CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_lag,
 LeadLagData,
-                                          WindowFunctionLagImpl);
-CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_lead,
 LeadLagData,
-                                          WindowFunctionLeadImpl);
-CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_first,
 FirstLastData,
-                                          WindowFunctionFirstImpl);
-CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_last,
 FirstLastData,
-                                          WindowFunctionLastImpl);
-CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_nth_value,
 NthValueData,
-                                          WindowFunctionNthValueImpl);
+// Defined in separate translation units to reduce per-file template 
instantiation cost:
+//   aggregate_function_window_lag.cpp
+//   aggregate_function_window_lead.cpp
+//   aggregate_function_window_first.cpp
+//   aggregate_function_window_last.cpp
+//   aggregate_function_window_nth_value.cpp
+AggregateFunctionPtr create_aggregate_function_window_lag(const std::string& 
name,
+                                                          const DataTypes& 
argument_types,
+                                                          const DataTypePtr& 
result_type,
+                                                          const bool 
result_is_nullable,
+                                                          const 
AggregateFunctionAttr& attr);
+AggregateFunctionPtr create_aggregate_function_window_lead(const std::string& 
name,
+                                                           const DataTypes& 
argument_types,
+                                                           const DataTypePtr& 
result_type,
+                                                           const bool 
result_is_nullable,
+                                                           const 
AggregateFunctionAttr& attr);
+AggregateFunctionPtr create_aggregate_function_window_first(const std::string& 
name,
+                                                            const DataTypes& 
argument_types,
+                                                            const DataTypePtr& 
result_type,
+                                                            const bool 
result_is_nullable,
+                                                            const 
AggregateFunctionAttr& attr);
+AggregateFunctionPtr create_aggregate_function_window_last(const std::string& 
name,
+                                                           const DataTypes& 
argument_types,
+                                                           const DataTypePtr& 
result_type,
+                                                           const bool 
result_is_nullable,
+                                                           const 
AggregateFunctionAttr& attr);
+AggregateFunctionPtr create_aggregate_function_window_nth_value(const 
std::string& name,
+                                                                const 
DataTypes& argument_types,
+                                                                const 
DataTypePtr& result_type,
+                                                                const bool 
result_is_nullable,
+                                                                const 
AggregateFunctionAttr& attr);
 
 template <typename AggregateFunctionTemplate>
 AggregateFunctionPtr create_empty_arg_window(const std::string& name,
diff --git a/be/src/exprs/aggregate/aggregate_function_window_first.cpp 
b/be/src/exprs/aggregate/aggregate_function_window_first.cpp
new file mode 100644
index 00000000000..63b7054d5d4
--- /dev/null
+++ b/be/src/exprs/aggregate/aggregate_function_window_first.cpp
@@ -0,0 +1,27 @@
+// 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 "exprs/aggregate/aggregate_function_window_impl.h"
+
+namespace doris {
+#include "common/compile_check_begin.h"
+
+CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_first,
 FirstLastData,
+                                          WindowFunctionFirstImpl);
+
+#include "common/compile_check_end.h"
+} // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_window.cpp 
b/be/src/exprs/aggregate/aggregate_function_window_impl.h
similarity index 84%
copy from be/src/exprs/aggregate/aggregate_function_window.cpp
copy to be/src/exprs/aggregate/aggregate_function_window_impl.h
index f0ef6284a1a..c3f6f0d4033 100644
--- a/be/src/exprs/aggregate/aggregate_function_window.cpp
+++ b/be/src/exprs/aggregate/aggregate_function_window_impl.h
@@ -14,11 +14,8 @@
 // KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
-// This file is copied from
-// 
https://github.com/ClickHouse/ClickHouse/blob/master/src/Processors/Transforms/WindowTransform.cpp
-// and modified by Doris
 
-#include "exprs/aggregate/aggregate_function_window.h"
+#pragma once
 
 #include <string>
 #include <variant>
@@ -26,6 +23,7 @@
 #include "core/data_type/data_type.h"
 #include "exec/common/template_helpers.hpp"
 #include "exprs/aggregate/aggregate_function_simple_factory.h"
+#include "exprs/aggregate/aggregate_function_window.h"
 #include "exprs/aggregate/helpers.h"
 
 namespace doris {
@@ -355,49 +353,5 @@ AggregateFunctionPtr 
create_function_lead_lag_first_last(const String& name,
         return res;                                                            
                    \
     }
 
-CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_lag,
 LeadLagData,
-                                          WindowFunctionLagImpl);
-CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_lead,
 LeadLagData,
-                                          WindowFunctionLeadImpl);
-CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_first,
 FirstLastData,
-                                          WindowFunctionFirstImpl);
-CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_last,
 FirstLastData,
-                                          WindowFunctionLastImpl);
-CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_nth_value,
 NthValueData,
-                                          WindowFunctionNthValueImpl);
-
-template <typename AggregateFunctionTemplate>
-AggregateFunctionPtr create_empty_arg_window(const std::string& name,
-                                             const DataTypes& argument_types,
-                                             const DataTypePtr& result_type,
-                                             const bool result_is_nullable,
-                                             const AggregateFunctionAttr& 
attr) {
-    if (!argument_types.empty()) {
-        throw doris::Exception(
-                Status::InternalError("create_window: argument_types must be 
empty"));
-    }
-    std::unique_ptr<IAggregateFunction> result =
-            std::make_unique<AggregateFunctionTemplate>(argument_types);
-    CHECK_AGG_FUNCTION_SERIALIZED_TYPE(AggregateFunctionTemplate);
-    return AggregateFunctionPtr(result.release());
-}
-
-void register_aggregate_function_window_rank(AggregateFunctionSimpleFactory& 
factory) {
-    factory.register_function("dense_rank", 
create_empty_arg_window<WindowFunctionDenseRank>);
-    factory.register_function("rank", 
create_empty_arg_window<WindowFunctionRank>);
-    factory.register_function("percent_rank", 
create_empty_arg_window<WindowFunctionPercentRank>);
-    factory.register_function("row_number", 
create_empty_arg_window<WindowFunctionRowNumber>);
-    factory.register_function("ntile", 
creator_without_type::creator<WindowFunctionNTile>);
-    factory.register_function("cume_dist", 
create_empty_arg_window<WindowFunctionCumeDist>);
-}
-
-void register_aggregate_function_window_lead_lag_first_last(
-        AggregateFunctionSimpleFactory& factory) {
-    factory.register_function_both("lead", 
create_aggregate_function_window_lead);
-    factory.register_function_both("lag", 
create_aggregate_function_window_lag);
-    factory.register_function_both("first_value", 
create_aggregate_function_window_first);
-    factory.register_function_both("last_value", 
create_aggregate_function_window_last);
-    factory.register_function_both("nth_value", 
create_aggregate_function_window_nth_value);
-}
-
+#include "common/compile_check_end.h"
 } // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_window_lag.cpp 
b/be/src/exprs/aggregate/aggregate_function_window_lag.cpp
new file mode 100644
index 00000000000..73b7af57cfa
--- /dev/null
+++ b/be/src/exprs/aggregate/aggregate_function_window_lag.cpp
@@ -0,0 +1,27 @@
+// 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 "exprs/aggregate/aggregate_function_window_impl.h"
+
+namespace doris {
+#include "common/compile_check_begin.h"
+
+CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_lag,
 LeadLagData,
+                                          WindowFunctionLagImpl);
+
+#include "common/compile_check_end.h"
+} // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_window_last.cpp 
b/be/src/exprs/aggregate/aggregate_function_window_last.cpp
new file mode 100644
index 00000000000..7b864404817
--- /dev/null
+++ b/be/src/exprs/aggregate/aggregate_function_window_last.cpp
@@ -0,0 +1,27 @@
+// 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 "exprs/aggregate/aggregate_function_window_impl.h"
+
+namespace doris {
+#include "common/compile_check_begin.h"
+
+CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_last,
 FirstLastData,
+                                          WindowFunctionLastImpl);
+
+#include "common/compile_check_end.h"
+} // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_window_lead.cpp 
b/be/src/exprs/aggregate/aggregate_function_window_lead.cpp
new file mode 100644
index 00000000000..dacf7e51e29
--- /dev/null
+++ b/be/src/exprs/aggregate/aggregate_function_window_lead.cpp
@@ -0,0 +1,27 @@
+// 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 "exprs/aggregate/aggregate_function_window_impl.h"
+
+namespace doris {
+#include "common/compile_check_begin.h"
+
+CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_lead,
 LeadLagData,
+                                          WindowFunctionLeadImpl);
+
+#include "common/compile_check_end.h"
+} // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_window_nth_value.cpp 
b/be/src/exprs/aggregate/aggregate_function_window_nth_value.cpp
new file mode 100644
index 00000000000..d2efa2144fb
--- /dev/null
+++ b/be/src/exprs/aggregate/aggregate_function_window_nth_value.cpp
@@ -0,0 +1,27 @@
+// 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 "exprs/aggregate/aggregate_function_window_impl.h"
+
+namespace doris {
+#include "common/compile_check_begin.h"
+
+CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_nth_value,
 NthValueData,
+                                          WindowFunctionNthValueImpl);
+
+#include "common/compile_check_end.h"
+} // namespace doris


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to