Coverage Report

Created: 2026-07-25 15:41

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
112
char* SimpleItoaWithCommas(T i, char* buffer, int32_t buffer_size) {
65
112
    char* p = buffer + buffer_size;
66
    // Need to use unsigned T instead of T to correctly handle
67
112
    std::make_unsigned_t<T> n = i;
68
112
    if (i < 0) {
69
40
        n = 0 - n;
70
40
    }
71
112
    *--p = '0' + n % 10; // this case deals with the number "0"
72
112
    n /= 10;
73
284
    while (n) {
74
254
        *--p = '0' + n % 10;
75
254
        n /= 10;
76
254
        if (n == 0) {
77
50
            break;
78
50
        }
79
80
204
        *--p = '0' + n % 10;
81
204
        n /= 10;
82
204
        if (n == 0) {
83
32
            break;
84
32
        }
85
86
172
        *--p = ',';
87
172
        *--p = '0' + n % 10;
88
172
        n /= 10;
89
        // For this unrolling, we check if n == 0 in the main while loop
90
172
    }
91
112
    if (i < 0) {
92
40
        *--p = '-';
93
40
    }
94
112
    return p;
95
112
}
_ZN5doris20SimpleItoaWithCommasInEEPcT_S1_i
Line
Count
Source
64
58
char* SimpleItoaWithCommas(T i, char* buffer, int32_t buffer_size) {
65
58
    char* p = buffer + buffer_size;
66
    // Need to use unsigned T instead of T to correctly handle
67
58
    std::make_unsigned_t<T> n = i;
68
58
    if (i < 0) {
69
20
        n = 0 - n;
70
20
    }
71
58
    *--p = '0' + n % 10; // this case deals with the number "0"
72
58
    n /= 10;
73
148
    while (n) {
74
128
        *--p = '0' + n % 10;
75
128
        n /= 10;
76
128
        if (n == 0) {
77
16
            break;
78
16
        }
79
80
112
        *--p = '0' + n % 10;
81
112
        n /= 10;
82
112
        if (n == 0) {
83
22
            break;
84
22
        }
85
86
90
        *--p = ',';
87
90
        *--p = '0' + n % 10;
88
90
        n /= 10;
89
        // For this unrolling, we check if n == 0 in the main while loop
90
90
    }
91
58
    if (i < 0) {
92
20
        *--p = '-';
93
20
    }
94
58
    return p;
95
58
}
_ZN5doris20SimpleItoaWithCommasIlEEPcT_S1_i
Line
Count
Source
64
54
char* SimpleItoaWithCommas(T i, char* buffer, int32_t buffer_size) {
65
54
    char* p = buffer + buffer_size;
66
    // Need to use unsigned T instead of T to correctly handle
67
54
    std::make_unsigned_t<T> n = i;
68
54
    if (i < 0) {
69
20
        n = 0 - n;
70
20
    }
71
54
    *--p = '0' + n % 10; // this case deals with the number "0"
72
54
    n /= 10;
73
136
    while (n) {
74
126
        *--p = '0' + n % 10;
75
126
        n /= 10;
76
126
        if (n == 0) {
77
34
            break;
78
34
        }
79
80
92
        *--p = '0' + n % 10;
81
92
        n /= 10;
82
92
        if (n == 0) {
83
10
            break;
84
10
        }
85
86
82
        *--p = ',';
87
82
        *--p = '0' + n % 10;
88
82
        n /= 10;
89
        // For this unrolling, we check if n == 0 in the main while loop
90
82
    }
91
54
    if (i < 0) {
92
20
        *--p = '-';
93
20
    }
94
54
    return p;
95
54
}
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
50
StringRef do_money_format(FunctionContext* context, UInt32 scale, T int_value, T frac_value) {
136
50
    static_assert(std::is_integral<T>::value);
137
50
    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
50
    if (scale > 2) {
142
38
        DCHECK(scale <= 38);
143
        // do rounding, so we need to reserve 3 digits.
144
38
        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
38
        frac_value = std::abs(static_cast<int>(frac_value / multiplier)) + 5;
148
38
        frac_value /= 10;
149
38
    } else if (scale < 2) {
150
12
        DCHECK(frac_value < 100);
151
        // since scale <= 2, overflow is impossiable
152
12
        frac_value = frac_value * common::exp10_i32(2 - scale);
153
12
    }
154
155
50
    if (frac_value == 100) {
156
6
        if (is_negative) {
157
4
            int_value -= 1;
158
4
        } else {
159
2
            int_value += 1;
160
2
        }
161
6
        frac_value = 0;
162
6
    }
163
164
50
    bool append_sign_manually = false;
165
50
    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
4
        append_sign_manually = true;
170
4
    }
171
172
50
    char local[N];
173
50
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
174
50
    const Int32 integer_str_len = N - (p - local);
175
50
    const Int32 frac_str_len = 2;
176
50
    const Int32 whole_decimal_str_len =
177
50
            (append_sign_manually ? 1 : 0) + integer_str_len + 1 + frac_str_len;
178
179
50
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
180
    // Modify a string passed via stringref
181
50
    char* result_data = const_cast<char*>(result.data);
182
183
50
    if (append_sign_manually) {
184
4
        memset(result_data, '-', 1);
185
4
    }
186
187
50
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
188
50
    *(result_data + whole_decimal_str_len - 3) = '.';
189
50
    *(result_data + whole_decimal_str_len - 2) = '0' + std::abs(static_cast<int>(frac_value / 10));
190
50
    *(result_data + whole_decimal_str_len - 1) = '0' + std::abs(static_cast<int>(frac_value % 10));
191
50
    return result;
192
50
};
_ZN5doris11MoneyFormat15do_money_formatInLm80EEENS_9StringRefEPNS_15FunctionContextEjT_S5_
Line
Count
Source
135
28
StringRef do_money_format(FunctionContext* context, UInt32 scale, T int_value, T frac_value) {
136
28
    static_assert(std::is_integral<T>::value);
137
28
    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
28
    if (scale > 2) {
142
28
        DCHECK(scale <= 38);
143
        // do rounding, so we need to reserve 3 digits.
144
28
        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
28
        frac_value = std::abs(static_cast<int>(frac_value / multiplier)) + 5;
148
28
        frac_value /= 10;
149
28
    } 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
28
    if (frac_value == 100) {
156
6
        if (is_negative) {
157
4
            int_value -= 1;
158
4
        } else {
159
2
            int_value += 1;
160
2
        }
161
6
        frac_value = 0;
162
6
    }
163
164
28
    bool append_sign_manually = false;
165
28
    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
4
        append_sign_manually = true;
170
4
    }
171
172
28
    char local[N];
173
28
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
174
28
    const Int32 integer_str_len = N - (p - local);
175
28
    const Int32 frac_str_len = 2;
176
28
    const Int32 whole_decimal_str_len =
177
28
            (append_sign_manually ? 1 : 0) + integer_str_len + 1 + frac_str_len;
178
179
28
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
180
    // Modify a string passed via stringref
181
28
    char* result_data = const_cast<char*>(result.data);
182
183
28
    if (append_sign_manually) {
184
4
        memset(result_data, '-', 1);
185
4
    }
186
187
28
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
188
28
    *(result_data + whole_decimal_str_len - 3) = '.';
189
28
    *(result_data + whole_decimal_str_len - 2) = '0' + std::abs(static_cast<int>(frac_value / 10));
190
28
    *(result_data + whole_decimal_str_len - 1) = '0' + std::abs(static_cast<int>(frac_value % 10));
191
28
    return result;
192
28
};
Unexecuted instantiation: _ZN5doris11MoneyFormat15do_money_formatIlLm32EEENS_9StringRefEPNS_15FunctionContextEjT_S5_
_ZN5doris11MoneyFormat15do_money_formatIlLm56EEENS_9StringRefEPNS_15FunctionContextEjT_S5_
Line
Count
Source
135
10
StringRef do_money_format(FunctionContext* context, UInt32 scale, T int_value, T frac_value) {
136
10
    static_assert(std::is_integral<T>::value);
137
10
    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
10
    if (scale > 2) {
142
10
        DCHECK(scale <= 38);
143
        // do rounding, so we need to reserve 3 digits.
144
10
        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
10
        frac_value = std::abs(static_cast<int>(frac_value / multiplier)) + 5;
148
10
        frac_value /= 10;
149
10
    } 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
10
    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
10
    bool append_sign_manually = false;
165
10
    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
10
    char local[N];
173
10
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
174
10
    const Int32 integer_str_len = N - (p - local);
175
10
    const Int32 frac_str_len = 2;
176
10
    const Int32 whole_decimal_str_len =
177
10
            (append_sign_manually ? 1 : 0) + integer_str_len + 1 + frac_str_len;
178
179
10
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
180
    // Modify a string passed via stringref
181
10
    char* result_data = const_cast<char*>(result.data);
182
183
10
    if (append_sign_manually) {
184
0
        memset(result_data, '-', 1);
185
0
    }
186
187
10
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
188
10
    *(result_data + whole_decimal_str_len - 3) = '.';
189
10
    *(result_data + whole_decimal_str_len - 2) = '0' + std::abs(static_cast<int>(frac_value / 10));
190
10
    *(result_data + whole_decimal_str_len - 1) = '0' + std::abs(static_cast<int>(frac_value % 10));
191
10
    return result;
192
10
};
_ZN5doris11MoneyFormat15do_money_formatInLm112EEENS_9StringRefEPNS_15FunctionContextEjT_S5_
Line
Count
Source
135
6
StringRef do_money_format(FunctionContext* context, UInt32 scale, T int_value, T frac_value) {
136
6
    static_assert(std::is_integral<T>::value);
137
6
    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
6
    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
6
    } 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
6
    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
6
    bool append_sign_manually = false;
165
6
    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
6
    char local[N];
173
6
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
174
6
    const Int32 integer_str_len = N - (p - local);
175
6
    const Int32 frac_str_len = 2;
176
6
    const Int32 whole_decimal_str_len =
177
6
            (append_sign_manually ? 1 : 0) + integer_str_len + 1 + frac_str_len;
178
179
6
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
180
    // Modify a string passed via stringref
181
6
    char* result_data = const_cast<char*>(result.data);
182
183
6
    if (append_sign_manually) {
184
0
        memset(result_data, '-', 1);
185
0
    }
186
187
6
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
188
6
    *(result_data + whole_decimal_str_len - 3) = '.';
189
6
    *(result_data + whole_decimal_str_len - 2) = '0' + std::abs(static_cast<int>(frac_value / 10));
190
6
    *(result_data + whole_decimal_str_len - 1) = '0' + std::abs(static_cast<int>(frac_value % 10));
191
6
    return result;
192
6
};
_ZN5doris11MoneyFormat15do_money_formatIlLm60EEENS_9StringRefEPNS_15FunctionContextEjT_S5_
Line
Count
Source
135
6
StringRef do_money_format(FunctionContext* context, UInt32 scale, T int_value, T frac_value) {
136
6
    static_assert(std::is_integral<T>::value);
137
6
    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
6
    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
6
    } 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
6
    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
6
    bool append_sign_manually = false;
165
6
    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
6
    char local[N];
173
6
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
174
6
    const Int32 integer_str_len = N - (p - local);
175
6
    const Int32 frac_str_len = 2;
176
6
    const Int32 whole_decimal_str_len =
177
6
            (append_sign_manually ? 1 : 0) + integer_str_len + 1 + frac_str_len;
178
179
6
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
180
    // Modify a string passed via stringref
181
6
    char* result_data = const_cast<char*>(result.data);
182
183
6
    if (append_sign_manually) {
184
0
        memset(result_data, '-', 1);
185
0
    }
186
187
6
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
188
6
    *(result_data + whole_decimal_str_len - 3) = '.';
189
6
    *(result_data + whole_decimal_str_len - 2) = '0' + std::abs(static_cast<int>(frac_value / 10));
190
6
    *(result_data + whole_decimal_str_len - 1) = '0' + std::abs(static_cast<int>(frac_value % 10));
191
6
    return result;
192
6
};
193
194
// Note string value must be valid decimal string which contains two digits after the decimal point
195
8
static StringRef do_money_format(FunctionContext* context, const std::string& value) {
196
8
    bool is_positive = (value[0] != '-');
197
8
    int32_t result_len = value.size() + (value.size() - (is_positive ? 4 : 5)) / 3;
198
8
    StringRef result = context->create_temp_string_val(result_len);
199
    // Modify a string passed via stringref
200
8
    char* result_data = const_cast<char*>(result.data);
201
8
    if (!is_positive) {
202
4
        *result_data = '-';
203
4
    }
204
20
    for (int i = value.size() - 4, j = result_len - 4; i >= 0; i = i - 3) {
205
18
        *(result_data + j) = *(value.data() + i);
206
18
        if (i - 1 < 0) {
207
4
            break;
208
4
        }
209
14
        *(result_data + j - 1) = *(value.data() + i - 1);
210
14
        if (i - 2 < 0) {
211
2
            break;
212
2
        }
213
12
        *(result_data + j - 2) = *(value.data() + i - 2);
214
12
        if (j - 3 > 1 || (j - 3 == 1 && is_positive)) {
215
8
            *(result_data + j - 3) = ',';
216
8
            j -= 4;
217
8
        } else {
218
4
            j -= 3;
219
4
        }
220
12
    }
221
8
    memcpy(result_data + result_len - 3, value.data() + value.size() - 3, 3);
222
8
    return result;
223
8
};
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
8
static StringRef do_money_format(FunctionContext* context, const std::string& value) {
196
8
    bool is_positive = (value[0] != '-');
197
8
    int32_t result_len = value.size() + (value.size() - (is_positive ? 4 : 5)) / 3;
198
8
    StringRef result = context->create_temp_string_val(result_len);
199
    // Modify a string passed via stringref
200
8
    char* result_data = const_cast<char*>(result.data);
201
8
    if (!is_positive) {
202
4
        *result_data = '-';
203
4
    }
204
20
    for (int i = value.size() - 4, j = result_len - 4; i >= 0; i = i - 3) {
205
18
        *(result_data + j) = *(value.data() + i);
206
18
        if (i - 1 < 0) {
207
4
            break;
208
4
        }
209
14
        *(result_data + j - 1) = *(value.data() + i - 1);
210
14
        if (i - 2 < 0) {
211
2
            break;
212
2
        }
213
12
        *(result_data + j - 2) = *(value.data() + i - 2);
214
12
        if (j - 3 > 1 || (j - 3 == 1 && is_positive)) {
215
8
            *(result_data + j - 3) = ',';
216
8
            j -= 4;
217
8
        } else {
218
4
            j -= 3;
219
4
        }
220
12
    }
221
8
    memcpy(result_data + result_len - 3, value.data() + value.size() - 3, 3);
222
8
    return result;
223
8
};
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
62
                          Int32 decimal_places) {
267
62
    static_assert(std::is_integral<T>::value);
268
62
    const bool is_negative = int_value < 0 || frac_value < 0;
269
270
    // do round to frac_part based on decimal_places
271
62
    if (scale > decimal_places && decimal_places > 0) {
272
28
        DCHECK(scale <= 38);
273
        // do rounding, so we need to reserve decimal_places + 1 digits
274
28
        auto multiplier =
275
28
                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
28
        frac_value = std::abs(static_cast<int>(frac_value / multiplier)) + 5;
279
28
        frac_value /= 10;
280
34
    } else if (scale < decimal_places && decimal_places > 0) {
281
        // since scale <= decimal_places, overflow is impossible
282
26
        frac_value = frac_value * common::exp10_i32(decimal_places - scale);
283
26
    }
284
285
    // Calculate power of 10 for decimal_places
286
62
    T decimal_power = common::exp10_i32(decimal_places);
287
62
    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
62
    bool append_sign_manually = false;
297
62
    if (is_negative && int_value == 0) {
298
0
        append_sign_manually = true;
299
0
    }
300
301
62
    char local[N];
302
62
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
303
62
    const Int32 integer_str_len = N - (p - local);
304
62
    const Int32 frac_str_len = decimal_places;
305
62
    const Int32 whole_decimal_str_len = (append_sign_manually ? 1 : 0) + integer_str_len +
306
62
                                        (decimal_places > 0 ? 1 : 0) + frac_str_len;
307
308
62
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
309
    // Modify a string passed via stringref
310
62
    char* result_data = const_cast<char*>(result.data);
311
312
62
    if (append_sign_manually) {
313
0
        memset(result_data, '-', 1);
314
0
    }
315
316
62
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
317
62
    if (decimal_places > 0) {
318
54
        *(result_data + whole_decimal_str_len - (frac_str_len + 1)) = '.';
319
54
    }
320
321
    // Convert fractional part to string with proper padding
322
62
    T remaining_frac = std::abs(static_cast<int>(frac_value));
323
278
    for (int i = 0; i <= decimal_places - 1; ++i) {
324
216
        *(result_data + whole_decimal_str_len - 1 - i) = '0' + (remaining_frac % 10);
325
216
        remaining_frac /= 10;
326
216
    }
327
62
    return result;
328
62
}
_ZN5doris11FormatRound15do_format_roundIlLm60EEENS_9StringRefEPNS_15FunctionContextEjT_S5_i
Line
Count
Source
266
16
                          Int32 decimal_places) {
267
16
    static_assert(std::is_integral<T>::value);
268
16
    const bool is_negative = int_value < 0 || frac_value < 0;
269
270
    // do round to frac_part based on decimal_places
271
16
    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
16
    } else if (scale < decimal_places && decimal_places > 0) {
281
        // since scale <= decimal_places, overflow is impossible
282
12
        frac_value = frac_value * common::exp10_i32(decimal_places - scale);
283
12
    }
284
285
    // Calculate power of 10 for decimal_places
286
16
    T decimal_power = common::exp10_i32(decimal_places);
287
16
    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
16
    bool append_sign_manually = false;
297
16
    if (is_negative && int_value == 0) {
298
0
        append_sign_manually = true;
299
0
    }
300
301
16
    char local[N];
302
16
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
303
16
    const Int32 integer_str_len = N - (p - local);
304
16
    const Int32 frac_str_len = decimal_places;
305
16
    const Int32 whole_decimal_str_len = (append_sign_manually ? 1 : 0) + integer_str_len +
306
16
                                        (decimal_places > 0 ? 1 : 0) + frac_str_len;
307
308
16
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
309
    // Modify a string passed via stringref
310
16
    char* result_data = const_cast<char*>(result.data);
311
312
16
    if (append_sign_manually) {
313
0
        memset(result_data, '-', 1);
314
0
    }
315
316
16
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
317
16
    if (decimal_places > 0) {
318
12
        *(result_data + whole_decimal_str_len - (frac_str_len + 1)) = '.';
319
12
    }
320
321
    // Convert fractional part to string with proper padding
322
16
    T remaining_frac = std::abs(static_cast<int>(frac_value));
323
94
    for (int i = 0; i <= decimal_places - 1; ++i) {
324
78
        *(result_data + whole_decimal_str_len - 1 - i) = '0' + (remaining_frac % 10);
325
78
        remaining_frac /= 10;
326
78
    }
327
16
    return result;
328
16
}
_ZN5doris11FormatRound15do_format_roundInLm112EEENS_9StringRefEPNS_15FunctionContextEjT_S5_i
Line
Count
Source
266
18
                          Int32 decimal_places) {
267
18
    static_assert(std::is_integral<T>::value);
268
18
    const bool is_negative = int_value < 0 || frac_value < 0;
269
270
    // do round to frac_part based on decimal_places
271
18
    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
18
    } else if (scale < decimal_places && decimal_places > 0) {
281
        // since scale <= decimal_places, overflow is impossible
282
14
        frac_value = frac_value * common::exp10_i32(decimal_places - scale);
283
14
    }
284
285
    // Calculate power of 10 for decimal_places
286
18
    T decimal_power = common::exp10_i32(decimal_places);
287
18
    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
18
    bool append_sign_manually = false;
297
18
    if (is_negative && int_value == 0) {
298
0
        append_sign_manually = true;
299
0
    }
300
301
18
    char local[N];
302
18
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
303
18
    const Int32 integer_str_len = N - (p - local);
304
18
    const Int32 frac_str_len = decimal_places;
305
18
    const Int32 whole_decimal_str_len = (append_sign_manually ? 1 : 0) + integer_str_len +
306
18
                                        (decimal_places > 0 ? 1 : 0) + frac_str_len;
307
308
18
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
309
    // Modify a string passed via stringref
310
18
    char* result_data = const_cast<char*>(result.data);
311
312
18
    if (append_sign_manually) {
313
0
        memset(result_data, '-', 1);
314
0
    }
315
316
18
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
317
18
    if (decimal_places > 0) {
318
14
        *(result_data + whole_decimal_str_len - (frac_str_len + 1)) = '.';
319
14
    }
320
321
    // Convert fractional part to string with proper padding
322
18
    T remaining_frac = std::abs(static_cast<int>(frac_value));
323
100
    for (int i = 0; i <= decimal_places - 1; ++i) {
324
82
        *(result_data + whole_decimal_str_len - 1 - i) = '0' + (remaining_frac % 10);
325
82
        remaining_frac /= 10;
326
82
    }
327
18
    return result;
328
18
}
_ZN5doris11FormatRound15do_format_roundInLm80EEENS_9StringRefEPNS_15FunctionContextEjT_S5_i
Line
Count
Source
266
6
                          Int32 decimal_places) {
267
6
    static_assert(std::is_integral<T>::value);
268
6
    const bool is_negative = int_value < 0 || frac_value < 0;
269
270
    // do round to frac_part based on decimal_places
271
6
    if (scale > decimal_places && decimal_places > 0) {
272
6
        DCHECK(scale <= 38);
273
        // do rounding, so we need to reserve decimal_places + 1 digits
274
6
        auto multiplier =
275
6
                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
6
        frac_value = std::abs(static_cast<int>(frac_value / multiplier)) + 5;
279
6
        frac_value /= 10;
280
6
    } 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
6
    T decimal_power = common::exp10_i32(decimal_places);
287
6
    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
6
    bool append_sign_manually = false;
297
6
    if (is_negative && int_value == 0) {
298
0
        append_sign_manually = true;
299
0
    }
300
301
6
    char local[N];
302
6
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
303
6
    const Int32 integer_str_len = N - (p - local);
304
6
    const Int32 frac_str_len = decimal_places;
305
6
    const Int32 whole_decimal_str_len = (append_sign_manually ? 1 : 0) + integer_str_len +
306
6
                                        (decimal_places > 0 ? 1 : 0) + frac_str_len;
307
308
6
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
309
    // Modify a string passed via stringref
310
6
    char* result_data = const_cast<char*>(result.data);
311
312
6
    if (append_sign_manually) {
313
0
        memset(result_data, '-', 1);
314
0
    }
315
316
6
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
317
6
    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
6
    T remaining_frac = std::abs(static_cast<int>(frac_value));
323
18
    for (int i = 0; i <= decimal_places - 1; ++i) {
324
12
        *(result_data + whole_decimal_str_len - 1 - i) = '0' + (remaining_frac % 10);
325
12
        remaining_frac /= 10;
326
12
    }
327
6
    return result;
328
6
}
Unexecuted instantiation: _ZN5doris11FormatRound15do_format_roundIlLm32EEENS_9StringRefEPNS_15FunctionContextEjT_S5_i
_ZN5doris11FormatRound15do_format_roundIlLm56EEENS_9StringRefEPNS_15FunctionContextEjT_S5_i
Line
Count
Source
266
22
                          Int32 decimal_places) {
267
22
    static_assert(std::is_integral<T>::value);
268
22
    const bool is_negative = int_value < 0 || frac_value < 0;
269
270
    // do round to frac_part based on decimal_places
271
22
    if (scale > decimal_places && decimal_places > 0) {
272
22
        DCHECK(scale <= 38);
273
        // do rounding, so we need to reserve decimal_places + 1 digits
274
22
        auto multiplier =
275
22
                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
22
        frac_value = std::abs(static_cast<int>(frac_value / multiplier)) + 5;
279
22
        frac_value /= 10;
280
22
    } 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
22
    T decimal_power = common::exp10_i32(decimal_places);
287
22
    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
22
    bool append_sign_manually = false;
297
22
    if (is_negative && int_value == 0) {
298
0
        append_sign_manually = true;
299
0
    }
300
301
22
    char local[N];
302
22
    char* p = SimpleItoaWithCommas<T>(int_value, local, sizeof(local));
303
22
    const Int32 integer_str_len = N - (p - local);
304
22
    const Int32 frac_str_len = decimal_places;
305
22
    const Int32 whole_decimal_str_len = (append_sign_manually ? 1 : 0) + integer_str_len +
306
22
                                        (decimal_places > 0 ? 1 : 0) + frac_str_len;
307
308
22
    StringRef result = context->create_temp_string_val(whole_decimal_str_len);
309
    // Modify a string passed via stringref
310
22
    char* result_data = const_cast<char*>(result.data);
311
312
22
    if (append_sign_manually) {
313
0
        memset(result_data, '-', 1);
314
0
    }
315
316
22
    memcpy(result_data + (append_sign_manually ? 1 : 0), p, integer_str_len);
317
22
    if (decimal_places > 0) {
318
22
        *(result_data + whole_decimal_str_len - (frac_str_len + 1)) = '.';
319
22
    }
320
321
    // Convert fractional part to string with proper padding
322
22
    T remaining_frac = std::abs(static_cast<int>(frac_value));
323
66
    for (int i = 0; i <= decimal_places - 1; ++i) {
324
44
        *(result_data + whole_decimal_str_len - 1 - i) = '0' + (remaining_frac % 10);
325
44
        remaining_frac /= 10;
326
44
    }
327
22
    return result;
328
22
}
329
330
} // namespace FormatRound
331
332
template <typename Impl>
333
class FunctionMoneyFormat : public IFunction {
334
public:
335
    static constexpr auto name = "money_format";
336
50
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
_ZN5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE20EEEE6createEv
Line
Count
Source
336
8
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
_ZN5doris19FunctionMoneyFormatINS_21MoneyFormatDoubleImplEE6createEv
Line
Count
Source
336
6
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
_ZN5doris19FunctionMoneyFormatINS_20MoneyFormatInt64ImplEE6createEv
Line
Count
Source
336
6
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
_ZN5doris19FunctionMoneyFormatINS_21MoneyFormatInt128ImplEE6createEv
Line
Count
Source
336
6
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
_ZN5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE28EEEE6createEv
Line
Count
Source
336
4
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
_ZN5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE29EEEE6createEv
Line
Count
Source
336
12
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
_ZN5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE30EEEE6createEv
Line
Count
Source
336
4
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
_ZN5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE35EEEE6createEv
Line
Count
Source
336
4
    static FunctionPtr create() { return std::make_shared<FunctionMoneyFormat>(); }
337
16
    String get_name() const override { return name; }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE20EEEE8get_nameB5cxx11Ev
Line
Count
Source
337
2
    String get_name() const override { return name; }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatDoubleImplEE8get_nameB5cxx11Ev
Line
Count
Source
337
2
    String get_name() const override { return name; }
_ZNK5doris19FunctionMoneyFormatINS_20MoneyFormatInt64ImplEE8get_nameB5cxx11Ev
Line
Count
Source
337
2
    String get_name() const override { return name; }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatInt128ImplEE8get_nameB5cxx11Ev
Line
Count
Source
337
2
    String get_name() const override { return name; }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE28EEEE8get_nameB5cxx11Ev
Line
Count
Source
337
2
    String get_name() const override { return name; }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE29EEEE8get_nameB5cxx11Ev
Line
Count
Source
337
2
    String get_name() const override { return name; }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE30EEEE8get_nameB5cxx11Ev
Line
Count
Source
337
2
    String get_name() const override { return name; }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE35EEEE8get_nameB5cxx11Ev
Line
Count
Source
337
2
    String get_name() const override { return name; }
338
339
16
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
340
16
        if (arguments.size() != 1) {
341
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
342
0
                                   "Function {} requires exactly 1 argument", name);
343
0
        }
344
345
16
        return std::make_shared<DataTypeString>();
346
16
    }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE20EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Line
Count
Source
339
2
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
340
2
        if (arguments.size() != 1) {
341
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
342
0
                                   "Function {} requires exactly 1 argument", name);
343
0
        }
344
345
2
        return std::make_shared<DataTypeString>();
346
2
    }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatDoubleImplEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
339
2
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
340
2
        if (arguments.size() != 1) {
341
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
342
0
                                   "Function {} requires exactly 1 argument", name);
343
0
        }
344
345
2
        return std::make_shared<DataTypeString>();
346
2
    }
_ZNK5doris19FunctionMoneyFormatINS_20MoneyFormatInt64ImplEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
339
2
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
340
2
        if (arguments.size() != 1) {
341
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
342
0
                                   "Function {} requires exactly 1 argument", name);
343
0
        }
344
345
2
        return std::make_shared<DataTypeString>();
346
2
    }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatInt128ImplEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
339
2
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
340
2
        if (arguments.size() != 1) {
341
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
342
0
                                   "Function {} requires exactly 1 argument", name);
343
0
        }
344
345
2
        return std::make_shared<DataTypeString>();
346
2
    }
Unexecuted instantiation: _ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE28EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE29EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Line
Count
Source
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
    }
Unexecuted instantiation: _ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE30EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE35EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
347
16
    DataTypes get_variadic_argument_types_impl() const override {
348
16
        return Impl::get_variadic_argument_types();
349
16
    }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE20EEEE32get_variadic_argument_types_implEv
Line
Count
Source
347
2
    DataTypes get_variadic_argument_types_impl() const override {
348
2
        return Impl::get_variadic_argument_types();
349
2
    }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatDoubleImplEE32get_variadic_argument_types_implEv
Line
Count
Source
347
2
    DataTypes get_variadic_argument_types_impl() const override {
348
2
        return Impl::get_variadic_argument_types();
349
2
    }
_ZNK5doris19FunctionMoneyFormatINS_20MoneyFormatInt64ImplEE32get_variadic_argument_types_implEv
Line
Count
Source
347
2
    DataTypes get_variadic_argument_types_impl() const override {
348
2
        return Impl::get_variadic_argument_types();
349
2
    }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatInt128ImplEE32get_variadic_argument_types_implEv
Line
Count
Source
347
2
    DataTypes get_variadic_argument_types_impl() const override {
348
2
        return Impl::get_variadic_argument_types();
349
2
    }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE28EEEE32get_variadic_argument_types_implEv
Line
Count
Source
347
2
    DataTypes get_variadic_argument_types_impl() const override {
348
2
        return Impl::get_variadic_argument_types();
349
2
    }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE29EEEE32get_variadic_argument_types_implEv
Line
Count
Source
347
2
    DataTypes get_variadic_argument_types_impl() const override {
348
2
        return Impl::get_variadic_argument_types();
349
2
    }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE30EEEE32get_variadic_argument_types_implEv
Line
Count
Source
347
2
    DataTypes get_variadic_argument_types_impl() const override {
348
2
        return Impl::get_variadic_argument_types();
349
2
    }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE35EEEE32get_variadic_argument_types_implEv
Line
Count
Source
347
2
    DataTypes get_variadic_argument_types_impl() const override {
348
2
        return Impl::get_variadic_argument_types();
349
2
    }
350
16
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE20EEEE23get_number_of_argumentsEv
Line
Count
Source
350
2
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatDoubleImplEE23get_number_of_argumentsEv
Line
Count
Source
350
2
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris19FunctionMoneyFormatINS_20MoneyFormatInt64ImplEE23get_number_of_argumentsEv
Line
Count
Source
350
2
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatInt128ImplEE23get_number_of_argumentsEv
Line
Count
Source
350
2
    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
8
    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
16
                        uint32_t result, size_t input_rows_count) const override {
354
16
        auto res_column = ColumnString::create();
355
16
        ColumnPtr argument_column = block.get_by_position(arguments[0]).column;
356
357
16
        auto result_column = res_column.get();
358
359
16
        Impl::execute(context, result_column, argument_column, input_rows_count);
360
361
16
        block.replace_by_position(result, std::move(res_column));
362
16
        return Status::OK();
363
16
    }
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE20EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
353
4
                        uint32_t result, size_t input_rows_count) const override {
354
4
        auto res_column = ColumnString::create();
355
4
        ColumnPtr argument_column = block.get_by_position(arguments[0]).column;
356
357
4
        auto result_column = res_column.get();
358
359
4
        Impl::execute(context, result_column, argument_column, input_rows_count);
360
361
4
        block.replace_by_position(result, std::move(res_column));
362
4
        return Status::OK();
363
4
    }
_ZNK5doris19FunctionMoneyFormatINS_21MoneyFormatDoubleImplEE12execute_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 = 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_20MoneyFormatInt64ImplEE12execute_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 = 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_21MoneyFormatInt128ImplEE12execute_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 = 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
    }
Unexecuted instantiation: _ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE28EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
_ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE29EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
353
6
                        uint32_t result, size_t input_rows_count) const override {
354
6
        auto res_column = ColumnString::create();
355
6
        ColumnPtr argument_column = block.get_by_position(arguments[0]).column;
356
357
6
        auto result_column = res_column.get();
358
359
6
        Impl::execute(context, result_column, argument_column, input_rows_count);
360
361
6
        block.replace_by_position(result, std::move(res_column));
362
6
        return Status::OK();
363
6
    }
Unexecuted instantiation: _ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE30EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris19FunctionMoneyFormatINS_22MoneyFormatDecimalImplILNS_13PrimitiveTypeE35EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
364
};
365
366
struct MoneyFormatDoubleImpl {
367
2
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeFloat64>()}; }
368
369
    static void execute(FunctionContext* context, ColumnString* result_column,
370
2
                        const ColumnPtr col_ptr, size_t input_rows_count) {
371
2
        const auto* data_column = assert_cast<const ColumnFloat64*>(col_ptr.get());
372
        // when scale is above 38, we will go here
373
10
        for (size_t i = 0; i < input_rows_count; i++) {
374
            // round to 2 decimal places
375
8
            double value =
376
8
                    MathFunctions::my_double_round(data_column->get_element(i), 2, false, false);
377
8
            StringRef str = MoneyFormat::do_money_format(context, fmt::format("{:.2f}", value));
378
8
            result_column->insert_data(str.data, str.size);
379
8
        }
380
2
    }
381
};
382
383
struct MoneyFormatInt64Impl {
384
2
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeInt64>()}; }
385
386
    static void execute(FunctionContext* context, ColumnString* result_column,
387
2
                        const ColumnPtr col_ptr, size_t input_rows_count) {
388
2
        const auto* data_column = assert_cast<const ColumnInt64*>(col_ptr.get());
389
8
        for (size_t i = 0; i < input_rows_count; i++) {
390
6
            Int64 value = data_column->get_element(i);
391
6
            StringRef str =
392
6
                    MoneyFormat::do_money_format<Int64, MoneyFormat::MAX_FORMAT_LEN_INT64()>(
393
6
                            context, 0, value, 0);
394
6
            result_column->insert_data(str.data, str.size);
395
6
        }
396
2
    }
397
};
398
399
struct MoneyFormatInt128Impl {
400
2
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeInt128>()}; }
401
402
    static void execute(FunctionContext* context, ColumnString* result_column,
403
2
                        const ColumnPtr col_ptr, size_t input_rows_count) {
404
2
        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
8
        for (size_t i = 0; i < input_rows_count; i++) {
409
6
            Int128 value = data_column->get_element(i);
410
6
            StringRef str =
411
6
                    MoneyFormat::do_money_format<Int128, MoneyFormat::MAX_FORMAT_LEN_INT128()>(
412
6
                            context, 0, value, 0);
413
6
            result_column->insert_data(str.data, str.size);
414
6
        }
415
2
    }
416
};
417
418
template <PrimitiveType Type>
419
struct MoneyFormatDecimalImpl {
420
10
    static DataTypes get_variadic_argument_types() {
421
10
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>()};
422
10
    }
_ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE20EE27get_variadic_argument_typesEv
Line
Count
Source
420
2
    static DataTypes get_variadic_argument_types() {
421
2
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>()};
422
2
    }
_ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE28EE27get_variadic_argument_typesEv
Line
Count
Source
420
2
    static DataTypes get_variadic_argument_types() {
421
2
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>()};
422
2
    }
_ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE29EE27get_variadic_argument_typesEv
Line
Count
Source
420
2
    static DataTypes get_variadic_argument_types() {
421
2
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>()};
422
2
    }
_ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE30EE27get_variadic_argument_typesEv
Line
Count
Source
420
2
    static DataTypes get_variadic_argument_types() {
421
2
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>()};
422
2
    }
_ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE35EE27get_variadic_argument_typesEv
Line
Count
Source
420
2
    static DataTypes get_variadic_argument_types() {
421
2
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>()};
422
2
    }
423
424
    static void execute(FunctionContext* context, ColumnString* result_column, ColumnPtr col_ptr,
425
10
                        size_t input_rows_count) {
426
10
        if (auto* decimalv2_column = check_and_get_column<ColumnDecimal128V2>(*col_ptr)) {
427
32
            for (size_t i = 0; i < input_rows_count; i++) {
428
28
                const auto& value = decimalv2_column->get_element(i);
429
                // unified_frac_value has 3 digits
430
28
                auto unified_frac_value = value.frac_value() / 1000000;
431
28
                StringRef str =
432
28
                        MoneyFormat::do_money_format<Int128,
433
28
                                                     MoneyFormat::MAX_FORMAT_LEN_DEC128V2()>(
434
28
                                context, 3, value.int_value(), unified_frac_value);
435
436
28
                result_column->insert_data(str.data, str.size);
437
28
            }
438
6
        } 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
6
        } else if (auto* decimal64_column = check_and_get_column<ColumnDecimal64>(*col_ptr)) {
451
6
            const UInt32 scale = decimal64_column->get_scale();
452
16
            for (size_t i = 0; i < input_rows_count; i++) {
453
10
                const Int64& frac_part = decimal64_column->get_fractional_part(i);
454
10
                const Int64& whole_part = decimal64_column->get_intergral_part(i);
455
456
10
                StringRef str =
457
10
                        MoneyFormat::do_money_format<Int64, MoneyFormat::MAX_FORMAT_LEN_DEC64()>(
458
10
                                context, scale, whole_part, frac_part);
459
460
10
                result_column->insert_data(str.data, str.size);
461
10
            }
462
6
        } 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
10
    }
_ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE20EE7executeEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EEm
Line
Count
Source
425
4
                        size_t input_rows_count) {
426
4
        if (auto* decimalv2_column = check_and_get_column<ColumnDecimal128V2>(*col_ptr)) {
427
32
            for (size_t i = 0; i < input_rows_count; i++) {
428
28
                const auto& value = decimalv2_column->get_element(i);
429
                // unified_frac_value has 3 digits
430
28
                auto unified_frac_value = value.frac_value() / 1000000;
431
28
                StringRef str =
432
28
                        MoneyFormat::do_money_format<Int128,
433
28
                                                     MoneyFormat::MAX_FORMAT_LEN_DEC128V2()>(
434
28
                                context, 3, value.int_value(), unified_frac_value);
435
436
28
                result_column->insert_data(str.data, str.size);
437
28
            }
438
4
        } 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
4
    }
Unexecuted instantiation: _ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE28EE7executeEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EEm
_ZN5doris22MoneyFormatDecimalImplILNS_13PrimitiveTypeE29EE7executeEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EEm
Line
Count
Source
425
6
                        size_t input_rows_count) {
426
6
        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
6
        } 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
6
        } else if (auto* decimal64_column = check_and_get_column<ColumnDecimal64>(*col_ptr)) {
451
6
            const UInt32 scale = decimal64_column->get_scale();
452
16
            for (size_t i = 0; i < input_rows_count; i++) {
453
10
                const Int64& frac_part = decimal64_column->get_fractional_part(i);
454
10
                const Int64& whole_part = decimal64_column->get_intergral_part(i);
455
456
10
                StringRef str =
457
10
                        MoneyFormat::do_money_format<Int64, MoneyFormat::MAX_FORMAT_LEN_DEC64()>(
458
10
                                context, scale, whole_part, frac_part);
459
460
10
                result_column->insert_data(str.data, str.size);
461
10
            }
462
6
        } 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
6
    }
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
62
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
_ZN5doris25FunctionStringFormatRoundINS_21FormatRoundDoubleImplEE6createEv
Line
Count
Source
507
6
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
_ZN5doris25FunctionStringFormatRoundINS_20FormatRoundInt64ImplEE6createEv
Line
Count
Source
507
6
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
_ZN5doris25FunctionStringFormatRoundINS_21FormatRoundInt128ImplEE6createEv
Line
Count
Source
507
6
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
_ZN5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE20EEEE6createEv
Line
Count
Source
507
6
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
_ZN5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE28EEEE6createEv
Line
Count
Source
507
4
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
_ZN5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE29EEEE6createEv
Line
Count
Source
507
26
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
_ZN5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE30EEEE6createEv
Line
Count
Source
507
4
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
_ZN5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE35EEEE6createEv
Line
Count
Source
507
4
    static FunctionPtr create() { return std::make_shared<FunctionStringFormatRound>(); }
508
16
    String get_name() const override { return name; }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundDoubleImplEE8get_nameB5cxx11Ev
Line
Count
Source
508
2
    String get_name() const override { return name; }
_ZNK5doris25FunctionStringFormatRoundINS_20FormatRoundInt64ImplEE8get_nameB5cxx11Ev
Line
Count
Source
508
2
    String get_name() const override { return name; }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundInt128ImplEE8get_nameB5cxx11Ev
Line
Count
Source
508
2
    String get_name() const override { return name; }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE20EEEE8get_nameB5cxx11Ev
Line
Count
Source
508
2
    String get_name() const override { return name; }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE28EEEE8get_nameB5cxx11Ev
Line
Count
Source
508
2
    String get_name() const override { return name; }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE29EEEE8get_nameB5cxx11Ev
Line
Count
Source
508
2
    String get_name() const override { return name; }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE30EEEE8get_nameB5cxx11Ev
Line
Count
Source
508
2
    String get_name() const override { return name; }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE35EEEE8get_nameB5cxx11Ev
Line
Count
Source
508
2
    String get_name() const override { return name; }
509
510
30
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
511
30
        if (arguments.size() != 2) {
512
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
513
0
                                   "Function {} requires exactly 2 argument", name);
514
0
        }
515
30
        return std::make_shared<DataTypeString>();
516
30
    }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundDoubleImplEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
510
2
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
511
2
        if (arguments.size() != 2) {
512
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
513
0
                                   "Function {} requires exactly 2 argument", name);
514
0
        }
515
2
        return std::make_shared<DataTypeString>();
516
2
    }
_ZNK5doris25FunctionStringFormatRoundINS_20FormatRoundInt64ImplEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
510
2
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
511
2
        if (arguments.size() != 2) {
512
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
513
0
                                   "Function {} requires exactly 2 argument", name);
514
0
        }
515
2
        return std::make_shared<DataTypeString>();
516
2
    }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundInt128ImplEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
510
2
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
511
2
        if (arguments.size() != 2) {
512
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
513
0
                                   "Function {} requires exactly 2 argument", name);
514
0
        }
515
2
        return std::make_shared<DataTypeString>();
516
2
    }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE20EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Line
Count
Source
510
2
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
511
2
        if (arguments.size() != 2) {
512
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
513
0
                                   "Function {} requires exactly 2 argument", name);
514
0
        }
515
2
        return std::make_shared<DataTypeString>();
516
2
    }
Unexecuted instantiation: _ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE28EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE29EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Line
Count
Source
510
22
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
511
22
        if (arguments.size() != 2) {
512
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
513
0
                                   "Function {} requires exactly 2 argument", name);
514
0
        }
515
22
        return std::make_shared<DataTypeString>();
516
22
    }
Unexecuted instantiation: _ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE30EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE35EEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
517
16
    DataTypes get_variadic_argument_types_impl() const override {
518
16
        return Impl::get_variadic_argument_types();
519
16
    }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundDoubleImplEE32get_variadic_argument_types_implEv
Line
Count
Source
517
2
    DataTypes get_variadic_argument_types_impl() const override {
518
2
        return Impl::get_variadic_argument_types();
519
2
    }
_ZNK5doris25FunctionStringFormatRoundINS_20FormatRoundInt64ImplEE32get_variadic_argument_types_implEv
Line
Count
Source
517
2
    DataTypes get_variadic_argument_types_impl() const override {
518
2
        return Impl::get_variadic_argument_types();
519
2
    }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundInt128ImplEE32get_variadic_argument_types_implEv
Line
Count
Source
517
2
    DataTypes get_variadic_argument_types_impl() const override {
518
2
        return Impl::get_variadic_argument_types();
519
2
    }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE20EEEE32get_variadic_argument_types_implEv
Line
Count
Source
517
2
    DataTypes get_variadic_argument_types_impl() const override {
518
2
        return Impl::get_variadic_argument_types();
519
2
    }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE28EEEE32get_variadic_argument_types_implEv
Line
Count
Source
517
2
    DataTypes get_variadic_argument_types_impl() const override {
518
2
        return Impl::get_variadic_argument_types();
519
2
    }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE29EEEE32get_variadic_argument_types_implEv
Line
Count
Source
517
2
    DataTypes get_variadic_argument_types_impl() const override {
518
2
        return Impl::get_variadic_argument_types();
519
2
    }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE30EEEE32get_variadic_argument_types_implEv
Line
Count
Source
517
2
    DataTypes get_variadic_argument_types_impl() const override {
518
2
        return Impl::get_variadic_argument_types();
519
2
    }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE35EEEE32get_variadic_argument_types_implEv
Line
Count
Source
517
2
    DataTypes get_variadic_argument_types_impl() const override {
518
2
        return Impl::get_variadic_argument_types();
519
2
    }
520
30
    size_t get_number_of_arguments() const override { return 2; }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundDoubleImplEE23get_number_of_argumentsEv
Line
Count
Source
520
2
    size_t get_number_of_arguments() const override { return 2; }
_ZNK5doris25FunctionStringFormatRoundINS_20FormatRoundInt64ImplEE23get_number_of_argumentsEv
Line
Count
Source
520
2
    size_t get_number_of_arguments() const override { return 2; }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundInt128ImplEE23get_number_of_argumentsEv
Line
Count
Source
520
2
    size_t get_number_of_arguments() const override { return 2; }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE20EEEE23get_number_of_argumentsEv
Line
Count
Source
520
2
    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
22
    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
24
                        uint32_t result, size_t input_rows_count) const override {
524
24
        auto res_column = ColumnString::create();
525
24
        ColumnPtr argument_column =
526
24
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
527
24
        ColumnPtr argument_column_2;
528
24
        bool is_const;
529
24
        std::tie(argument_column_2, is_const) =
530
24
                unpack_if_const(block.get_by_position(arguments[1]).column);
531
24
        auto* result_column = res_column.get();
532
533
24
        if (is_const) {
534
4
            RETURN_IF_ERROR(Impl::template execute<true>(context, result_column, argument_column,
535
4
                                                         argument_column_2, input_rows_count));
536
20
        } else {
537
20
            RETURN_IF_ERROR(Impl::template execute<false>(context, result_column, argument_column,
538
20
                                                          argument_column_2, input_rows_count));
539
20
        }
540
541
24
        block.replace_by_position(result, std::move(res_column));
542
24
        return Status::OK();
543
24
    }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundDoubleImplEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
523
2
                        uint32_t result, size_t input_rows_count) const override {
524
2
        auto res_column = ColumnString::create();
525
2
        ColumnPtr argument_column =
526
2
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
527
2
        ColumnPtr argument_column_2;
528
2
        bool is_const;
529
2
        std::tie(argument_column_2, is_const) =
530
2
                unpack_if_const(block.get_by_position(arguments[1]).column);
531
2
        auto* result_column = res_column.get();
532
533
2
        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
2
        } else {
537
2
            RETURN_IF_ERROR(Impl::template execute<false>(context, result_column, argument_column,
538
2
                                                          argument_column_2, input_rows_count));
539
2
        }
540
541
2
        block.replace_by_position(result, std::move(res_column));
542
2
        return Status::OK();
543
2
    }
_ZNK5doris25FunctionStringFormatRoundINS_20FormatRoundInt64ImplEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
523
2
                        uint32_t result, size_t input_rows_count) const override {
524
2
        auto res_column = ColumnString::create();
525
2
        ColumnPtr argument_column =
526
2
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
527
2
        ColumnPtr argument_column_2;
528
2
        bool is_const;
529
2
        std::tie(argument_column_2, is_const) =
530
2
                unpack_if_const(block.get_by_position(arguments[1]).column);
531
2
        auto* result_column = res_column.get();
532
533
2
        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
2
        } else {
537
2
            RETURN_IF_ERROR(Impl::template execute<false>(context, result_column, argument_column,
538
2
                                                          argument_column_2, input_rows_count));
539
2
        }
540
541
2
        block.replace_by_position(result, std::move(res_column));
542
2
        return Status::OK();
543
2
    }
_ZNK5doris25FunctionStringFormatRoundINS_21FormatRoundInt128ImplEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
523
2
                        uint32_t result, size_t input_rows_count) const override {
524
2
        auto res_column = ColumnString::create();
525
2
        ColumnPtr argument_column =
526
2
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
527
2
        ColumnPtr argument_column_2;
528
2
        bool is_const;
529
2
        std::tie(argument_column_2, is_const) =
530
2
                unpack_if_const(block.get_by_position(arguments[1]).column);
531
2
        auto* result_column = res_column.get();
532
533
2
        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
2
        } else {
537
2
            RETURN_IF_ERROR(Impl::template execute<false>(context, result_column, argument_column,
538
2
                                                          argument_column_2, input_rows_count));
539
2
        }
540
541
2
        block.replace_by_position(result, std::move(res_column));
542
2
        return Status::OK();
543
2
    }
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE20EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
523
2
                        uint32_t result, size_t input_rows_count) const override {
524
2
        auto res_column = ColumnString::create();
525
2
        ColumnPtr argument_column =
526
2
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
527
2
        ColumnPtr argument_column_2;
528
2
        bool is_const;
529
2
        std::tie(argument_column_2, is_const) =
530
2
                unpack_if_const(block.get_by_position(arguments[1]).column);
531
2
        auto* result_column = res_column.get();
532
533
2
        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
2
        } else {
537
2
            RETURN_IF_ERROR(Impl::template execute<false>(context, result_column, argument_column,
538
2
                                                          argument_column_2, input_rows_count));
539
2
        }
540
541
2
        block.replace_by_position(result, std::move(res_column));
542
2
        return Status::OK();
543
2
    }
Unexecuted instantiation: _ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE28EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
_ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE29EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
523
16
                        uint32_t result, size_t input_rows_count) const override {
524
16
        auto res_column = ColumnString::create();
525
16
        ColumnPtr argument_column =
526
16
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
527
16
        ColumnPtr argument_column_2;
528
16
        bool is_const;
529
16
        std::tie(argument_column_2, is_const) =
530
16
                unpack_if_const(block.get_by_position(arguments[1]).column);
531
16
        auto* result_column = res_column.get();
532
533
16
        if (is_const) {
534
4
            RETURN_IF_ERROR(Impl::template execute<true>(context, result_column, argument_column,
535
4
                                                         argument_column_2, input_rows_count));
536
12
        } else {
537
12
            RETURN_IF_ERROR(Impl::template execute<false>(context, result_column, argument_column,
538
12
                                                          argument_column_2, input_rows_count));
539
12
        }
540
541
16
        block.replace_by_position(result, std::move(res_column));
542
16
        return Status::OK();
543
16
    }
Unexecuted instantiation: _ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE30EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris25FunctionStringFormatRoundINS_22FormatRoundDecimalImplILNS_13PrimitiveTypeE35EEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
544
};
545
546
struct FormatRoundDoubleImpl {
547
2
    static DataTypes get_variadic_argument_types() {
548
2
        return {std::make_shared<DataTypeFloat64>(), std::make_shared<DataTypeInt32>()};
549
2
    }
550
551
8
    static std::string add_thousands_separator(const std::string& formatted_num) {
552
        //  Find the position of the decimal point
553
8
        size_t dot_pos = formatted_num.find('.');
554
8
        if (dot_pos == std::string::npos) {
555
0
            dot_pos = formatted_num.size();
556
0
        }
557
558
        // Handle the integer part
559
8
        int start = (formatted_num[0] == '-') ? 1 : 0;
560
8
        int digit_count = dot_pos - start;
561
562
        // There is no need to add commas.
563
8
        if (digit_count <= 3) {
564
4
            return formatted_num;
565
4
        }
566
567
4
        std::string result;
568
569
4
        if (start == 1) result += '-';
570
571
        // Add the integer part (with comma)
572
4
        int first_group = digit_count % 3;
573
4
        if (first_group == 0) first_group = 3;
574
4
        result.append(formatted_num, start, first_group);
575
576
12
        for (size_t i = start + first_group; i < dot_pos; i += 3) {
577
8
            result += ',';
578
8
            result.append(formatted_num, i, 3);
579
8
        }
580
581
        // Add the decimal part (keep as it is)
582
4
        if (dot_pos != formatted_num.size()) {
583
4
            result.append(formatted_num, dot_pos);
584
4
        }
585
586
4
        return result;
587
8
    }
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
2
                          size_t input_rows_count) {
593
2
        const auto& arg_column_data_2 =
594
2
                assert_cast<const ColumnInt32*>(decimal_places_col_ptr.get())->get_data();
595
2
        const auto* data_column = assert_cast<const ColumnFloat64*>(col_ptr.get());
596
        // when scale is above 38, we will go here
597
10
        for (size_t i = 0; i < input_rows_count; i++) {
598
8
            int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
599
8
            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
8
            double value = MathFunctions::my_double_round(data_column->get_element(i),
606
8
                                                          decimal_places, false, false);
607
8
            std::string formatted_value = fmt::format("{:.{}f}", value, decimal_places);
608
8
            if (std::isfinite(value)) {
609
8
                result_column->insert_value(add_thousands_separator(formatted_value));
610
8
            } 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
8
        }
616
2
        return Status::OK();
617
2
    }
Unexecuted instantiation: _ZN5doris21FormatRoundDoubleImpl7executeILb1EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EESC_m
_ZN5doris21FormatRoundDoubleImpl7executeILb0EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EESC_m
Line
Count
Source
592
2
                          size_t input_rows_count) {
593
2
        const auto& arg_column_data_2 =
594
2
                assert_cast<const ColumnInt32*>(decimal_places_col_ptr.get())->get_data();
595
2
        const auto* data_column = assert_cast<const ColumnFloat64*>(col_ptr.get());
596
        // when scale is above 38, we will go here
597
10
        for (size_t i = 0; i < input_rows_count; i++) {
598
8
            int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
599
8
            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
8
            double value = MathFunctions::my_double_round(data_column->get_element(i),
606
8
                                                          decimal_places, false, false);
607
8
            std::string formatted_value = fmt::format("{:.{}f}", value, decimal_places);
608
8
            if (std::isfinite(value)) {
609
8
                result_column->insert_value(add_thousands_separator(formatted_value));
610
8
            } 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
8
        }
616
2
        return Status::OK();
617
2
    }
618
};
619
620
struct FormatRoundInt64Impl {
621
2
    static DataTypes get_variadic_argument_types() {
622
2
        return {std::make_shared<DataTypeInt64>(), std::make_shared<DataTypeInt32>()};
623
2
    }
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
2
                          size_t input_rows_count) {
629
2
        const auto* data_column = assert_cast<const ColumnInt64*>(col_ptr.get());
630
2
        const auto& arg_column_data_2 =
631
2
                assert_cast<const ColumnInt32*>(decimal_places_col_ptr.get())->get_data();
632
18
        for (size_t i = 0; i < input_rows_count; i++) {
633
16
            int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
634
16
            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
16
            Int64 value = data_column->get_element(i);
640
16
            StringRef str =
641
16
                    FormatRound::do_format_round<Int64, FormatRound::MAX_FORMAT_LEN_INT64()>(
642
16
                            context, 0, value, 0, decimal_places);
643
16
            result_column->insert_data(str.data, str.size);
644
16
        }
645
2
        return Status::OK();
646
2
    }
Unexecuted instantiation: _ZN5doris20FormatRoundInt64Impl7executeILb1EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EESC_m
_ZN5doris20FormatRoundInt64Impl7executeILb0EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EESC_m
Line
Count
Source
628
2
                          size_t input_rows_count) {
629
2
        const auto* data_column = assert_cast<const ColumnInt64*>(col_ptr.get());
630
2
        const auto& arg_column_data_2 =
631
2
                assert_cast<const ColumnInt32*>(decimal_places_col_ptr.get())->get_data();
632
18
        for (size_t i = 0; i < input_rows_count; i++) {
633
16
            int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
634
16
            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
16
            Int64 value = data_column->get_element(i);
640
16
            StringRef str =
641
16
                    FormatRound::do_format_round<Int64, FormatRound::MAX_FORMAT_LEN_INT64()>(
642
16
                            context, 0, value, 0, decimal_places);
643
16
            result_column->insert_data(str.data, str.size);
644
16
        }
645
2
        return Status::OK();
646
2
    }
647
};
648
649
struct FormatRoundInt128Impl {
650
2
    static DataTypes get_variadic_argument_types() {
651
2
        return {std::make_shared<DataTypeInt128>(), std::make_shared<DataTypeInt32>()};
652
2
    }
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
2
                          size_t input_rows_count) {
658
2
        const auto* data_column = assert_cast<const ColumnInt128*>(col_ptr.get());
659
2
        const auto& arg_column_data_2 =
660
2
                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
20
        for (size_t i = 0; i < input_rows_count; i++) {
665
18
            int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
666
18
            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
18
            Int128 value = data_column->get_element(i);
672
18
            StringRef str =
673
18
                    FormatRound::do_format_round<Int128, FormatRound::MAX_FORMAT_LEN_INT128()>(
674
18
                            context, 0, value, 0, decimal_places);
675
18
            result_column->insert_data(str.data, str.size);
676
18
        }
677
2
        return Status::OK();
678
2
    }
Unexecuted instantiation: _ZN5doris21FormatRoundInt128Impl7executeILb1EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EESC_m
_ZN5doris21FormatRoundInt128Impl7executeILb0EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EESC_m
Line
Count
Source
657
2
                          size_t input_rows_count) {
658
2
        const auto* data_column = assert_cast<const ColumnInt128*>(col_ptr.get());
659
2
        const auto& arg_column_data_2 =
660
2
                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
20
        for (size_t i = 0; i < input_rows_count; i++) {
665
18
            int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
666
18
            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
18
            Int128 value = data_column->get_element(i);
672
18
            StringRef str =
673
18
                    FormatRound::do_format_round<Int128, FormatRound::MAX_FORMAT_LEN_INT128()>(
674
18
                            context, 0, value, 0, decimal_places);
675
18
            result_column->insert_data(str.data, str.size);
676
18
        }
677
2
        return Status::OK();
678
2
    }
679
};
680
681
template <PrimitiveType Type>
682
struct FormatRoundDecimalImpl {
683
10
    static DataTypes get_variadic_argument_types() {
684
10
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>(),
685
10
                std::make_shared<DataTypeInt32>()};
686
10
    }
_ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE20EE27get_variadic_argument_typesEv
Line
Count
Source
683
2
    static DataTypes get_variadic_argument_types() {
684
2
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>(),
685
2
                std::make_shared<DataTypeInt32>()};
686
2
    }
_ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE28EE27get_variadic_argument_typesEv
Line
Count
Source
683
2
    static DataTypes get_variadic_argument_types() {
684
2
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>(),
685
2
                std::make_shared<DataTypeInt32>()};
686
2
    }
_ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE29EE27get_variadic_argument_typesEv
Line
Count
Source
683
2
    static DataTypes get_variadic_argument_types() {
684
2
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>(),
685
2
                std::make_shared<DataTypeInt32>()};
686
2
    }
_ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE30EE27get_variadic_argument_typesEv
Line
Count
Source
683
2
    static DataTypes get_variadic_argument_types() {
684
2
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>(),
685
2
                std::make_shared<DataTypeInt32>()};
686
2
    }
_ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE35EE27get_variadic_argument_typesEv
Line
Count
Source
683
2
    static DataTypes get_variadic_argument_types() {
684
2
        return {std::make_shared<typename PrimitiveTypeTraits<Type>::DataType>(),
685
2
                std::make_shared<DataTypeInt32>()};
686
2
    }
687
688
    template <bool is_const>
689
    static Status execute(FunctionContext* context, ColumnString* result_column, ColumnPtr col_ptr,
690
18
                          ColumnPtr decimal_places_col_ptr, size_t input_rows_count) {
691
18
        const auto& arg_column_data_2 =
692
18
                assert_cast<const ColumnInt32*>(decimal_places_col_ptr.get())->get_data();
693
18
        if (const auto* decimalv2_column = check_and_get_column<ColumnDecimal128V2>(*col_ptr)) {
694
8
            for (size_t i = 0; i < input_rows_count; i++) {
695
6
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
696
6
                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
6
                const auto& value = decimalv2_column->get_element(i);
702
                // unified_frac_value has 3 digits
703
6
                auto unified_frac_value = value.frac_value() / 1000000;
704
6
                StringRef str =
705
6
                        FormatRound::do_format_round<Int128,
706
6
                                                     FormatRound::MAX_FORMAT_LEN_DEC128V2()>(
707
6
                                context, 3, value.int_value(), unified_frac_value, decimal_places);
708
709
6
                result_column->insert_data(str.data, str.size);
710
6
            }
711
16
        } 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
16
        } else if (const auto* decimal64_column = check_and_get_column<ColumnDecimal64>(*col_ptr)) {
730
16
            const UInt32 scale = decimal64_column->get_scale();
731
38
            for (size_t i = 0; i < input_rows_count; i++) {
732
22
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
733
22
                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
22
                const Int64& frac_part = decimal64_column->get_fractional_part(i);
739
22
                const Int64& whole_part = decimal64_column->get_intergral_part(i);
740
741
22
                StringRef str =
742
22
                        FormatRound::do_format_round<Int64, FormatRound::MAX_FORMAT_LEN_DEC64()>(
743
22
                                context, scale, whole_part, frac_part, decimal_places);
744
745
22
                result_column->insert_data(str.data, str.size);
746
22
            }
747
16
        } 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
18
        return Status::OK();
772
18
    }
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
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
8
            for (size_t i = 0; i < input_rows_count; i++) {
695
6
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
696
6
                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
6
                const auto& value = decimalv2_column->get_element(i);
702
                // unified_frac_value has 3 digits
703
6
                auto unified_frac_value = value.frac_value() / 1000000;
704
6
                StringRef str =
705
6
                        FormatRound::do_format_round<Int128,
706
6
                                                     FormatRound::MAX_FORMAT_LEN_DEC128V2()>(
707
6
                                context, 3, value.int_value(), unified_frac_value, decimal_places);
708
709
6
                result_column->insert_data(str.data, str.size);
710
6
            }
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
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
2
        return Status::OK();
772
2
    }
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
4
                          ColumnPtr decimal_places_col_ptr, size_t input_rows_count) {
691
4
        const auto& arg_column_data_2 =
692
4
                assert_cast<const ColumnInt32*>(decimal_places_col_ptr.get())->get_data();
693
4
        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
4
        } 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
4
        } else if (const auto* decimal64_column = check_and_get_column<ColumnDecimal64>(*col_ptr)) {
730
4
            const UInt32 scale = decimal64_column->get_scale();
731
8
            for (size_t i = 0; i < input_rows_count; i++) {
732
4
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
733
4
                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
4
                const Int64& frac_part = decimal64_column->get_fractional_part(i);
739
4
                const Int64& whole_part = decimal64_column->get_intergral_part(i);
740
741
4
                StringRef str =
742
4
                        FormatRound::do_format_round<Int64, FormatRound::MAX_FORMAT_LEN_DEC64()>(
743
4
                                context, scale, whole_part, frac_part, decimal_places);
744
745
4
                result_column->insert_data(str.data, str.size);
746
4
            }
747
4
        } 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
4
        return Status::OK();
772
4
    }
_ZN5doris22FormatRoundDecimalImplILNS_13PrimitiveTypeE29EE7executeILb0EEENS_6StatusEPNS_15FunctionContextEPNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrISB_EESE_m
Line
Count
Source
690
12
                          ColumnPtr decimal_places_col_ptr, size_t input_rows_count) {
691
12
        const auto& arg_column_data_2 =
692
12
                assert_cast<const ColumnInt32*>(decimal_places_col_ptr.get())->get_data();
693
12
        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
12
        } 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
12
        } else if (const auto* decimal64_column = check_and_get_column<ColumnDecimal64>(*col_ptr)) {
730
12
            const UInt32 scale = decimal64_column->get_scale();
731
30
            for (size_t i = 0; i < input_rows_count; i++) {
732
18
                int32_t decimal_places = arg_column_data_2[index_check_const<is_const>(i)];
733
18
                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
18
                const Int64& frac_part = decimal64_column->get_fractional_part(i);
739
18
                const Int64& whole_part = decimal64_column->get_intergral_part(i);
740
741
18
                StringRef str =
742
18
                        FormatRound::do_format_round<Int64, FormatRound::MAX_FORMAT_LEN_DEC64()>(
743
18
                                context, scale, whole_part, frac_part, decimal_places);
744
745
18
                result_column->insert_data(str.data, str.size);
746
18
            }
747
12
        } 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
12
        return Status::OK();
772
12
    }
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