Coverage Report

Created: 2026-06-11 20:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/doris/be/src/storage/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 "core/arena.h"
25
#include "core/value/map_value.h"
26
#include "runtime/collection_value.h"
27
#include "storage/key_coder.h"
28
#include "storage/olap_common.h"
29
#include "storage/olap_define.h"
30
#include "storage/tablet/tablet_schema.h"
31
#include "storage/types.h"
32
#include "storage/utils.h"
33
#include "util/hash_util.hpp"
34
#include "util/json/path_in_data.h"
35
#include "util/slice.h"
36
37
namespace doris {
38
#include "common/compile_check_begin.h"
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 StorageField {
42
public:
43
    StorageField(const TabletColumn& column)
44
32.8k
            : _type_info(get_type_info(&column)),
45
32.8k
              _desc(column),
46
32.8k
              _length(column.length()),
47
32.8k
              _key_coder(get_key_coder(column.type())),
48
32.8k
              _name(column.name()),
49
32.8k
              _index_size(column.index_length()),
50
32.8k
              _is_nullable(column.is_nullable()),
51
32.8k
              _unique_id(column.unique_id()),
52
32.8k
              _parent_unique_id(column.parent_unique_id()),
53
32.8k
              _is_extracted_column(column.is_extracted_column()),
54
32.8k
              _path(column.path_info_ptr()) {}
55
56
32.8k
    virtual ~StorageField() = default;
57
58
724k
    size_t size() const { return _type_info->size(); }
59
5
    size_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
12.0k
    int32_t unique_id() const { return _unique_id; }
63
9
    int32_t parent_unique_id() const { return _parent_unique_id; }
64
12.0k
    bool is_extracted_column() const { return _is_extracted_column; }
65
42.9k
    const std::string& name() const { return _name; }
66
0
    const PathInDataPtr& path() const { return _path; }
67
68
12
    virtual StorageField* clone() const {
69
12
        auto* local = new StorageField(_desc);
70
12
        this->clone(local);
71
12
        return local;
72
12
    }
73
74
1.01M
    FieldType type() const { return _type_info->type(); }
75
2.31k
    const TypeInfo* type_info() const { return _type_info.get(); }
76
66.8k
    bool is_nullable() const { return _is_nullable; }
77
78
    // similar to `full_encode_ascending`, but only encode part (the first `index_size` bytes) of the value.
79
    // only applicable to string type
80
6
    void encode_ascending(const void* value, std::string* buf) const {
81
6
        _key_coder->encode_ascending(value, _index_size, buf);
82
6
    }
83
84
    // encode the provided `value` into `buf`.
85
5
    void full_encode_ascending(const void* value, std::string* buf) const {
86
5
        _key_coder->full_encode_ascending(value, buf);
87
5
    }
88
89
322k
    const KeyCoder* key_coder() const { return _key_coder; }
90
707
    void add_sub_field(std::unique_ptr<StorageField> sub_field) {
91
707
        _sub_fields.emplace_back(std::move(sub_field));
92
707
    }
93
19
    StorageField* get_sub_field(size_t i) const { return _sub_fields[i].get(); }
94
2
    size_t get_sub_field_count() const { return _sub_fields.size(); }
95
96
34
    void set_precision(int32_t precision) { _precision = precision; }
97
34
    void set_scale(int32_t scale) { _scale = scale; }
98
0
    int32_t get_precision() const { return _precision; }
99
0
    int32_t get_scale() const { return _scale; }
100
75.3k
    const TabletColumn& get_desc() const { return _desc; }
101
102
7.08k
    int32_t get_unique_id() const {
103
7.08k
        return is_extracted_column() ? parent_unique_id() : unique_id();
104
7.08k
    }
105
106
protected:
107
    TypeInfoPtr _type_info;
108
    TabletColumn _desc;
109
    // unit : byte
110
    // except for strings, other types have fixed lengths
111
    // Note that, the struct type itself has fixed length, but due to
112
    // its number of subfields is a variable, so the actual length of
113
    // a struct field is not fixed.
114
    size_t _length;
115
116
12
    void clone(StorageField* other) const {
117
12
        other->_type_info = clone_type_info(this->_type_info.get());
118
12
        other->_key_coder = this->_key_coder;
119
12
        other->_name = this->_name;
120
12
        other->_index_size = this->_index_size;
121
12
        other->_is_nullable = this->_is_nullable;
122
12
        other->_sub_fields.clear();
123
12
        other->_precision = this->_precision;
124
12
        other->_scale = this->_scale;
125
12
        other->_unique_id = this->_unique_id;
126
12
        other->_parent_unique_id = this->_parent_unique_id;
127
12
        other->_is_extracted_column = this->_is_extracted_column;
128
12
        for (const auto& f : _sub_fields) {
129
0
            StorageField* item = f->clone();
130
0
            other->add_sub_field(std::unique_ptr<StorageField>(item));
131
0
        }
132
12
    }
133
134
private:
135
    // maximum length of Field, unit : bytes
136
    // usually equal to length, except for variable-length strings
137
    const KeyCoder* _key_coder;
138
    std::string _name;
139
    size_t _index_size;
140
    bool _is_nullable;
141
    std::vector<std::unique_ptr<StorageField>> _sub_fields;
142
    int32_t _precision;
143
    int32_t _scale;
144
    int32_t _unique_id;
145
    int32_t _parent_unique_id;
146
    bool _is_extracted_column = false;
147
    PathInDataPtr _path;
148
};
149
150
class MapField : public StorageField {
151
public:
152
333
    MapField(const TabletColumn& column) : StorageField(column) {}
153
};
154
155
class StructField : public StorageField {
156
public:
157
0
    StructField(const TabletColumn& column) : StorageField(column) {}
158
};
159
160
class ArrayField : public StorageField {
161
public:
162
41
    ArrayField(const TabletColumn& column) : StorageField(column) {}
163
};
164
165
class CharField : public StorageField {
166
public:
167
11
    CharField(const TabletColumn& column) : StorageField(column) {}
168
169
0
    CharField* clone() const override {
170
0
        auto* local = new CharField(_desc);
171
0
        StorageField::clone(local);
172
0
        return local;
173
0
    }
174
};
175
176
class VarcharField : public StorageField {
177
public:
178
58
    VarcharField(const TabletColumn& column) : StorageField(column) {}
179
180
0
    VarcharField* clone() const override {
181
0
        auto* local = new VarcharField(_desc);
182
0
        StorageField::clone(local);
183
0
        return local;
184
0
    }
185
};
186
class StringField : public StorageField {
187
public:
188
9.59k
    StringField(const TabletColumn& column) : StorageField(column) {}
189
190
0
    StringField* clone() const override {
191
0
        auto* local = new StringField(_desc);
192
0
        StorageField::clone(local);
193
0
        return local;
194
0
    }
195
};
196
197
class BitmapAggField : public StorageField {
198
public:
199
0
    BitmapAggField(const TabletColumn& column) : StorageField(column) {}
200
201
0
    BitmapAggField* clone() const override {
202
0
        auto* local = new BitmapAggField(_desc);
203
0
        StorageField::clone(local);
204
0
        return local;
205
0
    }
206
};
207
208
class QuantileStateAggField : public StorageField {
209
public:
210
0
    QuantileStateAggField(const TabletColumn& column) : StorageField(column) {}
211
212
0
    QuantileStateAggField* clone() const override {
213
0
        auto* local = new QuantileStateAggField(_desc);
214
0
        StorageField::clone(local);
215
0
        return local;
216
0
    }
217
};
218
219
class AggStateField : public StorageField {
220
public:
221
0
    AggStateField(const TabletColumn& column) : StorageField(column) {}
222
223
0
    AggStateField* clone() const override {
224
0
        auto* local = new AggStateField(_desc);
225
0
        StorageField::clone(local);
226
0
        return local;
227
0
    }
228
};
229
230
class HllAggField : public StorageField {
231
public:
232
0
    HllAggField(const TabletColumn& column) : StorageField(column) {}
233
234
0
    HllAggField* clone() const override {
235
0
        auto* local = new HllAggField(_desc);
236
0
        StorageField::clone(local);
237
0
        return local;
238
0
    }
239
};
240
241
class StorageFieldFactory {
242
public:
243
32.8k
    static StorageField* create(const TabletColumn& column) {
244
        // for key column
245
32.8k
        if (column.is_key()) {
246
5.93k
            switch (column.type()) {
247
10
            case FieldType::OLAP_FIELD_TYPE_CHAR:
248
10
                return new CharField(column);
249
142
            case FieldType::OLAP_FIELD_TYPE_VARCHAR:
250
430
            case FieldType::OLAP_FIELD_TYPE_STRING:
251
430
                return new StringField(column);
252
0
            case FieldType::OLAP_FIELD_TYPE_STRUCT: {
253
0
                auto* local = new StructField(column);
254
0
                for (uint32_t i = 0; i < column.get_subtype_count(); i++) {
255
0
                    std::unique_ptr<StorageField> sub_field(
256
0
                            StorageFieldFactory::create(column.get_sub_column(i)));
257
0
                    local->add_sub_field(std::move(sub_field));
258
0
                }
259
0
                return local;
260
142
            }
261
0
            case FieldType::OLAP_FIELD_TYPE_ARRAY: {
262
0
                std::unique_ptr<StorageField> item_field(
263
0
                        StorageFieldFactory::create(column.get_sub_column(0)));
264
0
                auto* local = new ArrayField(column);
265
0
                local->add_sub_field(std::move(item_field));
266
0
                return local;
267
142
            }
268
0
            case FieldType::OLAP_FIELD_TYPE_MAP: {
269
0
                std::unique_ptr<StorageField> key_field(
270
0
                        StorageFieldFactory::create(column.get_sub_column(0)));
271
0
                std::unique_ptr<StorageField> val_field(
272
0
                        StorageFieldFactory::create(column.get_sub_column(1)));
273
0
                auto* local = new MapField(column);
274
0
                local->add_sub_field(std::move(key_field));
275
0
                local->add_sub_field(std::move(val_field));
276
0
                return local;
277
142
            }
278
5
            case FieldType::OLAP_FIELD_TYPE_DECIMAL:
279
5
                [[fallthrough]];
280
9
            case FieldType::OLAP_FIELD_TYPE_DECIMAL32:
281
9
                [[fallthrough]];
282
11
            case FieldType::OLAP_FIELD_TYPE_DECIMAL64:
283
11
                [[fallthrough]];
284
14
            case FieldType::OLAP_FIELD_TYPE_DECIMAL128I:
285
14
                [[fallthrough]];
286
16
            case FieldType::OLAP_FIELD_TYPE_DECIMAL256:
287
16
                [[fallthrough]];
288
17
            case FieldType::OLAP_FIELD_TYPE_TIMESTAMPTZ:
289
17
                [[fallthrough]];
290
22
            case FieldType::OLAP_FIELD_TYPE_DATETIMEV2: {
291
22
                StorageField* field = new StorageField(column);
292
22
                field->set_precision(column.precision());
293
22
                field->set_scale(column.frac());
294
22
                return field;
295
17
            }
296
5.47k
            default:
297
5.47k
                return new StorageField(column);
298
5.93k
            }
299
5.93k
        }
300
301
        // for value column
302
26.9k
        switch (column.aggregation()) {
303
26.1k
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_NONE:
304
26.9k
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_SUM:
305
26.9k
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_MIN:
306
26.9k
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_MAX:
307
26.9k
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_REPLACE:
308
26.9k
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_REPLACE_IF_NOT_NULL:
309
26.9k
            switch (column.type()) {
310
1
            case FieldType::OLAP_FIELD_TYPE_CHAR:
311
1
                return new CharField(column);
312
58
            case FieldType::OLAP_FIELD_TYPE_VARCHAR:
313
58
                return new VarcharField(column);
314
9.16k
            case FieldType::OLAP_FIELD_TYPE_STRING:
315
9.16k
                return new StringField(column);
316
0
            case FieldType::OLAP_FIELD_TYPE_STRUCT: {
317
0
                auto* local = new StructField(column);
318
0
                for (uint32_t i = 0; i < column.get_subtype_count(); i++) {
319
0
                    std::unique_ptr<StorageField> sub_field(
320
0
                            StorageFieldFactory::create(column.get_sub_column(i)));
321
0
                    local->add_sub_field(std::move(sub_field));
322
0
                }
323
0
                return local;
324
0
            }
325
41
            case FieldType::OLAP_FIELD_TYPE_ARRAY: {
326
41
                std::unique_ptr<StorageField> item_field(
327
41
                        StorageFieldFactory::create(column.get_sub_column(0)));
328
41
                auto* local = new ArrayField(column);
329
41
                local->add_sub_field(std::move(item_field));
330
41
                return local;
331
0
            }
332
333
            case FieldType::OLAP_FIELD_TYPE_MAP: {
333
333
                DCHECK(column.get_subtype_count() == 2);
334
333
                auto* local = new MapField(column);
335
333
                std::unique_ptr<StorageField> key_field(
336
333
                        StorageFieldFactory::create(column.get_sub_column(0)));
337
333
                std::unique_ptr<StorageField> value_field(
338
333
                        StorageFieldFactory::create(column.get_sub_column(1)));
339
333
                local->add_sub_field(std::move(key_field));
340
333
                local->add_sub_field(std::move(value_field));
341
333
                return local;
342
0
            }
343
2
            case FieldType::OLAP_FIELD_TYPE_DECIMAL:
344
2
                [[fallthrough]];
345
3
            case FieldType::OLAP_FIELD_TYPE_DECIMAL32:
346
3
                [[fallthrough]];
347
4
            case FieldType::OLAP_FIELD_TYPE_DECIMAL64:
348
4
                [[fallthrough]];
349
5
            case FieldType::OLAP_FIELD_TYPE_DECIMAL128I:
350
5
                [[fallthrough]];
351
6
            case FieldType::OLAP_FIELD_TYPE_DECIMAL256:
352
6
                [[fallthrough]];
353
10
            case FieldType::OLAP_FIELD_TYPE_TIMESTAMPTZ:
354
10
                [[fallthrough]];
355
12
            case FieldType::OLAP_FIELD_TYPE_DATETIMEV2: {
356
12
                StorageField* field = new StorageField(column);
357
12
                field->set_precision(column.precision());
358
12
                field->set_scale(column.frac());
359
12
                return field;
360
10
            }
361
17.3k
            default:
362
17.3k
                return new StorageField(column);
363
26.9k
            }
364
0
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_HLL_UNION:
365
0
            return new HllAggField(column);
366
0
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_BITMAP_UNION:
367
0
            return new BitmapAggField(column);
368
0
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_QUANTILE_UNION:
369
0
            return new QuantileStateAggField(column);
370
0
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_GENERIC:
371
0
            return new AggStateField(column);
372
0
        case FieldAggregationMethod::OLAP_FIELD_AGGREGATION_UNKNOWN:
373
0
            CHECK(false) << ", value column no agg type";
374
0
            return nullptr;
375
26.9k
        }
376
0
        return nullptr;
377
26.9k
    }
378
379
2
    static StorageField* create_by_type(const FieldType& type) {
380
2
        TabletColumn column(FieldAggregationMethod::OLAP_FIELD_AGGREGATION_NONE, type);
381
2
        return create(column);
382
2
    }
383
};
384
#include "common/compile_check_end.h"
385
} // namespace doris