Coverage Report

Created: 2026-01-15 17:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/doris/be/src/runtime/decimalv2_value.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 <glog/logging.h>
21
#include <stdint.h>
22
23
// IWYU pragma: no_include <bits/std_abs.h>
24
#include <cmath> // IWYU pragma: keep
25
#include <cstdint>
26
#include <cstdlib>
27
#include <iostream>
28
#include <string>
29
#include <string_view>
30
31
#include "runtime/define_primitive_type.h"
32
#include "util/hash_util.hpp"
33
#include "vec/core/extended_types.h"
34
35
namespace doris {
36
#include "common/compile_check_begin.h"
37
38
typedef __int128_t int128_t;
39
40
enum DecimalError {
41
    E_DEC_OK = 0,
42
    E_DEC_TRUNCATED = 1,
43
    E_DEC_OVERFLOW = 2,
44
    E_DEC_DIV_ZERO = 4,
45
    E_DEC_BAD_NUM = 8,
46
    E_DEC_OOM = 16,
47
48
    E_DEC_ERROR = 31,
49
    E_DEC_FATAL_ERROR = 30
50
};
51
52
enum DecimalRoundMode { HALF_UP = 1, HALF_EVEN = 2, CEILING = 3, FLOOR = 4, TRUNCATE = 5 };
53
54
class DecimalV2Value {
55
public:
56
    static constexpr PrimitiveType PType = TYPE_DECIMALV2;
57
    using NativeType = __int128_t;
58
    friend DecimalV2Value operator+(const DecimalV2Value& v1, const DecimalV2Value& v2);
59
    friend DecimalV2Value operator-(const DecimalV2Value& v1, const DecimalV2Value& v2);
60
    friend DecimalV2Value operator*(const DecimalV2Value& v1, const DecimalV2Value& v2);
61
    friend DecimalV2Value operator/(const DecimalV2Value& v1, const DecimalV2Value& v2);
62
    friend std::istream& operator>>(std::istream& ism, DecimalV2Value& decimal_value);
63
    friend DecimalV2Value operator-(const DecimalV2Value& v);
64
65
    static constexpr int32_t PRECISION = 27;
66
    static constexpr int32_t SCALE = 9;
67
    static constexpr int32_t SCALE_TRIM_ARRAY[SCALE + 1] = {
68
            1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1};
69
    static constexpr uint32_t ONE_BILLION = 1000000000;
70
    static constexpr int64_t MAX_INT_VALUE = 999999999999999999;
71
    static constexpr int32_t MAX_FRAC_VALUE = 999999999;
72
    static constexpr int64_t MAX_INT64 = 9223372036854775807ll;
73
    // In sqrt, the integer part and the decimal part of the square root to be solved separately are
74
    // multiplied by the PRECISION/2 power of 10, so that they can be placed in an int128_t variable
75
    static const int128_t SQRT_MOLECULAR_MAGNIFICATION;
76
    // sqrt(ONE_BILLION) * pow(10, PRECISION/2 - SCALE), it is used to calculate SCALE of the sqrt result
77
    static const int128_t SQRT_DENOMINATOR;
78
79
    static const int128_t MAX_DECIMAL_VALUE =
80
            static_cast<int128_t>(MAX_INT64) * ONE_BILLION + MAX_FRAC_VALUE;
81
0
    static constexpr int max_string_length() { return PRECISION + 1; }
82
83
    DecimalV2Value() = default;
84
429k
    const int128_t& value() const { return _value; }
85
10.4k
    int128_t& value() { return _value; }
86
87
63
    DecimalV2Value(const std::string& decimal_str) {
88
63
        parse_from_str(decimal_str.c_str(), decimal_str.size());
89
63
    }
90
91
0
    DecimalV2Value(const std::string_view& decimal_str) {
92
0
        parse_from_str(decimal_str.data(), decimal_str.size());
93
0
    }
94
    // Construct from olap engine
95
38
    DecimalV2Value(int64_t int_value, int64_t frac_value) {
96
38
        from_olap_decimal(int_value, frac_value);
97
38
    }
98
99
38
    bool from_olap_decimal(int64_t int_value, int64_t frac_value) {
100
38
        bool success = true;
101
38
        bool is_negative = (int_value < 0 || frac_value < 0);
102
38
        if (is_negative) {
103
12
            int_value = std::abs(int_value);
104
12
            frac_value = std::abs(frac_value);
105
12
        }
106
107
        //if (int_value > MAX_INT_VALUE) {
108
        //    int_value = MAX_INT_VALUE;
109
        //    success = false;
110
        //}
111
112
38
        if (frac_value > MAX_FRAC_VALUE) {
113
1
            frac_value = MAX_FRAC_VALUE;
114
1
            success = false;
115
1
        }
116
117
38
        _value = static_cast<int128_t>(int_value) * ONE_BILLION + frac_value;
118
38
        if (is_negative) _value = -_value;
119
120
38
        return success;
121
38
    }
122
123
33.9k
    explicit DecimalV2Value(int128_t int_value) { _value = int_value; }
124
125
50
    void set_value(int128_t value) { _value = value; }
126
127
1
    DecimalV2Value& assign_from_float(const float float_value) {
128
1
        _value = static_cast<int128_t>(float_value * ONE_BILLION);
129
1
        return *this;
130
1
    }
131
132
57
    DecimalV2Value& assign_from_double(const double double_value) {
133
57
        _value = static_cast<int128_t>(double_value * ONE_BILLION);
134
57
        return *this;
135
57
    }
136
137
    // These cast functions are needed in "functions.cc", which is generated by python script.
138
    // e.g. "ComputeFunctions::Cast_DecimalV2Value_double()"
139
    // Discard the scale part
140
    // ATTN: invoker must make sure no OVERFLOW
141
17.7k
    operator int64_t() const { return static_cast<int64_t>(_value / ONE_BILLION); }
142
143
    // These cast functions are needed in "functions.cc", which is generated by python script.
144
    // e.g. "ComputeFunctions::Cast_DecimalV2Value_double()"
145
    // Discard the scale part
146
    // ATTN: invoker must make sure no OVERFLOW
147
0
    operator int128_t() const { return static_cast<int128_t>(_value / ONE_BILLION); }
148
149
0
    operator wide::Int256() const {
150
0
        wide::Int256 result;
151
0
        wide::Int256::_impl::wide_integer_from_builtin(result, _value);
152
0
        return result;
153
0
    }
154
155
0
    operator bool() const { return _value != 0; }
156
157
0
    operator int8_t() const { return static_cast<char>(operator int64_t()); }
158
159
0
    operator int16_t() const { return static_cast<int16_t>(operator int64_t()); }
160
161
0
    operator int32_t() const { return static_cast<int32_t>(operator int64_t()); }
162
163
0
    operator size_t() const { return static_cast<size_t>(operator int64_t()); }
164
165
0
    operator float() const { return (float)operator double(); }
166
167
0
    operator double() const {
168
0
        std::string str_buff = to_string();
169
0
        double result = std::strtod(str_buff.c_str(), nullptr);
170
0
        return result;
171
0
    }
172
173
    DecimalV2Value& operator+=(const DecimalV2Value& other);
174
175
    // To be Compatible with OLAP
176
    // ATTN: NO-OVERFLOW should be guaranteed.
177
17.7k
    int64_t int_value() const { return operator int64_t(); }
178
179
    // To be Compatible with OLAP
180
    // NOTE: return a negative value if decimal is negative.
181
    // ATTN: the max length of fraction part in OLAP is 9, so the 'big digits' except the first one
182
    // will be truncated.
183
17.7k
    int32_t frac_value() const { return static_cast<int32_t>(_value % ONE_BILLION); }
184
185
38.2k
    bool operator==(const DecimalV2Value& other) const { return _value == other.value(); }
186
187
387k
    auto operator<=>(const DecimalV2Value& other) const { return _value <=> other.value(); }
188
189
    // change to maximum value for given precision and scale
190
    // precision/scale - see decimal_bin_size() below
191
    // to              - decimal where where the result will be stored
192
    void to_max_decimal(int precision, int frac);
193
0
    void to_min_decimal(int precision, int frac) {
194
0
        to_max_decimal(precision, frac);
195
0
        if (_value > 0) _value = -_value;
196
0
    }
197
198
    // The maximum of fraction part is "scale".
199
    // If the length of fraction part is less than "scale", '0' will be filled.
200
    std::string to_string(int scale) const;
201
202
    int32_t to_buffer(char* buffer, int scale) const;
203
204
    // Output actual "scale", remove ending zeroes.
205
    std::string to_string() const;
206
207
    // Convert string to decimal
208
    // @param from - value to convert. Doesn't have to be \0 terminated!
209
    //               will stop at the fist non-digit char(nor '.' 'e' 'E'),
210
    //               or reaches the length
211
    // @param length - maximum length
212
    // @return error number.
213
    //
214
    // E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_BAD_NUM/E_DEC_OOM
215
    // In case of E_DEC_FATAL_ERROR *to is set to decimal zero
216
    // (to make error handling easier)
217
    //
218
    // e.g. "1.2"  ".2"  "1.2e-3"  "1.2e3"
219
    int parse_from_str(const char* decimal_str, size_t length);
220
221
0
    std::string get_debug_info() const { return to_string(); }
222
223
6
    static DecimalV2Value get_min_decimal() {
224
6
        return DecimalV2Value(-MAX_INT_VALUE, MAX_FRAC_VALUE);
225
6
    }
226
227
6
    static DecimalV2Value get_max_decimal() {
228
6
        return DecimalV2Value(MAX_INT_VALUE, MAX_FRAC_VALUE);
229
6
    }
230
231
0
    static DecimalV2Value get_min_decimal(int precision, int scale) {
232
0
        DCHECK(precision > 0 && precision <= 27 && scale >= 0 && scale <= 9 && precision >= scale &&
233
0
               (precision - scale <= 18));
234
0
        return DecimalV2Value(
235
0
                -MAX_INT_VALUE % static_cast<int64_t>(get_scale_base(18 - precision + scale)),
236
0
                MAX_FRAC_VALUE / static_cast<int64_t>(get_scale_base(9 - scale)) *
237
0
                        static_cast<int64_t>(get_scale_base(9 - scale)));
238
0
    }
239
240
0
    static DecimalV2Value get_max_decimal(int precision, int scale) {
241
0
        DCHECK(precision > 0 && precision <= 27 && scale >= 0 && scale <= 9 && precision >= scale &&
242
0
               (precision - scale <= 18));
243
0
        return DecimalV2Value(
244
0
                MAX_INT_VALUE % static_cast<int64_t>(get_scale_base(18 - precision + scale)),
245
0
                MAX_FRAC_VALUE / static_cast<int64_t>(get_scale_base(9 - scale)) *
246
0
                        static_cast<int64_t>(get_scale_base(9 - scale)));
247
0
    }
248
249
    // Solve Square root for int128
250
    static DecimalV2Value sqrt(const DecimalV2Value& v);
251
252
    // set DecimalV2Value to zero
253
0
    void set_to_zero() { _value = 0; }
254
255
0
    void to_abs_value() {
256
0
        if (_value < 0) _value = -_value;
257
0
    }
258
259
150
    uint32_t hash(uint32_t seed) const { return HashUtil::hash(&_value, sizeof(_value), seed); }
260
261
1
    int32_t precision() const { return PRECISION; }
262
263
2
    int32_t scale() const { return SCALE; }
264
265
    bool greater_than_scale(int scale);
266
267
    int round(DecimalV2Value* to, int scale, DecimalRoundMode mode);
268
269
52
    inline static int128_t get_scale_base(int scale) {
270
52
        static const int128_t values[] = {
271
52
                static_cast<int128_t>(1ll),
272
52
                static_cast<int128_t>(10ll),
273
52
                static_cast<int128_t>(100ll),
274
52
                static_cast<int128_t>(1000ll),
275
52
                static_cast<int128_t>(10000ll),
276
52
                static_cast<int128_t>(100000ll),
277
52
                static_cast<int128_t>(1000000ll),
278
52
                static_cast<int128_t>(10000000ll),
279
52
                static_cast<int128_t>(100000000ll),
280
52
                static_cast<int128_t>(1000000000ll),
281
52
                static_cast<int128_t>(10000000000ll),
282
52
                static_cast<int128_t>(100000000000ll),
283
52
                static_cast<int128_t>(1000000000000ll),
284
52
                static_cast<int128_t>(10000000000000ll),
285
52
                static_cast<int128_t>(100000000000000ll),
286
52
                static_cast<int128_t>(1000000000000000ll),
287
52
                static_cast<int128_t>(10000000000000000ll),
288
52
                static_cast<int128_t>(100000000000000000ll),
289
52
                static_cast<int128_t>(1000000000000000000ll),
290
52
                static_cast<int128_t>(1000000000000000000ll) * 10ll,
291
52
                static_cast<int128_t>(1000000000000000000ll) * 100ll,
292
52
                static_cast<int128_t>(1000000000000000000ll) * 1000ll,
293
52
                static_cast<int128_t>(1000000000000000000ll) * 10000ll,
294
52
                static_cast<int128_t>(1000000000000000000ll) * 100000ll,
295
52
                static_cast<int128_t>(1000000000000000000ll) * 1000000ll,
296
52
                static_cast<int128_t>(1000000000000000000ll) * 10000000ll,
297
52
                static_cast<int128_t>(1000000000000000000ll) * 100000000ll,
298
52
                static_cast<int128_t>(1000000000000000000ll) * 1000000000ll,
299
52
                static_cast<int128_t>(1000000000000000000ll) * 10000000000ll,
300
52
                static_cast<int128_t>(1000000000000000000ll) * 100000000000ll,
301
52
                static_cast<int128_t>(1000000000000000000ll) * 1000000000000ll,
302
52
                static_cast<int128_t>(1000000000000000000ll) * 10000000000000ll,
303
52
                static_cast<int128_t>(1000000000000000000ll) * 100000000000000ll,
304
52
                static_cast<int128_t>(1000000000000000000ll) * 1000000000000000ll,
305
52
                static_cast<int128_t>(1000000000000000000ll) * 10000000000000000ll,
306
52
                static_cast<int128_t>(1000000000000000000ll) * 100000000000000000ll,
307
52
                static_cast<int128_t>(1000000000000000000ll) * 100000000000000000ll * 10ll,
308
52
                static_cast<int128_t>(1000000000000000000ll) * 100000000000000000ll * 100ll,
309
52
                static_cast<int128_t>(1000000000000000000ll) * 100000000000000000ll * 1000ll};
310
52
        if (scale >= 0 && scale < 38) return values[scale];
311
0
        return -1; // Overflow
312
52
    }
313
314
2
    bool is_zero() const { return _value == 0; }
315
316
private:
317
    int128_t _value;
318
};
319
320
DecimalV2Value operator+(const DecimalV2Value& v1, const DecimalV2Value& v2);
321
DecimalV2Value operator-(const DecimalV2Value& v1, const DecimalV2Value& v2);
322
DecimalV2Value operator*(const DecimalV2Value& v1, const DecimalV2Value& v2);
323
DecimalV2Value operator/(const DecimalV2Value& v1, const DecimalV2Value& v2);
324
DecimalV2Value operator%(const DecimalV2Value& v1, const DecimalV2Value& v2);
325
326
DecimalV2Value operator-(const DecimalV2Value& v);
327
328
std::ostream& operator<<(std::ostream& os, DecimalV2Value const& decimal_value);
329
std::istream& operator>>(std::istream& ism, DecimalV2Value& decimal_value);
330
331
std::size_t hash_value(DecimalV2Value const& value);
332
333
#include "common/compile_check_end.h"
334
} // end namespace doris
335
336
template <>
337
struct std::hash<doris::DecimalV2Value> {
338
0
    size_t operator()(const doris::DecimalV2Value& v) const { return doris::hash_value(v); }
339
};
340
341
template <>
342
struct std::equal_to<doris::DecimalV2Value> {
343
85
    bool operator()(const doris::DecimalV2Value& lhs, const doris::DecimalV2Value& rhs) const {
344
85
        return lhs == rhs;
345
85
    }
346
};