Coverage Report

Created: 2026-04-14 20:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/function/function_string_format.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 <fmt/format.h>
21
22
#include <cmath>
23
#include <cstddef>
24
#include <cstring>
25
#include <string>
26
#include <type_traits>
27
28
#include "common/status.h"
29
#include "core/assert_cast.h"
30
#include "core/block/block.h"
31
#include "core/block/column_numbers.h"
32
#include "core/column/column_const.h"
33
#include "core/column/column_decimal.h"
34
#include "core/column/column_string.h"
35
#include "core/column/column_vector.h"
36
#include "core/data_type/data_type_decimal.h"
37
#include "core/data_type/data_type_number.h"
38
#include "core/data_type/data_type_string.h"
39
#include "core/data_type/define_primitive_type.h"
40
#include "core/data_type/primitive_type.h"
41
#include "core/string_ref.h"
42
#include "core/types.h"
43
#include "core/value/decimalv2_value.h"
44
#include "exec/common/int_exp.h"
45
#include "exec/common/stringop_substring.h"
46
#include "exec/common/template_helpers.hpp"
47
#include "exprs/function/function.h"
48
#include "exprs/function/function_helpers.h"
49
#include "exprs/function_context.h"
50
#include "exprs/math_functions.h"
51
52
namespace doris {
53
#include "common/compile_check_avoid_begin.h"
54
55
// ----------------------------------------------------------------------
56
// SimpleItoaWithCommas()
57
//    Description: converts an integer to a string.
58
//    Puts commas every 3 spaces.
59
//    Faster than printf("%d")?
60
//
61
//    Return value: string
62
// ----------------------------------------------------------------------
63
template <typename T>
64
56
char* SimpleItoaWithCommas(T i, char* buffer, int32_t buffer_size) {
65
56
    char* p = buffer + buffer_size;
66
    // Need to use unsigned T instead of T to correctly handle
67
56
    std::make_unsigned_t<T> n = i;
68
56
    if (i < 0) {
69
20
        n = 0 - n;
70
20
    }
71
56
    *--p = '0' + n % 10; // this case deals with the number "0"
72
56
    n /= 10;
73
142
    while (n) {
74
127
        *--p = '0' + n % 10;
75
127
        n /= 10;
76
127
        if (n == 0) {
77
25
            break;
78
25
        }
79
80
102
        *--p = '0' + n % 10;
81
102
        n /= 10;
82
102
        if (n == 0) {
83
16
            break;
84
16
        }
85
86
86
        *--p = ',';
87
86
        *--p = '0' + n % 10;
88
86
        n /= 10;
89
        // For this unrolling, we check if n == 0 in the main while loop
90
86
    }
91
56
    if (i < 0) {
92
20
        *--p = '-';
93
20
    }
94
56
    return p;
95
56
}
_ZN5doris20SimpleItoaWithCommasInEEPcT_S1_i
Line
Count
Source
64
29
char* SimpleItoaWithCommas(T i, char* buffer, int32_t buffer_size) {
65
29
    char* p = buffer + buffer_size;
66
    // Need to use unsigned T instead of T to correctly handle
67
29
    std::make_unsigned_t<T> n = i;
68
29
    if (i < 0) {
69
10
        n = 0 - n;
70
10
    }
71
29
    *--p = '0' + n % 10; // this case deals with the number "0"
72
29
    n /= 10;
73
74
    while (n) {
74
64
        *--p = '0' + n % 10;
75
64
        n /= 10;
76
64
        if (n == 0) {
77
8
            break;
78
8
        }
79
80
56
        *--p = '0' + n % 10;
81
56
        n /= 10;
82
56
        if (n == 0) {
83
11
            break;
84
11
        }
85
86
45
        *--p = ',';
87
45
        *--p = '0' + n % 10;
88
45
        n /= 10;
89
        // For this unrolling, we check if n == 0 in the main while loop
90
45
    }
91
29
    if (i < 0) {
92
10
        *--p = '-';
93
10
    }
94
29
    return p;
95
29
}
_ZN5doris20SimpleItoaWithCommasIlEEPcT_S1_i
Line
Count
Source
64
27
char* SimpleItoaWithCommas(T i, char* buffer, int32_t buffer_size) {
65
27
    char* p = buffer + buffer_size;
66
    // Need to use unsigned T instead of T to correctly handle
67
27
    std::make_unsigned_t<T> n = i;
68
27
    if (i < 0) {
69
10
        n = 0 - n;
70
10
    }
71
27
    *--p = '0' + n % 10; // this case deals with the number "0"
72
27
    n /= 10;
73
68
    while (n) {
74
63
        *--p = '0' + n % 10;
75
63
        n /= 10;
76
63
        if (n == 0) {
77
17
            break;
78
17
        }
79
80
46
        *--p = '0' + n % 10;
81
46
        n /= 10;
82
46
        if (n == 0) {
83
5
            break;
84
5
        }
85
86
41
        *--p = ',';
87
41
        *--p = '0' + n % 10;
88
41
        n /= 10;
89
        // For this unrolling, we check if n == 0 in the main while loop
90
41
    }
91
27
    if (i < 0) {
92
10
        *--p = '-';
93
10
    }
94
27
    return p;
95
27
}
96
97
namespace MoneyFormat {
98
99
0
constexpr size_t MAX_FORMAT_LEN_DEC32() {
100
0
    // Decimal(9, 0)
101
0
    // Double the size to avoid some unexpected bug.
102
0
    return 2 * (1 + 9 + (9 / 3) + 3);
103
0
}
104
105
0
constexpr size_t MAX_FORMAT_LEN_DEC64() {
106
0
    // Decimal(18, 0)
107
0
    // Double the size to avoid some unexpected bug.
108
0
    return 2 * (1 + 18 + (18 / 3) + 3);
109
0
}
110
111
0
constexpr size_t MAX_FORMAT_LEN_DEC128V2() {
112
0
    // DecimalV2 has at most 27 digits
113
0
    // Double the size to avoid some unexpected bug.
114
0
    return 2 * (1 + 27 + (27 / 3) + 3);
115
0
}
116
117
0
constexpr size_t MAX_FORMAT_LEN_DEC128V3() {
118
0
    // Decimal(38, 0)
119
0
    // Double the size to avoid some unexpected bug.
120
0
    return 2 * (1 + 39 + (39 / 3) + 3);
121
0
}
122
123
0
constexpr size_t MAX_FORMAT_LEN_INT64() {
124
0
    // INT_MIN = -9223372036854775807
125
0
    // Double the size to avoid some unexpected bug.
126
0
    return 2 * (1 + 20 + (20 / 3) + 3);
127
0
}
128
129
0
constexpr size_t MAX_FORMAT_LEN_INT128() {
130
0
    // INT128_MIN = -170141183460469231731687303715884105728
131
0
    return 2 * (1 + 39 + (39 / 3) + 3);
132
0
}
133
134
template <typename T, size_t N>
135
25
StringRef do_money_format(FunctionContext* context, UInt32 scale, T int_value, T frac_value) {
136
25
    static_assert(std::is_integral<T>::value);
137
25
    const bool is_negative = int_value < 0 || frac_value < 0;
138
139
    // do round to frac_part
140
    // magic number 2: since we need to round frac_part to 2 digits
141
25
    if (scale > 2) {
142
19
        DCHECK(scale <= 38);
143
        // do rounding, so we need to reserve 3 digits.
144
19
        auto multiplier = common::exp10_i128(std::abs(static_cast<int>(scale - 3)));
145
        // do devide first to avoid overflow
146
        // after round frac_value will be positive by design.
147
19
        frac_value = std::abs(static_cast<int>(frac_value / multiplier)) + 5;
148
19
        frac_value /= 10;
149
19
    } else if (scale < 2) {
150
6
        DCHECK(frac_value < 100);
151
        // since scale <= 2, overflow is impossiable
152
6
        frac_value = frac_value * common::exp10_i32(2 - scale);
153
6
    }
154
155
25
    if (frac_value == 100) {
156
3
        if (is_negative) {
157
2
            int_value -= 1;
158
2
        } else {
159
1
            int_value += 1;
160
1
        }
161
3
        frac_value = 0;
162
3
    }
163
164
25
    bool append_sign_manually = false;
165
25
    if (is_negative && int_value == 0) {
166
        // when int_value is 0, result of SimpleItoaWithCommas will contains just zero
167
        // for Decimal like -0.1234, this will leads to problem, because negative sign is discarded.
168
        // this is why we introduce argument append_sing_manually.
169
2
        append_sign_manually = true;
170
2
    }
171
172
25
    char local[N];
173
25
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
174
25
    const Int32 integer_str_len = N - (p - local);
175
25
    const Int32 frac_str_len = 2;
176
25
    const Int32 whole_decimal_str_len =
177
25
            (append_sign_manually ? 1 : 0) + integer_str_len + 1 + frac_str_len;
178
179
25
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
180
    // Modify a string passed via stringref
181
25
    char* result_data = const_cast<char*>(result.data);
182
183
25
    if (append_sign_manually) {
184
2
        memset(result_data, '-', 1);
185
2
    }
186
187
25
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
188
25
    *(result_data + whole_decimal_str_len - 3) = '.';
189
25
    *(result_data + whole_decimal_str_len - 2) = '0' + std::abs(static_cast<int>(frac_value / 10));
190
25
    *(result_data + whole_decimal_str_len - 1) = '0' + std::abs(static_cast<int>(frac_value % 10));
191
25
    return result;
192
25
};
_ZN5doris11MoneyFormat15do_money_formatInLm80EEENS_9StringRefEPNS_15FunctionContextEjT_S5_
Line
Count
Source
135
14
StringRef do_money_format(FunctionContext* context, UInt32 scale, T int_value, T frac_value) {
136
14
    static_assert(std::is_integral<T>::value);
137
14
    const bool is_negative = int_value < 0 || frac_value < 0;
138
139
    // do round to frac_part
140
    // magic number 2: since we need to round frac_part to 2 digits
141
14
    if (scale > 2) {
142
14
        DCHECK(scale <= 38);
143
        // do rounding, so we need to reserve 3 digits.
144
14
        auto multiplier = common::exp10_i128(std::abs(static_cast<int>(scale - 3)));
145
        // do devide first to avoid overflow
146
        // after round frac_value will be positive by design.
147
14
        frac_value = std::abs(static_cast<int>(frac_value / multiplier)) + 5;
148
14
        frac_value /= 10;
149
14
    } else if (scale < 2) {
150
0
        DCHECK(frac_value < 100);
151
        // since scale <= 2, overflow is impossiable
152
0
        frac_value = frac_value * common::exp10_i32(2 - scale);
153
0
    }
154
155
14
    if (frac_value == 100) {
156
3
        if (is_negative) {
157
2
            int_value -= 1;
158
2
        } else {
159
1
            int_value += 1;
160
1
        }
161
3
        frac_value = 0;
162
3
    }
163
164
14
    bool append_sign_manually = false;
165
14
    if (is_negative && int_value == 0) {
166
        // when int_value is 0, result of SimpleItoaWithCommas will contains just zero
167
        // for Decimal like -0.1234, this will leads to problem, because negative sign is discarded.
168
        // this is why we introduce argument append_sing_manually.
169
2
        append_sign_manually = true;
170
2
    }
171
172
14
    char local[N];
173
14
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
174
14
    const Int32 integer_str_len = N - (p - local);
175
14
    const Int32 frac_str_len = 2;
176
14
    const Int32 whole_decimal_str_len =
177
14
            (append_sign_manually ? 1 : 0) + integer_str_len + 1 + frac_str_len;
178
179
14
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
180
    // Modify a string passed via stringref
181
14
    char* result_data = const_cast<char*>(result.data);
182
183
14
    if (append_sign_manually) {
184
2
        memset(result_data, '-', 1);
185
2
    }
186
187
14
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
188
14
    *(result_data + whole_decimal_str_len - 3) = '.';
189
14
    *(result_data + whole_decimal_str_len - 2) = '0' + std::abs(static_cast<int>(frac_value / 10));
190
14
    *(result_data + whole_decimal_str_len - 1) = '0' + std::abs(static_cast<int>(frac_value % 10));
191
14
    return result;
192
14
};
Unexecuted instantiation: _ZN5doris11MoneyFormat15do_money_formatIlLm32EEENS_9StringRefEPNS_15FunctionContextEjT_S5_
_ZN5doris11MoneyFormat15do_money_formatIlLm56EEENS_9StringRefEPNS_15FunctionContextEjT_S5_
Line
Count
Source
135
5
StringRef do_money_format(FunctionContext* context, UInt32 scale, T int_value, T frac_value) {
136
5
    static_assert(std::is_integral<T>::value);
137
5
    const bool is_negative = int_value < 0 || frac_value < 0;
138
139
    // do round to frac_part
140
    // magic number 2: since we need to round frac_part to 2 digits
141
5
    if (scale > 2) {
142
5
        DCHECK(scale <= 38);
143
        // do rounding, so we need to reserve 3 digits.
144
5
        auto multiplier = common::exp10_i128(std::abs(static_cast<int>(scale - 3)));
145
        // do devide first to avoid overflow
146
        // after round frac_value will be positive by design.
147
5
        frac_value = std::abs(static_cast<int>(frac_value / multiplier)) + 5;
148
5
        frac_value /= 10;
149
5
    } else if (scale < 2) {
150
0
        DCHECK(frac_value < 100);
151
        // since scale <= 2, overflow is impossiable
152
0
        frac_value = frac_value * common::exp10_i32(2 - scale);
153
0
    }
154
155
5
    if (frac_value == 100) {
156
0
        if (is_negative) {
157
0
            int_value -= 1;
158
0
        } else {
159
0
            int_value += 1;
160
0
        }
161
0
        frac_value = 0;
162
0
    }
163
164
5
    bool append_sign_manually = false;
165
5
    if (is_negative && int_value == 0) {
166
        // when int_value is 0, result of SimpleItoaWithCommas will contains just zero
167
        // for Decimal like -0.1234, this will leads to problem, because negative sign is discarded.
168
        // this is why we introduce argument append_sing_manually.
169
0
        append_sign_manually = true;
170
0
    }
171
172
5
    char local[N];
173
5
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
174
5
    const Int32 integer_str_len = N - (p - local);
175
5
    const Int32 frac_str_len = 2;
176
5
    const Int32 whole_decimal_str_len =
177
5
            (append_sign_manually ? 1 : 0) + integer_str_len + 1 + frac_str_len;
178
179
5
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
180
    // Modify a string passed via stringref
181
5
    char* result_data = const_cast<char*>(result.data);
182
183
5
    if (append_sign_manually) {
184
0
        memset(result_data, '-', 1);
185
0
    }
186
187
5
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
188
5
    *(result_data + whole_decimal_str_len - 3) = '.';
189
5
    *(result_data + whole_decimal_str_len - 2) = '0' + std::abs(static_cast<int>(frac_value / 10));
190
5
    *(result_data + whole_decimal_str_len - 1) = '0' + std::abs(static_cast<int>(frac_value % 10));
191
5
    return result;
192
5
};
_ZN5doris11MoneyFormat15do_money_formatInLm112EEENS_9StringRefEPNS_15FunctionContextEjT_S5_
Line
Count
Source
135
3
StringRef do_money_format(FunctionContext* context, UInt32 scale, T int_value, T frac_value) {
136
3
    static_assert(std::is_integral<T>::value);
137
3
    const bool is_negative = int_value < 0 || frac_value < 0;
138
139
    // do round to frac_part
140
    // magic number 2: since we need to round frac_part to 2 digits
141
3
    if (scale > 2) {
142
0
        DCHECK(scale <= 38);
143
        // do rounding, so we need to reserve 3 digits.
144
0
        auto multiplier = common::exp10_i128(std::abs(static_cast<int>(scale - 3)));
145
        // do devide first to avoid overflow
146
        // after round frac_value will be positive by design.
147
0
        frac_value = std::abs(static_cast<int>(frac_value / multiplier)) + 5;
148
0
        frac_value /= 10;
149
3
    } else if (scale < 2) {
150
3
        DCHECK(frac_value < 100);
151
        // since scale <= 2, overflow is impossiable
152
3
        frac_value = frac_value * common::exp10_i32(2 - scale);
153
3
    }
154
155
3
    if (frac_value == 100) {
156
0
        if (is_negative) {
157
0
            int_value -= 1;
158
0
        } else {
159
0
            int_value += 1;
160
0
        }
161
0
        frac_value = 0;
162
0
    }
163
164
3
    bool append_sign_manually = false;
165
3
    if (is_negative && int_value == 0) {
166
        // when int_value is 0, result of SimpleItoaWithCommas will contains just zero
167
        // for Decimal like -0.1234, this will leads to problem, because negative sign is discarded.
168
        // this is why we introduce argument append_sing_manually.
169
0
        append_sign_manually = true;
170
0
    }
171
172
3
    char local[N];
173
3
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
174
3
    const Int32 integer_str_len = N - (p - local);
175
3
    const Int32 frac_str_len = 2;
176
3
    const Int32 whole_decimal_str_len =
177
3
            (append_sign_manually ? 1 : 0) + integer_str_len + 1 + frac_str_len;
178
179
3
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
180
    // Modify a string passed via stringref
181
3
    char* result_data = const_cast<char*>(result.data);
182
183
3
    if (append_sign_manually) {
184
0
        memset(result_data, '-', 1);
185
0
    }
186
187
3
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
188
3
    *(result_data + whole_decimal_str_len - 3) = '.';
189
3
    *(result_data + whole_decimal_str_len - 2) = '0' + std::abs(static_cast<int>(frac_value / 10));
190
3
    *(result_data + whole_decimal_str_len - 1) = '0' + std::abs(static_cast<int>(frac_value % 10));
191
3
    return result;
192
3
};
_ZN5doris11MoneyFormat15do_money_formatIlLm60EEENS_9StringRefEPNS_15FunctionContextEjT_S5_
Line
Count
Source
135
3
StringRef do_money_format(FunctionContext* context, UInt32 scale, T int_value, T frac_value) {
136
3
    static_assert(std::is_integral<T>::value);
137
3
    const bool is_negative = int_value < 0 || frac_value < 0;
138
139
    // do round to frac_part
140
    // magic number 2: since we need to round frac_part to 2 digits
141
3
    if (scale > 2) {
142
0
        DCHECK(scale <= 38);
143
        // do rounding, so we need to reserve 3 digits.
144
0
        auto multiplier = common::exp10_i128(std::abs(static_cast<int>(scale - 3)));
145
        // do devide first to avoid overflow
146
        // after round frac_value will be positive by design.
147
0
        frac_value = std::abs(static_cast<int>(frac_value / multiplier)) + 5;
148
0
        frac_value /= 10;
149
3
    } else if (scale < 2) {
150
3
        DCHECK(frac_value < 100);
151
        // since scale <= 2, overflow is impossiable
152
3
        frac_value = frac_value * common::exp10_i32(2 - scale);
153
3
    }
154
155
3
    if (frac_value == 100) {
156
0
        if (is_negative) {
157
0
            int_value -= 1;
158
0
        } else {
159
0
            int_value += 1;
160
0
        }
161
0
        frac_value = 0;
162
0
    }
163
164
3
    bool append_sign_manually = false;
165
3
    if (is_negative && int_value == 0) {
166
        // when int_value is 0, result of SimpleItoaWithCommas will contains just zero
167
        // for Decimal like -0.1234, this will leads to problem, because negative sign is discarded.
168
        // this is why we introduce argument append_sing_manually.
169
0
        append_sign_manually = true;
170
0
    }
171
172
3
    char local[N];
173
3
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
174
3
    const Int32 integer_str_len = N - (p - local);
175
3
    const Int32 frac_str_len = 2;
176
3
    const Int32 whole_decimal_str_len =
177
3
            (append_sign_manually ? 1 : 0) + integer_str_len + 1 + frac_str_len;
178
179
3
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
180
    // Modify a string passed via stringref
181
3
    char* result_data = const_cast<char*>(result.data);
182
183
3
    if (append_sign_manually) {
184
0
        memset(result_data, '-', 1);
185
0
    }
186
187
3
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
188
3
    *(result_data + whole_decimal_str_len - 3) = '.';
189
3
    *(result_data + whole_decimal_str_len - 2) = '0' + std::abs(static_cast<int>(frac_value / 10));
190
3
    *(result_data + whole_decimal_str_len - 1) = '0' + std::abs(static_cast<int>(frac_value % 10));
191
3
    return result;
192
3
};
193
194
// Note string value must be valid decimal string which contains two digits after the decimal point
195
4
static StringRef do_money_format(FunctionContext* context, const std::string& value) {
196
4
    bool is_positive = (value[0] != '-');
197
4
    int32_t result_len = value.size() + (value.size() - (is_positive ? 4 : 5)) / 3;
198
4
    StringRef result = context->create_temp_string_val(result_len);
199
    // Modify a string passed via stringref
200
4
    char* result_data = const_cast<char*>(result.data);
201
4
    if (!is_positive) {
202
2
        *result_data = '-';
203
2
    }
204
10
    for (int i = value.size() - 4, j = result_len - 4; i >= 0; i = i - 3) {
205
9
        *(result_data + j) = *(value.data() + i);
206
9
        if (i - 1 < 0) {
207
2
            break;
208
2
        }
209
7
        *(result_data + j - 1) = *(value.data() + i - 1);
210
7
        if (i - 2 < 0) {
211
1
            break;
212
1
        }
213
6
        *(result_data + j - 2) = *(value.data() + i - 2);
214
6
        if (j - 3 > 1 || (j - 3 == 1 && is_positive)) {
215
4
            *(result_data + j - 3) = ',';
216
4
            j -= 4;
217
4
        } else {
218
2
            j -= 3;
219
2
        }
220
6
    }
221
4
    memcpy(result_data + result_len - 3, value.data() + value.size() - 3, 3);
222
4
    return result;
223
4
};
Unexecuted instantiation: function_money_format_test.cpp:_ZN5doris11MoneyFormatL15do_money_formatEPNS_15FunctionContextERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
function_string.cpp:_ZN5doris11MoneyFormatL15do_money_formatEPNS_15FunctionContextERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
195
4
static StringRef do_money_format(FunctionContext* context, const std::string& value) {
196
4
    bool is_positive = (value[0] != '-');
197
4
    int32_t result_len = value.size() + (value.size() - (is_positive ? 4 : 5)) / 3;
198
4
    StringRef result = context->create_temp_string_val(result_len);
199
    // Modify a string passed via stringref
200
4
    char* result_data = const_cast<char*>(result.data);
201
4
    if (!is_positive) {
202
2
        *result_data = '-';
203
2
    }
204
10
    for (int i = value.size() - 4, j = result_len - 4; i >= 0; i = i - 3) {
205
9
        *(result_data + j) = *(value.data() + i);
206
9
        if (i - 1 < 0) {
207
2
            break;
208
2
        }
209
7
        *(result_data + j - 1) = *(value.data() + i - 1);
210
7
        if (i - 2 < 0) {
211
1
            break;
212
1
        }
213
6
        *(result_data + j - 2) = *(value.data() + i - 2);
214
6
        if (j - 3 > 1 || (j - 3 == 1 && is_positive)) {
215
4
            *(result_data + j - 3) = ',';
216
4
            j -= 4;
217
4
        } else {
218
2
            j -= 3;
219
2
        }
220
6
    }
221
4
    memcpy(result_data + result_len - 3, value.data() + value.size() - 3, 3);
222
4
    return result;
223
4
};
224
225
} // namespace MoneyFormat
226
227
namespace FormatRound {
228
229
0
constexpr size_t MAX_FORMAT_LEN_DEC32() {
230
0
    // Decimal(9, 0)
231
0
    // Double the size to avoid some unexpected bug.
232
0
    return 2 * (1 + 9 + (9 / 3) + 3);
233
0
}
234
235
0
constexpr size_t MAX_FORMAT_LEN_DEC64() {
236
0
    // Decimal(18, 0)
237
0
    // Double the size to avoid some unexpected bug.
238
0
    return 2 * (1 + 18 + (18 / 3) + 3);
239
0
}
240
241
0
constexpr size_t MAX_FORMAT_LEN_DEC128V2() {
242
0
    // DecimalV2 has at most 27 digits
243
0
    // Double the size to avoid some unexpected bug.
244
0
    return 2 * (1 + 27 + (27 / 3) + 3);
245
0
}
246
247
0
constexpr size_t MAX_FORMAT_LEN_DEC128V3() {
248
0
    // Decimal(38, 0)
249
0
    // Double the size to avoid some unexpected bug.
250
0
    return 2 * (1 + 39 + (39 / 3) + 3);
251
0
}
252
253
0
constexpr size_t MAX_FORMAT_LEN_INT64() {
254
0
    // INT_MIN = -9223372036854775807
255
0
    // Double the size to avoid some unexpected bug.
256
0
    return 2 * (1 + 20 + (20 / 3) + 3);
257
0
}
258
259
0
constexpr size_t MAX_FORMAT_LEN_INT128() {
260
0
    // INT128_MIN = -170141183460469231731687303715884105728
261
0
    return 2 * (1 + 39 + (39 / 3) + 3);
262
0
}
263
264
template <typename T, size_t N>
265
StringRef do_format_round(FunctionContext* context, UInt32 scale, T int_value, T frac_value,
266
31
                          Int32 decimal_places) {
267
31
    static_assert(std::is_integral<T>::value);
268
31
    const bool is_negative = int_value < 0 || frac_value < 0;
269
270
    // do round to frac_part based on decimal_places
271
31
    if (scale > decimal_places && decimal_places > 0) {
272
14
        DCHECK(scale <= 38);
273
        // do rounding, so we need to reserve decimal_places + 1 digits
274
14
        auto multiplier =
275
14
                common::exp10_i128(std::abs(static_cast<int>(scale - (decimal_places + 1))));
276
        // do divide first to avoid overflow
277
        // after round frac_value will be positive by design
278
14
        frac_value = std::abs(static_cast<int>(frac_value / multiplier)) + 5;
279
14
        frac_value /= 10;
280
17
    } else if (scale < decimal_places && decimal_places > 0) {
281
        // since scale <= decimal_places, overflow is impossible
282
13
        frac_value = frac_value * common::exp10_i32(decimal_places - scale);
283
13
    }
284
285
    // Calculate power of 10 for decimal_places
286
31
    T decimal_power = common::exp10_i32(decimal_places);
287
31
    if (frac_value == decimal_power) {
288
0
        if (is_negative) {
289
0
            int_value -= 1;
290
0
        } else {
291
0
            int_value += 1;
292
0
        }
293
0
        frac_value = 0;
294
0
    }
295
296
31
    bool append_sign_manually = false;
297
31
    if (is_negative && int_value == 0) {
298
0
        append_sign_manually = true;
299
0
    }
300
301
31
    char local[N];
302
31
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
303
31
    const Int32 integer_str_len = N - (p - local);
304
31
    const Int32 frac_str_len = decimal_places;
305
31
    const Int32 whole_decimal_str_len = (append_sign_manually ? 1 : 0) + integer_str_len +
306
31
                                        (decimal_places > 0 ? 1 : 0) + frac_str_len;
307
308
31
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
309
    // Modify a string passed via stringref
310
31
    char* result_data = const_cast<char*>(result.data);
311
312
31
    if (append_sign_manually) {
313
0
        memset(result_data, '-', 1);
314
0
    }
315
316
31
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
317
31
    if (decimal_places > 0) {
318
27
        *(result_data + whole_decimal_str_len - (frac_str_len + 1)) = '.';
319
27
    }
320
321
    // Convert fractional part to string with proper padding
322
31
    T remaining_frac = std::abs(static_cast<int>(frac_value));
323
139
    for (int i = 0; i <= decimal_places - 1; ++i) {
324
108
        *(result_data + whole_decimal_str_len - 1 - i) = '0' + (remaining_frac % 10);
325
108
        remaining_frac /= 10;
326
108
    }
327
31
    return result;
328
31
}
_ZN5doris11FormatRound15do_format_roundIlLm60EEENS_9StringRefEPNS_15FunctionContextEjT_S5_i
Line
Count
Source
266
8
                          Int32 decimal_places) {
267
8
    static_assert(std::is_integral<T>::value);
268
8
    const bool is_negative = int_value < 0 || frac_value < 0;
269
270
    // do round to frac_part based on decimal_places
271
8
    if (scale > decimal_places && decimal_places > 0) {
272
0
        DCHECK(scale <= 38);
273
        // do rounding, so we need to reserve decimal_places + 1 digits
274
0
        auto multiplier =
275
0
                common::exp10_i128(std::abs(static_cast<int>(scale - (decimal_places + 1))));
276
        // do divide first to avoid overflow
277
        // after round frac_value will be positive by design
278
0
        frac_value = std::abs(static_cast<int>(frac_value / multiplier)) + 5;
279
0
        frac_value /= 10;
280
8
    } else if (scale < decimal_places && decimal_places > 0) {
281
        // since scale <= decimal_places, overflow is impossible
282
6
        frac_value = frac_value * common::exp10_i32(decimal_places - scale);
283
6
    }
284
285
    // Calculate power of 10 for decimal_places
286
8
    T decimal_power = common::exp10_i32(decimal_places);
287
8
    if (frac_value == decimal_power) {
288
0
        if (is_negative) {
289
0
            int_value -= 1;
290
0
        } else {
291
0
            int_value += 1;
292
0
        }
293
0
        frac_value = 0;
294
0
    }
295
296
8
    bool append_sign_manually = false;
297
8
    if (is_negative && int_value == 0) {
298
0
        append_sign_manually = true;
299
0
    }
300
301
8
    char local[N];
302
8
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
303
8
    const Int32 integer_str_len = N - (p - local);
304
8
    const Int32 frac_str_len = decimal_places;
305
8
    const Int32 whole_decimal_str_len = (append_sign_manually ? 1 : 0) + integer_str_len +
306
8
                                        (decimal_places > 0 ? 1 : 0) + frac_str_len;
307
308
8
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
309
    // Modify a string passed via stringref
310
8
    char* result_data = const_cast<char*>(result.data);
311
312
8
    if (append_sign_manually) {
313
0
        memset(result_data, '-', 1);
314
0
    }
315
316
8
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
317
8
    if (decimal_places > 0) {
318
6
        *(result_data + whole_decimal_str_len - (frac_str_len + 1)) = '.';
319
6
    }
320
321
    // Convert fractional part to string with proper padding
322
8
    T remaining_frac = std::abs(static_cast<int>(frac_value));
323
47
    for (int i = 0; i <= decimal_places - 1; ++i) {
324
39
        *(result_data + whole_decimal_str_len - 1 - i) = '0' + (remaining_frac % 10);
325
39
        remaining_frac /= 10;
326
39
    }
327
8
    return result;
328
8
}
_ZN5doris11FormatRound15do_format_roundInLm112EEENS_9StringRefEPNS_15FunctionContextEjT_S5_i
Line
Count
Source
266
9
                          Int32 decimal_places) {
267
9
    static_assert(std::is_integral<T>::value);
268
9
    const bool is_negative = int_value < 0 || frac_value < 0;
269
270
    // do round to frac_part based on decimal_places
271
9
    if (scale > decimal_places && decimal_places > 0) {
272
0
        DCHECK(scale <= 38);
273
        // do rounding, so we need to reserve decimal_places + 1 digits
274
0
        auto multiplier =
275
0
                common::exp10_i128(std::abs(static_cast<int>(scale - (decimal_places + 1))));
276
        // do divide first to avoid overflow
277
        // after round frac_value will be positive by design
278
0
        frac_value = std::abs(static_cast<int>(frac_value / multiplier)) + 5;
279
0
        frac_value /= 10;
280
9
    } else if (scale < decimal_places && decimal_places > 0) {
281
        // since scale <= decimal_places, overflow is impossible
282
7
        frac_value = frac_value * common::exp10_i32(decimal_places - scale);
283
7
    }
284
285
    // Calculate power of 10 for decimal_places
286
9
    T decimal_power = common::exp10_i32(decimal_places);
287
9
    if (frac_value == decimal_power) {
288
0
        if (is_negative) {
289
0
            int_value -= 1;
290
0
        } else {
291
0
            int_value += 1;
292
0
        }
293
0
        frac_value = 0;
294
0
    }
295
296
9
    bool append_sign_manually = false;
297
9
    if (is_negative && int_value == 0) {
298
0
        append_sign_manually = true;
299
0
    }
300
301
9
    char local[N];
302
9
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
303
9
    const Int32 integer_str_len = N - (p - local);
304
9
    const Int32 frac_str_len = decimal_places;
305
9
    const Int32 whole_decimal_str_len = (append_sign_manually ? 1 : 0) + integer_str_len +
306
9
                                        (decimal_places > 0 ? 1 : 0) + frac_str_len;
307
308
9
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
309
    // Modify a string passed via stringref
310
9
    char* result_data = const_cast<char*>(result.data);
311
312
9
    if (append_sign_manually) {
313
0
        memset(result_data, '-', 1);
314
0
    }
315
316
9
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
317
9
    if (decimal_places > 0) {
318
7
        *(result_data + whole_decimal_str_len - (frac_str_len + 1)) = '.';
319
7
    }
320
321
    // Convert fractional part to string with proper padding
322
9
    T remaining_frac = std::abs(static_cast<int>(frac_value));
323
50
    for (int i = 0; i <= decimal_places - 1; ++i) {
324
41
        *(result_data + whole_decimal_str_len - 1 - i) = '0' + (remaining_frac % 10);
325
41
        remaining_frac /= 10;
326
41
    }
327
9
    return result;
328
9
}
_ZN5doris11FormatRound15do_format_roundInLm80EEENS_9StringRefEPNS_15FunctionContextEjT_S5_i
Line
Count
Source
266
3
                          Int32 decimal_places) {
267
3
    static_assert(std::is_integral<T>::value);
268
3
    const bool is_negative = int_value < 0 || frac_value < 0;
269
270
    // do round to frac_part based on decimal_places
271
3
    if (scale > decimal_places && decimal_places > 0) {
272
3
        DCHECK(scale <= 38);
273
        // do rounding, so we need to reserve decimal_places + 1 digits
274
3
        auto multiplier =
275
3
                common::exp10_i128(std::abs(static_cast<int>(scale - (decimal_places + 1))));
276
        // do divide first to avoid overflow
277
        // after round frac_value will be positive by design
278
3
        frac_value = std::abs(static_cast<int>(frac_value / multiplier)) + 5;
279
3
        frac_value /= 10;
280
3
    } else if (scale < decimal_places && decimal_places > 0) {
281
        // since scale <= decimal_places, overflow is impossible
282
0
        frac_value = frac_value * common::exp10_i32(decimal_places - scale);
283
0
    }
284
285
    // Calculate power of 10 for decimal_places
286
3
    T decimal_power = common::exp10_i32(decimal_places);
287
3
    if (frac_value == decimal_power) {
288
0
        if (is_negative) {
289
0
            int_value -= 1;
290
0
        } else {
291
0
            int_value += 1;
292
0
        }
293
0
        frac_value = 0;
294
0
    }
295
296
3
    bool append_sign_manually = false;
297
3
    if (is_negative && int_value == 0) {
298
0
        append_sign_manually = true;
299
0
    }
300
301
3
    char local[N];
302
3
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
303
3
    const Int32 integer_str_len = N - (p - local);
304
3
    const Int32 frac_str_len = decimal_places;
305
3
    const Int32 whole_decimal_str_len = (append_sign_manually ? 1 : 0) + integer_str_len +
306
3
                                        (decimal_places > 0 ? 1 : 0) + frac_str_len;
307
308
3
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
309
    // Modify a string passed via stringref
310
3
    char* result_data = const_cast<char*>(result.data);
311
312
3
    if (append_sign_manually) {
313
0
        memset(result_data, '-', 1);
314
0
    }
315
316
3
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
317
3
    if (decimal_places > 0) {
318
3
        *(result_data + whole_decimal_str_len - (frac_str_len + 1)) = '.';
319
3
    }
320
321
    // Convert fractional part to string with proper padding
322
3
    T remaining_frac = std::abs(static_cast<int>(frac_value));
323
9
    for (int i = 0; i <= decimal_places - 1; ++i) {
324
6
        *(result_data + whole_decimal_str_len - 1 - i) = '0' + (remaining_frac % 10);
325
6
        remaining_frac /= 10;
326
6
    }
327
3
    return result;
328
3
}
Unexecuted instantiation: _ZN5doris11FormatRound15do_format_roundIlLm32EEENS_9StringRefEPNS_15FunctionContextEjT_S5_i
_ZN5doris11FormatRound15do_format_roundIlLm56EEENS_9StringRefEPNS_15FunctionContextEjT_S5_i
Line
Count
Source
266
11
                          Int32 decimal_places) {
267
11
    static_assert(std::is_integral<T>::value);
268
11
    const bool is_negative = int_value < 0 || frac_value < 0;
269
270
    // do round to frac_part based on decimal_places
271
11
    if (scale > decimal_places && decimal_places > 0) {
272
11
        DCHECK(scale <= 38);
273
        // do rounding, so we need to reserve decimal_places + 1 digits
274
11
        auto multiplier =
275
11
                common::exp10_i128(std::abs(static_cast<int>(scale - (decimal_places + 1))));
276
        // do divide first to avoid overflow
277
        // after round frac_value will be positive by design
278
11
        frac_value = std::abs(static_cast<int>(frac_value / multiplier)) + 5;
279
11
        frac_value /= 10;
280
11
    } else if (scale < decimal_places && decimal_places > 0) {
281
        // since scale <= decimal_places, overflow is impossible
282
0
        frac_value = frac_value * common::exp10_i32(decimal_places - scale);
283
0
    }
284
285
    // Calculate power of 10 for decimal_places
286
11
    T decimal_power = common::exp10_i32(decimal_places);
287
11
    if (frac_value == decimal_power) {
288
0
        if (is_negative) {
289
0
            int_value -= 1;
290
0
        } else {
291
0
            int_value += 1;
292
0
        }
293
0
        frac_value = 0;
294
0
    }
295
296
11
    bool append_sign_manually = false;
297
11
    if (is_negative && int_value == 0) {
298
0
        append_sign_manually = true;
299
0
    }
300
301
11
    char local[N];
302
11
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
303
11
    const Int32 integer_str_len = N - (p - local);
304
11
    const Int32 frac_str_len = decimal_places;
305
11
    const Int32 whole_decimal_str_len = (append_sign_manually ? 1 : 0) + integer_str_len +
306
11
                                        (decimal_places > 0 ? 1 : 0) + frac_str_len;
307
308
11
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
309
    // Modify a string passed via stringref
310
11
    char* result_data = const_cast<char*>(result.data);
311
312
11
    if (append_sign_manually) {
313
0
        memset(result_data, '-', 1);
314
0
    }
315
316
11
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
317
11
    if (decimal_places > 0) {
318
11
        *(result_data + whole_decimal_str_len - (frac_str_len + 1)) = '.';
319
11
    }
320
321
    // Convert fractional part to string with proper padding
322
11
    T remaining_frac = std::abs(static_cast<int>(frac_value));
323
33
    for (int i = 0; i <= decimal_places - 1; ++i) {
324
22
        *(result_data + whole_decimal_str_len - 1 - i) = '0' + (remaining_frac % 10);
325
22
        remaining_frac /= 10;
326
22
    }
327
11
    return result;
328
11
}
329
330
} // namespace FormatRound
331
332
template <typename Impl>
333
class FunctionMoneyFormat : public IFunction {
334
public:
335
    static constexpr auto name = "money_format";
336
25
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
_ZN5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE20EEEE6createEv
Line
Count
Source
336
4
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
_ZN5doris19FunctionMoneyFormatINS_21MoneyFormatDoubleImplEE6createEv
Line
Count
Source
336
3
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
_ZN5doris19FunctionMoneyFormatINS_20MoneyFormatInt64ImplEE6createEv
Line
Count
Source
336
3
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
_ZN5doris19FunctionMoneyFormatINS_21MoneyFormatInt128ImplEE6createEv
Line
Count
Source
336
3
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
_ZN5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE28EEEE6createEv
Line
Count
Source
336
2
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
_ZN5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE29EEEE6createEv
Line
Count
Source
336
6
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
_ZN5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE30EEEE6createEv
Line
Count
Source
336
2
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
_ZN5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE35EEEE6createEv
Line
Count
Source
336
2
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
337
8
    String get_name() const override { return name; }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE20EEEE8get_nameB5cxx11Ev
Line
Count
Source
337
1
    String get_name() const override { return name; }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatDoubleImplEE8get_nameB5cxx11Ev
Line
Count
Source
337
1
    String get_name() const override { return name; }
_ZNK5doris19FunctionMoneyFormatINS_20MoneyFormatInt64ImplEE8get_nameB5cxx11Ev
Line
Count
Source
337
1
    String get_name() const override { return name; }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatInt128ImplEE8get_nameB5cxx11Ev
Line
Count
Source
337
1
    String get_name() const override { return name; }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE28EEEE8get_nameB5cxx11Ev
Line
Count
Source
337
1
    String get_name() const override { return name; }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE29EEEE8get_nameB5cxx11Ev
Line
Count
Source
337
1
    String get_name() const override { return name; }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE30EEEE8get_nameB5cxx11Ev
Line
Count
Source
337
1
    String get_name() const override { return name; }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE35EEEE8get_nameB5cxx11Ev
Line
Count
Source
337
1
    String get_name() const override { return name; }
338
339
8
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
340
8
        if (arguments.size() != 1) {
341
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
342
0
                                   "Function {} requires exactly 1 argument", name);
343
0
        }
344
345
8
        return std::make_shared<DataTypeString>();
346
8
    }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE20EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Line
Count
Source
339
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
340
1
        if (arguments.size() != 1) {
341
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
342
0
                                   "Function {} requires exactly 1 argument", name);
343
0
        }
344
345
1
        return std::make_shared<DataTypeString>();
346
1
    }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatDoubleImplEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
339
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
340
1
        if (arguments.size() != 1) {
341
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
342
0
                                   "Function {} requires exactly 1 argument", name);
343
0
        }
344
345
1
        return std::make_shared<DataTypeString>();
346
1
    }
_ZNK5doris19FunctionMoneyFormatINS_20MoneyFormatInt64ImplEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
339
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
340
1
        if (arguments.size() != 1) {
341
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
342
0
                                   "Function {} requires exactly 1 argument", name);
343
0
        }
344
345
1
        return std::make_shared<DataTypeString>();
346
1
    }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatInt128ImplEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
339
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
340
1
        if (arguments.size() != 1) {
341
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
342
0
                                   "Function {} requires exactly 1 argument", name);
343
0
        }
344
345
1
        return std::make_shared<DataTypeString>();
346
1
    }
Unexecuted instantiation: _ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE28EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE29EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Line
Count
Source
339
4
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
340
4
        if (arguments.size() != 1) {
341
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
342
0
                                   "Function {} requires exactly 1 argument", name);
343
0
        }
344
345
4
        return std::make_shared<DataTypeString>();
346
4
    }
Unexecuted instantiation: _ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE30EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE35EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
347
8
    DataTypes get_variadic_argument_types_impl() const override {
348
8
        return Impl::get_variadic_argument_types();
349
8
    }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE20EEEE32get_variadic_argument_types_implEv
Line
Count
Source
347
1
    DataTypes get_variadic_argument_types_impl() const override {
348
1
        return Impl::get_variadic_argument_types();
349
1
    }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatDoubleImplEE32get_variadic_argument_types_implEv
Line
Count
Source
347
1
    DataTypes get_variadic_argument_types_impl() const override {
348
1
        return Impl::get_variadic_argument_types();
349
1
    }
_ZNK5doris19FunctionMoneyFormatINS_20MoneyFormatInt64ImplEE32get_variadic_argument_types_implEv
Line
Count
Source
347
1
    DataTypes get_variadic_argument_types_impl() const override {
348
1
        return Impl::get_variadic_argument_types();
349
1
    }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatInt128ImplEE32get_variadic_argument_types_implEv
Line
Count
Source
347
1
    DataTypes get_variadic_argument_types_impl() const override {
348
1
        return Impl::get_variadic_argument_types();
349
1
    }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE28EEEE32get_variadic_argument_types_implEv
Line
Count
Source
347
1
    DataTypes get_variadic_argument_types_impl() const override {
348
1
        return Impl::get_variadic_argument_types();
349
1
    }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE29EEEE32get_variadic_argument_types_implEv
Line
Count
Source
347
1
    DataTypes get_variadic_argument_types_impl() const override {
348
1
        return Impl::get_variadic_argument_types();
349
1
    }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE30EEEE32get_variadic_argument_types_implEv
Line
Count
Source
347
1
    DataTypes get_variadic_argument_types_impl() const override {
348
1
        return Impl::get_variadic_argument_types();
349
1
    }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE35EEEE32get_variadic_argument_types_implEv
Line
Count
Source
347
1
    DataTypes get_variadic_argument_types_impl() const override {
348
1
        return Impl::get_variadic_argument_types();
349
1
    }
350
8
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE20EEEE23get_number_of_argumentsEv
Line
Count
Source
350
1
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatDoubleImplEE23get_number_of_argumentsEv
Line
Count
Source
350
1
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris19FunctionMoneyFormatINS_20MoneyFormatInt64ImplEE23get_number_of_argumentsEv
Line
Count
Source
350
1
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatInt128ImplEE23get_number_of_argumentsEv
Line
Count
Source
350
1
    size_t get_number_of_arguments() const override { return 1; }
Unexecuted instantiation: _ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE28EEEE23get_number_of_argumentsEv
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE29EEEE23get_number_of_argumentsEv
Line
Count
Source
350
4
    size_t get_number_of_arguments() const override { return 1; }
Unexecuted instantiation: _ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE30EEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE35EEEE23get_number_of_argumentsEv
351
352
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
353
8
                        uint32_t result, size_t input_rows_count) const override {
354
8
        auto res_column = ColumnString::create();
355
8
        ColumnPtr argument_column = block.get_by_position(arguments[0]).column;
356
357
8
        auto result_column = assert_cast<ColumnString*>(res_column.get());
358
359
8
        Impl::execute(context, result_column, argument_column, input_rows_count);
360
361
8
        block.replace_by_position(result, std::move(res_column));
362
8
        return Status::OK();
363
8
    }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE20EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
353
2
                        uint32_t result, size_t input_rows_count) const override {
354
2
        auto res_column = ColumnString::create();
355
2
        ColumnPtr argument_column = block.get_by_position(arguments[0]).column;
356
357
2
        auto result_column = assert_cast<ColumnString*>(res_column.get());
358
359
2
        Impl::execute(context, result_column, argument_column, input_rows_count);
360
361
2
        block.replace_by_position(result, std::move(res_column));
362
2
        return Status::OK();
363
2
    }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatDoubleImplEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
353
1
                        uint32_t result, size_t input_rows_count) const override {
354
1
        auto res_column = ColumnString::create();
355
1
        ColumnPtr argument_column = block.get_by_position(arguments[0]).column;
356
357
1
        auto result_column = assert_cast<ColumnString*>(res_column.get());
358
359
1
        Impl::execute(context, result_column, argument_column, input_rows_count);
360
361
1
        block.replace_by_position(result, std::move(res_column));
362
1
        return Status::OK();
363
1
    }
_ZNK5doris19FunctionMoneyFormatINS_20MoneyFormatInt64ImplEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
353
1
                        uint32_t result, size_t input_rows_count) const override {
354
1
        auto res_column = ColumnString::create();
355
1
        ColumnPtr argument_column = block.get_by_position(arguments[0]).column;
356
357
1
        auto result_column = assert_cast<ColumnString*>(res_column.get());
358
359
1
        Impl::execute(context, result_column, argument_column, input_rows_count);
360
361
1
        block.replace_by_position(result, std::move(res_column));
362
1
        return Status::OK();
363
1
    }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatInt128ImplEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
353
1
                        uint32_t result, size_t input_rows_count) const override {
354
1
        auto res_column = ColumnString::create();
355
1
        ColumnPtr argument_column = block.get_by_position(arguments[0]).column;
356
357
1
        auto result_column = assert_cast<ColumnString*>(res_column.get());
358
359
1
        Impl::execute(context, result_column, argument_column, input_rows_count);
360
361
1
        block.replace_by_position(result, std::move(res_column));
362
1
        return Status::OK();
363
1
    }
Unexecuted instantiation: _ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE28EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE29EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
353
3
                        uint32_t result, size_t input_rows_count) const override {
354
3
        auto res_column = ColumnString::create();
355
3
        ColumnPtr argument_column = block.get_by_position(arguments[0]).column;
356
357
3
        auto result_column = assert_cast<ColumnString*>(res_column.get());
358
359
3
        Impl::execute(context, result_column, argument_column, input_rows_count);
360
361
3
        block.replace_by_position(result, std::move(res_column));
362
3
        return Status::OK();
363
3
    }
Unexecuted instantiation: _ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE30EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE35EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
364
};
365
366
struct MoneyFormatDoubleImpl {
367
1
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeFloat64>()}; }
368
369
    static void execute(FunctionContext* context, ColumnString* result_column,
370
1
                        const ColumnPtr col_ptr, size_t input_rows_count) {
371
1
        const auto* data_column = assert_cast<const ColumnFloat64*>(col_ptr.get());
372
        // when scale is above 38, we will go here
373
5
        for (size_t i = 0; i < input_rows_count; i++) {
374
            // round to 2 decimal places
375
4
            double value =
376
4
                    MathFunctions::my_double_round(data_column->get_element(i), 2, false, false);
377
4
            StringRef str = MoneyFormat::do_money_format(context, fmt::format("{:.2f}", value));
378
4
            result_column->insert_data(str.data, str.size);
379
4
        }
380
1
    }
381
};
382
383
struct MoneyFormatInt64Impl {
384
1
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeInt64>()}; }
385
386
    static void execute(FunctionContext* context, ColumnString* result_column,
387
1
                        const ColumnPtr col_ptr, size_t input_rows_count) {
388
1
        const auto* data_column = assert_cast<const ColumnInt64*>(col_ptr.get());
389
4
        for (size_t i = 0; i < input_rows_count; i++) {
390
3
            Int64 value = data_column->get_element(i);
391
3
            StringRef str =
392
3
                    MoneyFormat::do_money_format<Int64, MoneyFormat::MAX_FORMAT_LEN_INT64()>(
393
3
                            context, 0, value, 0);
394
3
            result_column->insert_data(str.data, str.size);
395
3
        }
396
1
    }
397
};
398
399
struct MoneyFormatInt128Impl {
400
1
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeInt128>()}; }
401
402
    static void execute(FunctionContext* context, ColumnString* result_column,
403
1
                        const ColumnPtr col_ptr, size_t input_rows_count) {
404
1
        const auto* data_column = assert_cast<const ColumnInt128*>(col_ptr.get());
405
        // SELECT money_format(170141183460469231731687303715884105728/*INT128_MAX + 1*/) will
406
        // get "170,141,183,460,469,231,731,687,303,715,884,105,727.00" in doris,
407
        // see https://github.com/apache/doris/blob/788abf2d7c3c7c2d57487a9608e889e7662d5fb2/be/src/vec/data_types/data_type_number_base.cpp#L124
408
4
        for (size_t i = 0; i < input_rows_count; i++) {
409
3
            Int128 value = data_column->get_element(i);
410
3
            StringRef str =
411
3
                    MoneyFormat::do_money_format<Int128, MoneyFormat::MAX_FORMAT_LEN_INT128()>(
412
3
                            context, 0, value, 0);
413
3
            result_column->insert_data(str.data, str.size);
414
3
        }
415
1
    }
416
};
417
418
template <PrimitiveType Type>
419
struct MoneyFormatDecimalImpl {
420
5
    static DataTypes get_variadic_argument_types() {
421
5
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>()};
422
5
    }
_ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE20EE27get_variadic_argument_typesEv
Line
Count
Source
420
1
    static DataTypes get_variadic_argument_types() {
421
1
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>()};
422
1
    }
_ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE28EE27get_variadic_argument_typesEv
Line
Count
Source
420
1
    static DataTypes get_variadic_argument_types() {
421
1
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>()};
422
1
    }
_ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE29EE27get_variadic_argument_typesEv
Line
Count
Source
420
1
    static DataTypes get_variadic_argument_types() {
421
1
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>()};
422
1
    }
_ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE30EE27get_variadic_argument_typesEv
Line
Count
Source
420
1
    static DataTypes get_variadic_argument_types() {
421
1
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>()};
422
1
    }
_ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE35EE27get_variadic_argument_typesEv
Line
Count
Source
420
1
    static DataTypes get_variadic_argument_types() {
421
1
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>()};
422
1
    }
423
424
    static void execute(FunctionContext* context, ColumnString* result_column, ColumnPtr col_ptr,
425
5
                        size_t input_rows_count) {
426
5
        if (auto* decimalv2_column = check_and_get_column<ColumnDecimal128V2>(*col_ptr)) {
427
16
            for (size_t i = 0; i < input_rows_count; i++) {
428
14
                const auto& value = decimalv2_column->get_element(i);
429
                // unified_frac_value has 3 digits
430
14
                auto unified_frac_value = value.frac_value() / 1000000;
431
14
                StringRef str =
432
14
                        MoneyFormat::do_money_format<Int128,
433
14
                                                     MoneyFormat::MAX_FORMAT_LEN_DEC128V2()>(
434
14
                                context, 3, value.int_value(), unified_frac_value);
435
436
14
                result_column->insert_data(str.data, str.size);
437
14
            }
438
3
        } else if (auto* decimal32_column = check_and_get_column<ColumnDecimal32>(*col_ptr)) {
439
0
            const UInt32 scale = decimal32_column->get_scale();
440
0
            for (size_t i = 0; i < input_rows_count; i++) {
441
0
                const Int32& frac_part = decimal32_column->get_fractional_part(i);
442
0
                const Int32& whole_part = decimal32_column->get_intergral_part(i);
443
0
                StringRef str =
444
0
                        MoneyFormat::do_money_format<Int64, MoneyFormat::MAX_FORMAT_LEN_DEC32()>(
445
0
                                context, scale, static_cast<Int64>(whole_part),
446
0
                                static_cast<Int64>(frac_part));
447
448
0
                result_column->insert_data(str.data, str.size);
449
0
            }
450
3
        } else if (auto* decimal64_column = check_and_get_column<ColumnDecimal64>(*col_ptr)) {
451
3
            const UInt32 scale = decimal64_column->get_scale();
452
8
            for (size_t i = 0; i < input_rows_count; i++) {
453
5
                const Int64& frac_part = decimal64_column->get_fractional_part(i);
454
5
                const Int64& whole_part = decimal64_column->get_intergral_part(i);
455
456
5
                StringRef str =
457
5
                        MoneyFormat::do_money_format<Int64, MoneyFormat::MAX_FORMAT_LEN_DEC64()>(
458
5
                                context, scale, whole_part, frac_part);
459
460
5
                result_column->insert_data(str.data, str.size);
461
5
            }
462
3
        } else if (auto* decimal128_column = check_and_get_column<ColumnDecimal128V3>(*col_ptr)) {
463
0
            const UInt32 scale = decimal128_column->get_scale();
464
0
            for (size_t i = 0; i < input_rows_count; i++) {
465
0
                const Int128& frac_part = decimal128_column->get_fractional_part(i);
466
0
                const Int128& whole_part = decimal128_column->get_intergral_part(i);
467
468
0
                StringRef str =
469
0
                        MoneyFormat::do_money_format<Int128,
470
0
                                                     MoneyFormat::MAX_FORMAT_LEN_DEC128V3()>(
471
0
                                context, scale, whole_part, frac_part);
472
473
0
                result_column->insert_data(str.data, str.size);
474
0
            }
475
0
        } else {
476
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
477
0
                                   "Not supported input argument type {}", col_ptr->get_name());
478
0
        }
479
        // TODO: decimal256
480
        /* else if (auto* decimal256_column =
481
                           check_and_get_column<ColumnDecimal<Decimal256>>(*col_ptr)) {
482
            const UInt32 scale = decimal256_column->get_scale();
483
            const auto multiplier =
484
                    scale > 2 ? common::exp10_i32(scale - 2) : common::exp10_i32(2 - scale);
485
            for (size_t i = 0; i < input_rows_count; i++) {
486
                Decimal256 frac_part = decimal256_column->get_fractional_part(i);
487
                if (scale > 2) {
488
                    int delta = ((frac_part % multiplier) << 1) > multiplier;
489
                    frac_part = Decimal256(frac_part / multiplier + delta);
490
                } else if (scale < 2) {
491
                    frac_part = Decimal256(frac_part * multiplier);
492
                }
493
494
                StringRef str = MoneyFormat::do_money_format<int64_t, 26>(
495
                        context, decimal256_column->get_intergral_part(i), frac_part);
496
497
                result_column->insert_data(str.data, str.size);
498
            }
499
        }*/
500
5
    }
_ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE20EE7executeEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EEm
Line
Count
Source
425
2
                        size_t input_rows_count) {
426
2
        if (auto* decimalv2_column = check_and_get_column<ColumnDecimal128V2>(*col_ptr)) {
427
16
            for (size_t i = 0; i < input_rows_count; i++) {
428
14
                const auto& value = decimalv2_column->get_element(i);
429
                // unified_frac_value has 3 digits
430
14
                auto unified_frac_value = value.frac_value() / 1000000;
431
14
                StringRef str =
432
14
                        MoneyFormat::do_money_format<Int128,
433
14
                                                     MoneyFormat::MAX_FORMAT_LEN_DEC128V2()>(
434
14
                                context, 3, value.int_value(), unified_frac_value);
435
436
14
                result_column->insert_data(str.data, str.size);
437
14
            }
438
2
        } else if (auto* decimal32_column = check_and_get_column<ColumnDecimal32>(*col_ptr)) {
439
0
            const UInt32 scale = decimal32_column->get_scale();
440
0
            for (size_t i = 0; i < input_rows_count; i++) {
441
0
                const Int32& frac_part = decimal32_column->get_fractional_part(i);
442
0
                const Int32& whole_part = decimal32_column->get_intergral_part(i);
443
0
                StringRef str =
444
0
                        MoneyFormat::do_money_format<Int64, MoneyFormat::MAX_FORMAT_LEN_DEC32()>(
445
0
                                context, scale, static_cast<Int64>(whole_part),
446
0
                                static_cast<Int64>(frac_part));
447
448
0
                result_column->insert_data(str.data, str.size);
449
0
            }
450
0
        } else if (auto* decimal64_column = check_and_get_column<ColumnDecimal64>(*col_ptr)) {
451
0
            const UInt32 scale = decimal64_column->get_scale();
452
0
            for (size_t i = 0; i < input_rows_count; i++) {
453
0
                const Int64& frac_part = decimal64_column->get_fractional_part(i);
454
0
                const Int64& whole_part = decimal64_column->get_intergral_part(i);
455
456
0
                StringRef str =
457
0
                        MoneyFormat::do_money_format<Int64, MoneyFormat::MAX_FORMAT_LEN_DEC64()>(
458
0
                                context, scale, whole_part, frac_part);
459
460
0
                result_column->insert_data(str.data, str.size);
461
0
            }
462
0
        } else if (auto* decimal128_column = check_and_get_column<ColumnDecimal128V3>(*col_ptr)) {
463
0
            const UInt32 scale = decimal128_column->get_scale();
464
0
            for (size_t i = 0; i < input_rows_count; i++) {
465
0
                const Int128& frac_part = decimal128_column->get_fractional_part(i);
466
0
                const Int128& whole_part = decimal128_column->get_intergral_part(i);
467
468
0
                StringRef str =
469
0
                        MoneyFormat::do_money_format<Int128,
470
0
                                                     MoneyFormat::MAX_FORMAT_LEN_DEC128V3()>(
471
0
                                context, scale, whole_part, frac_part);
472
473
0
                result_column->insert_data(str.data, str.size);
474
0
            }
475
0
        } else {
476
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
477
0
                                   "Not supported input argument type {}", col_ptr->get_name());
478
0
        }
479
        // TODO: decimal256
480
        /* else if (auto* decimal256_column =
481
                           check_and_get_column<ColumnDecimal<Decimal256>>(*col_ptr)) {
482
            const UInt32 scale = decimal256_column->get_scale();
483
            const auto multiplier =
484
                    scale > 2 ? common::exp10_i32(scale - 2) : common::exp10_i32(2 - scale);
485
            for (size_t i = 0; i < input_rows_count; i++) {
486
                Decimal256 frac_part = decimal256_column->get_fractional_part(i);
487
                if (scale > 2) {
488
                    int delta = ((frac_part % multiplier) << 1) > multiplier;
489
                    frac_part = Decimal256(frac_part / multiplier + delta);
490
                } else if (scale < 2) {
491
                    frac_part = Decimal256(frac_part * multiplier);
492
                }
493
494
                StringRef str = MoneyFormat::do_money_format<int64_t, 26>(
495
                        context, decimal256_column->get_intergral_part(i), frac_part);
496
497
                result_column->insert_data(str.data, str.size);
498
            }
499
        }*/
500
2
    }
Unexecuted instantiation: _ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE28EE7executeEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EEm
_ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE29EE7executeEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EEm
Line
Count
Source
425
3
                        size_t input_rows_count) {
426
3
        if (auto* decimalv2_column = check_and_get_column<ColumnDecimal128V2>(*col_ptr)) {
427
0
            for (size_t i = 0; i < input_rows_count; i++) {
428
0
                const auto& value = decimalv2_column->get_element(i);
429
                // unified_frac_value has 3 digits
430
0
                auto unified_frac_value = value.frac_value() / 1000000;
431
0
                StringRef str =
432
0
                        MoneyFormat::do_money_format<Int128,
433
0
                                                     MoneyFormat::MAX_FORMAT_LEN_DEC128V2()>(
434
0
                                context, 3, value.int_value(), unified_frac_value);
435
436
0
                result_column->insert_data(str.data, str.size);
437
0
            }
438
3
        } else if (auto* decimal32_column = check_and_get_column<ColumnDecimal32>(*col_ptr)) {
439
0
            const UInt32 scale = decimal32_column->get_scale();
440
0
            for (size_t i = 0; i < input_rows_count; i++) {
441
0
                const Int32& frac_part = decimal32_column->get_fractional_part(i);
442
0
                const Int32& whole_part = decimal32_column->get_intergral_part(i);
443
0
                StringRef str =
444
0
                        MoneyFormat::do_money_format<Int64, MoneyFormat::MAX_FORMAT_LEN_DEC32()>(
445
0
                                context, scale, static_cast<Int64>(whole_part),
446
0
                                static_cast<Int64>(frac_part));
447
448
0
                result_column->insert_data(str.data, str.size);
449
0
            }
450
3
        } else if (auto* decimal64_column = check_and_get_column<ColumnDecimal64>(*col_ptr)) {
451
3
            const UInt32 scale = decimal64_column->get_scale();
452
8
            for (size_t i = 0; i < input_rows_count; i++) {
453
5
                const Int64& frac_part = decimal64_column->get_fractional_part(i);
454
5
                const Int64& whole_part = decimal64_column->get_intergral_part(i);
455
456
5
                StringRef str =
457
5
                        MoneyFormat::do_money_format<Int64, MoneyFormat::MAX_FORMAT_LEN_DEC64()>(
458
5
                                context, scale, whole_part, frac_part);
459
460
5
                result_column->insert_data(str.data, str.size);
461
5
            }
462
3
        } else if (auto* decimal128_column = check_and_get_column<ColumnDecimal128V3>(*col_ptr)) {
463
0
            const UInt32 scale = decimal128_column->get_scale();
464
0
            for (size_t i = 0; i < input_rows_count; i++) {
465
0
                const Int128& frac_part = decimal128_column->get_fractional_part(i);
466
0
                const Int128& whole_part = decimal128_column->get_intergral_part(i);
467
468
0
                StringRef str =
469
0
                        MoneyFormat::do_money_format<Int128,
470
0
                                                     MoneyFormat::MAX_FORMAT_LEN_DEC128V3()>(
471
0
                                context, scale, whole_part, frac_part);
472
473
0
                result_column->insert_data(str.data, str.size);
474
0
            }
475
0
        } else {
476
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
477
0
                                   "Not supported input argument type {}", col_ptr->get_name());
478
0
        }
479
        // TODO: decimal256
480
        /* else if (auto* decimal256_column =
481
                           check_and_get_column<ColumnDecimal<Decimal256>>(*col_ptr)) {
482
            const UInt32 scale = decimal256_column->get_scale();
483
            const auto multiplier =
484
                    scale > 2 ? common::exp10_i32(scale - 2) : common::exp10_i32(2 - scale);
485
            for (size_t i = 0; i < input_rows_count; i++) {
486
                Decimal256 frac_part = decimal256_column->get_fractional_part(i);
487
                if (scale > 2) {
488
                    int delta = ((frac_part % multiplier) << 1) > multiplier;
489
                    frac_part = Decimal256(frac_part / multiplier + delta);
490
                } else if (scale < 2) {
491
                    frac_part = Decimal256(frac_part * multiplier);
492
                }
493
494
                StringRef str = MoneyFormat::do_money_format<int64_t, 26>(
495
                        context, decimal256_column->get_intergral_part(i), frac_part);
496
497
                result_column->insert_data(str.data, str.size);
498
            }
499
        }*/
500
3
    }
Unexecuted instantiation: _ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE30EE7executeEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EEm
Unexecuted instantiation: _ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE35EE7executeEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EEm
501
};
502
503
template <typename Impl>
504
class FunctionStringFormatRound : public IFunction {
505
public:
506
    static constexpr auto name = "format_round";
507
31
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
_ZN5doris25FunctionStringFormatRoundINS_21FormatRoundDoubleImplEE6createEv
Line
Count
Source
507
3
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
_ZN5doris25FunctionStringFormatRoundINS_20FormatRoundInt64ImplEE6createEv
Line
Count
Source
507
3
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
_ZN5doris25FunctionStringFormatRoundINS_21FormatRoundInt128ImplEE6createEv
Line
Count
Source
507
3
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
_ZN5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE20EEEE6createEv
Line
Count
Source
507
3
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
_ZN5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE28EEEE6createEv
Line
Count
Source
507
2
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
_ZN5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE29EEEE6createEv
Line
Count
Source
507
13
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
_ZN5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE30EEEE6createEv
Line
Count
Source
507
2
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
_ZN5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE35EEEE6createEv
Line
Count
Source
507
2
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
508
8
    String get_name() const override { return name; }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundDoubleImplEE8get_nameB5cxx11Ev
Line
Count
Source
508
1
    String get_name() const override { return name; }
_ZNK5doris25FunctionStringFormatRoundINS_20FormatRoundInt64ImplEE8get_nameB5cxx11Ev
Line
Count
Source
508
1
    String get_name() const override { return name; }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundInt128ImplEE8get_nameB5cxx11Ev
Line
Count
Source
508
1
    String get_name() const override { return name; }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE20EEEE8get_nameB5cxx11Ev
Line
Count
Source
508
1
    String get_name() const override { return name; }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE28EEEE8get_nameB5cxx11Ev
Line
Count
Source
508
1
    String get_name() const override { return name; }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE29EEEE8get_nameB5cxx11Ev
Line
Count
Source
508
1
    String get_name() const override { return name; }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE30EEEE8get_nameB5cxx11Ev
Line
Count
Source
508
1
    String get_name() const override { return name; }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE35EEEE8get_nameB5cxx11Ev
Line
Count
Source
508
1
    String get_name() const override { return name; }
509
510
15
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
511
15
        if (arguments.size() != 2) {
512
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
513
0
                                   "Function {} requires exactly 2 argument", name);
514
0
        }
515
15
        return std::make_shared<DataTypeString>();
516
15
    }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundDoubleImplEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
510
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
511
1
        if (arguments.size() != 2) {
512
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
513
0
                                   "Function {} requires exactly 2 argument", name);
514
0
        }
515
1
        return std::make_shared<DataTypeString>();
516
1
    }
_ZNK5doris25FunctionStringFormatRoundINS_20FormatRoundInt64ImplEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
510
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
511
1
        if (arguments.size() != 2) {
512
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
513
0
                                   "Function {} requires exactly 2 argument", name);
514
0
        }
515
1
        return std::make_shared<DataTypeString>();
516
1
    }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundInt128ImplEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
510
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
511
1
        if (arguments.size() != 2) {
512
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
513
0
                                   "Function {} requires exactly 2 argument", name);
514
0
        }
515
1
        return std::make_shared<DataTypeString>();
516
1
    }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE20EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Line
Count
Source
510
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
511
1
        if (arguments.size() != 2) {
512
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
513
0
                                   "Function {} requires exactly 2 argument", name);
514
0
        }
515
1
        return std::make_shared<DataTypeString>();
516
1
    }
Unexecuted instantiation: _ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE28EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE29EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Line
Count
Source
510
11
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
511
11
        if (arguments.size() != 2) {
512
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
513
0
                                   "Function {} requires exactly 2 argument", name);
514
0
        }
515
11
        return std::make_shared<DataTypeString>();
516
11
    }
Unexecuted instantiation: _ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE30EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE35EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
517
8
    DataTypes get_variadic_argument_types_impl() const override {
518
8
        return Impl::get_variadic_argument_types();
519
8
    }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundDoubleImplEE32get_variadic_argument_types_implEv
Line
Count
Source
517
1
    DataTypes get_variadic_argument_types_impl() const override {
518
1
        return Impl::get_variadic_argument_types();
519
1
    }
_ZNK5doris25FunctionStringFormatRoundINS_20FormatRoundInt64ImplEE32get_variadic_argument_types_implEv
Line
Count
Source
517
1
    DataTypes get_variadic_argument_types_impl() const override {
518
1
        return Impl::get_variadic_argument_types();
519
1
    }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundInt128ImplEE32get_variadic_argument_types_implEv
Line
Count
Source
517
1
    DataTypes get_variadic_argument_types_impl() const override {
518
1
        return Impl::get_variadic_argument_types();
519
1
    }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE20EEEE32get_variadic_argument_types_implEv
Line
Count
Source
517
1
    DataTypes get_variadic_argument_types_impl() const override {
518
1
        return Impl::get_variadic_argument_types();
519
1
    }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE28EEEE32get_variadic_argument_types_implEv
Line
Count
Source
517
1
    DataTypes get_variadic_argument_types_impl() const override {
518
1
        return Impl::get_variadic_argument_types();
519
1
    }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE29EEEE32get_variadic_argument_types_implEv
Line
Count
Source
517
1
    DataTypes get_variadic_argument_types_impl() const override {
518
1
        return Impl::get_variadic_argument_types();
519
1
    }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE30EEEE32get_variadic_argument_types_implEv
Line
Count
Source
517
1
    DataTypes get_variadic_argument_types_impl() const override {
518
1
        return Impl::get_variadic_argument_types();
519
1
    }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE35EEEE32get_variadic_argument_types_implEv
Line
Count
Source
517
1
    DataTypes get_variadic_argument_types_impl() const override {
518
1
        return Impl::get_variadic_argument_types();
519
1
    }
520
15
    size_t get_number_of_arguments() const override { return 2; }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundDoubleImplEE23get_number_of_argumentsEv
Line
Count
Source
520
1
    size_t get_number_of_arguments() const override { return 2; }
_ZNK5doris25FunctionStringFormatRoundINS_20FormatRoundInt64ImplEE23get_number_of_argumentsEv
Line
Count
Source
520
1
    size_t get_number_of_arguments() const override { return 2; }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundInt128ImplEE23get_number_of_argumentsEv
Line
Count
Source
520
1
    size_t get_number_of_arguments() const override { return 2; }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE20EEEE23get_number_of_argumentsEv
Line
Count
Source
520
1
    size_t get_number_of_arguments() const override { return 2; }
Unexecuted instantiation: _ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE28EEEE23get_number_of_argumentsEv
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE29EEEE23get_number_of_argumentsEv
Line
Count
Source
520
11
    size_t get_number_of_arguments() const override { return 2; }
Unexecuted instantiation: _ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE30EEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE35EEEE23get_number_of_argumentsEv
521
522
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
523
12
                        uint32_t result, size_t input_rows_count) const override {
524
12
        auto res_column = ColumnString::create();
525
12
        ColumnPtr argument_column =
526
12
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
527
12
        ColumnPtr argument_column_2;
528
12
        bool is_const;
529
12
        std::tie(argument_column_2, is_const) =
530
12
                unpack_if_const(block.get_by_position(arguments[1]).column);
531
12
        auto* result_column = assert_cast<ColumnString*>(res_column.get());
532
533
12
        if (is_const) {
534
2
            RETURN_IF_ERROR(Impl::template execute<true>(context, result_column, argument_column,
535
2
                                                         argument_column_2, input_rows_count));
536
10
        } else {
537
10
            RETURN_IF_ERROR(Impl::template execute<false>(context, result_column, argument_column,
538
10
                                                          argument_column_2, input_rows_count));
539
10
        }
540
541
12
        block.replace_by_position(result, std::move(res_column));
542
12
        return Status::OK();
543
12
    }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundDoubleImplEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
523
1
                        uint32_t result, size_t input_rows_count) const override {
524
1
        auto res_column = ColumnString::create();
525
1
        ColumnPtr argument_column =
526
1
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
527
1
        ColumnPtr argument_column_2;
528
1
        bool is_const;
529
1
        std::tie(argument_column_2, is_const) =
530
1
                unpack_if_const(block.get_by_position(arguments[1]).column);
531
1
        auto* result_column = assert_cast<ColumnString*>(res_column.get());
532
533
1
        if (is_const) {
534
0
            RETURN_IF_ERROR(Impl::template execute<true>(context, result_column, argument_column,
535
0
                                                         argument_column_2, input_rows_count));
536
1
        } else {
537
1
            RETURN_IF_ERROR(Impl::template execute<false>(context, result_column, argument_column,
538
1
                                                          argument_column_2, input_rows_count));
539
1
        }
540
541
1
        block.replace_by_position(result, std::move(res_column));
542
1
        return Status::OK();
543
1
    }
_ZNK5doris25FunctionStringFormatRoundINS_20FormatRoundInt64ImplEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
523
1
                        uint32_t result, size_t input_rows_count) const override {
524
1
        auto res_column = ColumnString::create();
525
1
        ColumnPtr argument_column =
526
1
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
527
1
        ColumnPtr argument_column_2;
528
1
        bool is_const;
529
1
        std::tie(argument_column_2, is_const) =
530
1
                unpack_if_const(block.get_by_position(arguments[1]).column);
531
1
        auto* result_column = assert_cast<ColumnString*>(res_column.get());
532
533
1
        if (is_const) {
534
0
            RETURN_IF_ERROR(Impl::template execute<true>(context, result_column, argument_column,
535
0
                                                         argument_column_2, input_rows_count));
536
1
        } else {
537
1
            RETURN_IF_ERROR(Impl::template execute<false>(context, result_column, argument_column,
538
1
                                                          argument_column_2, input_rows_count));
539
1
        }
540
541
1
        block.replace_by_position(result, std::move(res_column));
542
1
        return Status::OK();
543
1
    }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundInt128ImplEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
523
1
                        uint32_t result, size_t input_rows_count) const override {
524
1
        auto res_column = ColumnString::create();
525
1
        ColumnPtr argument_column =
526
1
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
527
1
        ColumnPtr argument_column_2;
528
1
        bool is_const;
529
1
        std::tie(argument_column_2, is_const) =
530
1
                unpack_if_const(block.get_by_position(arguments[1]).column);
531
1
        auto* result_column = assert_cast<ColumnString*>(res_column.get());
532
533
1
        if (is_const) {
534
0
            RETURN_IF_ERROR(Impl::template execute<true>(context, result_column, argument_column,
535
0
                                                         argument_column_2, input_rows_count));
536
1
        } else {
537
1
            RETURN_IF_ERROR(Impl::template execute<false>(context, result_column, argument_column,
538
1
                                                          argument_column_2, input_rows_count));
539
1
        }
540
541
1
        block.replace_by_position(result, std::move(res_column));
542
1
        return Status::OK();
543
1
    }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE20EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
523
1
                        uint32_t result, size_t input_rows_count) const override {
524
1
        auto res_column = ColumnString::create();
525
1
        ColumnPtr argument_column =
526
1
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
527
1
        ColumnPtr argument_column_2;
528
1
        bool is_const;
529
1
        std::tie(argument_column_2, is_const) =
530
1
                unpack_if_const(block.get_by_position(arguments[1]).column);
531
1
        auto* result_column = assert_cast<ColumnString*>(res_column.get());
532
533
1
        if (is_const) {
534
0
            RETURN_IF_ERROR(Impl::template execute<true>(context, result_column, argument_column,
535
0
                                                         argument_column_2, input_rows_count));
536
1
        } else {
537
1
            RETURN_IF_ERROR(Impl::template execute<false>(context, result_column, argument_column,
538
1
                                                          argument_column_2, input_rows_count));
539
1
        }
540
541
1
        block.replace_by_position(result, std::move(res_column));
542
1
        return Status::OK();
543
1
    }
Unexecuted instantiation: _ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE28EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE29EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
523
8
                        uint32_t result, size_t input_rows_count) const override {
524
8
        auto res_column = ColumnString::create();
525
8
        ColumnPtr argument_column =
526
8
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
527
8
        ColumnPtr argument_column_2;
528
8
        bool is_const;
529
8
        std::tie(argument_column_2, is_const) =
530
8
                unpack_if_const(block.get_by_position(arguments[1]).column);
531
8
        auto* result_column = assert_cast<ColumnString*>(res_column.get());
532
533
8
        if (is_const) {
534
2
            RETURN_IF_ERROR(Impl::template execute<true>(context, result_column, argument_column,
535
2
                                                         argument_column_2, input_rows_count));
536
6
        } else {
537
6
            RETURN_IF_ERROR(Impl::template execute<false>(context, result_column, argument_column,
538
6
                                                          argument_column_2, input_rows_count));
539
6
        }
540
541
8
        block.replace_by_position(result, std::move(res_column));
542
8
        return Status::OK();
543
8
    }
Unexecuted instantiation: _ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE30EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE35EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
544
};
545
546
struct FormatRoundDoubleImpl {
547
1
    static DataTypes get_variadic_argument_types() {
548
1
        return {std::make_shared<DataTypeFloat64>(), std::make_shared<DataTypeInt32>()};
549
1
    }
550
551
4
    static std::string add_thousands_separator(const std::string& formatted_num) {
552
        //  Find the position of the decimal point
553
4
        size_t dot_pos = formatted_num.find('.');
554
4
        if (dot_pos == std::string::npos) {
555
0
            dot_pos = formatted_num.size();
556
0
        }
557
558
        // Handle the integer part
559
4
        int start = (formatted_num[0] == '-') ? 1 : 0;
560
4
        int digit_count = dot_pos - start;
561
562
        // There is no need to add commas.
563
4
        if (digit_count <= 3) {
564
2
            return formatted_num;
565
2
        }
566
567
2
        std::string result;
568
569
2
        if (start == 1) result += '-';
570
571
        // Add the integer part (with comma)
572
2
        int first_group = digit_count % 3;
573
2
        if (first_group == 0) first_group = 3;
574
2
        result.append(formatted_num, start, first_group);
575
576
6
        for (size_t i = start + first_group; i < dot_pos; i += 3) {
577
4
            result += ',';
578
4
            result.append(formatted_num, i, 3);
579
4
        }
580
581
        // Add the decimal part (keep as it is)
582
2
        if (dot_pos != formatted_num.size()) {
583
2
            result.append(formatted_num, dot_pos);
584
2
        }
585
586
2
        return result;
587
4
    }
588
589
    template <bool is_const>
590
    static Status execute(FunctionContext* context, ColumnString* result_column,
591
                          const ColumnPtr col_ptr, ColumnPtr decimal_places_col_ptr,
592
1
                          size_t input_rows_count) {
593
1
        const auto& arg_column_data_2 =
594
1
                assert_cast<const ColumnInt32*>(decimal_places_col_ptr.get())->get_data();
595
1
        const auto* data_column = assert_cast<const ColumnFloat64*>(col_ptr.get());
596
        // when scale is above 38, we will go here
597
5
        for (size_t i = 0; i < input_rows_count; i++) {
598
4
            int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
599
4
            if (decimal_places < 0 || decimal_places > 1024) {
600
0
                return Status::InvalidArgument(
601
0
                        "The second argument is {}, it should be in range [0, 1024].",
602
0
                        decimal_places);
603
0
            }
604
            // round to `decimal_places` decimal places
605
4
            double value = MathFunctions::my_double_round(data_column->get_element(i),
606
4
                                                          decimal_places, false, false);
607
4
            std::string formatted_value = fmt::format("{:.{}f}", value, decimal_places);
608
4
            if (std::isfinite(value)) {
609
4
                result_column->insert_value(add_thousands_separator(formatted_value));
610
4
            } else {
611
                // if value is not finite, we just insert the original formatted value
612
                // e.g. "inf", "-inf", "nan"
613
0
                result_column->insert_value(formatted_value);
614
0
            }
615
4
        }
616
1
        return Status::OK();
617
1
    }
Unexecuted instantiation: _ZN5doris21FormatRoundDoubleImpl7executeILb1EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EESC_m
_ZN5doris21FormatRoundDoubleImpl7executeILb0EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EESC_m
Line
Count
Source
592
1
                          size_t input_rows_count) {
593
1
        const auto& arg_column_data_2 =
594
1
                assert_cast<const ColumnInt32*>(decimal_places_col_ptr.get())->get_data();
595
1
        const auto* data_column = assert_cast<const ColumnFloat64*>(col_ptr.get());
596
        // when scale is above 38, we will go here
597
5
        for (size_t i = 0; i < input_rows_count; i++) {
598
4
            int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
599
4
            if (decimal_places < 0 || decimal_places > 1024) {
600
0
                return Status::InvalidArgument(
601
0
                        "The second argument is {}, it should be in range [0, 1024].",
602
0
                        decimal_places);
603
0
            }
604
            // round to `decimal_places` decimal places
605
4
            double value = MathFunctions::my_double_round(data_column->get_element(i),
606
4
                                                          decimal_places, false, false);
607
4
            std::string formatted_value = fmt::format("{:.{}f}", value, decimal_places);
608
4
            if (std::isfinite(value)) {
609
4
                result_column->insert_value(add_thousands_separator(formatted_value));
610
4
            } else {
611
                // if value is not finite, we just insert the original formatted value
612
                // e.g. "inf", "-inf", "nan"
613
0
                result_column->insert_value(formatted_value);
614
0
            }
615
4
        }
616
1
        return Status::OK();
617
1
    }
618
};
619
620
struct FormatRoundInt64Impl {
621
1
    static DataTypes get_variadic_argument_types() {
622
1
        return {std::make_shared<DataTypeInt64>(), std::make_shared<DataTypeInt32>()};
623
1
    }
624
625
    template <bool is_const>
626
    static Status execute(FunctionContext* context, ColumnString* result_column,
627
                          const ColumnPtr col_ptr, ColumnPtr decimal_places_col_ptr,
628
1
                          size_t input_rows_count) {
629
1
        const auto* data_column = assert_cast<const ColumnInt64*>(col_ptr.get());
630
1
        const auto& arg_column_data_2 =
631
1
                assert_cast<const ColumnInt32*>(decimal_places_col_ptr.get())->get_data();
632
9
        for (size_t i = 0; i < input_rows_count; i++) {
633
8
            int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
634
8
            if (decimal_places < 0 || decimal_places > 1024) {
635
0
                return Status::InvalidArgument(
636
0
                        "The second argument is {}, it should be in range [0, 1024].",
637
0
                        decimal_places);
638
0
            }
639
8
            Int64 value = data_column->get_element(i);
640
8
            StringRef str =
641
8
                    FormatRound::do_format_round<Int64, FormatRound::MAX_FORMAT_LEN_INT64()>(
642
8
                            context, 0, value, 0, decimal_places);
643
8
            result_column->insert_data(str.data, str.size);
644
8
        }
645
1
        return Status::OK();
646
1
    }
Unexecuted instantiation: _ZN5doris20FormatRoundInt64Impl7executeILb1EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EESC_m
_ZN5doris20FormatRoundInt64Impl7executeILb0EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EESC_m
Line
Count
Source
628
1
                          size_t input_rows_count) {
629
1
        const auto* data_column = assert_cast<const ColumnInt64*>(col_ptr.get());
630
1
        const auto& arg_column_data_2 =
631
1
                assert_cast<const ColumnInt32*>(decimal_places_col_ptr.get())->get_data();
632
9
        for (size_t i = 0; i < input_rows_count; i++) {
633
8
            int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
634
8
            if (decimal_places < 0 || decimal_places > 1024) {
635
0
                return Status::InvalidArgument(
636
0
                        "The second argument is {}, it should be in range [0, 1024].",
637
0
                        decimal_places);
638
0
            }
639
8
            Int64 value = data_column->get_element(i);
640
8
            StringRef str =
641
8
                    FormatRound::do_format_round<Int64, FormatRound::MAX_FORMAT_LEN_INT64()>(
642
8
                            context, 0, value, 0, decimal_places);
643
8
            result_column->insert_data(str.data, str.size);
644
8
        }
645
1
        return Status::OK();
646
1
    }
647
};
648
649
struct FormatRoundInt128Impl {
650
1
    static DataTypes get_variadic_argument_types() {
651
1
        return {std::make_shared<DataTypeInt128>(), std::make_shared<DataTypeInt32>()};
652
1
    }
653
654
    template <bool is_const>
655
    static Status execute(FunctionContext* context, ColumnString* result_column,
656
                          const ColumnPtr col_ptr, ColumnPtr decimal_places_col_ptr,
657
1
                          size_t input_rows_count) {
658
1
        const auto* data_column = assert_cast<const ColumnInt128*>(col_ptr.get());
659
1
        const auto& arg_column_data_2 =
660
1
                assert_cast<const ColumnInt32*>(decimal_places_col_ptr.get())->get_data();
661
        // SELECT money_format(170141183460469231731687303715884105728/*INT128_MAX + 1*/) will
662
        // get "170,141,183,460,469,231,731,687,303,715,884,105,727.00" in doris,
663
        // see https://github.com/apache/doris/blob/788abf2d7c3c7c2d57487a9608e889e7662d5fb2/be/src/vec/data_types/data_type_number_base.cpp#L124
664
10
        for (size_t i = 0; i < input_rows_count; i++) {
665
9
            int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
666
9
            if (decimal_places < 0 || decimal_places > 1024) {
667
0
                return Status::InvalidArgument(
668
0
                        "The second argument is {}, it should be in range [0, 1024].",
669
0
                        decimal_places);
670
0
            }
671
9
            Int128 value = data_column->get_element(i);
672
9
            StringRef str =
673
9
                    FormatRound::do_format_round<Int128, FormatRound::MAX_FORMAT_LEN_INT128()>(
674
9
                            context, 0, value, 0, decimal_places);
675
9
            result_column->insert_data(str.data, str.size);
676
9
        }
677
1
        return Status::OK();
678
1
    }
Unexecuted instantiation: _ZN5doris21FormatRoundInt128Impl7executeILb1EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EESC_m
_ZN5doris21FormatRoundInt128Impl7executeILb0EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EESC_m
Line
Count
Source
657
1
                          size_t input_rows_count) {
658
1
        const auto* data_column = assert_cast<const ColumnInt128*>(col_ptr.get());
659
1
        const auto& arg_column_data_2 =
660
1
                assert_cast<const ColumnInt32*>(decimal_places_col_ptr.get())->get_data();
661
        // SELECT money_format(170141183460469231731687303715884105728/*INT128_MAX + 1*/) will
662
        // get "170,141,183,460,469,231,731,687,303,715,884,105,727.00" in doris,
663
        // see https://github.com/apache/doris/blob/788abf2d7c3c7c2d57487a9608e889e7662d5fb2/be/src/vec/data_types/data_type_number_base.cpp#L124
664
10
        for (size_t i = 0; i < input_rows_count; i++) {
665
9
            int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
666
9
            if (decimal_places < 0 || decimal_places > 1024) {
667
0
                return Status::InvalidArgument(
668
0
                        "The second argument is {}, it should be in range [0, 1024].",
669
0
                        decimal_places);
670
0
            }
671
9
            Int128 value = data_column->get_element(i);
672
9
            StringRef str =
673
9
                    FormatRound::do_format_round<Int128, FormatRound::MAX_FORMAT_LEN_INT128()>(
674
9
                            context, 0, value, 0, decimal_places);
675
9
            result_column->insert_data(str.data, str.size);
676
9
        }
677
1
        return Status::OK();
678
1
    }
679
};
680
681
template <PrimitiveType Type>
682
struct FormatRoundDecimalImpl {
683
5
    static DataTypes get_variadic_argument_types() {
684
5
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>(),
685
5
                std::make_shared<DataTypeInt32>()};
686
5
    }
_ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE20EE27get_variadic_argument_typesEv
Line
Count
Source
683
1
    static DataTypes get_variadic_argument_types() {
684
1
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>(),
685
1
                std::make_shared<DataTypeInt32>()};
686
1
    }
_ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE28EE27get_variadic_argument_typesEv
Line
Count
Source
683
1
    static DataTypes get_variadic_argument_types() {
684
1
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>(),
685
1
                std::make_shared<DataTypeInt32>()};
686
1
    }
_ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE29EE27get_variadic_argument_typesEv
Line
Count
Source
683
1
    static DataTypes get_variadic_argument_types() {
684
1
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>(),
685
1
                std::make_shared<DataTypeInt32>()};
686
1
    }
_ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE30EE27get_variadic_argument_typesEv
Line
Count
Source
683
1
    static DataTypes get_variadic_argument_types() {
684
1
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>(),
685
1
                std::make_shared<DataTypeInt32>()};
686
1
    }
_ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE35EE27get_variadic_argument_typesEv
Line
Count
Source
683
1
    static DataTypes get_variadic_argument_types() {
684
1
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>(),
685
1
                std::make_shared<DataTypeInt32>()};
686
1
    }
687
688
    template <bool is_const>
689
    static Status execute(FunctionContext* context, ColumnString* result_column, ColumnPtr col_ptr,
690
9
                          ColumnPtr decimal_places_col_ptr, size_t input_rows_count) {
691
9
        const auto& arg_column_data_2 =
692
9
                assert_cast<const ColumnInt32*>(decimal_places_col_ptr.get())->get_data();
693
9
        if (const auto* decimalv2_column = check_and_get_column<ColumnDecimal128V2>(*col_ptr)) {
694
4
            for (size_t i = 0; i < input_rows_count; i++) {
695
3
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
696
3
                if (decimal_places < 0 || decimal_places > 1024) {
697
0
                    return Status::InvalidArgument(
698
0
                            "The second argument is {}, it should be in range [0, 1024].",
699
0
                            decimal_places);
700
0
                }
701
3
                const auto& value = decimalv2_column->get_element(i);
702
                // unified_frac_value has 3 digits
703
3
                auto unified_frac_value = value.frac_value() / 1000000;
704
3
                StringRef str =
705
3
                        FormatRound::do_format_round<Int128,
706
3
                                                     FormatRound::MAX_FORMAT_LEN_DEC128V2()>(
707
3
                                context, 3, value.int_value(), unified_frac_value, decimal_places);
708
709
3
                result_column->insert_data(str.data, str.size);
710
3
            }
711
8
        } else if (const auto* decimal32_column = check_and_get_column<ColumnDecimal32>(*col_ptr)) {
712
0
            const UInt32 scale = decimal32_column->get_scale();
713
0
            for (size_t i = 0; i < input_rows_count; i++) {
714
0
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
715
0
                if (decimal_places < 0 || decimal_places > 1024) {
716
0
                    return Status::InvalidArgument(
717
0
                            "The second argument is {}, it should be in range [0, 1024].",
718
0
                            decimal_places);
719
0
                }
720
0
                const Int32& frac_part = decimal32_column->get_fractional_part(i);
721
0
                const Int32& whole_part = decimal32_column->get_intergral_part(i);
722
0
                StringRef str =
723
0
                        FormatRound::do_format_round<Int64, FormatRound::MAX_FORMAT_LEN_DEC32()>(
724
0
                                context, scale, static_cast<Int64>(whole_part),
725
0
                                static_cast<Int64>(frac_part), decimal_places);
726
727
0
                result_column->insert_data(str.data, str.size);
728
0
            }
729
8
        } else if (const auto* decimal64_column = check_and_get_column<ColumnDecimal64>(*col_ptr)) {
730
8
            const UInt32 scale = decimal64_column->get_scale();
731
19
            for (size_t i = 0; i < input_rows_count; i++) {
732
11
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
733
11
                if (decimal_places < 0 || decimal_places > 1024) {
734
0
                    return Status::InvalidArgument(
735
0
                            "The second argument is {}, it should be in range [0, 1024].",
736
0
                            decimal_places);
737
0
                }
738
11
                const Int64& frac_part = decimal64_column->get_fractional_part(i);
739
11
                const Int64& whole_part = decimal64_column->get_intergral_part(i);
740
741
11
                StringRef str =
742
11
                        FormatRound::do_format_round<Int64, FormatRound::MAX_FORMAT_LEN_DEC64()>(
743
11
                                context, scale, whole_part, frac_part, decimal_places);
744
745
11
                result_column->insert_data(str.data, str.size);
746
11
            }
747
8
        } else if (const auto* decimal128_column =
748
0
                           check_and_get_column<ColumnDecimal128V3>(*col_ptr)) {
749
0
            const UInt32 scale = decimal128_column->get_scale();
750
0
            for (size_t i = 0; i < input_rows_count; i++) {
751
0
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
752
0
                if (decimal_places < 0 || decimal_places > 1024) {
753
0
                    return Status::InvalidArgument(
754
0
                            "The second argument is {}, it should be in range [0, 1024].",
755
0
                            decimal_places);
756
0
                }
757
0
                const Int128& frac_part = decimal128_column->get_fractional_part(i);
758
0
                const Int128& whole_part = decimal128_column->get_intergral_part(i);
759
760
0
                StringRef str =
761
0
                        FormatRound::do_format_round<Int128,
762
0
                                                     FormatRound::MAX_FORMAT_LEN_DEC128V3()>(
763
0
                                context, scale, whole_part, frac_part, decimal_places);
764
765
0
                result_column->insert_data(str.data, str.size);
766
0
            }
767
0
        } else {
768
0
            return Status::InternalError("Not supported input argument type {}",
769
0
                                         col_ptr->get_name());
770
0
        }
771
9
        return Status::OK();
772
9
    }
Unexecuted instantiation: _ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE20EE7executeILb1EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrISB_EESE_m
_ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE20EE7executeILb0EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrISB_EESE_m
Line
Count
Source
690
1
                          ColumnPtr decimal_places_col_ptr, size_t input_rows_count) {
691
1
        const auto& arg_column_data_2 =
692
1
                assert_cast<const ColumnInt32*>(decimal_places_col_ptr.get())->get_data();
693
1
        if (const auto* decimalv2_column = check_and_get_column<ColumnDecimal128V2>(*col_ptr)) {
694
4
            for (size_t i = 0; i < input_rows_count; i++) {
695
3
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
696
3
                if (decimal_places < 0 || decimal_places > 1024) {
697
0
                    return Status::InvalidArgument(
698
0
                            "The second argument is {}, it should be in range [0, 1024].",
699
0
                            decimal_places);
700
0
                }
701
3
                const auto& value = decimalv2_column->get_element(i);
702
                // unified_frac_value has 3 digits
703
3
                auto unified_frac_value = value.frac_value() / 1000000;
704
3
                StringRef str =
705
3
                        FormatRound::do_format_round<Int128,
706
3
                                                     FormatRound::MAX_FORMAT_LEN_DEC128V2()>(
707
3
                                context, 3, value.int_value(), unified_frac_value, decimal_places);
708
709
3
                result_column->insert_data(str.data, str.size);
710
3
            }
711
1
        } else if (const auto* decimal32_column = check_and_get_column<ColumnDecimal32>(*col_ptr)) {
712
0
            const UInt32 scale = decimal32_column->get_scale();
713
0
            for (size_t i = 0; i < input_rows_count; i++) {
714
0
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
715
0
                if (decimal_places < 0 || decimal_places > 1024) {
716
0
                    return Status::InvalidArgument(
717
0
                            "The second argument is {}, it should be in range [0, 1024].",
718
0
                            decimal_places);
719
0
                }
720
0
                const Int32& frac_part = decimal32_column->get_fractional_part(i);
721
0
                const Int32& whole_part = decimal32_column->get_intergral_part(i);
722
0
                StringRef str =
723
0
                        FormatRound::do_format_round<Int64, FormatRound::MAX_FORMAT_LEN_DEC32()>(
724
0
                                context, scale, static_cast<Int64>(whole_part),
725
0
                                static_cast<Int64>(frac_part), decimal_places);
726
727
0
                result_column->insert_data(str.data, str.size);
728
0
            }
729
0
        } else if (const auto* decimal64_column = check_and_get_column<ColumnDecimal64>(*col_ptr)) {
730
0
            const UInt32 scale = decimal64_column->get_scale();
731
0
            for (size_t i = 0; i < input_rows_count; i++) {
732
0
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
733
0
                if (decimal_places < 0 || decimal_places > 1024) {
734
0
                    return Status::InvalidArgument(
735
0
                            "The second argument is {}, it should be in range [0, 1024].",
736
0
                            decimal_places);
737
0
                }
738
0
                const Int64& frac_part = decimal64_column->get_fractional_part(i);
739
0
                const Int64& whole_part = decimal64_column->get_intergral_part(i);
740
741
0
                StringRef str =
742
0
                        FormatRound::do_format_round<Int64, FormatRound::MAX_FORMAT_LEN_DEC64()>(
743
0
                                context, scale, whole_part, frac_part, decimal_places);
744
745
0
                result_column->insert_data(str.data, str.size);
746
0
            }
747
0
        } else if (const auto* decimal128_column =
748
0
                           check_and_get_column<ColumnDecimal128V3>(*col_ptr)) {
749
0
            const UInt32 scale = decimal128_column->get_scale();
750
0
            for (size_t i = 0; i < input_rows_count; i++) {
751
0
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
752
0
                if (decimal_places < 0 || decimal_places > 1024) {
753
0
                    return Status::InvalidArgument(
754
0
                            "The second argument is {}, it should be in range [0, 1024].",
755
0
                            decimal_places);
756
0
                }
757
0
                const Int128& frac_part = decimal128_column->get_fractional_part(i);
758
0
                const Int128& whole_part = decimal128_column->get_intergral_part(i);
759
760
0
                StringRef str =
761
0
                        FormatRound::do_format_round<Int128,
762
0
                                                     FormatRound::MAX_FORMAT_LEN_DEC128V3()>(
763
0
                                context, scale, whole_part, frac_part, decimal_places);
764
765
0
                result_column->insert_data(str.data, str.size);
766
0
            }
767
0
        } else {
768
0
            return Status::InternalError("Not supported input argument type {}",
769
0
                                         col_ptr->get_name());
770
0
        }
771
1
        return Status::OK();
772
1
    }
Unexecuted instantiation: _ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE28EE7executeILb1EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrISB_EESE_m
Unexecuted instantiation: _ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE28EE7executeILb0EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrISB_EESE_m
_ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE29EE7executeILb1EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrISB_EESE_m
Line
Count
Source
690
2
                          ColumnPtr decimal_places_col_ptr, size_t input_rows_count) {
691
2
        const auto& arg_column_data_2 =
692
2
                assert_cast<const ColumnInt32*>(decimal_places_col_ptr.get())->get_data();
693
2
        if (const auto* decimalv2_column = check_and_get_column<ColumnDecimal128V2>(*col_ptr)) {
694
0
            for (size_t i = 0; i < input_rows_count; i++) {
695
0
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
696
0
                if (decimal_places < 0 || decimal_places > 1024) {
697
0
                    return Status::InvalidArgument(
698
0
                            "The second argument is {}, it should be in range [0, 1024].",
699
0
                            decimal_places);
700
0
                }
701
0
                const auto& value = decimalv2_column->get_element(i);
702
                // unified_frac_value has 3 digits
703
0
                auto unified_frac_value = value.frac_value() / 1000000;
704
0
                StringRef str =
705
0
                        FormatRound::do_format_round<Int128,
706
0
                                                     FormatRound::MAX_FORMAT_LEN_DEC128V2()>(
707
0
                                context, 3, value.int_value(), unified_frac_value, decimal_places);
708
709
0
                result_column->insert_data(str.data, str.size);
710
0
            }
711
2
        } else if (const auto* decimal32_column = check_and_get_column<ColumnDecimal32>(*col_ptr)) {
712
0
            const UInt32 scale = decimal32_column->get_scale();
713
0
            for (size_t i = 0; i < input_rows_count; i++) {
714
0
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
715
0
                if (decimal_places < 0 || decimal_places > 1024) {
716
0
                    return Status::InvalidArgument(
717
0
                            "The second argument is {}, it should be in range [0, 1024].",
718
0
                            decimal_places);
719
0
                }
720
0
                const Int32& frac_part = decimal32_column->get_fractional_part(i);
721
0
                const Int32& whole_part = decimal32_column->get_intergral_part(i);
722
0
                StringRef str =
723
0
                        FormatRound::do_format_round<Int64, FormatRound::MAX_FORMAT_LEN_DEC32()>(
724
0
                                context, scale, static_cast<Int64>(whole_part),
725
0
                                static_cast<Int64>(frac_part), decimal_places);
726
727
0
                result_column->insert_data(str.data, str.size);
728
0
            }
729
2
        } else if (const auto* decimal64_column = check_and_get_column<ColumnDecimal64>(*col_ptr)) {
730
2
            const UInt32 scale = decimal64_column->get_scale();
731
4
            for (size_t i = 0; i < input_rows_count; i++) {
732
2
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
733
2
                if (decimal_places < 0 || decimal_places > 1024) {
734
0
                    return Status::InvalidArgument(
735
0
                            "The second argument is {}, it should be in range [0, 1024].",
736
0
                            decimal_places);
737
0
                }
738
2
                const Int64& frac_part = decimal64_column->get_fractional_part(i);
739
2
                const Int64& whole_part = decimal64_column->get_intergral_part(i);
740
741
2
                StringRef str =
742
2
                        FormatRound::do_format_round<Int64, FormatRound::MAX_FORMAT_LEN_DEC64()>(
743
2
                                context, scale, whole_part, frac_part, decimal_places);
744
745
2
                result_column->insert_data(str.data, str.size);
746
2
            }
747
2
        } else if (const auto* decimal128_column =
748
0
                           check_and_get_column<ColumnDecimal128V3>(*col_ptr)) {
749
0
            const UInt32 scale = decimal128_column->get_scale();
750
0
            for (size_t i = 0; i < input_rows_count; i++) {
751
0
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
752
0
                if (decimal_places < 0 || decimal_places > 1024) {
753
0
                    return Status::InvalidArgument(
754
0
                            "The second argument is {}, it should be in range [0, 1024].",
755
0
                            decimal_places);
756
0
                }
757
0
                const Int128& frac_part = decimal128_column->get_fractional_part(i);
758
0
                const Int128& whole_part = decimal128_column->get_intergral_part(i);
759
760
0
                StringRef str =
761
0
                        FormatRound::do_format_round<Int128,
762
0
                                                     FormatRound::MAX_FORMAT_LEN_DEC128V3()>(
763
0
                                context, scale, whole_part, frac_part, decimal_places);
764
765
0
                result_column->insert_data(str.data, str.size);
766
0
            }
767
0
        } else {
768
0
            return Status::InternalError("Not supported input argument type {}",
769
0
                                         col_ptr->get_name());
770
0
        }
771
2
        return Status::OK();
772
2
    }
_ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE29EE7executeILb0EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrISB_EESE_m
Line
Count
Source
690
6
                          ColumnPtr decimal_places_col_ptr, size_t input_rows_count) {
691
6
        const auto& arg_column_data_2 =
692
6
                assert_cast<const ColumnInt32*>(decimal_places_col_ptr.get())->get_data();
693
6
        if (const auto* decimalv2_column = check_and_get_column<ColumnDecimal128V2>(*col_ptr)) {
694
0
            for (size_t i = 0; i < input_rows_count; i++) {
695
0
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
696
0
                if (decimal_places < 0 || decimal_places > 1024) {
697
0
                    return Status::InvalidArgument(
698
0
                            "The second argument is {}, it should be in range [0, 1024].",
699
0
                            decimal_places);
700
0
                }
701
0
                const auto& value = decimalv2_column->get_element(i);
702
                // unified_frac_value has 3 digits
703
0
                auto unified_frac_value = value.frac_value() / 1000000;
704
0
                StringRef str =
705
0
                        FormatRound::do_format_round<Int128,
706
0
                                                     FormatRound::MAX_FORMAT_LEN_DEC128V2()>(
707
0
                                context, 3, value.int_value(), unified_frac_value, decimal_places);
708
709
0
                result_column->insert_data(str.data, str.size);
710
0
            }
711
6
        } else if (const auto* decimal32_column = check_and_get_column<ColumnDecimal32>(*col_ptr)) {
712
0
            const UInt32 scale = decimal32_column->get_scale();
713
0
            for (size_t i = 0; i < input_rows_count; i++) {
714
0
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
715
0
                if (decimal_places < 0 || decimal_places > 1024) {
716
0
                    return Status::InvalidArgument(
717
0
                            "The second argument is {}, it should be in range [0, 1024].",
718
0
                            decimal_places);
719
0
                }
720
0
                const Int32& frac_part = decimal32_column->get_fractional_part(i);
721
0
                const Int32& whole_part = decimal32_column->get_intergral_part(i);
722
0
                StringRef str =
723
0
                        FormatRound::do_format_round<Int64, FormatRound::MAX_FORMAT_LEN_DEC32()>(
724
0
                                context, scale, static_cast<Int64>(whole_part),
725
0
                                static_cast<Int64>(frac_part), decimal_places);
726
727
0
                result_column->insert_data(str.data, str.size);
728
0
            }
729
6
        } else if (const auto* decimal64_column = check_and_get_column<ColumnDecimal64>(*col_ptr)) {
730
6
            const UInt32 scale = decimal64_column->get_scale();
731
15
            for (size_t i = 0; i < input_rows_count; i++) {
732
9
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
733
9
                if (decimal_places < 0 || decimal_places > 1024) {
734
0
                    return Status::InvalidArgument(
735
0
                            "The second argument is {}, it should be in range [0, 1024].",
736
0
                            decimal_places);
737
0
                }
738
9
                const Int64& frac_part = decimal64_column->get_fractional_part(i);
739
9
                const Int64& whole_part = decimal64_column->get_intergral_part(i);
740
741
9
                StringRef str =
742
9
                        FormatRound::do_format_round<Int64, FormatRound::MAX_FORMAT_LEN_DEC64()>(
743
9
                                context, scale, whole_part, frac_part, decimal_places);
744
745
9
                result_column->insert_data(str.data, str.size);
746
9
            }
747
6
        } else if (const auto* decimal128_column =
748
0
                           check_and_get_column<ColumnDecimal128V3>(*col_ptr)) {
749
0
            const UInt32 scale = decimal128_column->get_scale();
750
0
            for (size_t i = 0; i < input_rows_count; i++) {
751
0
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
752
0
                if (decimal_places < 0 || decimal_places > 1024) {
753
0
                    return Status::InvalidArgument(
754
0
                            "The second argument is {}, it should be in range [0, 1024].",
755
0
                            decimal_places);
756
0
                }
757
0
                const Int128& frac_part = decimal128_column->get_fractional_part(i);
758
0
                const Int128& whole_part = decimal128_column->get_intergral_part(i);
759
760
0
                StringRef str =
761
0
                        FormatRound::do_format_round<Int128,
762
0
                                                     FormatRound::MAX_FORMAT_LEN_DEC128V3()>(
763
0
                                context, scale, whole_part, frac_part, decimal_places);
764
765
0
                result_column->insert_data(str.data, str.size);
766
0
            }
767
0
        } else {
768
0
            return Status::InternalError("Not supported input argument type {}",
769
0
                                         col_ptr->get_name());
770
0
        }
771
6
        return Status::OK();
772
6
    }
Unexecuted instantiation: _ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE30EE7executeILb1EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrISB_EESE_m
Unexecuted instantiation: _ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE30EE7executeILb0EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrISB_EESE_m
Unexecuted instantiation: _ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE35EE7executeILb1EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrISB_EESE_m
Unexecuted instantiation: _ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE35EE7executeILb0EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrISB_EESE_m
773
};
774
775
#include "common/compile_check_avoid_end.h"
776
} // namespace doris