/root/doris/be/src/olap/field.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 | | #pragma once |
19 | | |
20 | | #include <cstddef> |
21 | | #include <sstream> |
22 | | #include <string> |
23 | | |
24 | | #include "olap/key_coder.h" |
25 | | #include "olap/olap_common.h" |
26 | | #include "olap/olap_define.h" |
27 | | #include "olap/row_cursor_cell.h" |
28 | | #include "olap/tablet_schema.h" |
29 | | #include "olap/types.h" |
30 | | #include "olap/utils.h" |
31 | | #include "runtime/collection_value.h" |
32 | | #include "runtime/map_value.h" |
33 | | #include "util/hash_util.hpp" |
34 | | #include "util/slice.h" |
35 | | #include "vec/common/arena.h" |
36 | | #include "vec/json/path_in_data.h" |
37 | | |
38 | | namespace doris { |
39 | | #include "common/compile_check_begin.h" |
40 | | // A Field is used to represent a column in memory format. |
41 | | // User can use this class to access or deal with column data in memory. |
42 | | class Field { |
43 | | public: |
44 | | Field(const TabletColumn& column) |
45 | 26.3k | : _type_info(get_type_info(&column)), |
46 | 26.3k | _desc(column), |
47 | 26.3k | _length(column.length()), |
48 | 26.3k | _key_coder(get_key_coder(column.type())), |
49 | 26.3k | _name(column.name()), |
50 | 26.3k | _index_size(column.index_length()), |
51 | 26.3k | _is_nullable(column.is_nullable()), |
52 | 26.3k | _unique_id(column.unique_id()), |
53 | 26.3k | _parent_unique_id(column.parent_unique_id()), |
54 | 26.3k | _is_extracted_column(column.is_extracted_column()), |
55 | 26.3k | _path(column.path_info_ptr()) {} |
56 | | |
57 | 26.3k | virtual ~Field() = default; |
58 | | |
59 | 484k | size_t size() const { return _type_info->size(); } |
60 | 0 | size_t length() const { return _length; } |
61 | 0 | size_t field_size() const { return size() + 1; } |
62 | 0 | size_t index_size() const { return _index_size; } |
63 | 122k | int32_t unique_id() const { return _unique_id; } |
64 | 117k | int32_t parent_unique_id() const { return _parent_unique_id; } |
65 | 4.92k | bool is_extracted_column() const { return _is_extracted_column; } |
66 | 51.7k | const std::string& name() const { return _name; } |
67 | 117k | const vectorized::PathInDataPtr& path() const { return _path; } |
68 | | |
69 | 31.9k | virtual void set_to_max(char* buf) const { return _type_info->set_to_max(buf); } |
70 | 31.9k | virtual void set_to_zone_map_max(char* buf) const { set_to_max(buf); } |
71 | | |
72 | 31.9k | virtual void set_to_min(char* buf) const { return _type_info->set_to_min(buf); } |
73 | 31.9k | virtual void set_to_zone_map_min(char* buf) const { set_to_min(buf); } |
74 | | |
75 | 4 | void set_long_text_buf(char** buf) { _long_text_buf = buf; } |
76 | | |
77 | | // This function allocate memory from arena, other than allocate_memory |
78 | | // reserve memory from continuous memory. |
79 | 41.7k | virtual char* allocate_value(vectorized::Arena& arena) const { |
80 | 41.7k | return arena.alloc(_type_info->size()); |
81 | 41.7k | } |
82 | | |
83 | 41.7k | virtual char* allocate_zone_map_value(vectorized::Arena& arena) const { |
84 | 41.7k | return allocate_value(arena); |
85 | 41.7k | } |
86 | | |
87 | 225 | virtual size_t get_variable_len() const { return 0; } |
88 | | |
89 | 21.4k | virtual void modify_zone_map_index(char*) const {} |
90 | | |
91 | 0 | virtual Field* clone() const { |
92 | 0 | auto* local = new Field(_desc); |
93 | 0 | this->clone(local); |
94 | 0 | return local; |
95 | 0 | } |
96 | | |
97 | | // Only compare column content, without considering nullptr condition. |
98 | | // RETURNS: |
99 | | // 0 means equal, |
100 | | // -1 means left less than right, |
101 | | // 1 means left bigger than right |
102 | 33.6k | int compare(const void* left, const void* right) const { return _type_info->cmp(left, right); } |
103 | | |
104 | | // Compare two types of cell. |
105 | | // This function differs compare in that this function compare cell which |
106 | | // will consider the condition which cell may be nullptr. While compare only |
107 | | // compare column content without considering nullptr condition. |
108 | | // Only compare column content, without considering nullptr condition. |
109 | | // RETURNS: |
110 | | // 0 means equal, |
111 | | // -1 means left less than right, |
112 | | // 1 means left bigger than right |
113 | | template <typename LhsCellType, typename RhsCellType> |
114 | 0 | int compare_cell(const LhsCellType& lhs, const RhsCellType& rhs) const { |
115 | 0 | bool l_null = lhs.is_null(); |
116 | 0 | bool r_null = rhs.is_null(); |
117 | 0 | if (l_null != r_null) { |
118 | 0 | return l_null ? -1 : 1; |
119 | 0 | } |
120 | 0 | return l_null ? 0 : _type_info->cmp(lhs.cell_ptr(), rhs.cell_ptr()); |
121 | 0 | } Unexecuted instantiation: _ZNK5doris5Field12compare_cellINS_12WrapperFieldES2_EEiRKT_RKT0_ Unexecuted instantiation: _ZNK5doris5Field12compare_cellINS_13RowCursorCellES2_EEiRKT_RKT0_ |
122 | | |
123 | | // Copy source cell's content to destination cell directly. |
124 | | // For string type, this function assume that destination has |
125 | | // enough space and copy source content into destination without |
126 | | // memory allocation. |
127 | | template <typename DstCellType, typename SrcCellType> |
128 | 0 | void direct_copy(DstCellType* dst, const SrcCellType& src) const { |
129 | 0 | bool is_null = src.is_null(); |
130 | 0 | dst->set_is_null(is_null); |
131 | 0 | if (is_null) { |
132 | 0 | return; |
133 | 0 | } |
134 | 0 | if (type() == FieldType::OLAP_FIELD_TYPE_STRING) { |
135 | 0 | auto dst_slice = reinterpret_cast<Slice*>(dst->mutable_cell_ptr()); |
136 | 0 | auto src_slice = reinterpret_cast<const Slice*>(src.cell_ptr()); |
137 | 0 | if (dst_slice->size < src_slice->size) { |
138 | 0 | *_long_text_buf = static_cast<char*>(realloc(*_long_text_buf, src_slice->size)); |
139 | 0 | dst_slice->data = *_long_text_buf; |
140 | 0 | dst_slice->size = src_slice->size; |
141 | 0 | } |
142 | 0 | } |
143 | 0 | return _type_info->direct_copy(dst->mutable_cell_ptr(), src.cell_ptr()); |
144 | 0 | } |
145 | | |
146 | | // deep copy source cell' content to destination cell. |
147 | | // For string type, this will allocate data form arena, |
148 | | // and copy source's content. |
149 | | template <typename DstCellType, typename SrcCellType> |
150 | | void deep_copy(DstCellType* dst, const SrcCellType& src, vectorized::Arena& arena) const { |
151 | | bool is_null = src.is_null(); |
152 | | dst->set_is_null(is_null); |
153 | | if (is_null) { |
154 | | return; |
155 | | } |
156 | | _type_info->deep_copy(dst->mutable_cell_ptr(), src.cell_ptr(), arena); |
157 | | } |
158 | | |
159 | | // used by init scan key stored in string format |
160 | | // value_string should end with '\0' |
161 | | Status from_string(char* buf, const std::string& value_string, const int precision = 0, |
162 | 69 | const int scale = 0) const { |
163 | 69 | if (type() == FieldType::OLAP_FIELD_TYPE_STRING && !value_string.empty()) { |
164 | 4 | auto slice = reinterpret_cast<Slice*>(buf); |
165 | 4 | if (slice->size < value_string.size()) { |
166 | 0 | *_long_text_buf = static_cast<char*>(realloc(*_long_text_buf, value_string.size())); |
167 | 0 | slice->data = *_long_text_buf; |
168 | 0 | slice->size = value_string.size(); |
169 | 0 | } |
170 | 4 | } |
171 | 69 | return _type_info->from_string(buf, value_string, precision, scale); |
172 | 69 | } |
173 | | |
174 | | // convert inner value to string |
175 | | // performance is not considered, only for debug use |
176 | 53.2k | std::string to_string(const char* src) const { return _type_info->to_string(src); } |
177 | | |
178 | | template <typename CellType> |
179 | | std::string debug_string(const CellType& cell) const { |
180 | | std::stringstream ss; |
181 | | if (cell.is_null()) { |
182 | | ss << "(null)"; |
183 | | } else { |
184 | | ss << _type_info->to_string(cell.cell_ptr()); |
185 | | } |
186 | | return ss.str(); |
187 | | } |
188 | | |
189 | 43.5k | FieldType type() const { return _type_info->type(); } |
190 | 84.0k | const TypeInfo* type_info() const { return _type_info.get(); } |
191 | 244k | bool is_nullable() const { return _is_nullable; } |
192 | | |
193 | | // similar to `full_encode_ascending`, but only encode part (the first `index_size` bytes) of the value. |
194 | | // only applicable to string type |
195 | 4 | void encode_ascending(const void* value, std::string* buf) const { |
196 | 4 | _key_coder->encode_ascending(value, _index_size, buf); |
197 | 4 | } |
198 | | |
199 | | // encode the provided `value` into `buf`. |
200 | 322k | void full_encode_ascending(const void* value, std::string* buf) const { |
201 | 322k | _key_coder->full_encode_ascending(value, buf); |
202 | 322k | } |
203 | 11 | void add_sub_field(std::unique_ptr<Field> sub_field) { |
204 | 11 | _sub_fields.emplace_back(std::move(sub_field)); |
205 | 11 | } |
206 | 13 | Field* get_sub_field(size_t i) const { return _sub_fields[i].get(); } |
207 | 1 | size_t get_sub_field_count() const { return _sub_fields.size(); } |
208 | | |
209 | 26 | void set_precision(int32_t precision) { _precision = precision; } |
210 | 26 | void set_scale(int32_t scale) { _scale = scale; } |
211 | 2 | int32_t get_precision() const { return _precision; } |
212 | 2 | int32_t get_scale() const { return _scale; } |
213 | 126k | const TabletColumn& get_desc() const { return _desc; } |
214 | | |
215 | | protected: |
216 | | TypeInfoPtr _type_info; |
217 | | TabletColumn _desc; |
218 | | // unit : byte |
219 | | // except for strings, other types have fixed lengths |
220 | | // Note that, the struct type itself has fixed length, but due to |
221 | | // its number of subfields is a variable, so the actual length of |
222 | | // a struct field is not fixed. |
223 | | size_t _length; |
224 | | // Since the length of the STRING type cannot be determined, |
225 | | // only dynamic memory can be used. Arena cannot realize realloc. |
226 | | // The schema information is shared globally. Therefore, |
227 | | // dynamic memory can only be managed in thread local mode. |
228 | | // The memory will be created and released in rowcursor. |
229 | | char** _long_text_buf = nullptr; |
230 | | |
231 | 0 | char* allocate_string_value(vectorized::Arena& arena) const { |
232 | 0 | char* type_value = arena.alloc(sizeof(Slice)); |
233 | 0 | auto slice = reinterpret_cast<Slice*>(type_value); |
234 | 0 | slice->size = _length; |
235 | 0 | slice->data = arena.alloc(slice->size); |
236 | 0 | return type_value; |
237 | 0 | } |
238 | | |
239 | 2 | void clone(Field* other) const { |
240 | 2 | other->_type_info = clone_type_info(this->_type_info.get()); |
241 | 2 | other->_key_coder = this->_key_coder; |
242 | 2 | other->_name = this->_name; |
243 | 2 | other->_index_size = this->_index_size; |
244 | 2 | other->_is_nullable = this->_is_nullable; |
245 | 2 | other->_sub_fields.clear(); |
246 | 2 | other->_precision = this->_precision; |
247 | 2 | other->_scale = this->_scale; |
248 | 2 | other->_unique_id = this->_unique_id; |
249 | 2 | other->_parent_unique_id = this->_parent_unique_id; |
250 | 2 | other->_is_extracted_column = this->_is_extracted_column; |
251 | 2 | for (const auto& f : _sub_fields) { |
252 | 0 | Field* item = f->clone(); |
253 | 0 | other->add_sub_field(std::unique_ptr<Field>(item)); |
254 | 0 | } |
255 | 2 | } |
256 | | |
257 | | private: |
258 | | // maximum length of Field, unit : bytes |
259 | | // usually equal to length, except for variable-length strings |
260 | | const KeyCoder* _key_coder; |
261 | | std::string _name; |
262 | | size_t _index_size; |
263 | | bool _is_nullable; |
264 | | std::vector<std::unique_ptr<Field>> _sub_fields; |
265 | | int32_t _precision; |
266 | | int32_t _scale; |
267 | | int32_t _unique_id; |
268 | | int32_t _parent_unique_id; |
269 | | bool _is_extracted_column = false; |
270 | | vectorized::PathInDataPtr _path; |
271 | | }; |
272 | | |
273 | | class MapField : public Field { |
274 | | public: |
275 | 0 | MapField(const TabletColumn& column) : Field(column) {} |
276 | | |
277 | 0 | size_t get_variable_len() const override { return _length; } |
278 | | }; |
279 | | |
280 | | class StructField : public Field { |
281 | | public: |
282 | 0 | StructField(const TabletColumn& column) : Field(column) {} |
283 | | |
284 | 0 | size_t get_variable_len() const override { |
285 | 0 | size_t variable_len = _length; |
286 | 0 | for (size_t i = 0; i < get_sub_field_count(); i++) { |
287 | 0 | variable_len += get_sub_field(i)->get_variable_len(); |
288 | 0 | } |
289 | 0 | return variable_len; |
290 | 0 | } |
291 | | }; |
292 | | |
293 | | class ArrayField : public Field { |
294 | | public: |
295 | 11 | ArrayField(const TabletColumn& column) : Field(column) {} |
296 | | |
297 | 0 | size_t get_variable_len() const override { return _length; } |
298 | | }; |
299 | | |
300 | | class CharField : public Field { |
301 | | public: |
302 | 7 | CharField(const TabletColumn& column) : Field(column) {} |
303 | | |
304 | 2 | size_t get_variable_len() const override { return _length; } |
305 | | |
306 | 1 | CharField* clone() const override { |
307 | 1 | auto* local = new CharField(_desc); |
308 | 1 | Field::clone(local); |
309 | 1 | return local; |
310 | 1 | } |
311 | | |
312 | 0 | char* allocate_value(vectorized::Arena& arena) const override { |
313 | 0 | return Field::allocate_string_value(arena); |
314 | 0 | } |
315 | | |
316 | 0 | void set_to_max(char* ch) const override { |
317 | 0 | auto slice = reinterpret_cast<Slice*>(ch); |
318 | 0 | slice->size = _length; |
319 | 0 | memset(slice->data, 0xFF, slice->size); |
320 | 0 | } |
321 | | |
322 | | // To prevent zone map cost too many memory, if varchar length |
323 | | // longer than `MAX_ZONE_MAP_INDEX_SIZE`. we just allocate |
324 | | // `MAX_ZONE_MAP_INDEX_SIZE` of memory |
325 | 8 | char* allocate_zone_map_value(vectorized::Arena& arena) const override { |
326 | 8 | char* type_value = arena.alloc(sizeof(Slice)); |
327 | 8 | auto slice = reinterpret_cast<Slice*>(type_value); |
328 | 8 | slice->size = MAX_ZONE_MAP_INDEX_SIZE > _length ? _length : MAX_ZONE_MAP_INDEX_SIZE; |
329 | 8 | slice->data = arena.alloc(slice->size); |
330 | 8 | return type_value; |
331 | 8 | } |
332 | | |
333 | | // only varchar filed need modify zone map index when zone map max_value |
334 | | // index longer than `MAX_ZONE_MAP_INDEX_SIZE`. so here we add one |
335 | | // for the last byte |
336 | | // In UTF8 encoding, here do not appear 0xff in last byte |
337 | 6 | void modify_zone_map_index(char* src) const override { |
338 | 6 | auto slice = reinterpret_cast<Slice*>(src); |
339 | 6 | if (slice->size == MAX_ZONE_MAP_INDEX_SIZE) { |
340 | 0 | slice->mutable_data()[slice->size - 1] += 1; |
341 | 0 | } |
342 | 6 | } |
343 | | |
344 | 8 | void set_to_zone_map_max(char* ch) const override { |
345 | 8 | auto slice = reinterpret_cast<Slice*>(ch); |
346 | 8 | size_t length = _length < MAX_ZONE_MAP_INDEX_SIZE ? _length : MAX_ZONE_MAP_INDEX_SIZE; |
347 | 8 | slice->size = length; |
348 | 8 | memset(slice->data, 0xFF, slice->size); |
349 | 8 | } |
350 | | }; |
351 | | |
352 | | class VarcharField : public Field { |
353 | | public: |
354 | 53 | VarcharField(const TabletColumn& column) : Field(column) {} |
355 | | |
356 | 1 | size_t get_variable_len() const override { return _length - OLAP_VARCHAR_MAX_BYTES; } |
357 | | |
358 | 0 | VarcharField* clone() const override { |
359 | 0 | auto* local = new VarcharField(_desc); |
360 | 0 | Field::clone(local); |
361 | 0 | return local; |
362 | 0 | } |
363 | | |
364 | 0 | char* allocate_value(vectorized::Arena& arena) const override { |
365 | 0 | return Field::allocate_string_value(arena); |
366 | 0 | } |
367 | | |
368 | | // To prevent zone map cost too many memory, if varchar length |
369 | | // longer than `MAX_ZONE_MAP_INDEX_SIZE`. we just allocate |
370 | | // `MAX_ZONE_MAP_INDEX_SIZE` of memory |
371 | 0 | char* allocate_zone_map_value(vectorized::Arena& arena) const override { |
372 | 0 | char* type_value = arena.alloc(sizeof(Slice)); |
373 | 0 | auto slice = reinterpret_cast<Slice*>(type_value); |
374 | 0 | slice->size = MAX_ZONE_MAP_INDEX_SIZE > _length ? _length : MAX_ZONE_MAP_INDEX_SIZE; |
375 | 0 | slice->data = arena.alloc(slice->size); |
376 | 0 | return type_value; |
377 | 0 | } |
378 | | |
379 | | // only varchar/string filed need modify zone map index when zone map max_value |
380 | | // index longer than `MAX_ZONE_MAP_INDEX_SIZE`. so here we add one |
381 | | // for the last byte |
382 | | // In UTF8 encoding, here do not appear 0xff in last byte |
383 | 0 | void modify_zone_map_index(char* src) const override { |
384 | 0 | auto slice = reinterpret_cast<Slice*>(src); |
385 | 0 | if (slice->size == MAX_ZONE_MAP_INDEX_SIZE) { |
386 | 0 | slice->mutable_data()[slice->size - 1] += 1; |
387 | 0 | } |
388 | 0 | } |
389 | | |
390 | 2 | void set_to_max(char* ch) const override { |
391 | 2 | auto slice = reinterpret_cast<Slice*>(ch); |
392 | 2 | slice->size = _length - OLAP_VARCHAR_MAX_BYTES; |
393 | 2 | memset(slice->data, 0xFF, slice->size); |
394 | 2 | } |
395 | 0 | void set_to_zone_map_max(char* ch) const override { |
396 | 0 | auto slice = reinterpret_cast<Slice*>(ch); |
397 | 0 | size_t length = _length < MAX_ZONE_MAP_INDEX_SIZE ? _length : MAX_ZONE_MAP_INDEX_SIZE; |
398 | |
|
399 | 0 | slice->size = length - OLAP_VARCHAR_MAX_BYTES; |
400 | 0 | memset(slice->data, 0xFF, slice->size); |
401 | 0 | } |
402 | | }; |
403 | | class StringField : public Field { |
404 | | public: |
405 | 5.13k | StringField(const TabletColumn& column) : Field(column) {} |
406 | | |
407 | 1 | StringField* clone() const override { |
408 | 1 | auto* local = new StringField(_desc); |
409 | 1 | Field::clone(local); |
410 | 1 | return local; |
411 | 1 | } |
412 | | |
413 | 0 | char* allocate_value(vectorized::Arena& arena) const override { |
414 | 0 | return Field::allocate_string_value(arena); |
415 | 0 | } |
416 | | |
417 | 9.41k | char* allocate_zone_map_value(vectorized::Arena& arena) const override { |
418 | 9.41k | char* type_value = arena.alloc(sizeof(Slice)); |
419 | 9.41k | auto slice = reinterpret_cast<Slice*>(type_value); |
420 | 9.41k | slice->size = MAX_ZONE_MAP_INDEX_SIZE; |
421 | 9.41k | slice->data = arena.alloc(slice->size); |
422 | 9.41k | return type_value; |
423 | 9.41k | } |
424 | 0 | void set_to_max(char* ch) const override { |
425 | 0 | auto slice = reinterpret_cast<Slice*>(ch); |
426 | 0 | memset(slice->data, 0xFF, slice->size); |
427 | 0 | } |
428 | | // only varchar/string filed need modify zone map index when zone map max_value |
429 | | // index longer than `MAX_ZONE_MAP_INDEX_SIZE`. so here we add one |
430 | | // for the last byte |
431 | | // In UTF8 encoding, here do not appear 0xff in last byte |
432 | 8.17k | void modify_zone_map_index(char* src) const override { |
433 | 8.17k | auto slice = reinterpret_cast<Slice*>(src); |
434 | 8.17k | if (slice->size == MAX_ZONE_MAP_INDEX_SIZE) { |
435 | 6.80k | slice->mutable_data()[slice->size - 1] += 1; |
436 | 6.80k | } |
437 | 8.17k | } |
438 | | |
439 | 10.5k | void set_to_zone_map_max(char* ch) const override { |
440 | 10.5k | auto slice = reinterpret_cast<Slice*>(ch); |
441 | 10.5k | memset(slice->data, 0xFF, slice->size); |
442 | 10.5k | } |
443 | 10.5k | void set_to_zone_map_min(char* ch) const override { |
444 | 10.5k | auto slice = reinterpret_cast<Slice*>(ch); |
445 | 10.5k | memset(slice->data, 0x00, slice->size); |
446 | 10.5k | } |
447 | | }; |
448 | | |
449 | | class BitmapAggField : public Field { |
450 | | public: |
451 | 0 | BitmapAggField(const TabletColumn& column) : Field(column) {} |
452 | | |
453 | 0 | BitmapAggField* clone() const override { |
454 | 0 | auto* local = new BitmapAggField(_desc); |
455 | 0 | Field::clone(local); |
456 | 0 | return local; |
457 | 0 | } |
458 | | }; |
459 | | |
460 | | class QuantileStateAggField : public Field { |
461 | | public: |
462 | 0 | QuantileStateAggField(const TabletColumn& column) : Field(column) {} |
463 | | |
464 | 0 | QuantileStateAggField* clone() const override { |
465 | 0 | auto* local = new QuantileStateAggField(_desc); |
466 | 0 | Field::clone(local); |
467 | 0 | return local; |
468 | 0 | } |
469 | | }; |
470 | | |
471 | | class AggStateField : public Field { |
472 | | public: |
473 | 0 | AggStateField(const TabletColumn& column) : Field(column) {} |
474 | | |
475 | 0 | AggStateField* clone() const override { |
476 | 0 | auto* local = new AggStateField(_desc); |
477 | 0 | Field::clone(local); |
478 | 0 | return local; |
479 | 0 | } |
480 | | }; |
481 | | |
482 | | class HllAggField : public Field { |
483 | | public: |
484 | 1 | HllAggField(const TabletColumn& column) : Field(column) {} |
485 | | |
486 | 0 | HllAggField* clone() const override { |
487 | 0 | auto* local = new HllAggField(_desc); |
488 | 0 | Field::clone(local); |
489 | 0 | return local; |
490 | 0 | } |
491 | | }; |
492 | | |
493 | | class FieldFactory { |
494 | | public: |
495 | 26.3k | static Field* create(const TabletColumn& column) { |
496 | | // for key column |
497 | 26.3k | if (column.is_key()) { |
498 | 6.80k | switch (column.type()) { |
499 | 4 | case FieldType::OLAP_FIELD_TYPE_CHAR: |
500 | 4 | return new CharField(column); |
501 | 137 | case FieldType::OLAP_FIELD_TYPE_VARCHAR: |
502 | 353 | case FieldType::OLAP_FIELD_TYPE_STRING: |
503 | 353 | return new StringField(column); |
504 | 0 | case FieldType::OLAP_FIELD_TYPE_STRUCT: { |
505 | 0 | auto* local = new StructField(column); |
506 | 0 | for (uint32_t i = 0; i < column.get_subtype_count(); i++) { |
507 | 0 | std::unique_ptr<Field> sub_field( |
508 | 0 | FieldFactory::create(column.get_sub_column(i))); |
509 | 0 | local->add_sub_field(std::move(sub_field)); |
510 | 0 | } |
511 | 0 | return local; |
512 | 137 | } |
513 | 0 | case FieldType::OLAP_FIELD_TYPE_ARRAY: { |
514 | 0 | std::unique_ptr<Field> item_field(FieldFactory::create(column.get_sub_column(0))); |
515 | 0 | auto* local = new ArrayField(column); |
516 | 0 | local->add_sub_field(std::move(item_field)); |
517 | 0 | return local; |
518 | 137 | } |
519 | 0 | case FieldType::OLAP_FIELD_TYPE_MAP: { |
520 | 0 | std::unique_ptr<Field> key_field(FieldFactory::create(column.get_sub_column(0))); |
521 | 0 | std::unique_ptr<Field> val_field(FieldFactory::create(column.get_sub_column(1))); |
522 | 0 | auto* local = new MapField(column); |
523 | 0 | local->add_sub_field(std::move(key_field)); |
524 | 0 | local->add_sub_field(std::move(val_field)); |
525 | 0 | return local; |
526 | 137 | } |
527 | 3 | case FieldType::OLAP_FIELD_TYPE_DECIMAL: |
528 | 3 | [[fallthrough]]; |
529 | 3 | case FieldType::OLAP_FIELD_TYPE_DECIMAL32: |
530 | 3 | [[fallthrough]]; |
531 | 3 | case FieldType::OLAP_FIELD_TYPE_DECIMAL64: |
532 | 3 | [[fallthrough]]; |
533 | 3 | case FieldType::OLAP_FIELD_TYPE_DECIMAL128I: |
534 | 3 | [[fallthrough]]; |
535 | 3 | case FieldType::OLAP_FIELD_TYPE_DECIMAL256: |
536 | 3 | [[fallthrough]]; |
537 | 3 | case FieldType::OLAP_FIELD_TYPE_DATETIMEV2: { |
538 | 3 | Field* field = new Field(column); |
539 | 3 | field->set_precision(column.precision()); |
540 | 3 | field->set_scale(column.frac()); |
541 | 3 | return field; |
542 | 3 | } |
543 | 6.44k | default: |
544 | 6.44k | return new Field(column); |
545 | 6.80k | } |
546 | 6.80k | } |
547 | | |
548 | | // for value column |
549 | 19.5k | switch (column.aggregation()) { |
550 | 18.4k | case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_NONE: |
551 | 19.5k | case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_SUM: |
552 | 19.5k | case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_MIN: |
553 | 19.5k | case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_MAX: |
554 | 19.5k | case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_REPLACE: |
555 | 19.5k | case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_REPLACE_IF_NOT_NULL: |
556 | 19.5k | switch (column.type()) { |
557 | 2 | case FieldType::OLAP_FIELD_TYPE_CHAR: |
558 | 2 | return new CharField(column); |
559 | 53 | case FieldType::OLAP_FIELD_TYPE_VARCHAR: |
560 | 53 | return new VarcharField(column); |
561 | 4.78k | case FieldType::OLAP_FIELD_TYPE_STRING: |
562 | 4.78k | return new StringField(column); |
563 | 0 | case FieldType::OLAP_FIELD_TYPE_STRUCT: { |
564 | 0 | auto* local = new StructField(column); |
565 | 0 | for (uint32_t i = 0; i < column.get_subtype_count(); i++) { |
566 | 0 | std::unique_ptr<Field> sub_field( |
567 | 0 | FieldFactory::create(column.get_sub_column(i))); |
568 | 0 | local->add_sub_field(std::move(sub_field)); |
569 | 0 | } |
570 | 0 | return local; |
571 | 0 | } |
572 | 11 | case FieldType::OLAP_FIELD_TYPE_ARRAY: { |
573 | 11 | std::unique_ptr<Field> item_field(FieldFactory::create(column.get_sub_column(0))); |
574 | 11 | auto* local = new ArrayField(column); |
575 | 11 | local->add_sub_field(std::move(item_field)); |
576 | 11 | return local; |
577 | 0 | } |
578 | 0 | case FieldType::OLAP_FIELD_TYPE_MAP: { |
579 | 0 | DCHECK(column.get_subtype_count() == 2); |
580 | 0 | auto* local = new MapField(column); |
581 | 0 | std::unique_ptr<Field> key_field(FieldFactory::create(column.get_sub_column(0))); |
582 | 0 | std::unique_ptr<Field> value_field(FieldFactory::create(column.get_sub_column(1))); |
583 | 0 | local->add_sub_field(std::move(key_field)); |
584 | 0 | local->add_sub_field(std::move(value_field)); |
585 | 0 | return local; |
586 | 0 | } |
587 | 7 | case FieldType::OLAP_FIELD_TYPE_DECIMAL: |
588 | 7 | [[fallthrough]]; |
589 | 10 | case FieldType::OLAP_FIELD_TYPE_DECIMAL32: |
590 | 10 | [[fallthrough]]; |
591 | 13 | case FieldType::OLAP_FIELD_TYPE_DECIMAL64: |
592 | 13 | [[fallthrough]]; |
593 | 19 | case FieldType::OLAP_FIELD_TYPE_DECIMAL128I: |
594 | 19 | [[fallthrough]]; |
595 | 19 | case FieldType::OLAP_FIELD_TYPE_DECIMAL256: |
596 | 19 | [[fallthrough]]; |
597 | 23 | case FieldType::OLAP_FIELD_TYPE_DATETIMEV2: { |
598 | 23 | Field* field = new Field(column); |
599 | 23 | field->set_precision(column.precision()); |
600 | 23 | field->set_scale(column.frac()); |
601 | 23 | return field; |
602 | 19 | } |
603 | 14.6k | default: |
604 | 14.6k | return new Field(column); |
605 | 19.5k | } |
606 | 1 | case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_HLL_UNION: |
607 | 1 | return new HllAggField(column); |
608 | 0 | case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_BITMAP_UNION: |
609 | 0 | return new BitmapAggField(column); |
610 | 0 | case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_QUANTILE_UNION: |
611 | 0 | return new QuantileStateAggField(column); |
612 | 0 | case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_GENERIC: |
613 | 0 | return new AggStateField(column); |
614 | 0 | case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_UNKNOWN: |
615 | 0 | CHECK(false) << ", value column no agg type"; |
616 | 0 | return nullptr; |
617 | 19.5k | } |
618 | 0 | return nullptr; |
619 | 19.5k | } |
620 | | |
621 | 85 | static Field* create_by_type(const FieldType& type) { |
622 | 85 | TabletColumn column(FieldAggregationMethod::OLAP_FIELD_AGGREGATION_NONE, type); |
623 | 85 | return create(column); |
624 | 85 | } |
625 | | }; |
626 | | #include "common/compile_check_end.h" |
627 | | } // namespace doris |