Coverage Report

Created: 2026-03-15 08:11

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