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