Coverage Report

Created: 2026-03-13 14:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/function/function_format.cpp
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
#include <glog/logging.h>
19
20
#include <cstdio>
21
#include <regex>
22
#include <vector>
23
24
#include "common/status.h"
25
#include "core/assert_cast.h"
26
#include "core/column/column.h"
27
#include "core/column/column_vector.h"
28
#include "core/data_type/data_type_number.h"
29
#include "core/data_type/define_primitive_type.h"
30
#include "core/types.h"
31
#include "exprs/function/cast_type_to_either.h"
32
#include "exprs/function/simple_function_factory.h"
33
34
namespace doris {
35
36
class FunctionFormatNumber : public IFunction {
37
public:
38
    static constexpr auto name = "format_number";
39
40
    static constexpr const char* UNITS[6] = {"", "K", "M", "B", "T", "Q"};
41
42
47
    static FunctionPtr create() { return std::make_shared<FunctionFormatNumber>(); }
43
44
1
    String get_name() const override { return name; }
45
46
38
    size_t get_number_of_arguments() const override { return 1; }
47
48
39
    bool is_variadic() const override { return false; }
49
50
38
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
51
38
        return std::make_shared<DataTypeString>();
52
38
    }
53
54
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
55
46
                        uint32_t result, size_t input_rows_count) const override {
56
46
        auto column = block.get_by_position(arguments[0]).column;
57
46
        const auto& column_data = assert_cast<const ColumnFloat64*>(column.get())->get_data();
58
46
        auto col_res = ColumnString::create();
59
46
        fmt::memory_buffer buffer;
60
61
96
        for (auto i = 0; i < input_rows_count; ++i) {
62
50
            auto res_data = format_number(buffer, column_data[i]);
63
50
            col_res->insert_data(res_data.data(), res_data.length());
64
50
        }
65
46
        block.replace_by_position(result, std::move(col_res));
66
46
        return Status::OK();
67
46
    }
68
69
50
    std::string format_number(fmt::memory_buffer& buffer, double number) const {
70
50
        buffer.clear();
71
50
        double abs_number = std::abs(number);
72
50
        int unit_index = 0;
73
140
        while (abs_number >= 1000 && unit_index < 5) {
74
90
            abs_number /= 1000;
75
90
            ++unit_index;
76
90
        }
77
50
        if (number < 0) {
78
13
            fmt::format_to(buffer, "-");
79
13
        }
80
50
        if (abs_number == 1) {
81
            //eg: 1000 ---> 1K
82
8
            fmt::format_to(buffer, "{}", abs_number);
83
42
        } else if (abs_number < 10) {
84
            //eg: 1239 ---> 1.24K only want to show 2 decimal
85
19
            fmt::format_to(buffer, "{:.2f}", abs_number);
86
23
        } else if (abs_number < 100) {
87
            //eg: 12399999 ---> 12.4M only want to show 1 decimal
88
8
            fmt::format_to(buffer, "{:.1f}", abs_number);
89
15
        } else {
90
            // eg: 999999999999999 ---> 1000T only want to show 0 decimal
91
15
            fmt::format_to(buffer, "{:.0f}", abs_number);
92
15
        }
93
50
        fmt::format_to(buffer, UNITS[unit_index]);
94
50
        return fmt::to_string(buffer);
95
50
    }
96
};
97
98
class FunctionFormat : public IFunction {
99
public:
100
    static constexpr auto name = "format";
101
102
31
    static FunctionPtr create() { return std::make_shared<FunctionFormat>(); }
103
104
0
    String get_name() const override { return name; }
105
106
0
    size_t get_number_of_arguments() const override { return 0; }
107
108
23
    bool is_variadic() const override { return true; }
109
110
22
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
111
22
        return std::make_shared<DataTypeString>();
112
22
    }
113
114
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
115
28
                        uint32_t result, size_t input_rows_count) const override {
116
28
        DCHECK_GE(arguments.size(), 2);
117
28
        bool valid =
118
28
                cast_type(block.get_by_position(arguments[1]).type.get(), [&](const auto& type) {
119
28
                    using DataType = std::decay_t<decltype(type)>;
120
28
                    using ColVecData =
121
28
                            std::conditional_t<is_number(DataType::PType),
122
28
                                               ColumnVector<DataType::PType>, ColumnString>;
123
28
                    if (auto col = check_and_get_column<ColVecData>(
124
28
                                           block.get_by_position(arguments[1]).column.get()) ||
125
28
                                   is_column_const(*block.get_by_position(arguments[1]).column)) {
126
28
                        execute_inner<ColVecData, DataType::PType>(block, arguments, result,
127
28
                                                                   input_rows_count);
128
28
                        return true;
129
28
                    }
130
0
                    return false;
131
28
                });
_ZZNK5doris14FunctionFormat12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlRKT_E_clINS_14DataTypeNumberILNS_13PrimitiveTypeE3EEEEEDaSC_
Line
Count
Source
118
5
                cast_type(block.get_by_position(arguments[1]).type.get(), [&](const auto& type) {
119
5
                    using DataType = std::decay_t<decltype(type)>;
120
5
                    using ColVecData =
121
5
                            std::conditional_t<is_number(DataType::PType),
122
5
                                               ColumnVector<DataType::PType>, ColumnString>;
123
5
                    if (auto col = check_and_get_column<ColVecData>(
124
5
                                           block.get_by_position(arguments[1]).column.get()) ||
125
5
                                   is_column_const(*block.get_by_position(arguments[1]).column)) {
126
5
                        execute_inner<ColVecData, DataType::PType>(block, arguments, result,
127
5
                                                                   input_rows_count);
128
5
                        return true;
129
5
                    }
130
0
                    return false;
131
5
                });
_ZZNK5doris14FunctionFormat12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlRKT_E_clINS_14DataTypeNumberILNS_13PrimitiveTypeE4EEEEEDaSC_
Line
Count
Source
118
1
                cast_type(block.get_by_position(arguments[1]).type.get(), [&](const auto& type) {
119
1
                    using DataType = std::decay_t<decltype(type)>;
120
1
                    using ColVecData =
121
1
                            std::conditional_t<is_number(DataType::PType),
122
1
                                               ColumnVector<DataType::PType>, ColumnString>;
123
1
                    if (auto col = check_and_get_column<ColVecData>(
124
1
                                           block.get_by_position(arguments[1]).column.get()) ||
125
1
                                   is_column_const(*block.get_by_position(arguments[1]).column)) {
126
1
                        execute_inner<ColVecData, DataType::PType>(block, arguments, result,
127
1
                                                                   input_rows_count);
128
1
                        return true;
129
1
                    }
130
0
                    return false;
131
1
                });
Unexecuted instantiation: _ZZNK5doris14FunctionFormat12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlRKT_E_clINS_14DataTypeNumberILNS_13PrimitiveTypeE5EEEEEDaSC_
Unexecuted instantiation: _ZZNK5doris14FunctionFormat12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlRKT_E_clINS_14DataTypeNumberILNS_13PrimitiveTypeE6EEEEEDaSC_
_ZZNK5doris14FunctionFormat12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlRKT_E_clINS_14DataTypeNumberILNS_13PrimitiveTypeE7EEEEEDaSC_
Line
Count
Source
118
4
                cast_type(block.get_by_position(arguments[1]).type.get(), [&](const auto& type) {
119
4
                    using DataType = std::decay_t<decltype(type)>;
120
4
                    using ColVecData =
121
4
                            std::conditional_t<is_number(DataType::PType),
122
4
                                               ColumnVector<DataType::PType>, ColumnString>;
123
4
                    if (auto col = check_and_get_column<ColVecData>(
124
4
                                           block.get_by_position(arguments[1]).column.get()) ||
125
4
                                   is_column_const(*block.get_by_position(arguments[1]).column)) {
126
4
                        execute_inner<ColVecData, DataType::PType>(block, arguments, result,
127
4
                                                                   input_rows_count);
128
4
                        return true;
129
4
                    }
130
0
                    return false;
131
4
                });
Unexecuted instantiation: _ZZNK5doris14FunctionFormat12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlRKT_E_clINS_14DataTypeNumberILNS_13PrimitiveTypeE8EEEEEDaSC_
_ZZNK5doris14FunctionFormat12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlRKT_E_clINS_14DataTypeNumberILNS_13PrimitiveTypeE9EEEEEDaSC_
Line
Count
Source
118
10
                cast_type(block.get_by_position(arguments[1]).type.get(), [&](const auto& type) {
119
10
                    using DataType = std::decay_t<decltype(type)>;
120
10
                    using ColVecData =
121
10
                            std::conditional_t<is_number(DataType::PType),
122
10
                                               ColumnVector<DataType::PType>, ColumnString>;
123
10
                    if (auto col = check_and_get_column<ColVecData>(
124
10
                                           block.get_by_position(arguments[1]).column.get()) ||
125
10
                                   is_column_const(*block.get_by_position(arguments[1]).column)) {
126
10
                        execute_inner<ColVecData, DataType::PType>(block, arguments, result,
127
10
                                                                   input_rows_count);
128
10
                        return true;
129
10
                    }
130
0
                    return false;
131
10
                });
_ZZNK5doris14FunctionFormat12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlRKT_E_clINS_14DataTypeStringEEEDaSC_
Line
Count
Source
118
8
                cast_type(block.get_by_position(arguments[1]).type.get(), [&](const auto& type) {
119
8
                    using DataType = std::decay_t<decltype(type)>;
120
8
                    using ColVecData =
121
8
                            std::conditional_t<is_number(DataType::PType),
122
8
                                               ColumnVector<DataType::PType>, ColumnString>;
123
8
                    if (auto col = check_and_get_column<ColVecData>(
124
8
                                           block.get_by_position(arguments[1]).column.get()) ||
125
8
                                   is_column_const(*block.get_by_position(arguments[1]).column)) {
126
8
                        execute_inner<ColVecData, DataType::PType>(block, arguments, result,
127
8
                                                                   input_rows_count);
128
8
                        return true;
129
8
                    }
130
0
                    return false;
131
8
                });
132
28
        if (!valid) {
133
0
            return Status::RuntimeError(
134
0
                    "{}'s argument does not match the expected data type, type: {}, column: {}",
135
0
                    get_name(), block.get_by_position(arguments[1]).type->get_name(),
136
0
                    block.get_by_position(arguments[1]).column->dump_structure());
137
0
        }
138
28
        return Status::OK();
139
28
    }
140
141
    template <typename F>
142
28
    static bool cast_type(const IDataType* type, F&& f) {
143
28
        return cast_type_to_either<DataTypeInt8, DataTypeInt16, DataTypeInt32, DataTypeInt64,
144
28
                                   DataTypeInt128, DataTypeFloat32, DataTypeFloat64,
145
28
                                   DataTypeString>(type, std::forward<F>(f));
146
28
    }
147
148
    template <typename ColVecData, PrimitiveType T>
149
    void execute_inner(Block& block, const ColumnNumbers& arguments, uint32_t result,
150
28
                       size_t input_rows_count) const {
151
28
        size_t argument_size = arguments.size();
152
28
        std::vector<ColumnPtr> argument_columns(argument_size);
153
28
        auto result_column = ColumnString::create();
154
155
        // maybe most user is format(const, column), so only handle this case const column
156
28
        if (argument_size == 2) {
157
19
            std::vector<uint8_t> is_consts(argument_size);
158
19
            std::tie(argument_columns[0], is_consts[0]) =
159
19
                    unpack_if_const(block.get_by_position(arguments[0]).column);
160
19
            std::tie(argument_columns[1], is_consts[1]) =
161
19
                    unpack_if_const(block.get_by_position(arguments[1]).column);
162
19
            execute_for_two_argument<ColVecData, T>(argument_columns, is_consts,
163
19
                                                    assert_cast<ColumnString*>(result_column.get()),
164
19
                                                    input_rows_count);
165
19
        } else {
166
36
            for (size_t i = 0; i < argument_size; ++i) {
167
27
                argument_columns[i] = block.get_by_position(arguments[i])
168
27
                                              .column->convert_to_full_column_if_const();
169
27
            }
170
9
            execute_for_others_arg<ColVecData, T>(argument_columns,
171
9
                                                  assert_cast<ColumnString*>(result_column.get()),
172
9
                                                  argument_size, input_rows_count);
173
9
        }
174
175
28
        block.replace_by_position(result, std::move(result_column));
176
28
    }
_ZNK5doris14FunctionFormat13execute_innerINS_12ColumnVectorILNS_13PrimitiveTypeE3EEELS3_3EEEvRNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
150
5
                       size_t input_rows_count) const {
151
5
        size_t argument_size = arguments.size();
152
5
        std::vector<ColumnPtr> argument_columns(argument_size);
153
5
        auto result_column = ColumnString::create();
154
155
        // maybe most user is format(const, column), so only handle this case const column
156
5
        if (argument_size == 2) {
157
5
            std::vector<uint8_t> is_consts(argument_size);
158
5
            std::tie(argument_columns[0], is_consts[0]) =
159
5
                    unpack_if_const(block.get_by_position(arguments[0]).column);
160
5
            std::tie(argument_columns[1], is_consts[1]) =
161
5
                    unpack_if_const(block.get_by_position(arguments[1]).column);
162
5
            execute_for_two_argument<ColVecData, T>(argument_columns, is_consts,
163
5
                                                    assert_cast<ColumnString*>(result_column.get()),
164
5
                                                    input_rows_count);
165
5
        } else {
166
0
            for (size_t i = 0; i < argument_size; ++i) {
167
0
                argument_columns[i] = block.get_by_position(arguments[i])
168
0
                                              .column->convert_to_full_column_if_const();
169
0
            }
170
0
            execute_for_others_arg<ColVecData, T>(argument_columns,
171
0
                                                  assert_cast<ColumnString*>(result_column.get()),
172
0
                                                  argument_size, input_rows_count);
173
0
        }
174
175
5
        block.replace_by_position(result, std::move(result_column));
176
5
    }
_ZNK5doris14FunctionFormat13execute_innerINS_12ColumnVectorILNS_13PrimitiveTypeE4EEELS3_4EEEvRNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
150
1
                       size_t input_rows_count) const {
151
1
        size_t argument_size = arguments.size();
152
1
        std::vector<ColumnPtr> argument_columns(argument_size);
153
1
        auto result_column = ColumnString::create();
154
155
        // maybe most user is format(const, column), so only handle this case const column
156
1
        if (argument_size == 2) {
157
0
            std::vector<uint8_t> is_consts(argument_size);
158
0
            std::tie(argument_columns[0], is_consts[0]) =
159
0
                    unpack_if_const(block.get_by_position(arguments[0]).column);
160
0
            std::tie(argument_columns[1], is_consts[1]) =
161
0
                    unpack_if_const(block.get_by_position(arguments[1]).column);
162
0
            execute_for_two_argument<ColVecData, T>(argument_columns, is_consts,
163
0
                                                    assert_cast<ColumnString*>(result_column.get()),
164
0
                                                    input_rows_count);
165
1
        } else {
166
4
            for (size_t i = 0; i < argument_size; ++i) {
167
3
                argument_columns[i] = block.get_by_position(arguments[i])
168
3
                                              .column->convert_to_full_column_if_const();
169
3
            }
170
1
            execute_for_others_arg<ColVecData, T>(argument_columns,
171
1
                                                  assert_cast<ColumnString*>(result_column.get()),
172
1
                                                  argument_size, input_rows_count);
173
1
        }
174
175
1
        block.replace_by_position(result, std::move(result_column));
176
1
    }
Unexecuted instantiation: _ZNK5doris14FunctionFormat13execute_innerINS_12ColumnVectorILNS_13PrimitiveTypeE5EEELS3_5EEEvRNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris14FunctionFormat13execute_innerINS_12ColumnVectorILNS_13PrimitiveTypeE6EEELS3_6EEEvRNS_5BlockERKSt6vectorIjSaIjEEjm
_ZNK5doris14FunctionFormat13execute_innerINS_12ColumnVectorILNS_13PrimitiveTypeE7EEELS3_7EEEvRNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
150
4
                       size_t input_rows_count) const {
151
4
        size_t argument_size = arguments.size();
152
4
        std::vector<ColumnPtr> argument_columns(argument_size);
153
4
        auto result_column = ColumnString::create();
154
155
        // maybe most user is format(const, column), so only handle this case const column
156
4
        if (argument_size == 2) {
157
4
            std::vector<uint8_t> is_consts(argument_size);
158
4
            std::tie(argument_columns[0], is_consts[0]) =
159
4
                    unpack_if_const(block.get_by_position(arguments[0]).column);
160
4
            std::tie(argument_columns[1], is_consts[1]) =
161
4
                    unpack_if_const(block.get_by_position(arguments[1]).column);
162
4
            execute_for_two_argument<ColVecData, T>(argument_columns, is_consts,
163
4
                                                    assert_cast<ColumnString*>(result_column.get()),
164
4
                                                    input_rows_count);
165
4
        } else {
166
0
            for (size_t i = 0; i < argument_size; ++i) {
167
0
                argument_columns[i] = block.get_by_position(arguments[i])
168
0
                                              .column->convert_to_full_column_if_const();
169
0
            }
170
0
            execute_for_others_arg<ColVecData, T>(argument_columns,
171
0
                                                  assert_cast<ColumnString*>(result_column.get()),
172
0
                                                  argument_size, input_rows_count);
173
0
        }
174
175
4
        block.replace_by_position(result, std::move(result_column));
176
4
    }
Unexecuted instantiation: _ZNK5doris14FunctionFormat13execute_innerINS_12ColumnVectorILNS_13PrimitiveTypeE8EEELS3_8EEEvRNS_5BlockERKSt6vectorIjSaIjEEjm
_ZNK5doris14FunctionFormat13execute_innerINS_12ColumnVectorILNS_13PrimitiveTypeE9EEELS3_9EEEvRNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
150
10
                       size_t input_rows_count) const {
151
10
        size_t argument_size = arguments.size();
152
10
        std::vector<ColumnPtr> argument_columns(argument_size);
153
10
        auto result_column = ColumnString::create();
154
155
        // maybe most user is format(const, column), so only handle this case const column
156
10
        if (argument_size == 2) {
157
9
            std::vector<uint8_t> is_consts(argument_size);
158
9
            std::tie(argument_columns[0], is_consts[0]) =
159
9
                    unpack_if_const(block.get_by_position(arguments[0]).column);
160
9
            std::tie(argument_columns[1], is_consts[1]) =
161
9
                    unpack_if_const(block.get_by_position(arguments[1]).column);
162
9
            execute_for_two_argument<ColVecData, T>(argument_columns, is_consts,
163
9
                                                    assert_cast<ColumnString*>(result_column.get()),
164
9
                                                    input_rows_count);
165
9
        } else {
166
4
            for (size_t i = 0; i < argument_size; ++i) {
167
3
                argument_columns[i] = block.get_by_position(arguments[i])
168
3
                                              .column->convert_to_full_column_if_const();
169
3
            }
170
1
            execute_for_others_arg<ColVecData, T>(argument_columns,
171
1
                                                  assert_cast<ColumnString*>(result_column.get()),
172
1
                                                  argument_size, input_rows_count);
173
1
        }
174
175
10
        block.replace_by_position(result, std::move(result_column));
176
10
    }
_ZNK5doris14FunctionFormat13execute_innerINS_9ColumnStrIjEELNS_13PrimitiveTypeE23EEEvRNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
150
8
                       size_t input_rows_count) const {
151
8
        size_t argument_size = arguments.size();
152
8
        std::vector<ColumnPtr> argument_columns(argument_size);
153
8
        auto result_column = ColumnString::create();
154
155
        // maybe most user is format(const, column), so only handle this case const column
156
8
        if (argument_size == 2) {
157
1
            std::vector<uint8_t> is_consts(argument_size);
158
1
            std::tie(argument_columns[0], is_consts[0]) =
159
1
                    unpack_if_const(block.get_by_position(arguments[0]).column);
160
1
            std::tie(argument_columns[1], is_consts[1]) =
161
1
                    unpack_if_const(block.get_by_position(arguments[1]).column);
162
1
            execute_for_two_argument<ColVecData, T>(argument_columns, is_consts,
163
1
                                                    assert_cast<ColumnString*>(result_column.get()),
164
1
                                                    input_rows_count);
165
7
        } else {
166
28
            for (size_t i = 0; i < argument_size; ++i) {
167
21
                argument_columns[i] = block.get_by_position(arguments[i])
168
21
                                              .column->convert_to_full_column_if_const();
169
21
            }
170
7
            execute_for_others_arg<ColVecData, T>(argument_columns,
171
7
                                                  assert_cast<ColumnString*>(result_column.get()),
172
7
                                                  argument_size, input_rows_count);
173
7
        }
174
175
8
        block.replace_by_position(result, std::move(result_column));
176
8
    }
177
178
    template <typename ColVecData, PrimitiveType T>
179
    void execute_for_two_argument(std::vector<ColumnPtr>& argument_columns,
180
                                  std::vector<uint8_t>& is_consts, ColumnString* result_data_column,
181
19
                                  size_t input_rows_count) const {
182
19
        const auto& format_column = assert_cast<const ColumnString&>(*argument_columns[0].get());
183
19
        const auto& value_column = assert_cast<const ColVecData&>(*argument_columns[1].get());
184
37
        for (int i = 0; i < input_rows_count; ++i) {
185
19
            auto format =
186
19
                    format_column.get_data_at(index_check_const(i, is_consts[0])).to_string_view();
187
19
            std::string res;
188
19
            try {
189
19
                if constexpr (is_string_type(T)) {
190
1
                    auto value = value_column.get_data_at(index_check_const(i, is_consts[1]));
191
1
                    res = fmt::format(format, value);
192
18
                } else {
193
18
                    auto value = value_column.get_data()[index_check_const(i, is_consts[1])];
194
18
                    res = fmt::format(format, value);
195
18
                }
196
19
            } catch (const std::exception& e) {
197
1
                throw doris::Exception(
198
1
                        ErrorCode::INVALID_ARGUMENT,
199
1
                        "Invalid Input argument \"{}\" of function format, error: {}", format,
200
1
                        e.what());
201
1
            }
202
18
            result_data_column->insert_data(res.data(), res.length());
203
18
        }
204
19
    }
_ZNK5doris14FunctionFormat24execute_for_two_argumentINS_12ColumnVectorILNS_13PrimitiveTypeE3EEELS3_3EEEvRSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS7_EESaISA_EERS5_IhSaIhEEPNS_9ColumnStrIjEEm
Line
Count
Source
181
5
                                  size_t input_rows_count) const {
182
5
        const auto& format_column = assert_cast<const ColumnString&>(*argument_columns[0].get());
183
5
        const auto& value_column = assert_cast<const ColVecData&>(*argument_columns[1].get());
184
10
        for (int i = 0; i < input_rows_count; ++i) {
185
5
            auto format =
186
5
                    format_column.get_data_at(index_check_const(i, is_consts[0])).to_string_view();
187
5
            std::string res;
188
5
            try {
189
                if constexpr (is_string_type(T)) {
190
                    auto value = value_column.get_data_at(index_check_const(i, is_consts[1]));
191
                    res = fmt::format(format, value);
192
5
                } else {
193
5
                    auto value = value_column.get_data()[index_check_const(i, is_consts[1])];
194
5
                    res = fmt::format(format, value);
195
5
                }
196
5
            } catch (const std::exception& e) {
197
0
                throw doris::Exception(
198
0
                        ErrorCode::INVALID_ARGUMENT,
199
0
                        "Invalid Input argument \"{}\" of function format, error: {}", format,
200
0
                        e.what());
201
0
            }
202
5
            result_data_column->insert_data(res.data(), res.length());
203
5
        }
204
5
    }
Unexecuted instantiation: _ZNK5doris14FunctionFormat24execute_for_two_argumentINS_12ColumnVectorILNS_13PrimitiveTypeE4EEELS3_4EEEvRSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS7_EESaISA_EERS5_IhSaIhEEPNS_9ColumnStrIjEEm
Unexecuted instantiation: _ZNK5doris14FunctionFormat24execute_for_two_argumentINS_12ColumnVectorILNS_13PrimitiveTypeE5EEELS3_5EEEvRSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS7_EESaISA_EERS5_IhSaIhEEPNS_9ColumnStrIjEEm
Unexecuted instantiation: _ZNK5doris14FunctionFormat24execute_for_two_argumentINS_12ColumnVectorILNS_13PrimitiveTypeE6EEELS3_6EEEvRSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS7_EESaISA_EERS5_IhSaIhEEPNS_9ColumnStrIjEEm
_ZNK5doris14FunctionFormat24execute_for_two_argumentINS_12ColumnVectorILNS_13PrimitiveTypeE7EEELS3_7EEEvRSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS7_EESaISA_EERS5_IhSaIhEEPNS_9ColumnStrIjEEm
Line
Count
Source
181
4
                                  size_t input_rows_count) const {
182
4
        const auto& format_column = assert_cast<const ColumnString&>(*argument_columns[0].get());
183
4
        const auto& value_column = assert_cast<const ColVecData&>(*argument_columns[1].get());
184
8
        for (int i = 0; i < input_rows_count; ++i) {
185
4
            auto format =
186
4
                    format_column.get_data_at(index_check_const(i, is_consts[0])).to_string_view();
187
4
            std::string res;
188
4
            try {
189
                if constexpr (is_string_type(T)) {
190
                    auto value = value_column.get_data_at(index_check_const(i, is_consts[1]));
191
                    res = fmt::format(format, value);
192
4
                } else {
193
4
                    auto value = value_column.get_data()[index_check_const(i, is_consts[1])];
194
4
                    res = fmt::format(format, value);
195
4
                }
196
4
            } catch (const std::exception& e) {
197
0
                throw doris::Exception(
198
0
                        ErrorCode::INVALID_ARGUMENT,
199
0
                        "Invalid Input argument \"{}\" of function format, error: {}", format,
200
0
                        e.what());
201
0
            }
202
4
            result_data_column->insert_data(res.data(), res.length());
203
4
        }
204
4
    }
Unexecuted instantiation: _ZNK5doris14FunctionFormat24execute_for_two_argumentINS_12ColumnVectorILNS_13PrimitiveTypeE8EEELS3_8EEEvRSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS7_EESaISA_EERS5_IhSaIhEEPNS_9ColumnStrIjEEm
_ZNK5doris14FunctionFormat24execute_for_two_argumentINS_12ColumnVectorILNS_13PrimitiveTypeE9EEELS3_9EEEvRSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS7_EESaISA_EERS5_IhSaIhEEPNS_9ColumnStrIjEEm
Line
Count
Source
181
9
                                  size_t input_rows_count) const {
182
9
        const auto& format_column = assert_cast<const ColumnString&>(*argument_columns[0].get());
183
9
        const auto& value_column = assert_cast<const ColVecData&>(*argument_columns[1].get());
184
18
        for (int i = 0; i < input_rows_count; ++i) {
185
9
            auto format =
186
9
                    format_column.get_data_at(index_check_const(i, is_consts[0])).to_string_view();
187
9
            std::string res;
188
9
            try {
189
                if constexpr (is_string_type(T)) {
190
                    auto value = value_column.get_data_at(index_check_const(i, is_consts[1]));
191
                    res = fmt::format(format, value);
192
9
                } else {
193
9
                    auto value = value_column.get_data()[index_check_const(i, is_consts[1])];
194
9
                    res = fmt::format(format, value);
195
9
                }
196
9
            } catch (const std::exception& e) {
197
0
                throw doris::Exception(
198
0
                        ErrorCode::INVALID_ARGUMENT,
199
0
                        "Invalid Input argument \"{}\" of function format, error: {}", format,
200
0
                        e.what());
201
0
            }
202
9
            result_data_column->insert_data(res.data(), res.length());
203
9
        }
204
9
    }
_ZNK5doris14FunctionFormat24execute_for_two_argumentINS_9ColumnStrIjEELNS_13PrimitiveTypeE23EEEvRSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS7_EESaISA_EERS5_IhSaIhEEPS3_m
Line
Count
Source
181
1
                                  size_t input_rows_count) const {
182
1
        const auto& format_column = assert_cast<const ColumnString&>(*argument_columns[0].get());
183
1
        const auto& value_column = assert_cast<const ColVecData&>(*argument_columns[1].get());
184
1
        for (int i = 0; i < input_rows_count; ++i) {
185
1
            auto format =
186
1
                    format_column.get_data_at(index_check_const(i, is_consts[0])).to_string_view();
187
1
            std::string res;
188
1
            try {
189
1
                if constexpr (is_string_type(T)) {
190
1
                    auto value = value_column.get_data_at(index_check_const(i, is_consts[1]));
191
1
                    res = fmt::format(format, value);
192
                } else {
193
                    auto value = value_column.get_data()[index_check_const(i, is_consts[1])];
194
                    res = fmt::format(format, value);
195
                }
196
1
            } catch (const std::exception& e) {
197
1
                throw doris::Exception(
198
1
                        ErrorCode::INVALID_ARGUMENT,
199
1
                        "Invalid Input argument \"{}\" of function format, error: {}", format,
200
1
                        e.what());
201
1
            }
202
0
            result_data_column->insert_data(res.data(), res.length());
203
0
        }
204
1
    }
205
206
    template <typename ColVecData, PrimitiveType T>
207
    void execute_for_others_arg(std::vector<ColumnPtr>& argument_columns,
208
                                ColumnString* result_data_column, size_t argument_size,
209
9
                                size_t input_rows_count) const {
210
9
        const auto& format_column = assert_cast<const ColumnString&>(*argument_columns[0].get());
211
18
        for (int i = 0; i < input_rows_count; ++i) {
212
9
            auto format = format_column.get_data_at(i).to_string_view();
213
9
            std::string res;
214
9
            fmt::dynamic_format_arg_store<fmt::format_context> args;
215
9
            if constexpr (is_string_type(T)) {
216
21
                for (int col = 1; col < argument_size; ++col) {
217
14
                    const auto& arg_column_data =
218
14
                            assert_cast<const ColVecData&>(*argument_columns[col].get());
219
14
                    args.push_back(arg_column_data.get_data_at(i).to_string());
220
14
                }
221
7
            } else {
222
6
                for (int col = 1; col < argument_size; ++col) {
223
4
                    const auto& arg_column_data =
224
4
                            assert_cast<const ColVecData&>(*argument_columns[col].get()).get_data();
225
4
                    args.push_back(arg_column_data[i]);
226
4
                }
227
2
            }
228
9
            try {
229
9
                res = fmt::vformat(format, args);
230
9
            } catch (const std::exception& e) {
231
0
                throw doris::Exception(
232
0
                        ErrorCode::INVALID_ARGUMENT,
233
0
                        "Invalid Input argument \"{}\" of function format, error: {}", format,
234
0
                        e.what());
235
0
            }
236
9
            result_data_column->insert_data(res.data(), res.length());
237
9
        }
238
9
    }
Unexecuted instantiation: _ZNK5doris14FunctionFormat22execute_for_others_argINS_12ColumnVectorILNS_13PrimitiveTypeE3EEELS3_3EEEvRSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS7_EESaISA_EEPNS_9ColumnStrIjEEmm
_ZNK5doris14FunctionFormat22execute_for_others_argINS_12ColumnVectorILNS_13PrimitiveTypeE4EEELS3_4EEEvRSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS7_EESaISA_EEPNS_9ColumnStrIjEEmm
Line
Count
Source
209
1
                                size_t input_rows_count) const {
210
1
        const auto& format_column = assert_cast<const ColumnString&>(*argument_columns[0].get());
211
2
        for (int i = 0; i < input_rows_count; ++i) {
212
1
            auto format = format_column.get_data_at(i).to_string_view();
213
1
            std::string res;
214
1
            fmt::dynamic_format_arg_store<fmt::format_context> args;
215
            if constexpr (is_string_type(T)) {
216
                for (int col = 1; col < argument_size; ++col) {
217
                    const auto& arg_column_data =
218
                            assert_cast<const ColVecData&>(*argument_columns[col].get());
219
                    args.push_back(arg_column_data.get_data_at(i).to_string());
220
                }
221
1
            } else {
222
3
                for (int col = 1; col < argument_size; ++col) {
223
2
                    const auto& arg_column_data =
224
2
                            assert_cast<const ColVecData&>(*argument_columns[col].get()).get_data();
225
2
                    args.push_back(arg_column_data[i]);
226
2
                }
227
1
            }
228
1
            try {
229
1
                res = fmt::vformat(format, args);
230
1
            } catch (const std::exception& e) {
231
0
                throw doris::Exception(
232
0
                        ErrorCode::INVALID_ARGUMENT,
233
0
                        "Invalid Input argument \"{}\" of function format, error: {}", format,
234
0
                        e.what());
235
0
            }
236
1
            result_data_column->insert_data(res.data(), res.length());
237
1
        }
238
1
    }
Unexecuted instantiation: _ZNK5doris14FunctionFormat22execute_for_others_argINS_12ColumnVectorILNS_13PrimitiveTypeE5EEELS3_5EEEvRSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS7_EESaISA_EEPNS_9ColumnStrIjEEmm
Unexecuted instantiation: _ZNK5doris14FunctionFormat22execute_for_others_argINS_12ColumnVectorILNS_13PrimitiveTypeE6EEELS3_6EEEvRSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS7_EESaISA_EEPNS_9ColumnStrIjEEmm
Unexecuted instantiation: _ZNK5doris14FunctionFormat22execute_for_others_argINS_12ColumnVectorILNS_13PrimitiveTypeE7EEELS3_7EEEvRSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS7_EESaISA_EEPNS_9ColumnStrIjEEmm
Unexecuted instantiation: _ZNK5doris14FunctionFormat22execute_for_others_argINS_12ColumnVectorILNS_13PrimitiveTypeE8EEELS3_8EEEvRSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS7_EESaISA_EEPNS_9ColumnStrIjEEmm
_ZNK5doris14FunctionFormat22execute_for_others_argINS_12ColumnVectorILNS_13PrimitiveTypeE9EEELS3_9EEEvRSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS7_EESaISA_EEPNS_9ColumnStrIjEEmm
Line
Count
Source
209
1
                                size_t input_rows_count) const {
210
1
        const auto& format_column = assert_cast<const ColumnString&>(*argument_columns[0].get());
211
2
        for (int i = 0; i < input_rows_count; ++i) {
212
1
            auto format = format_column.get_data_at(i).to_string_view();
213
1
            std::string res;
214
1
            fmt::dynamic_format_arg_store<fmt::format_context> args;
215
            if constexpr (is_string_type(T)) {
216
                for (int col = 1; col < argument_size; ++col) {
217
                    const auto& arg_column_data =
218
                            assert_cast<const ColVecData&>(*argument_columns[col].get());
219
                    args.push_back(arg_column_data.get_data_at(i).to_string());
220
                }
221
1
            } else {
222
3
                for (int col = 1; col < argument_size; ++col) {
223
2
                    const auto& arg_column_data =
224
2
                            assert_cast<const ColVecData&>(*argument_columns[col].get()).get_data();
225
2
                    args.push_back(arg_column_data[i]);
226
2
                }
227
1
            }
228
1
            try {
229
1
                res = fmt::vformat(format, args);
230
1
            } catch (const std::exception& e) {
231
0
                throw doris::Exception(
232
0
                        ErrorCode::INVALID_ARGUMENT,
233
0
                        "Invalid Input argument \"{}\" of function format, error: {}", format,
234
0
                        e.what());
235
0
            }
236
1
            result_data_column->insert_data(res.data(), res.length());
237
1
        }
238
1
    }
_ZNK5doris14FunctionFormat22execute_for_others_argINS_9ColumnStrIjEELNS_13PrimitiveTypeE23EEEvRSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS7_EESaISA_EEPS3_mm
Line
Count
Source
209
7
                                size_t input_rows_count) const {
210
7
        const auto& format_column = assert_cast<const ColumnString&>(*argument_columns[0].get());
211
14
        for (int i = 0; i < input_rows_count; ++i) {
212
7
            auto format = format_column.get_data_at(i).to_string_view();
213
7
            std::string res;
214
7
            fmt::dynamic_format_arg_store<fmt::format_context> args;
215
7
            if constexpr (is_string_type(T)) {
216
21
                for (int col = 1; col < argument_size; ++col) {
217
14
                    const auto& arg_column_data =
218
14
                            assert_cast<const ColVecData&>(*argument_columns[col].get());
219
14
                    args.push_back(arg_column_data.get_data_at(i).to_string());
220
14
                }
221
            } else {
222
                for (int col = 1; col < argument_size; ++col) {
223
                    const auto& arg_column_data =
224
                            assert_cast<const ColVecData&>(*argument_columns[col].get()).get_data();
225
                    args.push_back(arg_column_data[i]);
226
                }
227
            }
228
7
            try {
229
7
                res = fmt::vformat(format, args);
230
7
            } catch (const std::exception& e) {
231
0
                throw doris::Exception(
232
0
                        ErrorCode::INVALID_ARGUMENT,
233
0
                        "Invalid Input argument \"{}\" of function format, error: {}", format,
234
0
                        e.what());
235
0
            }
236
7
            result_data_column->insert_data(res.data(), res.length());
237
7
        }
238
7
    }
239
};
240
241
8
void register_function_format(SimpleFunctionFactory& factory) {
242
8
    factory.register_function<FunctionFormatNumber>();
243
8
    factory.register_function<FunctionFormat>();
244
8
}
245
246
} // namespace doris