Coverage Report

Created: 2025-10-13 05:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
79.7M
            : _type_info(get_type_info(&column)),
46
79.7M
              _desc(column),
47
79.7M
              _length(column.length()),
48
79.7M
              _key_coder(get_key_coder(column.type())),
49
79.7M
              _name(column.name()),
50
79.7M
              _index_size(column.index_length()),
51
79.7M
              _is_nullable(column.is_nullable()),
52
79.7M
              _unique_id(column.unique_id()),
53
79.7M
              _parent_unique_id(column.parent_unique_id()),
54
79.7M
              _is_extracted_column(column.is_extracted_column()),
55
79.7M
              _path(column.path_info_ptr()) {}
56
57
80.5M
    virtual ~Field() = default;
58
59
76.8M
    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
55.6M
    int32_t unique_id() const { return _unique_id; }
64
60.9k
    int32_t parent_unique_id() const { return _parent_unique_id; }
65
48.0M
    bool is_extracted_column() const { return _is_extracted_column; }
66
85.6M
    const std::string& name() const { return _name; }
67
0
    const vectorized::PathInDataPtr& path() const { return _path; }
68
69
1.43M
    virtual void set_to_max(char* buf) const { return _type_info->set_to_max(buf); }
70
1.43M
    virtual void set_to_zone_map_max(char* buf) const { set_to_max(buf); }
71
72
1.72M
    virtual void set_to_min(char* buf) const { return _type_info->set_to_min(buf); }
73
1.72M
    virtual void set_to_zone_map_min(char* buf) const { set_to_min(buf); }
74
75
2.47M
    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
1.84M
    virtual char* allocate_value(vectorized::Arena& arena) const {
80
1.84M
        return arena.alloc(_type_info->size());
81
1.84M
    }
82
83
1.84M
    virtual char* allocate_zone_map_value(vectorized::Arena& arena) const {
84
1.84M
        return allocate_value(arena);
85
1.84M
    }
86
87
8.58M
    virtual size_t get_variable_len() const { return 0; }
88
89
973k
    virtual void modify_zone_map_index(char*) const {}
90
91
4.56M
    virtual Field* clone() const {
92
4.56M
        auto* local = new Field(_desc);
93
4.56M
        this->clone(local);
94
4.56M
        return local;
95
4.56M
    }
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
1.66M
    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
4.36M
    int compare_cell(const LhsCellType& lhs, const RhsCellType& rhs) const {
115
4.36M
        bool l_null = lhs.is_null();
116
4.36M
        bool r_null = rhs.is_null();
117
4.36M
        if (l_null != r_null) {
118
18.4E
            return l_null ? -1 : 1;
119
736k
        }
120
3.62M
        return l_null ? 0 : _type_info->cmp(lhs.cell_ptr(), rhs.cell_ptr());
121
4.36M
    }
Unexecuted instantiation: _ZNK5doris5Field12compare_cellINS_12WrapperFieldES2_EEiRKT_RKT0_
_ZNK5doris5Field12compare_cellINS_13RowCursorCellES2_EEiRKT_RKT0_
Line
Count
Source
114
4.36M
    int compare_cell(const LhsCellType& lhs, const RhsCellType& rhs) const {
115
4.36M
        bool l_null = lhs.is_null();
116
4.36M
        bool r_null = rhs.is_null();
117
4.36M
        if (l_null != r_null) {
118
18.4E
            return l_null ? -1 : 1;
119
736k
        }
120
3.62M
        return l_null ? 0 : _type_info->cmp(lhs.cell_ptr(), rhs.cell_ptr());
121
4.36M
    }
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
24.8M
                       const int scale = 0) const {
163
24.8M
        if (type() == FieldType::OLAP_FIELD_TYPE_STRING && !value_string.empty()) {
164
1.82M
            auto slice = reinterpret_cast<Slice*>(buf);
165
1.82M
            if (slice->size < value_string.size()) {
166
369
                *_long_text_buf = static_cast<char*>(realloc(*_long_text_buf, value_string.size()));
167
369
                slice->data = *_long_text_buf;
168
369
                slice->size = value_string.size();
169
369
            }
170
1.82M
        }
171
24.8M
        return _type_info->from_string(buf, value_string, precision, scale);
172
24.8M
    }
173
174
    //  convert inner value to string
175
    //  performance is not considered, only for debug use
176
1.92M
    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
108M
    FieldType type() const { return _type_info->type(); }
190
4.22M
    const TypeInfo* type_info() const { return _type_info.get(); }
191
61.4M
    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
1.11M
    void encode_ascending(const void* value, std::string* buf) const {
196
1.11M
        _key_coder->encode_ascending(value, _index_size, buf);
197
1.11M
    }
198
199
    // encode the provided `value` into `buf`.
200
11.5M
    void full_encode_ascending(const void* value, std::string* buf) const {
201
11.5M
        _key_coder->full_encode_ascending(value, buf);
202
11.5M
    }
203
447k
    void add_sub_field(std::unique_ptr<Field> sub_field) {
204
447k
        _sub_fields.emplace_back(std::move(sub_field));
205
447k
    }
206
137k
    Field* get_sub_field(size_t i) const { return _sub_fields[i].get(); }
207
43.9k
    size_t get_sub_field_count() const { return _sub_fields.size(); }
208
209
5.73M
    void set_precision(int32_t precision) { _precision = precision; }
210
5.73M
    void set_scale(int32_t scale) { _scale = scale; }
211
7.76M
    int32_t get_precision() const { return _precision; }
212
7.76M
    int32_t get_scale() const { return _scale; }
213
143M
    const TabletColumn& get_desc() const { return _desc; }
214
215
24.1M
    int32_t get_unique_id() const {
216
24.1M
        return is_extracted_column() ? parent_unique_id() : unique_id();
217
24.1M
    }
218
219
protected:
220
    TypeInfoPtr _type_info;
221
    TabletColumn _desc;
222
    // unit : byte
223
    // except for strings, other types have fixed lengths
224
    // Note that, the struct type itself has fixed length, but due to
225
    // its number of subfields is a variable, so the actual length of
226
    // a struct field is not fixed.
227
    size_t _length;
228
    // Since the length of the STRING type cannot be determined,
229
    // only dynamic memory can be used. Arena cannot realize realloc.
230
    // The schema information is shared globally. Therefore,
231
    // dynamic memory can only be managed in thread local mode.
232
    // The memory will be created and released in rowcursor.
233
    char** _long_text_buf = nullptr;
234
235
0
    char* allocate_string_value(vectorized::Arena& arena) const {
236
0
        char* type_value = arena.alloc(sizeof(Slice));
237
0
        auto slice = reinterpret_cast<Slice*>(type_value);
238
0
        slice->size = _length;
239
0
        slice->data = arena.alloc(slice->size);
240
0
        return type_value;
241
0
    }
242
243
14.6M
    void clone(Field* other) const {
244
14.6M
        other->_type_info = clone_type_info(this->_type_info.get());
245
14.6M
        other->_key_coder = this->_key_coder;
246
14.6M
        other->_name = this->_name;
247
14.6M
        other->_index_size = this->_index_size;
248
14.6M
        other->_is_nullable = this->_is_nullable;
249
14.6M
        other->_sub_fields.clear();
250
14.6M
        other->_precision = this->_precision;
251
14.6M
        other->_scale = this->_scale;
252
14.6M
        other->_unique_id = this->_unique_id;
253
14.6M
        other->_parent_unique_id = this->_parent_unique_id;
254
14.6M
        other->_is_extracted_column = this->_is_extracted_column;
255
14.6M
        for (const auto& f : _sub_fields) {
256
0
            Field* item = f->clone();
257
0
            other->add_sub_field(std::unique_ptr<Field>(item));
258
0
        }
259
14.6M
    }
260
261
private:
262
    // maximum length of Field, unit : bytes
263
    // usually equal to length, except for variable-length strings
264
    const KeyCoder* _key_coder;
265
    std::string _name;
266
    size_t _index_size;
267
    bool _is_nullable;
268
    std::vector<std::unique_ptr<Field>> _sub_fields;
269
    int32_t _precision;
270
    int32_t _scale;
271
    int32_t _unique_id;
272
    int32_t _parent_unique_id;
273
    bool _is_extracted_column = false;
274
    vectorized::PathInDataPtr _path;
275
};
276
277
class MapField : public Field {
278
public:
279
64.0k
    MapField(const TabletColumn& column) : Field(column) {}
280
281
0
    size_t get_variable_len() const override { return _length; }
282
};
283
284
class StructField : public Field {
285
public:
286
30.6k
    StructField(const TabletColumn& column) : Field(column) {}
287
288
0
    size_t get_variable_len() const override {
289
0
        size_t variable_len = _length;
290
0
        for (size_t i = 0; i < get_sub_field_count(); i++) {
291
0
            variable_len += get_sub_field(i)->get_variable_len();
292
0
        }
293
0
        return variable_len;
294
0
    }
295
};
296
297
class ArrayField : public Field {
298
public:
299
216k
    ArrayField(const TabletColumn& column) : Field(column) {}
300
301
0
    size_t get_variable_len() const override { return _length; }
302
};
303
304
class CharField : public Field {
305
public:
306
141k
    CharField(const TabletColumn& column) : Field(column) {}
307
308
1.14k
    size_t get_variable_len() const override { return _length; }
309
310
1.43k
    CharField* clone() const override {
311
1.43k
        auto* local = new CharField(_desc);
312
1.43k
        Field::clone(local);
313
1.43k
        return local;
314
1.43k
    }
315
316
0
    char* allocate_value(vectorized::Arena& arena) const override {
317
0
        return Field::allocate_string_value(arena);
318
0
    }
319
320
0
    void set_to_max(char* ch) const override {
321
0
        auto slice = reinterpret_cast<Slice*>(ch);
322
0
        slice->size = _length;
323
0
        memset(slice->data, 0xFF, slice->size);
324
0
    }
325
326
    // To prevent zone map cost too many memory, if varchar length
327
    // longer than `MAX_ZONE_MAP_INDEX_SIZE`. we just allocate
328
    // `MAX_ZONE_MAP_INDEX_SIZE` of memory
329
52.8k
    char* allocate_zone_map_value(vectorized::Arena& arena) const override {
330
52.8k
        char* type_value = arena.alloc(sizeof(Slice));
331
52.8k
        auto slice = reinterpret_cast<Slice*>(type_value);
332
52.8k
        slice->size = MAX_ZONE_MAP_INDEX_SIZE > _length ? _length : MAX_ZONE_MAP_INDEX_SIZE;
333
52.8k
        slice->data = arena.alloc(slice->size);
334
52.8k
        return type_value;
335
52.8k
    }
336
337
    // only varchar filed need modify zone map index when zone map max_value
338
    // index longer than `MAX_ZONE_MAP_INDEX_SIZE`. so here we add one
339
    // for the last byte
340
    // In UTF8 encoding, here do not appear 0xff in last byte
341
31.0k
    void modify_zone_map_index(char* src) const override {
342
31.0k
        auto slice = reinterpret_cast<Slice*>(src);
343
31.0k
        if (slice->size == MAX_ZONE_MAP_INDEX_SIZE) {
344
0
            slice->mutable_data()[slice->size - 1] += 1;
345
0
        }
346
31.0k
    }
347
348
44.2k
    void set_to_zone_map_max(char* ch) const override {
349
44.2k
        auto slice = reinterpret_cast<Slice*>(ch);
350
44.2k
        size_t length = _length < MAX_ZONE_MAP_INDEX_SIZE ? _length : MAX_ZONE_MAP_INDEX_SIZE;
351
44.2k
        slice->size = length;
352
44.2k
        memset(slice->data, 0xFF, slice->size);
353
44.2k
    }
354
};
355
356
class VarcharField : public Field {
357
public:
358
8.73M
    VarcharField(const TabletColumn& column) : Field(column) {}
359
360
1
    size_t get_variable_len() const override { return _length - OLAP_VARCHAR_MAX_BYTES; }
361
362
0
    VarcharField* clone() const override {
363
0
        auto* local = new VarcharField(_desc);
364
0
        Field::clone(local);
365
0
        return local;
366
0
    }
367
368
0
    char* allocate_value(vectorized::Arena& arena) const override {
369
0
        return Field::allocate_string_value(arena);
370
0
    }
371
372
    // To prevent zone map cost too many memory, if varchar length
373
    // longer than `MAX_ZONE_MAP_INDEX_SIZE`. we just allocate
374
    // `MAX_ZONE_MAP_INDEX_SIZE` of memory
375
320k
    char* allocate_zone_map_value(vectorized::Arena& arena) const override {
376
320k
        char* type_value = arena.alloc(sizeof(Slice));
377
320k
        auto slice = reinterpret_cast<Slice*>(type_value);
378
320k
        slice->size = MAX_ZONE_MAP_INDEX_SIZE > _length ? _length : MAX_ZONE_MAP_INDEX_SIZE;
379
320k
        slice->data = arena.alloc(slice->size);
380
320k
        return type_value;
381
320k
    }
382
383
    // only varchar/string filed need modify zone map index when zone map max_value
384
    // index longer than `MAX_ZONE_MAP_INDEX_SIZE`. so here we add one
385
    // for the last byte
386
    // In UTF8 encoding, here do not appear 0xff in last byte
387
170k
    void modify_zone_map_index(char* src) const override {
388
170k
        auto slice = reinterpret_cast<Slice*>(src);
389
170k
        if (slice->size == MAX_ZONE_MAP_INDEX_SIZE) {
390
86
            slice->mutable_data()[slice->size - 1] += 1;
391
86
        }
392
170k
    }
393
394
2
    void set_to_max(char* ch) const override {
395
2
        auto slice = reinterpret_cast<Slice*>(ch);
396
2
        slice->size = _length - OLAP_VARCHAR_MAX_BYTES;
397
2
        memset(slice->data, 0xFF, slice->size);
398
2
    }
399
250k
    void set_to_zone_map_max(char* ch) const override {
400
250k
        auto slice = reinterpret_cast<Slice*>(ch);
401
250k
        size_t length = _length < MAX_ZONE_MAP_INDEX_SIZE ? _length : MAX_ZONE_MAP_INDEX_SIZE;
402
403
250k
        slice->size = length - OLAP_VARCHAR_MAX_BYTES;
404
250k
        memset(slice->data, 0xFF, slice->size);
405
250k
    }
406
};
407
class StringField : public Field {
408
public:
409
32.2M
    StringField(const TabletColumn& column) : Field(column) {}
410
411
10.0M
    StringField* clone() const override {
412
10.0M
        auto* local = new StringField(_desc);
413
10.0M
        Field::clone(local);
414
10.0M
        return local;
415
10.0M
    }
416
417
0
    char* allocate_value(vectorized::Arena& arena) const override {
418
0
        return Field::allocate_string_value(arena);
419
0
    }
420
421
742k
    char* allocate_zone_map_value(vectorized::Arena& arena) const override {
422
742k
        char* type_value = arena.alloc(sizeof(Slice));
423
742k
        auto slice = reinterpret_cast<Slice*>(type_value);
424
742k
        slice->size = MAX_ZONE_MAP_INDEX_SIZE;
425
742k
        slice->data = arena.alloc(slice->size);
426
742k
        return type_value;
427
742k
    }
428
0
    void set_to_max(char* ch) const override {
429
0
        auto slice = reinterpret_cast<Slice*>(ch);
430
0
        memset(slice->data, 0xFF, slice->size);
431
0
    }
432
    // only varchar/string filed need modify zone map index when zone map max_value
433
    // index longer than `MAX_ZONE_MAP_INDEX_SIZE`. so here we add one
434
    // for the last byte
435
    // In UTF8 encoding, here do not appear 0xff in last byte
436
397k
    void modify_zone_map_index(char* src) const override {
437
397k
        auto slice = reinterpret_cast<Slice*>(src);
438
397k
        if (slice->size == MAX_ZONE_MAP_INDEX_SIZE) {
439
71.1k
            slice->mutable_data()[slice->size - 1] += 1;
440
71.1k
        }
441
397k
    }
442
443
582k
    void set_to_zone_map_max(char* ch) const override {
444
582k
        auto slice = reinterpret_cast<Slice*>(ch);
445
582k
        memset(slice->data, 0xFF, slice->size);
446
582k
    }
447
582k
    void set_to_zone_map_min(char* ch) const override {
448
582k
        auto slice = reinterpret_cast<Slice*>(ch);
449
582k
        memset(slice->data, 0x00, slice->size);
450
582k
    }
451
};
452
453
class BitmapAggField : public Field {
454
public:
455
13.7k
    BitmapAggField(const TabletColumn& column) : Field(column) {}
456
457
0
    BitmapAggField* clone() const override {
458
0
        auto* local = new BitmapAggField(_desc);
459
0
        Field::clone(local);
460
0
        return local;
461
0
    }
462
};
463
464
class QuantileStateAggField : public Field {
465
public:
466
5.66k
    QuantileStateAggField(const TabletColumn& column) : Field(column) {}
467
468
0
    QuantileStateAggField* clone() const override {
469
0
        auto* local = new QuantileStateAggField(_desc);
470
0
        Field::clone(local);
471
0
        return local;
472
0
    }
473
};
474
475
class AggStateField : public Field {
476
public:
477
4.02k
    AggStateField(const TabletColumn& column) : Field(column) {}
478
479
0
    AggStateField* clone() const override {
480
0
        auto* local = new AggStateField(_desc);
481
0
        Field::clone(local);
482
0
        return local;
483
0
    }
484
};
485
486
class HllAggField : public Field {
487
public:
488
7.95k
    HllAggField(const TabletColumn& column) : Field(column) {}
489
490
0
    HllAggField* clone() const override {
491
0
        auto* local = new HllAggField(_desc);
492
0
        Field::clone(local);
493
0
        return local;
494
0
    }
495
};
496
497
class FieldFactory {
498
public:
499
65.5M
    static Field* create(const TabletColumn& column) {
500
        // for key column
501
65.5M
        if (column.is_key()) {
502
22.9M
            switch (column.type()) {
503
22.4k
            case FieldType::OLAP_FIELD_TYPE_CHAR:
504
22.4k
                return new CharField(column);
505
17.7M
            case FieldType::OLAP_FIELD_TYPE_VARCHAR:
506
17.7M
            case FieldType::OLAP_FIELD_TYPE_STRING:
507
17.7M
                return new StringField(column);
508
0
            case FieldType::OLAP_FIELD_TYPE_STRUCT: {
509
0
                auto* local = new StructField(column);
510
0
                for (uint32_t i = 0; i < column.get_subtype_count(); i++) {
511
0
                    std::unique_ptr<Field> sub_field(
512
0
                            FieldFactory::create(column.get_sub_column(i)));
513
0
                    local->add_sub_field(std::move(sub_field));
514
0
                }
515
0
                return local;
516
17.7M
            }
517
0
            case FieldType::OLAP_FIELD_TYPE_ARRAY: {
518
0
                std::unique_ptr<Field> item_field(FieldFactory::create(column.get_sub_column(0)));
519
0
                auto* local = new ArrayField(column);
520
0
                local->add_sub_field(std::move(item_field));
521
0
                return local;
522
17.7M
            }
523
0
            case FieldType::OLAP_FIELD_TYPE_MAP: {
524
0
                std::unique_ptr<Field> key_field(FieldFactory::create(column.get_sub_column(0)));
525
0
                std::unique_ptr<Field> val_field(FieldFactory::create(column.get_sub_column(1)));
526
0
                auto* local = new MapField(column);
527
0
                local->add_sub_field(std::move(key_field));
528
0
                local->add_sub_field(std::move(val_field));
529
0
                return local;
530
17.7M
            }
531
20.0k
            case FieldType::OLAP_FIELD_TYPE_DECIMAL:
532
20.0k
                [[fallthrough]];
533
85.0k
            case FieldType::OLAP_FIELD_TYPE_DECIMAL32:
534
85.0k
                [[fallthrough]];
535
145k
            case FieldType::OLAP_FIELD_TYPE_DECIMAL64:
536
145k
                [[fallthrough]];
537
245k
            case FieldType::OLAP_FIELD_TYPE_DECIMAL128I:
538
245k
                [[fallthrough]];
539
308k
            case FieldType::OLAP_FIELD_TYPE_DECIMAL256:
540
308k
                [[fallthrough]];
541
369k
            case FieldType::OLAP_FIELD_TYPE_DATETIMEV2: {
542
369k
                Field* field = new Field(column);
543
369k
                field->set_precision(column.precision());
544
369k
                field->set_scale(column.frac());
545
369k
                return field;
546
308k
            }
547
4.77M
            default:
548
4.77M
                return new Field(column);
549
22.9M
            }
550
22.9M
        }
551
552
        // for value column
553
42.6M
        switch (column.aggregation()) {
554
42.0M
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_NONE:
555
42.1M
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_SUM:
556
42.1M
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_MIN:
557
42.2M
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_MAX:
558
42.3M
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_REPLACE:
559
42.4M
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_REPLACE_IF_NOT_NULL:
560
42.4M
            switch (column.type()) {
561
118k
            case FieldType::OLAP_FIELD_TYPE_CHAR:
562
118k
                return new CharField(column);
563
8.80M
            case FieldType::OLAP_FIELD_TYPE_VARCHAR:
564
8.80M
                return new VarcharField(column);
565
4.95M
            case FieldType::OLAP_FIELD_TYPE_STRING:
566
4.95M
                return new StringField(column);
567
30.8k
            case FieldType::OLAP_FIELD_TYPE_STRUCT: {
568
30.8k
                auto* local = new StructField(column);
569
131k
                for (uint32_t i = 0; i < column.get_subtype_count(); i++) {
570
100k
                    std::unique_ptr<Field> sub_field(
571
100k
                            FieldFactory::create(column.get_sub_column(i)));
572
100k
                    local->add_sub_field(std::move(sub_field));
573
100k
                }
574
30.8k
                return local;
575
0
            }
576
218k
            case FieldType::OLAP_FIELD_TYPE_ARRAY: {
577
218k
                std::unique_ptr<Field> item_field(FieldFactory::create(column.get_sub_column(0)));
578
218k
                auto* local = new ArrayField(column);
579
218k
                local->add_sub_field(std::move(item_field));
580
218k
                return local;
581
0
            }
582
64.6k
            case FieldType::OLAP_FIELD_TYPE_MAP: {
583
64.6k
                DCHECK(column.get_subtype_count() == 2);
584
64.6k
                auto* local = new MapField(column);
585
64.6k
                std::unique_ptr<Field> key_field(FieldFactory::create(column.get_sub_column(0)));
586
64.6k
                std::unique_ptr<Field> value_field(FieldFactory::create(column.get_sub_column(1)));
587
64.6k
                local->add_sub_field(std::move(key_field));
588
64.6k
                local->add_sub_field(std::move(value_field));
589
64.6k
                return local;
590
0
            }
591
3.03k
            case FieldType::OLAP_FIELD_TYPE_DECIMAL:
592
3.03k
                [[fallthrough]];
593
50.0k
            case FieldType::OLAP_FIELD_TYPE_DECIMAL32:
594
50.0k
                [[fallthrough]];
595
427k
            case FieldType::OLAP_FIELD_TYPE_DECIMAL64:
596
427k
                [[fallthrough]];
597
523k
            case FieldType::OLAP_FIELD_TYPE_DECIMAL128I:
598
523k
                [[fallthrough]];
599
533k
            case FieldType::OLAP_FIELD_TYPE_DECIMAL256:
600
533k
                [[fallthrough]];
601
5.36M
            case FieldType::OLAP_FIELD_TYPE_DATETIMEV2: {
602
5.36M
                Field* field = new Field(column);
603
5.36M
                field->set_precision(column.precision());
604
5.36M
                field->set_scale(column.frac());
605
5.36M
                return field;
606
533k
            }
607
22.9M
            default:
608
22.9M
                return new Field(column);
609
42.4M
            }
610
7.96k
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_HLL_UNION:
611
7.96k
            return new HllAggField(column);
612
13.8k
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_BITMAP_UNION:
613
13.8k
            return new BitmapAggField(column);
614
5.68k
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_QUANTILE_UNION:
615
5.68k
            return new QuantileStateAggField(column);
616
4.08k
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_GENERIC:
617
4.08k
            return new AggStateField(column);
618
0
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_UNKNOWN:
619
0
            CHECK(false) << ", value column no agg type";
620
0
            return nullptr;
621
42.6M
        }
622
0
        return nullptr;
623
42.6M
    }
624
625
17.9M
    static Field* create_by_type(const FieldType& type) {
626
17.9M
        TabletColumn column(FieldAggregationMethod::OLAP_FIELD_AGGREGATION_NONE, type);
627
17.9M
        return create(column);
628
17.9M
    }
629
};
630
#include "common/compile_check_end.h"
631
} // namespace doris