Coverage Report

Created: 2026-04-14 17:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/aggregate/aggregate_function_sequence_match.h
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
18
// This file is copied from
19
// https://github.com/ClickHouse/ClickHouse/blob/master/AggregateFunctionSequenceMatch.h
20
// and modified by Doris
21
22
#pragma once
23
24
#include <string.h>
25
26
#include <algorithm>
27
#include <bitset>
28
#include <boost/iterator/iterator_facade.hpp>
29
#include <cstdint>
30
#include <functional>
31
#include <iterator>
32
#include <memory>
33
#include <stack>
34
#include <string>
35
#include <tuple>
36
#include <utility>
37
#include <vector>
38
39
#include "common/logging.h"
40
#include "core/assert_cast.h"
41
#include "core/column/column_string.h"
42
#include "core/column/column_vector.h"
43
#include "core/data_type/data_type_number.h"
44
#include "core/pod_array_fwd.h"
45
#include "core/string_ref.h"
46
#include "core/types.h"
47
#include "exprs/aggregate/aggregate_function.h"
48
#include "util/io_helper.h"
49
50
namespace doris {
51
class Arena;
52
class BufferReadable;
53
class BufferWritable;
54
class IColumn;
55
} // namespace doris
56
57
namespace doris {
58
59
template <template <typename> class Comparator>
60
struct ComparePairFirst final {
61
    template <typename T1, typename T2>
62
30
    bool operator()(const std::pair<T1, T2>& lhs, const std::pair<T1, T2>& rhs) const {
63
30
        return Comparator<T1> {}(lhs.first, rhs.first);
64
30
    }
_ZNK5doris16ComparePairFirstISt4lessEclINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEEEbRKSt4pairIT_T0_ESE_
Line
Count
Source
62
30
    bool operator()(const std::pair<T1, T2>& lhs, const std::pair<T1, T2>& rhs) const {
63
30
        return Comparator<T1> {}(lhs.first, rhs.first);
64
30
    }
Unexecuted instantiation: _ZNK5doris16ComparePairFirstISt4lessEclINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEEEbRKSt4pairIT_T0_ESE_
65
};
66
67
static constexpr size_t MAX_EVENTS = 32;
68
69
/// Max number of iterations to match the pattern against a sequence, exception thrown when exceeded
70
constexpr auto sequence_match_max_iterations = 1000000l;
71
72
template <PrimitiveType T, typename Derived>
73
struct AggregateFunctionSequenceMatchData final {
74
    using Timestamp = typename PrimitiveTypeTraits<T>::CppType;
75
    using NativeType =
76
            std::conditional_t<T == TYPE_DATEV2, uint32_t,
77
                               std::conditional_t<T == TYPE_DATETIMEV2, uint64_t,
78
                                                  typename PrimitiveTypeTraits<T>::CppType>>;
79
    using Events = std::bitset<MAX_EVENTS>;
80
    using TimestampEvents = std::pair<Timestamp, Events>;
81
    using Comparator = ComparePairFirst<std::less>;
82
83
14
    AggregateFunctionSequenceMatchData() { reset(); }
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEEC2Ev
Line
Count
Source
83
7
    AggregateFunctionSequenceMatchData() { reset(); }
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEEC2Ev
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEEC2Ev
Line
Count
Source
83
7
    AggregateFunctionSequenceMatchData() { reset(); }
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEEC2Ev
84
85
public:
86
10
    const std::string get_pattern() const { return pattern; }
_ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE11get_patternB5cxx11Ev
Line
Count
Source
86
5
    const std::string get_pattern() const { return pattern; }
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE11get_patternB5cxx11Ev
_ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE11get_patternB5cxx11Ev
Line
Count
Source
86
5
    const std::string get_pattern() const { return pattern; }
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE11get_patternB5cxx11Ev
87
88
10
    size_t get_arg_count() const { return arg_count; }
_ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE13get_arg_countEv
Line
Count
Source
88
5
    size_t get_arg_count() const { return arg_count; }
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE13get_arg_countEv
_ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE13get_arg_countEv
Line
Count
Source
88
5
    size_t get_arg_count() const { return arg_count; }
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE13get_arg_countEv
89
90
26
    void init(const std::string pattern_, size_t arg_count_) {
91
26
        if (!init_flag) {
92
12
            this->pattern = pattern_;
93
12
            this->arg_count = arg_count_;
94
12
            parse_pattern();
95
12
            init_flag = true;
96
12
        }
97
26
    }
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE4initENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm
Line
Count
Source
90
13
    void init(const std::string pattern_, size_t arg_count_) {
91
13
        if (!init_flag) {
92
6
            this->pattern = pattern_;
93
6
            this->arg_count = arg_count_;
94
6
            parse_pattern();
95
6
            init_flag = true;
96
6
        }
97
13
    }
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE4initENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE4initENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm
Line
Count
Source
90
13
    void init(const std::string pattern_, size_t arg_count_) {
91
13
        if (!init_flag) {
92
6
            this->pattern = pattern_;
93
6
            this->arg_count = arg_count_;
94
6
            parse_pattern();
95
6
            init_flag = true;
96
6
        }
97
13
    }
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE4initENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm
98
99
14
    void reset() {
100
14
        sorted = true;
101
14
        init_flag = false;
102
14
        pattern_has_time = false;
103
14
        pattern = "";
104
14
        arg_count = 0;
105
14
        conditions_met.reset();
106
14
        conditions_in_pattern.reset();
107
108
14
        events_list.clear();
109
14
        actions.clear();
110
14
        dfa_states.clear();
111
14
    }
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE5resetEv
Line
Count
Source
99
7
    void reset() {
100
7
        sorted = true;
101
7
        init_flag = false;
102
7
        pattern_has_time = false;
103
7
        pattern = "";
104
7
        arg_count = 0;
105
7
        conditions_met.reset();
106
7
        conditions_in_pattern.reset();
107
108
7
        events_list.clear();
109
7
        actions.clear();
110
7
        dfa_states.clear();
111
7
    }
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE5resetEv
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE5resetEv
Line
Count
Source
99
7
    void reset() {
100
7
        sorted = true;
101
7
        init_flag = false;
102
7
        pattern_has_time = false;
103
7
        pattern = "";
104
7
        arg_count = 0;
105
7
        conditions_met.reset();
106
7
        conditions_in_pattern.reset();
107
108
7
        events_list.clear();
109
7
        actions.clear();
110
7
        dfa_states.clear();
111
7
    }
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE5resetEv
112
113
16
    void add(const Timestamp& timestamp, const Events& events) {
114
        /// store information exclusively for rows with at least one event
115
16
        if (events.any()) {
116
13
            events_list.emplace_back(timestamp, events);
117
13
            sorted = false;
118
13
            conditions_met |= events;
119
13
        }
120
16
    }
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE3addERKNS_11DateV2ValueINS_19DateTimeV2ValueTypeEEERKSt6bitsetILm32EE
Line
Count
Source
113
8
    void add(const Timestamp& timestamp, const Events& events) {
114
        /// store information exclusively for rows with at least one event
115
8
        if (events.any()) {
116
5
            events_list.emplace_back(timestamp, events);
117
5
            sorted = false;
118
5
            conditions_met |= events;
119
5
        }
120
8
    }
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE3addERKNS_11DateV2ValueINS_15DateV2ValueTypeEEERKSt6bitsetILm32EE
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE3addERKNS_11DateV2ValueINS_19DateTimeV2ValueTypeEEERKSt6bitsetILm32EE
Line
Count
Source
113
8
    void add(const Timestamp& timestamp, const Events& events) {
114
        /// store information exclusively for rows with at least one event
115
8
        if (events.any()) {
116
8
            events_list.emplace_back(timestamp, events);
117
8
            sorted = false;
118
8
            conditions_met |= events;
119
8
        }
120
8
    }
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE3addERKNS_11DateV2ValueINS_15DateV2ValueTypeEEERKSt6bitsetILm32EE
121
122
4
    void merge(const AggregateFunctionSequenceMatchData& other) {
123
4
        if (other.events_list.empty()) return;
124
125
2
        events_list.insert(std::end(events_list), std::begin(other.events_list),
126
2
                           std::end(other.events_list));
127
2
        sorted = false;
128
2
        conditions_met |= other.conditions_met;
129
2
    }
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE5mergeERKS4_
Line
Count
Source
122
2
    void merge(const AggregateFunctionSequenceMatchData& other) {
123
2
        if (other.events_list.empty()) return;
124
125
1
        events_list.insert(std::end(events_list), std::begin(other.events_list),
126
1
                           std::end(other.events_list));
127
1
        sorted = false;
128
1
        conditions_met |= other.conditions_met;
129
1
    }
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE5mergeERKS4_
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE5mergeERKS4_
Line
Count
Source
122
2
    void merge(const AggregateFunctionSequenceMatchData& other) {
123
2
        if (other.events_list.empty()) return;
124
125
1
        events_list.insert(std::end(events_list), std::begin(other.events_list),
126
1
                           std::end(other.events_list));
127
1
        sorted = false;
128
1
        conditions_met |= other.conditions_met;
129
1
    }
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE5mergeERKS4_
130
131
    // todo: rethink the sort method.
132
7
    void sort() {
133
7
        if (sorted) return;
134
135
7
        std::sort(std::begin(events_list), std::end(events_list), Comparator {});
136
7
        sorted = true;
137
7
    }
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE4sortEv
Line
Count
Source
132
3
    void sort() {
133
3
        if (sorted) return;
134
135
3
        std::sort(std::begin(events_list), std::end(events_list), Comparator {});
136
3
        sorted = true;
137
3
    }
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE4sortEv
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE4sortEv
Line
Count
Source
132
4
    void sort() {
133
4
        if (sorted) return;
134
135
4
        std::sort(std::begin(events_list), std::end(events_list), Comparator {});
136
4
        sorted = true;
137
4
    }
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE4sortEv
138
139
6
    void write(BufferWritable& buf) const {
140
6
        buf.write_binary(sorted);
141
6
        buf.write_binary(events_list.size());
142
143
10
        for (const auto& events : events_list) {
144
10
            buf.write_binary(events.first);
145
10
            buf.write_binary(events.second.to_ulong());
146
10
        }
147
148
        // This is std::bitset<32>, which will not exceed 32 bits.
149
6
        UInt32 conditions_met_value = (UInt32)conditions_met.to_ulong();
150
6
        buf.write_binary(conditions_met_value);
151
152
6
        buf.write_binary(pattern);
153
6
        buf.write_binary(arg_count);
154
6
    }
_ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE5writeERNS_14BufferWritableE
Line
Count
Source
139
3
    void write(BufferWritable& buf) const {
140
3
        buf.write_binary(sorted);
141
3
        buf.write_binary(events_list.size());
142
143
4
        for (const auto& events : events_list) {
144
4
            buf.write_binary(events.first);
145
4
            buf.write_binary(events.second.to_ulong());
146
4
        }
147
148
        // This is std::bitset<32>, which will not exceed 32 bits.
149
3
        UInt32 conditions_met_value = (UInt32)conditions_met.to_ulong();
150
3
        buf.write_binary(conditions_met_value);
151
152
3
        buf.write_binary(pattern);
153
3
        buf.write_binary(arg_count);
154
3
    }
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE5writeERNS_14BufferWritableE
_ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE5writeERNS_14BufferWritableE
Line
Count
Source
139
3
    void write(BufferWritable& buf) const {
140
3
        buf.write_binary(sorted);
141
3
        buf.write_binary(events_list.size());
142
143
6
        for (const auto& events : events_list) {
144
6
            buf.write_binary(events.first);
145
6
            buf.write_binary(events.second.to_ulong());
146
6
        }
147
148
        // This is std::bitset<32>, which will not exceed 32 bits.
149
3
        UInt32 conditions_met_value = (UInt32)conditions_met.to_ulong();
150
3
        buf.write_binary(conditions_met_value);
151
152
3
        buf.write_binary(pattern);
153
3
        buf.write_binary(arg_count);
154
3
    }
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE5writeERNS_14BufferWritableE
155
156
6
    void read(BufferReadable& buf) {
157
6
        buf.read_binary(sorted);
158
159
6
        size_t events_list_size;
160
6
        buf.read_binary(events_list_size);
161
162
6
        events_list.clear();
163
6
        events_list.reserve(events_list_size);
164
165
16
        for (size_t i = 0; i < events_list_size; ++i) {
166
10
            Timestamp timestamp;
167
10
            buf.read_binary(timestamp);
168
169
10
            UInt64 events;
170
10
            buf.read_binary(events);
171
172
10
            events_list.emplace_back(timestamp, Events {events});
173
10
        }
174
175
6
        UInt32 conditions_met_value;
176
6
        buf.read_binary(conditions_met_value);
177
6
        conditions_met = conditions_met_value;
178
179
6
        buf.read_binary(pattern);
180
6
        buf.read_binary(arg_count);
181
6
    }
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE4readERNS_14BufferReadableE
Line
Count
Source
156
3
    void read(BufferReadable& buf) {
157
3
        buf.read_binary(sorted);
158
159
3
        size_t events_list_size;
160
3
        buf.read_binary(events_list_size);
161
162
3
        events_list.clear();
163
3
        events_list.reserve(events_list_size);
164
165
7
        for (size_t i = 0; i < events_list_size; ++i) {
166
4
            Timestamp timestamp;
167
4
            buf.read_binary(timestamp);
168
169
4
            UInt64 events;
170
4
            buf.read_binary(events);
171
172
4
            events_list.emplace_back(timestamp, Events {events});
173
4
        }
174
175
3
        UInt32 conditions_met_value;
176
3
        buf.read_binary(conditions_met_value);
177
3
        conditions_met = conditions_met_value;
178
179
3
        buf.read_binary(pattern);
180
3
        buf.read_binary(arg_count);
181
3
    }
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE4readERNS_14BufferReadableE
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE4readERNS_14BufferReadableE
Line
Count
Source
156
3
    void read(BufferReadable& buf) {
157
3
        buf.read_binary(sorted);
158
159
3
        size_t events_list_size;
160
3
        buf.read_binary(events_list_size);
161
162
3
        events_list.clear();
163
3
        events_list.reserve(events_list_size);
164
165
9
        for (size_t i = 0; i < events_list_size; ++i) {
166
6
            Timestamp timestamp;
167
6
            buf.read_binary(timestamp);
168
169
6
            UInt64 events;
170
6
            buf.read_binary(events);
171
172
6
            events_list.emplace_back(timestamp, Events {events});
173
6
        }
174
175
3
        UInt32 conditions_met_value;
176
3
        buf.read_binary(conditions_met_value);
177
3
        conditions_met = conditions_met_value;
178
179
3
        buf.read_binary(pattern);
180
3
        buf.read_binary(arg_count);
181
3
    }
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE4readERNS_14BufferReadableE
182
183
private:
184
    enum class PatternActionType {
185
        SpecificEvent,
186
        AnyEvent,
187
        KleeneStar,
188
        TimeLessOrEqual,
189
        TimeLess,
190
        TimeGreaterOrEqual,
191
        TimeGreater,
192
        TimeEqual
193
    };
194
195
    struct PatternAction final {
196
        PatternActionType type;
197
        std::uint64_t extra;
198
199
        PatternAction() = default;
200
        explicit PatternAction(const PatternActionType type_, const std::uint64_t extra_ = 0)
201
32
                : type {type_}, extra {extra_} {}
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE13PatternActionC2ENS4_17PatternActionTypeEm
Line
Count
Source
201
16
                : type {type_}, extra {extra_} {}
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE13PatternActionC2ENS4_17PatternActionTypeEm
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE13PatternActionC2ENS4_17PatternActionTypeEm
Line
Count
Source
201
16
                : type {type_}, extra {extra_} {}
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE13PatternActionC2ENS4_17PatternActionTypeEm
202
    };
203
204
    using PatternActions = PODArrayWithStackMemory<PatternAction, 64>;
205
206
    Derived& derived() { return assert_cast<Derived&, TypeCheckOnRelease::DISABLE>(*this); }
207
208
12
    void parse_pattern() {
209
12
        actions.clear();
210
12
        actions.emplace_back(PatternActionType::KleeneStar);
211
212
12
        dfa_states.clear();
213
12
        dfa_states.emplace_back(true);
214
215
12
        pattern_has_time = false;
216
217
12
        const char* pos = pattern.data();
218
12
        const char* begin = pos;
219
12
        const char* end = pos + pattern.size();
220
221
        // Pattern is checked in fe, so pattern should be valid here, we check it and if pattern is invalid, we return.
222
12
        auto throw_exception = [&](const std::string& msg) {
223
0
            LOG(WARNING) << msg + " '" + std::string(pos, end) + "' at position " +
224
0
                                    std::to_string(pos - begin);
225
0
        };
Unexecuted instantiation: _ZZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE13parse_patternEvENKUlRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE_clESC_
Unexecuted instantiation: _ZZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE13parse_patternEvENKUlRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE_clESC_
Unexecuted instantiation: _ZZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE13parse_patternEvENKUlRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE_clESC_
Unexecuted instantiation: _ZZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE13parse_patternEvENKUlRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE_clESC_
226
227
60
        auto match = [&pos, end](const char* str) mutable {
228
60
            size_t length = strlen(str);
229
60
            if (pos + length <= end && 0 == memcmp(pos, str, length)) {
230
40
                pos += length;
231
40
                return true;
232
40
            }
233
20
            return false;
234
60
        };
_ZZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE13parse_patternEvENUlPKcE_clES6_
Line
Count
Source
227
30
        auto match = [&pos, end](const char* str) mutable {
228
30
            size_t length = strlen(str);
229
30
            if (pos + length <= end && 0 == memcmp(pos, str, length)) {
230
20
                pos += length;
231
20
                return true;
232
20
            }
233
10
            return false;
234
30
        };
Unexecuted instantiation: _ZZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE13parse_patternEvENUlPKcE_clES6_
_ZZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE13parse_patternEvENUlPKcE_clES6_
Line
Count
Source
227
30
        auto match = [&pos, end](const char* str) mutable {
228
30
            size_t length = strlen(str);
229
30
            if (pos + length <= end && 0 == memcmp(pos, str, length)) {
230
20
                pos += length;
231
20
                return true;
232
20
            }
233
10
            return false;
234
30
        };
Unexecuted instantiation: _ZZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE13parse_patternEvENUlPKcE_clES6_
235
236
32
        while (pos < end) {
237
20
            if (match("(?")) {
238
20
                if (match("t")) {
239
0
                    PatternActionType type;
240
241
0
                    if (match("<="))
242
0
                        type = PatternActionType::TimeLessOrEqual;
243
0
                    else if (match("<"))
244
0
                        type = PatternActionType::TimeLess;
245
0
                    else if (match(">="))
246
0
                        type = PatternActionType::TimeGreaterOrEqual;
247
0
                    else if (match(">"))
248
0
                        type = PatternActionType::TimeGreater;
249
0
                    else if (match("=="))
250
0
                        type = PatternActionType::TimeEqual;
251
0
                    else {
252
0
                        throw_exception("Unknown time condition");
253
0
                        return;
254
0
                    }
255
256
0
                    NativeType duration = 0;
257
0
                    const auto* prev_pos = pos;
258
0
                    pos = try_read_first_int_text(duration, pos, end);
259
0
                    if (pos == prev_pos) {
260
0
                        throw_exception("Could not parse number");
261
0
                        return;
262
0
                    }
263
264
0
                    if (actions.back().type != PatternActionType::SpecificEvent &&
265
0
                        actions.back().type != PatternActionType::AnyEvent &&
266
0
                        actions.back().type != PatternActionType::KleeneStar) {
267
0
                        throw_exception(
268
0
                                "Temporal condition should be preceded by an event condition");
269
0
                        return;
270
0
                    }
271
272
0
                    pattern_has_time = true;
273
0
                    actions.emplace_back(type, duration);
274
20
                } else {
275
20
                    UInt64 event_number = 0;
276
20
                    const auto* prev_pos = pos;
277
20
                    pos = try_read_first_int_text(event_number, pos, end);
278
20
                    if (pos == prev_pos) throw_exception("Could not parse number");
279
280
20
                    if (event_number > arg_count - 1) {
281
0
                        throw_exception("Event number " + std::to_string(event_number) +
282
0
                                        " is out of range");
283
0
                        return;
284
0
                    }
285
286
20
                    actions.emplace_back(PatternActionType::SpecificEvent, event_number - 1);
287
20
                    dfa_states.back().transition = DFATransition::SpecificEvent;
288
20
                    dfa_states.back().event = static_cast<uint32_t>(event_number - 1);
289
20
                    dfa_states.emplace_back();
290
20
                    conditions_in_pattern.set(event_number - 1);
291
20
                }
292
293
20
                if (!match(")")) {
294
0
                    throw_exception("Expected closing parenthesis, found");
295
0
                    return;
296
0
                }
297
298
20
            } else if (match(".*")) {
299
0
                actions.emplace_back(PatternActionType::KleeneStar);
300
0
                dfa_states.back().has_kleene = true;
301
0
            } else if (match(".")) {
302
0
                actions.emplace_back(PatternActionType::AnyEvent);
303
0
                dfa_states.back().transition = DFATransition::AnyEvent;
304
0
                dfa_states.emplace_back();
305
0
            } else {
306
0
                throw_exception("Could not parse pattern, unexpected starting symbol");
307
0
                return;
308
0
            }
309
20
        }
310
12
    }
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE13parse_patternEv
Line
Count
Source
208
6
    void parse_pattern() {
209
6
        actions.clear();
210
6
        actions.emplace_back(PatternActionType::KleeneStar);
211
212
6
        dfa_states.clear();
213
6
        dfa_states.emplace_back(true);
214
215
6
        pattern_has_time = false;
216
217
6
        const char* pos = pattern.data();
218
6
        const char* begin = pos;
219
6
        const char* end = pos + pattern.size();
220
221
        // Pattern is checked in fe, so pattern should be valid here, we check it and if pattern is invalid, we return.
222
6
        auto throw_exception = [&](const std::string& msg) {
223
6
            LOG(WARNING) << msg + " '" + std::string(pos, end) + "' at position " +
224
6
                                    std::to_string(pos - begin);
225
6
        };
226
227
6
        auto match = [&pos, end](const char* str) mutable {
228
6
            size_t length = strlen(str);
229
6
            if (pos + length <= end && 0 == memcmp(pos, str, length)) {
230
6
                pos += length;
231
6
                return true;
232
6
            }
233
6
            return false;
234
6
        };
235
236
16
        while (pos < end) {
237
10
            if (match("(?")) {
238
10
                if (match("t")) {
239
0
                    PatternActionType type;
240
241
0
                    if (match("<="))
242
0
                        type = PatternActionType::TimeLessOrEqual;
243
0
                    else if (match("<"))
244
0
                        type = PatternActionType::TimeLess;
245
0
                    else if (match(">="))
246
0
                        type = PatternActionType::TimeGreaterOrEqual;
247
0
                    else if (match(">"))
248
0
                        type = PatternActionType::TimeGreater;
249
0
                    else if (match("=="))
250
0
                        type = PatternActionType::TimeEqual;
251
0
                    else {
252
0
                        throw_exception("Unknown time condition");
253
0
                        return;
254
0
                    }
255
256
0
                    NativeType duration = 0;
257
0
                    const auto* prev_pos = pos;
258
0
                    pos = try_read_first_int_text(duration, pos, end);
259
0
                    if (pos == prev_pos) {
260
0
                        throw_exception("Could not parse number");
261
0
                        return;
262
0
                    }
263
264
0
                    if (actions.back().type != PatternActionType::SpecificEvent &&
265
0
                        actions.back().type != PatternActionType::AnyEvent &&
266
0
                        actions.back().type != PatternActionType::KleeneStar) {
267
0
                        throw_exception(
268
0
                                "Temporal condition should be preceded by an event condition");
269
0
                        return;
270
0
                    }
271
272
0
                    pattern_has_time = true;
273
0
                    actions.emplace_back(type, duration);
274
10
                } else {
275
10
                    UInt64 event_number = 0;
276
10
                    const auto* prev_pos = pos;
277
10
                    pos = try_read_first_int_text(event_number, pos, end);
278
10
                    if (pos == prev_pos) throw_exception("Could not parse number");
279
280
10
                    if (event_number > arg_count - 1) {
281
0
                        throw_exception("Event number " + std::to_string(event_number) +
282
0
                                        " is out of range");
283
0
                        return;
284
0
                    }
285
286
10
                    actions.emplace_back(PatternActionType::SpecificEvent, event_number - 1);
287
10
                    dfa_states.back().transition = DFATransition::SpecificEvent;
288
10
                    dfa_states.back().event = static_cast<uint32_t>(event_number - 1);
289
10
                    dfa_states.emplace_back();
290
10
                    conditions_in_pattern.set(event_number - 1);
291
10
                }
292
293
10
                if (!match(")")) {
294
0
                    throw_exception("Expected closing parenthesis, found");
295
0
                    return;
296
0
                }
297
298
10
            } else if (match(".*")) {
299
0
                actions.emplace_back(PatternActionType::KleeneStar);
300
0
                dfa_states.back().has_kleene = true;
301
0
            } else if (match(".")) {
302
0
                actions.emplace_back(PatternActionType::AnyEvent);
303
0
                dfa_states.back().transition = DFATransition::AnyEvent;
304
0
                dfa_states.emplace_back();
305
0
            } else {
306
0
                throw_exception("Could not parse pattern, unexpected starting symbol");
307
0
                return;
308
0
            }
309
10
        }
310
6
    }
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE13parse_patternEv
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE13parse_patternEv
Line
Count
Source
208
6
    void parse_pattern() {
209
6
        actions.clear();
210
6
        actions.emplace_back(PatternActionType::KleeneStar);
211
212
6
        dfa_states.clear();
213
6
        dfa_states.emplace_back(true);
214
215
6
        pattern_has_time = false;
216
217
6
        const char* pos = pattern.data();
218
6
        const char* begin = pos;
219
6
        const char* end = pos + pattern.size();
220
221
        // Pattern is checked in fe, so pattern should be valid here, we check it and if pattern is invalid, we return.
222
6
        auto throw_exception = [&](const std::string& msg) {
223
6
            LOG(WARNING) << msg + " '" + std::string(pos, end) + "' at position " +
224
6
                                    std::to_string(pos - begin);
225
6
        };
226
227
6
        auto match = [&pos, end](const char* str) mutable {
228
6
            size_t length = strlen(str);
229
6
            if (pos + length <= end && 0 == memcmp(pos, str, length)) {
230
6
                pos += length;
231
6
                return true;
232
6
            }
233
6
            return false;
234
6
        };
235
236
16
        while (pos < end) {
237
10
            if (match("(?")) {
238
10
                if (match("t")) {
239
0
                    PatternActionType type;
240
241
0
                    if (match("<="))
242
0
                        type = PatternActionType::TimeLessOrEqual;
243
0
                    else if (match("<"))
244
0
                        type = PatternActionType::TimeLess;
245
0
                    else if (match(">="))
246
0
                        type = PatternActionType::TimeGreaterOrEqual;
247
0
                    else if (match(">"))
248
0
                        type = PatternActionType::TimeGreater;
249
0
                    else if (match("=="))
250
0
                        type = PatternActionType::TimeEqual;
251
0
                    else {
252
0
                        throw_exception("Unknown time condition");
253
0
                        return;
254
0
                    }
255
256
0
                    NativeType duration = 0;
257
0
                    const auto* prev_pos = pos;
258
0
                    pos = try_read_first_int_text(duration, pos, end);
259
0
                    if (pos == prev_pos) {
260
0
                        throw_exception("Could not parse number");
261
0
                        return;
262
0
                    }
263
264
0
                    if (actions.back().type != PatternActionType::SpecificEvent &&
265
0
                        actions.back().type != PatternActionType::AnyEvent &&
266
0
                        actions.back().type != PatternActionType::KleeneStar) {
267
0
                        throw_exception(
268
0
                                "Temporal condition should be preceded by an event condition");
269
0
                        return;
270
0
                    }
271
272
0
                    pattern_has_time = true;
273
0
                    actions.emplace_back(type, duration);
274
10
                } else {
275
10
                    UInt64 event_number = 0;
276
10
                    const auto* prev_pos = pos;
277
10
                    pos = try_read_first_int_text(event_number, pos, end);
278
10
                    if (pos == prev_pos) throw_exception("Could not parse number");
279
280
10
                    if (event_number > arg_count - 1) {
281
0
                        throw_exception("Event number " + std::to_string(event_number) +
282
0
                                        " is out of range");
283
0
                        return;
284
0
                    }
285
286
10
                    actions.emplace_back(PatternActionType::SpecificEvent, event_number - 1);
287
10
                    dfa_states.back().transition = DFATransition::SpecificEvent;
288
10
                    dfa_states.back().event = static_cast<uint32_t>(event_number - 1);
289
10
                    dfa_states.emplace_back();
290
10
                    conditions_in_pattern.set(event_number - 1);
291
10
                }
292
293
10
                if (!match(")")) {
294
0
                    throw_exception("Expected closing parenthesis, found");
295
0
                    return;
296
0
                }
297
298
10
            } else if (match(".*")) {
299
0
                actions.emplace_back(PatternActionType::KleeneStar);
300
0
                dfa_states.back().has_kleene = true;
301
0
            } else if (match(".")) {
302
0
                actions.emplace_back(PatternActionType::AnyEvent);
303
0
                dfa_states.back().transition = DFATransition::AnyEvent;
304
0
                dfa_states.emplace_back();
305
0
            } else {
306
0
                throw_exception("Could not parse pattern, unexpected starting symbol");
307
0
                return;
308
0
            }
309
10
        }
310
6
    }
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE13parse_patternEv
311
312
public:
313
    /// Uses a DFA based approach in order to better handle patterns without
314
    /// time assertions.
315
    ///
316
    /// NOTE: This implementation relies on the assumption that the pattern is *small*.
317
    ///
318
    /// This algorithm performs in O(mn) (with m the number of DFA states and N the number
319
    /// of events) with a memory consumption and memory allocations in O(m). It means that
320
    /// if n >>> m (which is expected to be the case), this algorithm can be considered linear.
321
    template <typename EventEntry>
322
3
    bool dfa_match(EventEntry& events_it, const EventEntry events_end) const {
323
3
        using ActiveStates = std::vector<bool>;
324
        /// Those two vectors keep track of which states should be considered for the current
325
        /// event as well as the states which should be considered for the next event.
326
3
        ActiveStates active_states(dfa_states.size(), false);
327
3
        ActiveStates next_active_states(dfa_states.size(), false);
328
3
        active_states[0] = true;
329
330
        /// Keeps track of dead-ends in order not to iterate over all the events to realize that
331
        /// the match failed.
332
3
        size_t n_active = 1;
333
334
9
        for (/* empty */; events_it != events_end && n_active > 0 && !active_states.back();
335
6
             ++events_it) {
336
6
            n_active = 0;
337
6
            next_active_states.assign(dfa_states.size(), false);
338
339
24
            for (size_t state = 0; state < dfa_states.size(); ++state) {
340
18
                if (!active_states[state]) {
341
9
                    continue;
342
9
                }
343
344
9
                switch (dfa_states[state].transition) {
345
0
                case DFATransition::None:
346
0
                    break;
347
0
                case DFATransition::AnyEvent:
348
0
                    next_active_states[state + 1] = true;
349
0
                    ++n_active;
350
0
                    break;
351
9
                case DFATransition::SpecificEvent:
352
9
                    if (events_it->second.test(dfa_states[state].event)) {
353
6
                        next_active_states[state + 1] = true;
354
6
                        ++n_active;
355
6
                    }
356
9
                    break;
357
9
                }
358
359
9
                if (dfa_states[state].has_kleene) {
360
6
                    next_active_states[state] = true;
361
6
                    ++n_active;
362
6
                }
363
9
            }
364
6
            swap(active_states, next_active_states);
365
6
        }
366
367
3
        return active_states.back();
368
3
    }
_ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE9dfa_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_
Line
Count
Source
322
3
    bool dfa_match(EventEntry& events_it, const EventEntry events_end) const {
323
3
        using ActiveStates = std::vector<bool>;
324
        /// Those two vectors keep track of which states should be considered for the current
325
        /// event as well as the states which should be considered for the next event.
326
3
        ActiveStates active_states(dfa_states.size(), false);
327
3
        ActiveStates next_active_states(dfa_states.size(), false);
328
3
        active_states[0] = true;
329
330
        /// Keeps track of dead-ends in order not to iterate over all the events to realize that
331
        /// the match failed.
332
3
        size_t n_active = 1;
333
334
9
        for (/* empty */; events_it != events_end && n_active > 0 && !active_states.back();
335
6
             ++events_it) {
336
6
            n_active = 0;
337
6
            next_active_states.assign(dfa_states.size(), false);
338
339
24
            for (size_t state = 0; state < dfa_states.size(); ++state) {
340
18
                if (!active_states[state]) {
341
9
                    continue;
342
9
                }
343
344
9
                switch (dfa_states[state].transition) {
345
0
                case DFATransition::None:
346
0
                    break;
347
0
                case DFATransition::AnyEvent:
348
0
                    next_active_states[state + 1] = true;
349
0
                    ++n_active;
350
0
                    break;
351
9
                case DFATransition::SpecificEvent:
352
9
                    if (events_it->second.test(dfa_states[state].event)) {
353
6
                        next_active_states[state + 1] = true;
354
6
                        ++n_active;
355
6
                    }
356
9
                    break;
357
9
                }
358
359
9
                if (dfa_states[state].has_kleene) {
360
6
                    next_active_states[state] = true;
361
6
                    ++n_active;
362
6
                }
363
9
            }
364
6
            swap(active_states, next_active_states);
365
6
        }
366
367
3
        return active_states.back();
368
3
    }
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE9dfa_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_
369
370
    template <typename EventEntry>
371
7
    bool backtracking_match(EventEntry& events_it, const EventEntry events_end) const {
372
7
        const auto action_begin = std::begin(actions);
373
7
        const auto action_end = std::end(actions);
374
7
        auto action_it = action_begin;
375
376
7
        const auto events_begin = events_it;
377
7
        auto base_it = events_it;
378
379
        /// an iterator to action plus an iterator to row in events list plus timestamp at the start of sequence
380
7
        using backtrack_info = std::tuple<decltype(action_it), EventEntry, EventEntry>;
381
7
        std::stack<backtrack_info> back_stack;
382
383
        /// backtrack if possible
384
7
        const auto do_backtrack = [&] {
385
0
            while (!back_stack.empty()) {
386
0
                auto& top = back_stack.top();
387
388
0
                action_it = std::get<0>(top);
389
0
                events_it = std::next(std::get<1>(top));
390
0
                base_it = std::get<2>(top);
391
392
0
                back_stack.pop();
393
394
0
                if (events_it != events_end) return true;
395
0
            }
396
397
0
            return false;
398
0
        };
Unexecuted instantiation: _ZZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE18backtracking_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_ENKUlvE_clEv
Unexecuted instantiation: _ZZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE18backtracking_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_ENKUlvE_clEv
Unexecuted instantiation: _ZZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE18backtracking_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_ENKUlvE_clEv
Unexecuted instantiation: _ZZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE18backtracking_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_ENKUlvE_clEv
399
400
7
        size_t i = 0;
401
28
        while (action_it != action_end && events_it != events_end) {
402
21
            if (action_it->type == PatternActionType::SpecificEvent) {
403
14
                if (events_it->second.test(action_it->extra)) {
404
                    /// move to the next action and events
405
14
                    base_it = events_it;
406
14
                    ++action_it, ++events_it;
407
14
                } else if (!do_backtrack())
408
                    /// backtracking failed, bail out
409
0
                    break;
410
14
            } else if (action_it->type == PatternActionType::AnyEvent) {
411
0
                base_it = events_it;
412
0
                ++action_it, ++events_it;
413
7
            } else if (action_it->type == PatternActionType::KleeneStar) {
414
7
                back_stack.emplace(action_it, events_it, base_it);
415
7
                base_it = events_it;
416
7
                ++action_it;
417
7
            } else if (action_it->type == PatternActionType::TimeLessOrEqual) {
418
0
                if (events_it->first.datetime_diff_in_seconds(base_it->first) <= action_it->extra) {
419
                    /// condition satisfied, move onto next action
420
0
                    back_stack.emplace(action_it, events_it, base_it);
421
0
                    base_it = events_it;
422
0
                    ++action_it;
423
0
                } else if (!do_backtrack())
424
0
                    break;
425
0
            } else if (action_it->type == PatternActionType::TimeLess) {
426
0
                if (events_it->first.datetime_diff_in_seconds(base_it->first) < action_it->extra) {
427
0
                    back_stack.emplace(action_it, events_it, base_it);
428
0
                    base_it = events_it;
429
0
                    ++action_it;
430
0
                } else if (!do_backtrack())
431
0
                    break;
432
0
            } else if (action_it->type == PatternActionType::TimeGreaterOrEqual) {
433
0
                if (events_it->first.datetime_diff_in_seconds(base_it->first) >= action_it->extra) {
434
0
                    back_stack.emplace(action_it, events_it, base_it);
435
0
                    base_it = events_it;
436
0
                    ++action_it;
437
0
                } else if (++events_it == events_end && !do_backtrack())
438
0
                    break;
439
0
            } else if (action_it->type == PatternActionType::TimeGreater) {
440
0
                if (events_it->first.datetime_diff_in_seconds(base_it->first) > action_it->extra) {
441
0
                    back_stack.emplace(action_it, events_it, base_it);
442
0
                    base_it = events_it;
443
0
                    ++action_it;
444
0
                } else if (++events_it == events_end && !do_backtrack())
445
0
                    break;
446
0
            } else if (action_it->type == PatternActionType::TimeEqual) {
447
0
                if (events_it->first.datetime_diff_in_seconds(base_it->first) == action_it->extra) {
448
0
                    back_stack.emplace(action_it, events_it, base_it);
449
0
                    base_it = events_it;
450
0
                    ++action_it;
451
0
                } else if (++events_it == events_end && !do_backtrack())
452
0
                    break;
453
0
            } else {
454
0
                LOG(WARNING) << "Unknown PatternActionType";
455
0
                return false;
456
0
            }
457
458
21
            if (++i > sequence_match_max_iterations) {
459
0
                LOG(WARNING)
460
0
                        << "Pattern application proves too difficult, exceeding max iterations (" +
461
0
                                   std::to_string(sequence_match_max_iterations) + ")";
462
0
                return false;
463
0
            }
464
21
        }
465
466
        /// if there are some actions remaining
467
7
        if (action_it != action_end) {
468
            /// match multiple empty strings at end
469
0
            while (action_it->type == PatternActionType::KleeneStar ||
470
0
                   action_it->type == PatternActionType::TimeLessOrEqual ||
471
0
                   action_it->type == PatternActionType::TimeLess ||
472
0
                   (action_it->type == PatternActionType::TimeGreaterOrEqual &&
473
0
                    action_it->extra == 0))
474
0
                ++action_it;
475
0
        }
476
477
7
        if (events_it == events_begin) ++events_it;
478
479
7
        return action_it == action_end;
480
7
    }
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE18backtracking_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE18backtracking_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_
_ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE18backtracking_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_
Line
Count
Source
371
7
    bool backtracking_match(EventEntry& events_it, const EventEntry events_end) const {
372
7
        const auto action_begin = std::begin(actions);
373
7
        const auto action_end = std::end(actions);
374
7
        auto action_it = action_begin;
375
376
7
        const auto events_begin = events_it;
377
7
        auto base_it = events_it;
378
379
        /// an iterator to action plus an iterator to row in events list plus timestamp at the start of sequence
380
7
        using backtrack_info = std::tuple<decltype(action_it), EventEntry, EventEntry>;
381
7
        std::stack<backtrack_info> back_stack;
382
383
        /// backtrack if possible
384
7
        const auto do_backtrack = [&] {
385
7
            while (!back_stack.empty()) {
386
7
                auto& top = back_stack.top();
387
388
7
                action_it = std::get<0>(top);
389
7
                events_it = std::next(std::get<1>(top));
390
7
                base_it = std::get<2>(top);
391
392
7
                back_stack.pop();
393
394
7
                if (events_it != events_end) return true;
395
7
            }
396
397
7
            return false;
398
7
        };
399
400
7
        size_t i = 0;
401
28
        while (action_it != action_end && events_it != events_end) {
402
21
            if (action_it->type == PatternActionType::SpecificEvent) {
403
14
                if (events_it->second.test(action_it->extra)) {
404
                    /// move to the next action and events
405
14
                    base_it = events_it;
406
14
                    ++action_it, ++events_it;
407
14
                } else if (!do_backtrack())
408
                    /// backtracking failed, bail out
409
0
                    break;
410
14
            } else if (action_it->type == PatternActionType::AnyEvent) {
411
0
                base_it = events_it;
412
0
                ++action_it, ++events_it;
413
7
            } else if (action_it->type == PatternActionType::KleeneStar) {
414
7
                back_stack.emplace(action_it, events_it, base_it);
415
7
                base_it = events_it;
416
7
                ++action_it;
417
7
            } else if (action_it->type == PatternActionType::TimeLessOrEqual) {
418
0
                if (events_it->first.datetime_diff_in_seconds(base_it->first) <= action_it->extra) {
419
                    /// condition satisfied, move onto next action
420
0
                    back_stack.emplace(action_it, events_it, base_it);
421
0
                    base_it = events_it;
422
0
                    ++action_it;
423
0
                } else if (!do_backtrack())
424
0
                    break;
425
0
            } else if (action_it->type == PatternActionType::TimeLess) {
426
0
                if (events_it->first.datetime_diff_in_seconds(base_it->first) < action_it->extra) {
427
0
                    back_stack.emplace(action_it, events_it, base_it);
428
0
                    base_it = events_it;
429
0
                    ++action_it;
430
0
                } else if (!do_backtrack())
431
0
                    break;
432
0
            } else if (action_it->type == PatternActionType::TimeGreaterOrEqual) {
433
0
                if (events_it->first.datetime_diff_in_seconds(base_it->first) >= action_it->extra) {
434
0
                    back_stack.emplace(action_it, events_it, base_it);
435
0
                    base_it = events_it;
436
0
                    ++action_it;
437
0
                } else if (++events_it == events_end && !do_backtrack())
438
0
                    break;
439
0
            } else if (action_it->type == PatternActionType::TimeGreater) {
440
0
                if (events_it->first.datetime_diff_in_seconds(base_it->first) > action_it->extra) {
441
0
                    back_stack.emplace(action_it, events_it, base_it);
442
0
                    base_it = events_it;
443
0
                    ++action_it;
444
0
                } else if (++events_it == events_end && !do_backtrack())
445
0
                    break;
446
0
            } else if (action_it->type == PatternActionType::TimeEqual) {
447
0
                if (events_it->first.datetime_diff_in_seconds(base_it->first) == action_it->extra) {
448
0
                    back_stack.emplace(action_it, events_it, base_it);
449
0
                    base_it = events_it;
450
0
                    ++action_it;
451
0
                } else if (++events_it == events_end && !do_backtrack())
452
0
                    break;
453
0
            } else {
454
0
                LOG(WARNING) << "Unknown PatternActionType";
455
0
                return false;
456
0
            }
457
458
21
            if (++i > sequence_match_max_iterations) {
459
0
                LOG(WARNING)
460
0
                        << "Pattern application proves too difficult, exceeding max iterations (" +
461
0
                                   std::to_string(sequence_match_max_iterations) + ")";
462
0
                return false;
463
0
            }
464
21
        }
465
466
        /// if there are some actions remaining
467
7
        if (action_it != action_end) {
468
            /// match multiple empty strings at end
469
0
            while (action_it->type == PatternActionType::KleeneStar ||
470
0
                   action_it->type == PatternActionType::TimeLessOrEqual ||
471
0
                   action_it->type == PatternActionType::TimeLess ||
472
0
                   (action_it->type == PatternActionType::TimeGreaterOrEqual &&
473
0
                    action_it->extra == 0))
474
0
                ++action_it;
475
0
        }
476
477
7
        if (events_it == events_begin) ++events_it;
478
479
7
        return action_it == action_end;
480
7
    }
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE18backtracking_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_
481
482
    /// Splits the pattern into deterministic parts separated by non-deterministic fragments
483
    /// (time constraints and Kleene stars), and tries to match the deterministic parts in their specified order,
484
    /// ignoring the non-deterministic fragments.
485
    /// This function can quickly check that a full match is not possible if some deterministic fragment is missing.
486
    template <typename EventEntry>
487
    bool could_match_deterministic_parts(const EventEntry events_begin, const EventEntry events_end,
488
4
                                         bool limit_iterations = true) const {
489
4
        size_t events_processed = 0;
490
4
        auto events_it = events_begin;
491
492
4
        const auto actions_end = std::end(actions);
493
4
        auto actions_it = std::begin(actions);
494
4
        auto det_part_begin = actions_it;
495
496
4
        auto match_deterministic_part = [&events_it, events_end, &events_processed, det_part_begin,
497
8
                                         actions_it, limit_iterations]() {
498
8
            auto events_it_init = events_it;
499
8
            auto det_part_it = det_part_begin;
500
501
8
            while (det_part_it != actions_it && events_it != events_end) {
502
                /// matching any event
503
0
                if (det_part_it->type == PatternActionType::AnyEvent) ++events_it, ++det_part_it;
504
505
                /// matching specific event
506
0
                else {
507
0
                    if (events_it->second.test(det_part_it->extra)) ++events_it, ++det_part_it;
508
509
                    /// abandon current matching, try to match the deterministic fragment further in the list
510
0
                    else {
511
0
                        events_it = ++events_it_init;
512
0
                        det_part_it = det_part_begin;
513
0
                    }
514
0
                }
515
516
0
                if (limit_iterations && ++events_processed > sequence_match_max_iterations) {
517
0
                    LOG(WARNING) << "Pattern application proves too difficult, exceeding max "
518
0
                                    "iterations are " +
519
0
                                            std::to_string(sequence_match_max_iterations);
520
0
                    return false;
521
0
                }
522
0
            }
523
524
8
            return det_part_it == actions_it;
525
8
        };
Unexecuted instantiation: _ZZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE31could_match_deterministic_partsIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbT_SL_bENKUlvE_clEv
Unexecuted instantiation: _ZZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE31could_match_deterministic_partsIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbT_SL_bENKUlvE_clEv
_ZZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE31could_match_deterministic_partsIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbT_SL_bENKUlvE_clEv
Line
Count
Source
497
8
                                         actions_it, limit_iterations]() {
498
8
            auto events_it_init = events_it;
499
8
            auto det_part_it = det_part_begin;
500
501
8
            while (det_part_it != actions_it && events_it != events_end) {
502
                /// matching any event
503
0
                if (det_part_it->type == PatternActionType::AnyEvent) ++events_it, ++det_part_it;
504
505
                /// matching specific event
506
0
                else {
507
0
                    if (events_it->second.test(det_part_it->extra)) ++events_it, ++det_part_it;
508
509
                    /// abandon current matching, try to match the deterministic fragment further in the list
510
0
                    else {
511
0
                        events_it = ++events_it_init;
512
0
                        det_part_it = det_part_begin;
513
0
                    }
514
0
                }
515
516
0
                if (limit_iterations && ++events_processed > sequence_match_max_iterations) {
517
0
                    LOG(WARNING) << "Pattern application proves too difficult, exceeding max "
518
0
                                    "iterations are " +
519
0
                                            std::to_string(sequence_match_max_iterations);
520
0
                    return false;
521
0
                }
522
0
            }
523
524
8
            return det_part_it == actions_it;
525
8
        };
Unexecuted instantiation: _ZZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE31could_match_deterministic_partsIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbT_SL_bENKUlvE_clEv
526
527
16
        for (; actions_it != actions_end; ++actions_it)
528
12
            if (actions_it->type != PatternActionType::SpecificEvent &&
529
12
                actions_it->type != PatternActionType::AnyEvent) {
530
4
                if (!match_deterministic_part()) return false;
531
4
                det_part_begin = std::next(actions_it);
532
4
            }
533
534
4
        return match_deterministic_part();
535
4
    }
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE31could_match_deterministic_partsIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbT_SL_b
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE31could_match_deterministic_partsIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbT_SL_b
_ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE31could_match_deterministic_partsIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbT_SL_b
Line
Count
Source
488
4
                                         bool limit_iterations = true) const {
489
4
        size_t events_processed = 0;
490
4
        auto events_it = events_begin;
491
492
4
        const auto actions_end = std::end(actions);
493
4
        auto actions_it = std::begin(actions);
494
4
        auto det_part_begin = actions_it;
495
496
4
        auto match_deterministic_part = [&events_it, events_end, &events_processed, det_part_begin,
497
4
                                         actions_it, limit_iterations]() {
498
4
            auto events_it_init = events_it;
499
4
            auto det_part_it = det_part_begin;
500
501
4
            while (det_part_it != actions_it && events_it != events_end) {
502
                /// matching any event
503
4
                if (det_part_it->type == PatternActionType::AnyEvent) ++events_it, ++det_part_it;
504
505
                /// matching specific event
506
4
                else {
507
4
                    if (events_it->second.test(det_part_it->extra)) ++events_it, ++det_part_it;
508
509
                    /// abandon current matching, try to match the deterministic fragment further in the list
510
4
                    else {
511
4
                        events_it = ++events_it_init;
512
4
                        det_part_it = det_part_begin;
513
4
                    }
514
4
                }
515
516
4
                if (limit_iterations && ++events_processed > sequence_match_max_iterations) {
517
4
                    LOG(WARNING) << "Pattern application proves too difficult, exceeding max "
518
4
                                    "iterations are " +
519
4
                                            std::to_string(sequence_match_max_iterations);
520
4
                    return false;
521
4
                }
522
4
            }
523
524
4
            return det_part_it == actions_it;
525
4
        };
526
527
16
        for (; actions_it != actions_end; ++actions_it)
528
12
            if (actions_it->type != PatternActionType::SpecificEvent &&
529
12
                actions_it->type != PatternActionType::AnyEvent) {
530
4
                if (!match_deterministic_part()) return false;
531
4
                det_part_begin = std::next(actions_it);
532
4
            }
533
534
4
        return match_deterministic_part();
535
4
    }
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE31could_match_deterministic_partsIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbT_SL_b
536
537
private:
538
    enum class DFATransition : char {
539
        ///   .-------.
540
        ///   |       |
541
        ///   `-------'
542
        None,
543
        ///   .-------.  (?[0-9])
544
        ///   |       | ----------
545
        ///   `-------'
546
        SpecificEvent,
547
        ///   .-------.      .
548
        ///   |       | ----------
549
        ///   `-------'
550
        AnyEvent,
551
    };
552
553
    struct DFAState {
554
        explicit DFAState(bool has_kleene_ = false)
555
32
                : has_kleene {has_kleene_}, event {0}, transition {DFATransition::None} {}
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE8DFAStateC2Eb
Line
Count
Source
555
16
                : has_kleene {has_kleene_}, event {0}, transition {DFATransition::None} {}
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE8DFAStateC2Eb
_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE8DFAStateC2Eb
Line
Count
Source
555
16
                : has_kleene {has_kleene_}, event {0}, transition {DFATransition::None} {}
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE8DFAStateC2Eb
556
557
        ///   .-------.
558
        ///   |       | - - -
559
        ///   `-------'
560
        ///     |_^
561
        bool has_kleene;
562
        /// In the case of a state transitions with a `SpecificEvent`,
563
        /// `event` contains the value of the event.
564
        uint32_t event;
565
        /// The kind of transition out of this state.
566
        DFATransition transition;
567
    };
568
569
    using DFAStates = std::vector<DFAState>;
570
571
public:
572
    bool sorted = true;
573
    std::vector<TimestampEvents> events_list;
574
    // sequenceMatch conditions met at least once in events_list
575
    std::bitset<MAX_EVENTS> conditions_met;
576
    // sequenceMatch conditions met at least once in the pattern
577
    std::bitset<MAX_EVENTS> conditions_in_pattern;
578
    // `True` if the parsed pattern contains time assertions (?t...), `false` otherwise.
579
    bool pattern_has_time;
580
581
private:
582
    std::string pattern;
583
    size_t arg_count;
584
    bool init_flag = false;
585
586
    PatternActions actions;
587
    DFAStates dfa_states;
588
};
589
590
template <PrimitiveType T, typename Derived>
591
class AggregateFunctionSequenceBase
592
        : public IAggregateFunctionDataHelper<AggregateFunctionSequenceMatchData<T, Derived>,
593
                                              Derived> {
594
public:
595
    using NativeType = typename PrimitiveTypeTraits<T>::CppType;
596
    AggregateFunctionSequenceBase(const DataTypes& arguments)
597
15
            : IAggregateFunctionDataHelper<AggregateFunctionSequenceMatchData<T, Derived>, Derived>(
598
15
                      arguments) {
599
15
        arg_count = arguments.size();
600
15
    }
_ZN5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEEC2ERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Line
Count
Source
597
7
            : IAggregateFunctionDataHelper<AggregateFunctionSequenceMatchData<T, Derived>, Derived>(
598
7
                      arguments) {
599
7
        arg_count = arguments.size();
600
7
    }
Unexecuted instantiation: _ZN5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEEC2ERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
_ZN5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEEC2ERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Line
Count
Source
597
8
            : IAggregateFunctionDataHelper<AggregateFunctionSequenceMatchData<T, Derived>, Derived>(
598
8
                      arguments) {
599
8
        arg_count = arguments.size();
600
8
    }
Unexecuted instantiation: _ZN5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEEC2ERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
601
602
0
    void reset(AggregateDataPtr __restrict place) const override { this->data(place).reset(); }
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE5resetEPc
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE5resetEPc
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE5resetEPc
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE5resetEPc
603
604
    void add(AggregateDataPtr __restrict place, const IColumn** columns, const ssize_t row_num,
605
16
             Arena&) const override {
606
16
        std::string pattern =
607
16
                assert_cast<const ColumnString*, TypeCheckOnRelease::DISABLE>(columns[0])
608
16
                        ->get_data_at(0)
609
16
                        .to_string();
610
16
        this->data(place).init(pattern, arg_count);
611
612
16
        const auto& timestamp = assert_cast<const typename PrimitiveTypeTraits<T>::ColumnType&,
613
16
                                            TypeCheckOnRelease::DISABLE>(*columns[1])
614
16
                                        .get_data()[row_num];
615
16
        typename AggregateFunctionSequenceMatchData<T, Derived>::Events events;
616
617
52
        for (auto i = 2; i < arg_count; i++) {
618
36
            const auto event =
619
36
                    assert_cast<const ColumnUInt8*, TypeCheckOnRelease::DISABLE>(columns[i])
620
36
                            ->get_data()[row_num];
621
36
            events.set(i - 2, event);
622
36
        }
623
624
16
        this->data(place).add(timestamp, events);
625
16
    }
_ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE3addEPcPPKNS_7IColumnElRNS_5ArenaE
Line
Count
Source
605
8
             Arena&) const override {
606
8
        std::string pattern =
607
8
                assert_cast<const ColumnString*, TypeCheckOnRelease::DISABLE>(columns[0])
608
8
                        ->get_data_at(0)
609
8
                        .to_string();
610
8
        this->data(place).init(pattern, arg_count);
611
612
8
        const auto& timestamp = assert_cast<const typename PrimitiveTypeTraits<T>::ColumnType&,
613
8
                                            TypeCheckOnRelease::DISABLE>(*columns[1])
614
8
                                        .get_data()[row_num];
615
8
        typename AggregateFunctionSequenceMatchData<T, Derived>::Events events;
616
617
28
        for (auto i = 2; i < arg_count; i++) {
618
20
            const auto event =
619
20
                    assert_cast<const ColumnUInt8*, TypeCheckOnRelease::DISABLE>(columns[i])
620
20
                            ->get_data()[row_num];
621
20
            events.set(i - 2, event);
622
20
        }
623
624
8
        this->data(place).add(timestamp, events);
625
8
    }
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE3addEPcPPKNS_7IColumnElRNS_5ArenaE
_ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE3addEPcPPKNS_7IColumnElRNS_5ArenaE
Line
Count
Source
605
8
             Arena&) const override {
606
8
        std::string pattern =
607
8
                assert_cast<const ColumnString*, TypeCheckOnRelease::DISABLE>(columns[0])
608
8
                        ->get_data_at(0)
609
8
                        .to_string();
610
8
        this->data(place).init(pattern, arg_count);
611
612
8
        const auto& timestamp = assert_cast<const typename PrimitiveTypeTraits<T>::ColumnType&,
613
8
                                            TypeCheckOnRelease::DISABLE>(*columns[1])
614
8
                                        .get_data()[row_num];
615
8
        typename AggregateFunctionSequenceMatchData<T, Derived>::Events events;
616
617
24
        for (auto i = 2; i < arg_count; i++) {
618
16
            const auto event =
619
16
                    assert_cast<const ColumnUInt8*, TypeCheckOnRelease::DISABLE>(columns[i])
620
16
                            ->get_data()[row_num];
621
16
            events.set(i - 2, event);
622
16
        }
623
624
8
        this->data(place).add(timestamp, events);
625
8
    }
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE3addEPcPPKNS_7IColumnElRNS_5ArenaE
626
627
    void merge(AggregateDataPtr __restrict place, ConstAggregateDataPtr rhs,
628
4
               Arena&) const override {
629
4
        const std::string pattern = this->data(rhs).get_pattern();
630
4
        this->data(place).init(pattern, this->data(rhs).get_arg_count());
631
4
        this->data(place).merge(this->data(rhs));
632
4
    }
_ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE5mergeEPcPKcRNS_5ArenaE
Line
Count
Source
628
2
               Arena&) const override {
629
2
        const std::string pattern = this->data(rhs).get_pattern();
630
2
        this->data(place).init(pattern, this->data(rhs).get_arg_count());
631
2
        this->data(place).merge(this->data(rhs));
632
2
    }
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE5mergeEPcPKcRNS_5ArenaE
_ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE5mergeEPcPKcRNS_5ArenaE
Line
Count
Source
628
2
               Arena&) const override {
629
2
        const std::string pattern = this->data(rhs).get_pattern();
630
2
        this->data(place).init(pattern, this->data(rhs).get_arg_count());
631
2
        this->data(place).merge(this->data(rhs));
632
2
    }
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE5mergeEPcPKcRNS_5ArenaE
633
634
6
    void serialize(ConstAggregateDataPtr __restrict place, BufferWritable& buf) const override {
635
6
        this->data(place).write(buf);
636
6
    }
_ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE9serializeEPKcRNS_14BufferWritableE
Line
Count
Source
634
3
    void serialize(ConstAggregateDataPtr __restrict place, BufferWritable& buf) const override {
635
3
        this->data(place).write(buf);
636
3
    }
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE9serializeEPKcRNS_14BufferWritableE
_ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE9serializeEPKcRNS_14BufferWritableE
Line
Count
Source
634
3
    void serialize(ConstAggregateDataPtr __restrict place, BufferWritable& buf) const override {
635
3
        this->data(place).write(buf);
636
3
    }
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE9serializeEPKcRNS_14BufferWritableE
637
638
    void deserialize(AggregateDataPtr __restrict place, BufferReadable& buf,
639
6
                     Arena&) const override {
640
6
        this->data(place).read(buf);
641
6
        const std::string pattern = this->data(place).get_pattern();
642
6
        this->data(place).init(pattern, this->data(place).get_arg_count());
643
6
    }
_ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE11deserializeEPcRNS_14BufferReadableERNS_5ArenaE
Line
Count
Source
639
3
                     Arena&) const override {
640
3
        this->data(place).read(buf);
641
3
        const std::string pattern = this->data(place).get_pattern();
642
3
        this->data(place).init(pattern, this->data(place).get_arg_count());
643
3
    }
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE11deserializeEPcRNS_14BufferReadableERNS_5ArenaE
_ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE11deserializeEPcRNS_14BufferReadableERNS_5ArenaE
Line
Count
Source
639
3
                     Arena&) const override {
640
3
        this->data(place).read(buf);
641
3
        const std::string pattern = this->data(place).get_pattern();
642
3
        this->data(place).init(pattern, this->data(place).get_arg_count());
643
3
    }
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE11deserializeEPcRNS_14BufferReadableERNS_5ArenaE
644
645
private:
646
    size_t arg_count;
647
};
648
649
template <PrimitiveType T>
650
class AggregateFunctionSequenceMatch final
651
        : public AggregateFunctionSequenceBase<T, AggregateFunctionSequenceMatch<T>>,
652
          VarargsExpression,
653
          NullableAggregateFunction {
654
public:
655
    AggregateFunctionSequenceMatch(const DataTypes& arguments, const String& pattern_)
656
            : AggregateFunctionSequenceBase<T, AggregateFunctionSequenceMatch<T>>(arguments,
657
                                                                                  pattern_) {}
658
659
    using AggregateFunctionSequenceBase<
660
            T, AggregateFunctionSequenceMatch<T>>::AggregateFunctionSequenceBase;
661
662
0
    String get_name() const override { return "sequence_match"; }
Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceMatchILNS_13PrimitiveTypeE26EE8get_nameB5cxx11Ev
Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceMatchILNS_13PrimitiveTypeE25EE8get_nameB5cxx11Ev
663
664
0
    DataTypePtr get_return_type() const override { return std::make_shared<DataTypeUInt8>(); }
Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceMatchILNS_13PrimitiveTypeE26EE15get_return_typeEv
Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceMatchILNS_13PrimitiveTypeE25EE15get_return_typeEv
665
666
6
    void insert_result_into(ConstAggregateDataPtr __restrict place, IColumn& to) const override {
667
6
        auto& output = assert_cast<ColumnUInt8&>(to).get_data();
668
6
        if (!this->data(place).conditions_in_pattern.any()) {
669
2
            output.push_back(false);
670
2
            return;
671
2
        }
672
673
4
        if ((this->data(place).conditions_in_pattern & this->data(place).conditions_met) !=
674
4
            this->data(place).conditions_in_pattern) {
675
1
            output.push_back(false);
676
1
            return;
677
1
        }
678
        // place is essentially an AggregateDataPtr, passed as a ConstAggregateDataPtr.
679
3
        this->data(const_cast<AggregateDataPtr>(place)).sort();
680
681
3
        const auto& data_ref = this->data(place);
682
683
3
        const auto events_begin = std::begin(data_ref.events_list);
684
3
        const auto events_end = std::end(data_ref.events_list);
685
3
        auto events_it = events_begin;
686
687
3
        bool match = (this->data(place).pattern_has_time
688
3
                              ? (this->data(place).could_match_deterministic_parts(events_begin,
689
0
                                                                                   events_end) &&
690
0
                                 this->data(place).backtracking_match(events_it, events_end))
691
3
                              : this->data(place).dfa_match(events_it, events_end));
692
3
        output.push_back(match);
693
3
    }
_ZNK5doris30AggregateFunctionSequenceMatchILNS_13PrimitiveTypeE26EE18insert_result_intoEPKcRNS_7IColumnE
Line
Count
Source
666
6
    void insert_result_into(ConstAggregateDataPtr __restrict place, IColumn& to) const override {
667
6
        auto& output = assert_cast<ColumnUInt8&>(to).get_data();
668
6
        if (!this->data(place).conditions_in_pattern.any()) {
669
2
            output.push_back(false);
670
2
            return;
671
2
        }
672
673
4
        if ((this->data(place).conditions_in_pattern & this->data(place).conditions_met) !=
674
4
            this->data(place).conditions_in_pattern) {
675
1
            output.push_back(false);
676
1
            return;
677
1
        }
678
        // place is essentially an AggregateDataPtr, passed as a ConstAggregateDataPtr.
679
3
        this->data(const_cast<AggregateDataPtr>(place)).sort();
680
681
3
        const auto& data_ref = this->data(place);
682
683
3
        const auto events_begin = std::begin(data_ref.events_list);
684
3
        const auto events_end = std::end(data_ref.events_list);
685
3
        auto events_it = events_begin;
686
687
3
        bool match = (this->data(place).pattern_has_time
688
3
                              ? (this->data(place).could_match_deterministic_parts(events_begin,
689
0
                                                                                   events_end) &&
690
0
                                 this->data(place).backtracking_match(events_it, events_end))
691
3
                              : this->data(place).dfa_match(events_it, events_end));
692
3
        output.push_back(match);
693
3
    }
Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceMatchILNS_13PrimitiveTypeE25EE18insert_result_intoEPKcRNS_7IColumnE
694
};
695
696
template <PrimitiveType T>
697
class AggregateFunctionSequenceCount final
698
        : public AggregateFunctionSequenceBase<T, AggregateFunctionSequenceCount<T>>,
699
          VarargsExpression,
700
          NotNullableAggregateFunction {
701
public:
702
    AggregateFunctionSequenceCount(const DataTypes& arguments, const String& pattern_)
703
            : AggregateFunctionSequenceBase<T, AggregateFunctionSequenceCount<T>>(arguments,
704
                                                                                  pattern_) {}
705
706
    using AggregateFunctionSequenceBase<
707
            T, AggregateFunctionSequenceCount<T>>::AggregateFunctionSequenceBase;
708
709
0
    String get_name() const override { return "sequence_count"; }
Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceCountILNS_13PrimitiveTypeE26EE8get_nameB5cxx11Ev
Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceCountILNS_13PrimitiveTypeE25EE8get_nameB5cxx11Ev
710
711
0
    DataTypePtr get_return_type() const override { return std::make_shared<DataTypeInt64>(); }
Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceCountILNS_13PrimitiveTypeE26EE15get_return_typeEv
Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceCountILNS_13PrimitiveTypeE25EE15get_return_typeEv
712
713
6
    void insert_result_into(ConstAggregateDataPtr __restrict place, IColumn& to) const override {
714
6
        auto& output = assert_cast<ColumnInt64&>(to).get_data();
715
6
        if (!this->data(place).conditions_in_pattern.any()) {
716
2
            output.push_back(0);
717
2
            return;
718
2
        }
719
720
4
        if ((this->data(place).conditions_in_pattern & this->data(place).conditions_met) !=
721
4
            this->data(place).conditions_in_pattern) {
722
0
            output.push_back(0);
723
0
            return;
724
0
        }
725
        // place is essentially an AggregateDataPtr, passed as a ConstAggregateDataPtr.
726
4
        this->data(const_cast<AggregateDataPtr>(place)).sort();
727
4
        output.push_back(count(place));
728
4
    }
_ZNK5doris30AggregateFunctionSequenceCountILNS_13PrimitiveTypeE26EE18insert_result_intoEPKcRNS_7IColumnE
Line
Count
Source
713
6
    void insert_result_into(ConstAggregateDataPtr __restrict place, IColumn& to) const override {
714
6
        auto& output = assert_cast<ColumnInt64&>(to).get_data();
715
6
        if (!this->data(place).conditions_in_pattern.any()) {
716
2
            output.push_back(0);
717
2
            return;
718
2
        }
719
720
4
        if ((this->data(place).conditions_in_pattern & this->data(place).conditions_met) !=
721
4
            this->data(place).conditions_in_pattern) {
722
0
            output.push_back(0);
723
0
            return;
724
0
        }
725
        // place is essentially an AggregateDataPtr, passed as a ConstAggregateDataPtr.
726
4
        this->data(const_cast<AggregateDataPtr>(place)).sort();
727
4
        output.push_back(count(place));
728
4
    }
Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceCountILNS_13PrimitiveTypeE25EE18insert_result_intoEPKcRNS_7IColumnE
729
730
private:
731
4
    UInt64 count(ConstAggregateDataPtr __restrict place) const {
732
4
        const auto& data_ref = this->data(place);
733
734
4
        const auto events_begin = std::begin(data_ref.events_list);
735
4
        const auto events_end = std::end(data_ref.events_list);
736
4
        auto events_it = events_begin;
737
738
4
        size_t count = 0;
739
        // check if there is a chance of matching the sequence at least once
740
4
        if (this->data(place).could_match_deterministic_parts(events_begin, events_end)) {
741
11
            while (events_it != events_end &&
742
11
                   this->data(place).backtracking_match(events_it, events_end))
743
7
                ++count;
744
4
        }
745
746
4
        return count;
747
4
    }
_ZNK5doris30AggregateFunctionSequenceCountILNS_13PrimitiveTypeE26EE5countEPKc
Line
Count
Source
731
4
    UInt64 count(ConstAggregateDataPtr __restrict place) const {
732
4
        const auto& data_ref = this->data(place);
733
734
4
        const auto events_begin = std::begin(data_ref.events_list);
735
4
        const auto events_end = std::end(data_ref.events_list);
736
4
        auto events_it = events_begin;
737
738
4
        size_t count = 0;
739
        // check if there is a chance of matching the sequence at least once
740
4
        if (this->data(place).could_match_deterministic_parts(events_begin, events_end)) {
741
11
            while (events_it != events_end &&
742
11
                   this->data(place).backtracking_match(events_it, events_end))
743
7
                ++count;
744
4
        }
745
746
4
        return count;
747
4
    }
Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceCountILNS_13PrimitiveTypeE25EE5countEPKc
748
};
749
750
} // namespace doris