Coverage Report

Created: 2026-04-01 07:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/aggregate/aggregate_function_window.cpp
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
// This file is copied from
18
// https://github.com/ClickHouse/ClickHouse/blob/master/src/Processors/Transforms/WindowTransform.cpp
19
// and modified by Doris
20
21
#include "exprs/aggregate/aggregate_function_window.h"
22
23
#include <string>
24
25
#include "exprs/aggregate/aggregate_function_simple_factory.h"
26
#include "exprs/aggregate/helpers.h"
27
28
namespace doris {
29
#include "common/compile_check_begin.h"
30
31
// Defined in separate translation units to reduce per-file template instantiation cost:
32
//   aggregate_function_window_lag.cpp
33
//   aggregate_function_window_lead.cpp
34
//   aggregate_function_window_first.cpp
35
//   aggregate_function_window_last.cpp
36
//   aggregate_function_window_nth_value.cpp
37
AggregateFunctionPtr create_aggregate_function_window_lag(const std::string& name,
38
                                                          const DataTypes& argument_types,
39
                                                          const DataTypePtr& result_type,
40
                                                          const bool result_is_nullable,
41
                                                          const AggregateFunctionAttr& attr);
42
AggregateFunctionPtr create_aggregate_function_window_lead(const std::string& name,
43
                                                           const DataTypes& argument_types,
44
                                                           const DataTypePtr& result_type,
45
                                                           const bool result_is_nullable,
46
                                                           const AggregateFunctionAttr& attr);
47
AggregateFunctionPtr create_aggregate_function_window_first(const std::string& name,
48
                                                            const DataTypes& argument_types,
49
                                                            const DataTypePtr& result_type,
50
                                                            const bool result_is_nullable,
51
                                                            const AggregateFunctionAttr& attr);
52
AggregateFunctionPtr create_aggregate_function_window_first_ignore_null(
53
        const std::string& name, const DataTypes& argument_types, const DataTypePtr& result_type,
54
        const bool result_is_nullable, const AggregateFunctionAttr& attr);
55
AggregateFunctionPtr create_aggregate_function_window_last(const std::string& name,
56
                                                           const DataTypes& argument_types,
57
                                                           const DataTypePtr& result_type,
58
                                                           const bool result_is_nullable,
59
                                                           const AggregateFunctionAttr& attr);
60
AggregateFunctionPtr create_aggregate_function_window_last_ignore_null(
61
        const std::string& name, const DataTypes& argument_types, const DataTypePtr& result_type,
62
        const bool result_is_nullable, const AggregateFunctionAttr& attr);
63
AggregateFunctionPtr create_aggregate_function_window_nth_value(const std::string& name,
64
                                                                const DataTypes& argument_types,
65
                                                                const DataTypePtr& result_type,
66
                                                                const bool result_is_nullable,
67
                                                                const AggregateFunctionAttr& attr);
68
69
template <typename AggregateFunctionTemplate>
70
AggregateFunctionPtr create_empty_arg_window(const std::string& name,
71
                                             const DataTypes& argument_types,
72
                                             const DataTypePtr& result_type,
73
                                             const bool result_is_nullable,
74
351
                                             const AggregateFunctionAttr& attr) {
75
351
    if (!argument_types.empty()) {
76
0
        throw doris::Exception(
77
0
                Status::InternalError("create_window: argument_types must be empty"));
78
0
    }
79
351
    std::unique_ptr<IAggregateFunction> result =
80
351
            std::make_unique<AggregateFunctionTemplate>(argument_types);
81
351
    CHECK_AGG_FUNCTION_SERIALIZED_TYPE(AggregateFunctionTemplate);
82
351
    return AggregateFunctionPtr(result.release());
83
351
}
_ZN5doris23create_empty_arg_windowINS_23WindowFunctionDenseRankEEESt10shared_ptrINS_18IAggregateFunctionEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS2_IKNS_9IDataTypeEESaISG_EERKSG_bRKNS_21AggregateFunctionAttrE
Line
Count
Source
74
14
                                             const AggregateFunctionAttr& attr) {
75
14
    if (!argument_types.empty()) {
76
0
        throw doris::Exception(
77
0
                Status::InternalError("create_window: argument_types must be empty"));
78
0
    }
79
14
    std::unique_ptr<IAggregateFunction> result =
80
14
            std::make_unique<AggregateFunctionTemplate>(argument_types);
81
14
    CHECK_AGG_FUNCTION_SERIALIZED_TYPE(AggregateFunctionTemplate);
82
14
    return AggregateFunctionPtr(result.release());
83
14
}
_ZN5doris23create_empty_arg_windowINS_18WindowFunctionRankEEESt10shared_ptrINS_18IAggregateFunctionEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS2_IKNS_9IDataTypeEESaISG_EERKSG_bRKNS_21AggregateFunctionAttrE
Line
Count
Source
74
184
                                             const AggregateFunctionAttr& attr) {
75
184
    if (!argument_types.empty()) {
76
0
        throw doris::Exception(
77
0
                Status::InternalError("create_window: argument_types must be empty"));
78
0
    }
79
184
    std::unique_ptr<IAggregateFunction> result =
80
184
            std::make_unique<AggregateFunctionTemplate>(argument_types);
81
184
    CHECK_AGG_FUNCTION_SERIALIZED_TYPE(AggregateFunctionTemplate);
82
184
    return AggregateFunctionPtr(result.release());
83
184
}
_ZN5doris23create_empty_arg_windowINS_25WindowFunctionPercentRankEEESt10shared_ptrINS_18IAggregateFunctionEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS2_IKNS_9IDataTypeEESaISG_EERKSG_bRKNS_21AggregateFunctionAttrE
Line
Count
Source
74
8
                                             const AggregateFunctionAttr& attr) {
75
8
    if (!argument_types.empty()) {
76
0
        throw doris::Exception(
77
0
                Status::InternalError("create_window: argument_types must be empty"));
78
0
    }
79
8
    std::unique_ptr<IAggregateFunction> result =
80
8
            std::make_unique<AggregateFunctionTemplate>(argument_types);
81
8
    CHECK_AGG_FUNCTION_SERIALIZED_TYPE(AggregateFunctionTemplate);
82
8
    return AggregateFunctionPtr(result.release());
83
8
}
_ZN5doris23create_empty_arg_windowINS_23WindowFunctionRowNumberEEESt10shared_ptrINS_18IAggregateFunctionEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS2_IKNS_9IDataTypeEESaISG_EERKSG_bRKNS_21AggregateFunctionAttrE
Line
Count
Source
74
137
                                             const AggregateFunctionAttr& attr) {
75
137
    if (!argument_types.empty()) {
76
0
        throw doris::Exception(
77
0
                Status::InternalError("create_window: argument_types must be empty"));
78
0
    }
79
137
    std::unique_ptr<IAggregateFunction> result =
80
137
            std::make_unique<AggregateFunctionTemplate>(argument_types);
81
137
    CHECK_AGG_FUNCTION_SERIALIZED_TYPE(AggregateFunctionTemplate);
82
137
    return AggregateFunctionPtr(result.release());
83
137
}
_ZN5doris23create_empty_arg_windowINS_22WindowFunctionCumeDistEEESt10shared_ptrINS_18IAggregateFunctionEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS2_IKNS_9IDataTypeEESaISG_EERKSG_bRKNS_21AggregateFunctionAttrE
Line
Count
Source
74
8
                                             const AggregateFunctionAttr& attr) {
75
8
    if (!argument_types.empty()) {
76
0
        throw doris::Exception(
77
0
                Status::InternalError("create_window: argument_types must be empty"));
78
0
    }
79
8
    std::unique_ptr<IAggregateFunction> result =
80
8
            std::make_unique<AggregateFunctionTemplate>(argument_types);
81
8
    CHECK_AGG_FUNCTION_SERIALIZED_TYPE(AggregateFunctionTemplate);
82
8
    return AggregateFunctionPtr(result.release());
83
8
}
84
85
6
void register_aggregate_function_window_rank(AggregateFunctionSimpleFactory& factory) {
86
6
    factory.register_function("dense_rank", create_empty_arg_window<WindowFunctionDenseRank>);
87
6
    factory.register_function("rank", create_empty_arg_window<WindowFunctionRank>);
88
6
    factory.register_function("percent_rank", create_empty_arg_window<WindowFunctionPercentRank>);
89
6
    factory.register_function("row_number", create_empty_arg_window<WindowFunctionRowNumber>);
90
6
    factory.register_function("ntile", creator_without_type::creator<WindowFunctionNTile>);
91
6
    factory.register_function("cume_dist", create_empty_arg_window<WindowFunctionCumeDist>);
92
6
}
93
94
void register_aggregate_function_window_lead_lag_first_last(
95
6
        AggregateFunctionSimpleFactory& factory) {
96
6
    factory.register_function_both("lead", create_aggregate_function_window_lead);
97
6
    factory.register_function_both("lag", create_aggregate_function_window_lag);
98
    // FE rewrites first_value(k1, false) → first_value(k1), so argument_types.size() == 2
99
    // means arg_ignore_null = true. Dispatch at registration to avoid runtime branching
100
    // that would double template instantiations.
101
6
    factory.register_function_both(
102
6
            "first_value",
103
6
            [](const std::string& name, const DataTypes& argument_types,
104
6
               const DataTypePtr& result_type, const bool result_is_nullable,
105
6
               const AggregateFunctionAttr& attr) -> AggregateFunctionPtr {
106
1
                if (argument_types.size() == 2) {
107
0
                    return create_aggregate_function_window_first_ignore_null(
108
0
                            name, argument_types, result_type, result_is_nullable, attr);
109
0
                }
110
1
                return create_aggregate_function_window_first(name, argument_types, result_type,
111
1
                                                              result_is_nullable, attr);
112
1
            });
113
6
    factory.register_function_both(
114
6
            "last_value",
115
6
            [](const std::string& name, const DataTypes& argument_types,
116
6
               const DataTypePtr& result_type, const bool result_is_nullable,
117
6
               const AggregateFunctionAttr& attr) -> AggregateFunctionPtr {
118
0
                if (argument_types.size() == 2) {
119
0
                    return create_aggregate_function_window_last_ignore_null(
120
0
                            name, argument_types, result_type, result_is_nullable, attr);
121
0
                }
122
0
                return create_aggregate_function_window_last(name, argument_types, result_type,
123
0
                                                             result_is_nullable, attr);
124
0
            });
125
    // nth_value always has 2 args (column, N) from FE.
126
    // WindowFunctionNthValueImpl does not implement ignore-null logic,
127
    // so register directly without dispatch.
128
6
    factory.register_function_both("nth_value", create_aggregate_function_window_nth_value);
129
6
}
130
131
} // namespace doris