Coverage Report

Created: 2026-10-10 01:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/storage/storage_layout.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 <bit>
21
#include <cmath>
22
#include <cstdint>
23
#include <limits>
24
#include <type_traits>
25
26
#include "common/cast_set.h"
27
#include "core/data_type/primitive_type.h"
28
#include "core/data_type/storage_field_type.h"
29
#include "core/decimal12.h"
30
#include "core/uint24.h"
31
#include "core/value/decimalv2_value.h"
32
#include "core/value/vdatetime_value.h"
33
#include "storage/field_type.h"
34
#include "storage/types.h"
35
36
namespace doris {
37
38
// How a compute-layer value becomes what a segment stores for FieldType FT: its own
39
// bytes, except for the V1 DATE, DATETIME and DECIMAL layouts and NaN, stored as the
40
// quiet NaN. The two types are PrimitiveTypeTraits<PT>::CppType and
41
// CppTypeTraits<FT>::CppType; the aliases inside are private shorthand. Declared only,
42
// so a FieldType without a specialisation is a compile error, not a silent byte copy.
43
template <FieldType FT>
44
struct StorageLayout;
45
46
namespace storage_layout_detail {
47
48
// A StorageValue is the PrimitiveValue's own bytes.
49
template <FieldType FT>
50
struct BitCast {
51
private:
52
    using StorageValue = typename CppTypeTraits<FT>::CppType;
53
    using PrimitiveValue =
54
            typename PrimitiveTypeTraits<storage_field_type_to_primitive_type(FT)>::CppType;
55
    static_assert(sizeof(StorageValue) == sizeof(PrimitiveValue));
56
57
public:
58
372k
    static StorageValue to_storage(const PrimitiveValue& value) {
59
372k
        return std::bit_cast<StorageValue>(value);
60
372k
    }
_ZN5doris21storage_layout_detail7BitCastILNS_9FieldTypeE7EE10to_storageERKl
Line
Count
Source
58
51
    static StorageValue to_storage(const PrimitiveValue& value) {
59
51
        return std::bit_cast<StorageValue>(value);
60
51
    }
_ZN5doris21storage_layout_detail7BitCastILNS_9FieldTypeE24EE10to_storageERKh
Line
Count
Source
58
23
    static StorageValue to_storage(const PrimitiveValue& value) {
59
23
        return std::bit_cast<StorageValue>(value);
60
23
    }
_ZN5doris21storage_layout_detail7BitCastILNS_9FieldTypeE31EE10to_storageERKNS_7DecimalIiEE
Line
Count
Source
58
39
    static StorageValue to_storage(const PrimitiveValue& value) {
59
39
        return std::bit_cast<StorageValue>(value);
60
39
    }
_ZN5doris21storage_layout_detail7BitCastILNS_9FieldTypeE32EE10to_storageERKNS_7DecimalIlEE
Line
Count
Source
58
34
    static StorageValue to_storage(const PrimitiveValue& value) {
59
34
        return std::bit_cast<StorageValue>(value);
60
34
    }
_ZN5doris21storage_layout_detail7BitCastILNS_9FieldTypeE33EE10to_storageERKNS_12Decimal128V3E
Line
Count
Source
58
29
    static StorageValue to_storage(const PrimitiveValue& value) {
59
29
        return std::bit_cast<StorageValue>(value);
60
29
    }
_ZN5doris21storage_layout_detail7BitCastILNS_9FieldTypeE37EE10to_storageERKNS_7DecimalIN4wide7integerILm256EiEEEE
Line
Count
Source
58
29
    static StorageValue to_storage(const PrimitiveValue& value) {
59
29
        return std::bit_cast<StorageValue>(value);
60
29
    }
_ZN5doris21storage_layout_detail7BitCastILNS_9FieldTypeE28EE10to_storageERKNS_11DateV2ValueINS_15DateV2ValueTypeEEE
Line
Count
Source
58
28
    static StorageValue to_storage(const PrimitiveValue& value) {
59
28
        return std::bit_cast<StorageValue>(value);
60
28
    }
_ZN5doris21storage_layout_detail7BitCastILNS_9FieldTypeE29EE10to_storageERKNS_11DateV2ValueINS_19DateTimeV2ValueTypeEEE
Line
Count
Source
58
37
    static StorageValue to_storage(const PrimitiveValue& value) {
59
37
        return std::bit_cast<StorageValue>(value);
60
37
    }
_ZN5doris21storage_layout_detail7BitCastILNS_9FieldTypeE40EE10to_storageERKNS_16TimestampTzValueE
Line
Count
Source
58
52
    static StorageValue to_storage(const PrimitiveValue& value) {
59
52
        return std::bit_cast<StorageValue>(value);
60
52
    }
_ZN5doris21storage_layout_detail7BitCastILNS_9FieldTypeE1EE10to_storageERKa
Line
Count
Source
58
23
    static StorageValue to_storage(const PrimitiveValue& value) {
59
23
        return std::bit_cast<StorageValue>(value);
60
23
    }
_ZN5doris21storage_layout_detail7BitCastILNS_9FieldTypeE3EE10to_storageERKs
Line
Count
Source
58
23
    static StorageValue to_storage(const PrimitiveValue& value) {
59
23
        return std::bit_cast<StorageValue>(value);
60
23
    }
_ZN5doris21storage_layout_detail7BitCastILNS_9FieldTypeE5EE10to_storageERKi
Line
Count
Source
58
372k
    static StorageValue to_storage(const PrimitiveValue& value) {
59
372k
        return std::bit_cast<StorageValue>(value);
60
372k
    }
_ZN5doris21storage_layout_detail7BitCastILNS_9FieldTypeE9EE10to_storageERKn
Line
Count
Source
58
23
    static StorageValue to_storage(const PrimitiveValue& value) {
59
23
        return std::bit_cast<StorageValue>(value);
60
23
    }
_ZN5doris21storage_layout_detail7BitCastILNS_9FieldTypeE38EE10to_storageERKj
Line
Count
Source
58
20
    static StorageValue to_storage(const PrimitiveValue& value) {
59
20
        return std::bit_cast<StorageValue>(value);
60
20
    }
_ZN5doris21storage_layout_detail7BitCastILNS_9FieldTypeE39EE10to_storageERKo
Line
Count
Source
58
20
    static StorageValue to_storage(const PrimitiveValue& value) {
59
20
        return std::bit_cast<StorageValue>(value);
60
20
    }
_ZN5doris21storage_layout_detail7BitCastILNS_9FieldTypeE42EE10to_storageERKo
Line
Count
Source
58
21
    static StorageValue to_storage(const PrimitiveValue& value) {
59
21
        return std::bit_cast<StorageValue>(value);
60
21
    }
_ZN5doris21storage_layout_detail7BitCastILNS_9FieldTypeE41EE10to_storageERKNS_16TimeStampNsValueE
Line
Count
Source
58
27
    static StorageValue to_storage(const PrimitiveValue& value) {
59
27
        return std::bit_cast<StorageValue>(value);
60
27
    }
61
};
62
63
// Every NaN is stored as the quiet NaN, so equal values have equal stored bytes
64
// and the bloom filter / dictionary / key encodings that hash or compare bytes
65
// treat all NaNs as one value.
66
template <FieldType FT>
67
struct FloatingPoint {
68
private:
69
    using StorageValue = typename CppTypeTraits<FT>::CppType;
70
    using PrimitiveValue =
71
            typename PrimitiveTypeTraits<storage_field_type_to_primitive_type(FT)>::CppType;
72
    static_assert(std::is_floating_point_v<StorageValue>);
73
    static_assert(std::is_same_v<StorageValue, PrimitiveValue>);
74
75
public:
76
97.1k
    static StorageValue canonicalize_nan(StorageValue value) {
77
97.1k
        return std::isnan(value) ? std::numeric_limits<StorageValue>::quiet_NaN() : value;
78
97.1k
    }
_ZN5doris21storage_layout_detail13FloatingPointILNS_9FieldTypeE10EE16canonicalize_nanEf
Line
Count
Source
76
48.5k
    static StorageValue canonicalize_nan(StorageValue value) {
77
48.5k
        return std::isnan(value) ? std::numeric_limits<StorageValue>::quiet_NaN() : value;
78
48.5k
    }
_ZN5doris21storage_layout_detail13FloatingPointILNS_9FieldTypeE11EE16canonicalize_nanEd
Line
Count
Source
76
48.5k
    static StorageValue canonicalize_nan(StorageValue value) {
77
48.5k
        return std::isnan(value) ? std::numeric_limits<StorageValue>::quiet_NaN() : value;
78
48.5k
    }
79
64
    static StorageValue to_storage(PrimitiveValue value) { return canonicalize_nan(value); }
_ZN5doris21storage_layout_detail13FloatingPointILNS_9FieldTypeE10EE10to_storageEf
Line
Count
Source
79
33
    static StorageValue to_storage(PrimitiveValue value) { return canonicalize_nan(value); }
_ZN5doris21storage_layout_detail13FloatingPointILNS_9FieldTypeE11EE10to_storageEd
Line
Count
Source
79
31
    static StorageValue to_storage(PrimitiveValue value) { return canonicalize_nan(value); }
80
};
81
82
} // namespace storage_layout_detail
83
84
#define DORIS_STORAGE_LAYOUT_BIT_CAST(FT) \
85
    template <>                           \
86
    struct StorageLayout<FieldType::FT> : storage_layout_detail::BitCast<FieldType::FT> {};
87
88
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_BOOL)
89
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_TINYINT)
90
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_SMALLINT)
91
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_INT)
92
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_BIGINT)
93
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_LARGEINT)
94
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_UNSIGNED_INT)
95
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_UNSIGNED_BIGINT)
96
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_DECIMAL32)
97
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_DECIMAL64)
98
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_DECIMAL128I)
99
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_DECIMAL256)
100
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_DATEV2)
101
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_DATETIMEV2)
102
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_TIMESTAMP_NS)
103
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_TIMESTAMPTZ)
104
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_IPV4)
105
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_IPV6)
106
DORIS_STORAGE_LAYOUT_BIT_CAST(OLAP_FIELD_TYPE_UUID)
107
#undef DORIS_STORAGE_LAYOUT_BIT_CAST
108
109
template <>
110
struct StorageLayout<FieldType::OLAP_FIELD_TYPE_FLOAT>
111
        : storage_layout_detail::FloatingPoint<FieldType::OLAP_FIELD_TYPE_FLOAT> {};
112
113
template <>
114
struct StorageLayout<FieldType::OLAP_FIELD_TYPE_DOUBLE>
115
        : storage_layout_detail::FloatingPoint<FieldType::OLAP_FIELD_TYPE_DOUBLE> {};
116
117
// V1 DATE: three bytes of (year << 9) | (month << 5) | day.
118
template <>
119
struct StorageLayout<FieldType::OLAP_FIELD_TYPE_DATE> {
120
private:
121
    using StorageValue = typename CppTypeTraits<FieldType::OLAP_FIELD_TYPE_DATE>::CppType;
122
    using PrimitiveValue = typename PrimitiveTypeTraits<TYPE_DATE>::CppType;
123
    static_assert(std::is_same_v<StorageValue, uint24_t>);
124
125
public:
126
35
    static StorageValue to_storage(const PrimitiveValue& value) {
127
35
        return StorageValue(cast_set<uint32_t>(value.to_olap_date()));
128
35
    }
129
};
130
131
// V1 DATETIME: the decimal digits YYYYMMDDhhmmss packed into one integer.
132
template <>
133
struct StorageLayout<FieldType::OLAP_FIELD_TYPE_DATETIME> {
134
private:
135
    using StorageValue = typename CppTypeTraits<FieldType::OLAP_FIELD_TYPE_DATETIME>::CppType;
136
    using PrimitiveValue = typename PrimitiveTypeTraits<TYPE_DATETIME>::CppType;
137
    static_assert(std::is_same_v<StorageValue, int64_t>);
138
139
public:
140
36
    static StorageValue to_storage(const PrimitiveValue& value) {
141
36
        return static_cast<StorageValue>(value.to_olap_datetime());
142
36
    }
143
};
144
145
// V1 DECIMAL: the integer and the nine-digit fraction stored side by side.
146
template <>
147
struct StorageLayout<FieldType::OLAP_FIELD_TYPE_DECIMAL> {
148
private:
149
    using StorageValue = typename CppTypeTraits<FieldType::OLAP_FIELD_TYPE_DECIMAL>::CppType;
150
    using PrimitiveValue = typename PrimitiveTypeTraits<TYPE_DECIMALV2>::CppType;
151
    static_assert(std::is_same_v<StorageValue, decimal12_t>);
152
153
public:
154
27
    static StorageValue to_storage(const PrimitiveValue& value) {
155
27
        return {value.int_value(), value.frac_value()};
156
27
    }
157
};
158
159
} // namespace doris