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 |