forked from apache/doris
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcreate_predicate_function.h
More file actions
229 lines (207 loc) · 8.56 KB
/
Copy pathcreate_predicate_function.h
File metadata and controls
229 lines (207 loc) · 8.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include "common/exception.h"
#include "common/status.h"
#include "core/data_type/define_primitive_type.h"
#include "exprs/function_filter.h"
#include "exprs/hybrid_set.h"
#include "exprs/minmax_predicate.h"
#include "storage/predicate/bloom_filter_predicate.h"
#include "storage/predicate/column_predicate.h"
#include "storage/predicate/in_list_predicate.h"
#include "storage/predicate/like_column_predicate.h"
namespace doris {
class MinmaxFunctionTraits {
public:
using BasePtr = MinMaxFuncBase*;
template <PrimitiveType type, size_t N>
static BasePtr get_function(bool null_aware) {
using CppType = typename PrimitiveTypeTraits<type>::CppType;
return new MinMaxNumFunc<
std::conditional_t<std::is_same_v<CppType, StringRef>, std::string, CppType>>(
null_aware);
}
};
class HybridSetTraits {
public:
using BasePtr = HybridSetBase*;
template <PrimitiveType type, size_t N>
static BasePtr get_function(bool null_aware) {
if constexpr (is_string_type(type)) {
return new StringSet<>(null_aware);
} else if constexpr (type == TYPE_TINYINT || type == TYPE_SMALLINT) {
using CppType = typename PrimitiveTypeTraits<type>::CppType;
return new HybridSet<type, BitSetContainer<CppType>>(null_aware);
} else if constexpr (N >= 1 && N <= FIXED_CONTAINER_MAX_SIZE) {
using CppType = typename PrimitiveTypeTraits<type>::CppType;
return new HybridSet<type, FixedContainer<CppType, N>>(null_aware);
} else {
using CppType = typename PrimitiveTypeTraits<type>::CppType;
return new HybridSet<type, DynamicContainer<CppType>>(null_aware);
}
}
};
class BloomFilterTraits {
public:
using BasePtr = BloomFilterFuncBase*;
template <PrimitiveType type, size_t N>
static BasePtr get_function(bool null_aware) {
return new BloomFilterFunc<type>(null_aware);
}
};
template <class Traits>
class PredicateFunctionCreator {
public:
template <PrimitiveType type, size_t N = 0>
static typename Traits::BasePtr create(bool null_aware) {
return Traits::template get_function<type, N>(null_aware);
}
};
#define APPLY_FOR_PRIMTYPE(M) \
M(TYPE_TINYINT) \
M(TYPE_SMALLINT) \
M(TYPE_INT) \
M(TYPE_BIGINT) \
M(TYPE_LARGEINT) \
M(TYPE_FLOAT) \
M(TYPE_DOUBLE) \
M(TYPE_DATE) \
M(TYPE_DATETIME) \
M(TYPE_DATEV2) \
M(TYPE_DATETIMEV2) \
M(TYPE_TIMESTAMPTZ) \
M(TYPE_CHAR) \
M(TYPE_VARCHAR) \
M(TYPE_STRING) \
M(TYPE_DECIMAL32) \
M(TYPE_DECIMAL64) \
M(TYPE_DECIMAL128I) \
M(TYPE_DECIMAL256) \
M(TYPE_IPV4) \
M(TYPE_IPV6)
template <class Traits, size_t N = 0>
typename Traits::BasePtr create_predicate_function(PrimitiveType type, bool null_aware) {
using Creator = PredicateFunctionCreator<Traits>;
switch (type) {
case TYPE_BOOLEAN: {
return Creator::template create<TYPE_BOOLEAN, N>(null_aware);
}
case TYPE_DECIMALV2: {
return Creator::template create<TYPE_DECIMALV2, N>(null_aware);
}
#define M(NAME) \
case NAME: { \
return Creator::template create<NAME, N>(null_aware); \
}
APPLY_FOR_PRIMTYPE(M)
#undef M
default:
throw Exception(ErrorCode::INTERNAL_ERROR, "predicate with type " + type_to_string(type));
}
return nullptr;
}
inline auto create_minmax_filter(PrimitiveType type, bool null_aware) {
return create_predicate_function<MinmaxFunctionTraits>(type, null_aware);
}
template <size_t N = 0>
inline auto create_set(PrimitiveType type, bool null_aware) {
return create_predicate_function<HybridSetTraits, N>(type, null_aware);
}
inline auto create_set(PrimitiveType type, size_t size, bool null_aware) {
if (size == 0) {
return create_set<0>(type, null_aware);
} else if (size == 1) {
return create_set<1>(type, null_aware);
} else if (size == 2) {
return create_set<2>(type, null_aware);
} else if (size == 3) {
return create_set<3>(type, null_aware);
} else if (size == 4) {
return create_set<4>(type, null_aware);
} else if (size == 5) {
return create_set<5>(type, null_aware);
} else if (size == 6) {
return create_set<6>(type, null_aware);
} else if (size == 7) {
return create_set<7>(type, null_aware);
} else if (size == FIXED_CONTAINER_MAX_SIZE) {
return create_set<FIXED_CONTAINER_MAX_SIZE>(type, null_aware);
} else {
return create_set(type, null_aware);
}
}
inline HybridSetBase* create_string_value_set(bool null_aware) {
return new StringValueSet(null_aware);
}
inline HybridSetBase* create_string_value_set(size_t size, bool null_aware) {
return create_string_value_set(null_aware);
}
inline auto create_bloom_filter(PrimitiveType type, bool null_aware) {
return create_predicate_function<BloomFilterTraits>(type, null_aware);
}
template <PrimitiveType PT>
std::shared_ptr<const ColumnPredicate> create_olap_column_predicate(
uint32_t column_id, const std::shared_ptr<BloomFilterFuncBase>& filter, const TabletColumn*,
bool null_aware) {
std::shared_ptr<BloomFilterFuncBase> filter_olap;
filter_olap.reset(create_bloom_filter(PT, null_aware));
filter_olap->light_copy(filter.get());
// create a new filter to match the input filter and PT. For example, filter may be varchar, but PT is char
return BloomFilterColumnPredicate<PT>::create_shared(column_id, filter_olap);
}
template <PrimitiveType PT>
std::shared_ptr<const ColumnPredicate> create_olap_column_predicate(
uint32_t column_id, const std::shared_ptr<HybridSetBase>& filter,
const TabletColumn* column, bool) {
return create_in_list_predicate<PT, PredicateType::IN_LIST>(column_id, filter,
column->length());
}
template <PrimitiveType PT>
std::shared_ptr<ColumnPredicate> create_olap_column_predicate(
uint32_t column_id, const std::shared_ptr<FunctionFilter>& filter,
const TabletColumn* column, bool) {
// currently only support like predicate
if constexpr (PT == TYPE_CHAR || PT == TYPE_VARCHAR || PT == TYPE_STRING) {
return LikeColumnPredicate::create_shared(filter->_opposite, column_id, column->name(),
filter->_fn_ctx, filter->_string_param);
}
throw Exception(ErrorCode::INTERNAL_ERROR, "function filter do not support type {}", PT);
}
template <typename T>
std::shared_ptr<ColumnPredicate> create_column_predicate(uint32_t column_id,
const std::shared_ptr<T>& filter,
FieldType type, const TabletColumn* column,
bool null_aware = false) {
switch (type) {
#define M(NAME) \
case FieldType::OLAP_FIELD_##NAME: { \
return create_olap_column_predicate<NAME>(column_id, filter, column, null_aware); \
}
APPLY_FOR_PRIMTYPE(M)
#undef M
case FieldType::OLAP_FIELD_TYPE_DECIMAL: {
return create_olap_column_predicate<TYPE_DECIMALV2>(column_id, filter, column, null_aware);
}
case FieldType::OLAP_FIELD_TYPE_BOOL: {
return create_olap_column_predicate<TYPE_BOOLEAN>(column_id, filter, column, null_aware);
}
default:
return nullptr;
}
}
} // namespace doris