be/src/exprs/function/function_conv.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 <stdint.h> |
19 | | #include <stdlib.h> |
20 | | |
21 | | #include <boost/iterator/iterator_facade.hpp> |
22 | | // IWYU pragma: no_include <bits/std_abs.h> |
23 | | #include <algorithm> |
24 | | #include <cmath> // IWYU pragma: keep |
25 | | #include <memory> |
26 | | #include <utility> |
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/block/column_with_type_and_name.h" |
33 | | #include "core/column/column.h" |
34 | | #include "core/column/column_const.h" |
35 | | #include "core/column/column_nullable.h" |
36 | | #include "core/column/column_string.h" |
37 | | #include "core/column/column_vector.h" |
38 | | #include "core/data_type/data_type.h" |
39 | | #include "core/data_type/data_type_nullable.h" |
40 | | #include "core/data_type/data_type_number.h" |
41 | | #include "core/data_type/data_type_string.h" |
42 | | #include "core/string_ref.h" |
43 | | #include "core/types.h" |
44 | | #include "exprs/aggregate/aggregate_function.h" |
45 | | #include "exprs/function/function.h" |
46 | | #include "exprs/function/simple_function_factory.h" |
47 | | #include "exprs/math_functions.h" |
48 | | #include "util/string_parser.hpp" |
49 | | |
50 | | namespace doris { |
51 | | #include "common/compile_check_begin.h" |
52 | | class FunctionContext; |
53 | | } // namespace doris |
54 | | |
55 | | namespace doris { |
56 | | |
57 | | template <typename Impl> |
58 | | class FunctionConv : public IFunction { |
59 | | public: |
60 | | static constexpr auto name = "conv"; |
61 | 2 | String get_name() const override { return name; }_ZNK5doris12FunctionConvINS_13ConvInt64ImplEE8get_nameB5cxx11Ev Line | Count | Source | 61 | 1 | String get_name() const override { return name; } |
_ZNK5doris12FunctionConvINS_14ConvStringImplEE8get_nameB5cxx11Ev Line | Count | Source | 61 | 1 | String get_name() const override { return name; } |
|
62 | 79 | static FunctionPtr create() { return std::make_shared<FunctionConv<Impl>>(); }_ZN5doris12FunctionConvINS_13ConvInt64ImplEE6createEv Line | Count | Source | 62 | 41 | static FunctionPtr create() { return std::make_shared<FunctionConv<Impl>>(); } |
_ZN5doris12FunctionConvINS_14ConvStringImplEE6createEv Line | Count | Source | 62 | 38 | static FunctionPtr create() { return std::make_shared<FunctionConv<Impl>>(); } |
|
63 | | |
64 | 61 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
65 | 61 | return make_nullable(std::make_shared<DataTypeString>()); |
66 | 61 | } _ZNK5doris12FunctionConvINS_13ConvInt64ImplEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE Line | Count | Source | 64 | 32 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { | 65 | 32 | return make_nullable(std::make_shared<DataTypeString>()); | 66 | 32 | } |
_ZNK5doris12FunctionConvINS_14ConvStringImplEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE Line | Count | Source | 64 | 29 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { | 65 | 29 | return make_nullable(std::make_shared<DataTypeString>()); | 66 | 29 | } |
|
67 | 77 | DataTypes get_variadic_argument_types_impl() const override { |
68 | 77 | return {std::make_shared<typename Impl::DataType>(), std::make_shared<DataTypeInt8>(), |
69 | 77 | std::make_shared<DataTypeInt8>()}; |
70 | 77 | } _ZNK5doris12FunctionConvINS_13ConvInt64ImplEE32get_variadic_argument_types_implEv Line | Count | Source | 67 | 40 | DataTypes get_variadic_argument_types_impl() const override { | 68 | 40 | return {std::make_shared<typename Impl::DataType>(), std::make_shared<DataTypeInt8>(), | 69 | 40 | std::make_shared<DataTypeInt8>()}; | 70 | 40 | } |
_ZNK5doris12FunctionConvINS_14ConvStringImplEE32get_variadic_argument_types_implEv Line | Count | Source | 67 | 37 | DataTypes get_variadic_argument_types_impl() const override { | 68 | 37 | return {std::make_shared<typename Impl::DataType>(), std::make_shared<DataTypeInt8>(), | 69 | 37 | std::make_shared<DataTypeInt8>()}; | 70 | 37 | } |
|
71 | 61 | size_t get_number_of_arguments() const override { |
72 | 61 | return get_variadic_argument_types_impl().size(); |
73 | 61 | } _ZNK5doris12FunctionConvINS_13ConvInt64ImplEE23get_number_of_argumentsEv Line | Count | Source | 71 | 32 | size_t get_number_of_arguments() const override { | 72 | 32 | return get_variadic_argument_types_impl().size(); | 73 | 32 | } |
_ZNK5doris12FunctionConvINS_14ConvStringImplEE23get_number_of_argumentsEv Line | Count | Source | 71 | 29 | size_t get_number_of_arguments() const override { | 72 | 29 | return get_variadic_argument_types_impl().size(); | 73 | 29 | } |
|
74 | | |
75 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
76 | 62 | uint32_t result, size_t input_rows_count) const override { |
77 | 62 | auto result_column = ColumnString::create(); |
78 | 62 | auto result_null_map_column = ColumnUInt8::create(input_rows_count, 0); |
79 | | |
80 | 62 | bool col_const[3]; |
81 | 62 | ColumnPtr argument_columns[3]; |
82 | 248 | for (int i = 0; i < 3; ++i) { |
83 | 186 | col_const[i] = is_column_const(*block.get_by_position(arguments[i]).column); |
84 | 186 | } |
85 | 62 | argument_columns[0] = col_const[0] ? static_cast<const ColumnConst&>( |
86 | 0 | *block.get_by_position(arguments[0]).column) |
87 | 0 | .convert_to_full_column() |
88 | 62 | : block.get_by_position(arguments[0]).column; |
89 | | |
90 | 62 | default_preprocess_parameter_columns(argument_columns, col_const, {1, 2}, block, arguments); |
91 | | |
92 | 62 | if (col_const[1] && col_const[2]) { |
93 | 2 | execute_scalar_args( |
94 | 2 | context, |
95 | 2 | assert_cast<const typename Impl::DataType::ColumnType*>( |
96 | 2 | argument_columns[0].get()), |
97 | 2 | assert_cast<const ColumnInt8*>(argument_columns[1].get())->get_element(0), |
98 | 2 | assert_cast<const ColumnInt8*>(argument_columns[2].get())->get_element(0), |
99 | 2 | assert_cast<ColumnString*>(result_column.get()), |
100 | 2 | assert_cast<ColumnUInt8*>(result_null_map_column.get())->get_data(), |
101 | 2 | input_rows_count); |
102 | 60 | } else { |
103 | 60 | execute_straight(context, |
104 | 60 | assert_cast<const typename Impl::DataType::ColumnType*>( |
105 | 60 | argument_columns[0].get()), |
106 | 60 | assert_cast<const ColumnInt8*>(argument_columns[1].get()), |
107 | 60 | assert_cast<const ColumnInt8*>(argument_columns[2].get()), |
108 | 60 | assert_cast<ColumnString*>(result_column.get()), |
109 | 60 | assert_cast<ColumnUInt8*>(result_null_map_column.get())->get_data(), |
110 | 60 | input_rows_count); |
111 | 60 | } |
112 | | |
113 | 62 | block.get_by_position(result).column = |
114 | 62 | ColumnNullable::create(std::move(result_column), std::move(result_null_map_column)); |
115 | 62 | return Status::OK(); |
116 | 62 | } _ZNK5doris12FunctionConvINS_13ConvInt64ImplEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm Line | Count | Source | 76 | 23 | uint32_t result, size_t input_rows_count) const override { | 77 | 23 | auto result_column = ColumnString::create(); | 78 | 23 | auto result_null_map_column = ColumnUInt8::create(input_rows_count, 0); | 79 | | | 80 | 23 | bool col_const[3]; | 81 | 23 | ColumnPtr argument_columns[3]; | 82 | 92 | for (int i = 0; i < 3; ++i) { | 83 | 69 | col_const[i] = is_column_const(*block.get_by_position(arguments[i]).column); | 84 | 69 | } | 85 | 23 | argument_columns[0] = col_const[0] ? static_cast<const ColumnConst&>( | 86 | 0 | *block.get_by_position(arguments[0]).column) | 87 | 0 | .convert_to_full_column() | 88 | 23 | : block.get_by_position(arguments[0]).column; | 89 | | | 90 | 23 | default_preprocess_parameter_columns(argument_columns, col_const, {1, 2}, block, arguments); | 91 | | | 92 | 23 | if (col_const[1] && col_const[2]) { | 93 | 0 | execute_scalar_args( | 94 | 0 | context, | 95 | 0 | assert_cast<const typename Impl::DataType::ColumnType*>( | 96 | 0 | argument_columns[0].get()), | 97 | 0 | assert_cast<const ColumnInt8*>(argument_columns[1].get())->get_element(0), | 98 | 0 | assert_cast<const ColumnInt8*>(argument_columns[2].get())->get_element(0), | 99 | 0 | assert_cast<ColumnString*>(result_column.get()), | 100 | 0 | assert_cast<ColumnUInt8*>(result_null_map_column.get())->get_data(), | 101 | 0 | input_rows_count); | 102 | 23 | } else { | 103 | 23 | execute_straight(context, | 104 | 23 | assert_cast<const typename Impl::DataType::ColumnType*>( | 105 | 23 | argument_columns[0].get()), | 106 | 23 | assert_cast<const ColumnInt8*>(argument_columns[1].get()), | 107 | 23 | assert_cast<const ColumnInt8*>(argument_columns[2].get()), | 108 | 23 | assert_cast<ColumnString*>(result_column.get()), | 109 | 23 | assert_cast<ColumnUInt8*>(result_null_map_column.get())->get_data(), | 110 | 23 | input_rows_count); | 111 | 23 | } | 112 | | | 113 | 23 | block.get_by_position(result).column = | 114 | 23 | ColumnNullable::create(std::move(result_column), std::move(result_null_map_column)); | 115 | 23 | return Status::OK(); | 116 | 23 | } |
_ZNK5doris12FunctionConvINS_14ConvStringImplEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm Line | Count | Source | 76 | 39 | uint32_t result, size_t input_rows_count) const override { | 77 | 39 | auto result_column = ColumnString::create(); | 78 | 39 | auto result_null_map_column = ColumnUInt8::create(input_rows_count, 0); | 79 | | | 80 | 39 | bool col_const[3]; | 81 | 39 | ColumnPtr argument_columns[3]; | 82 | 156 | for (int i = 0; i < 3; ++i) { | 83 | 117 | col_const[i] = is_column_const(*block.get_by_position(arguments[i]).column); | 84 | 117 | } | 85 | 39 | argument_columns[0] = col_const[0] ? static_cast<const ColumnConst&>( | 86 | 0 | *block.get_by_position(arguments[0]).column) | 87 | 0 | .convert_to_full_column() | 88 | 39 | : block.get_by_position(arguments[0]).column; | 89 | | | 90 | 39 | default_preprocess_parameter_columns(argument_columns, col_const, {1, 2}, block, arguments); | 91 | | | 92 | 39 | if (col_const[1] && col_const[2]) { | 93 | 2 | execute_scalar_args( | 94 | 2 | context, | 95 | 2 | assert_cast<const typename Impl::DataType::ColumnType*>( | 96 | 2 | argument_columns[0].get()), | 97 | 2 | assert_cast<const ColumnInt8*>(argument_columns[1].get())->get_element(0), | 98 | 2 | assert_cast<const ColumnInt8*>(argument_columns[2].get())->get_element(0), | 99 | 2 | assert_cast<ColumnString*>(result_column.get()), | 100 | 2 | assert_cast<ColumnUInt8*>(result_null_map_column.get())->get_data(), | 101 | 2 | input_rows_count); | 102 | 37 | } else { | 103 | 37 | execute_straight(context, | 104 | 37 | assert_cast<const typename Impl::DataType::ColumnType*>( | 105 | 37 | argument_columns[0].get()), | 106 | 37 | assert_cast<const ColumnInt8*>(argument_columns[1].get()), | 107 | 37 | assert_cast<const ColumnInt8*>(argument_columns[2].get()), | 108 | 37 | assert_cast<ColumnString*>(result_column.get()), | 109 | 37 | assert_cast<ColumnUInt8*>(result_null_map_column.get())->get_data(), | 110 | 37 | input_rows_count); | 111 | 37 | } | 112 | | | 113 | 39 | block.get_by_position(result).column = | 114 | 39 | ColumnNullable::create(std::move(result_column), std::move(result_null_map_column)); | 115 | 39 | return Status::OK(); | 116 | 39 | } |
|
117 | | |
118 | | private: |
119 | | // check out of bound. |
120 | 113 | static bool _check_oob(const Int8 src_base, const Int8 dst_base) { |
121 | 113 | return std::abs(src_base) < MathFunctions::MIN_BASE || |
122 | 113 | std::abs(src_base) > MathFunctions::MAX_BASE || |
123 | 113 | std::abs(dst_base) < MathFunctions::MIN_BASE || |
124 | 113 | std::abs(dst_base) > MathFunctions::MAX_BASE; |
125 | 113 | } _ZN5doris12FunctionConvINS_13ConvInt64ImplEE10_check_oobEaa Line | Count | Source | 120 | 40 | static bool _check_oob(const Int8 src_base, const Int8 dst_base) { | 121 | 40 | return std::abs(src_base) < MathFunctions::MIN_BASE || | 122 | 40 | std::abs(src_base) > MathFunctions::MAX_BASE || | 123 | 40 | std::abs(dst_base) < MathFunctions::MIN_BASE || | 124 | 40 | std::abs(dst_base) > MathFunctions::MAX_BASE; | 125 | 40 | } |
_ZN5doris12FunctionConvINS_14ConvStringImplEE10_check_oobEaa Line | Count | Source | 120 | 73 | static bool _check_oob(const Int8 src_base, const Int8 dst_base) { | 121 | 73 | return std::abs(src_base) < MathFunctions::MIN_BASE || | 122 | 73 | std::abs(src_base) > MathFunctions::MAX_BASE || | 123 | 73 | std::abs(dst_base) < MathFunctions::MIN_BASE || | 124 | 73 | std::abs(dst_base) > MathFunctions::MAX_BASE; | 125 | 73 | } |
|
126 | | static void execute_straight(FunctionContext* context, |
127 | | const typename Impl::DataType::ColumnType* data_column, |
128 | | const ColumnInt8* src_base_column, |
129 | | const ColumnInt8* dst_base_column, ColumnString* result_column, |
130 | 60 | NullMap& result_null_map, size_t input_rows_count) { |
131 | 171 | for (size_t i = 0; i < input_rows_count; i++) { |
132 | 111 | Int8 src_base = src_base_column->get_element(i); |
133 | 111 | Int8 dst_base = dst_base_column->get_element(i); |
134 | 111 | if (_check_oob(src_base, dst_base)) { |
135 | 9 | result_null_map[i] = true; |
136 | 9 | result_column->insert_default(); |
137 | 102 | } else { |
138 | 102 | Impl::calculate_cell(context, data_column, src_base, dst_base, result_column, |
139 | 102 | result_null_map, i); |
140 | 102 | } |
141 | 111 | } |
142 | 60 | } _ZN5doris12FunctionConvINS_13ConvInt64ImplEE16execute_straightEPNS_15FunctionContextEPKNS_12ColumnVectorILNS_13PrimitiveTypeE6EEEPKNS5_ILS6_3EEESC_PNS_9ColumnStrIjEERNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEEm Line | Count | Source | 130 | 23 | NullMap& result_null_map, size_t input_rows_count) { | 131 | 63 | for (size_t i = 0; i < input_rows_count; i++) { | 132 | 40 | Int8 src_base = src_base_column->get_element(i); | 133 | 40 | Int8 dst_base = dst_base_column->get_element(i); | 134 | 40 | if (_check_oob(src_base, dst_base)) { | 135 | 3 | result_null_map[i] = true; | 136 | 3 | result_column->insert_default(); | 137 | 37 | } else { | 138 | 37 | Impl::calculate_cell(context, data_column, src_base, dst_base, result_column, | 139 | 37 | result_null_map, i); | 140 | 37 | } | 141 | 40 | } | 142 | 23 | } |
_ZN5doris12FunctionConvINS_14ConvStringImplEE16execute_straightEPNS_15FunctionContextEPKNS_9ColumnStrIjEEPKNS_12ColumnVectorILNS_13PrimitiveTypeE3EEESD_PS6_RNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEEm Line | Count | Source | 130 | 37 | NullMap& result_null_map, size_t input_rows_count) { | 131 | 108 | for (size_t i = 0; i < input_rows_count; i++) { | 132 | 71 | Int8 src_base = src_base_column->get_element(i); | 133 | 71 | Int8 dst_base = dst_base_column->get_element(i); | 134 | 71 | if (_check_oob(src_base, dst_base)) { | 135 | 6 | result_null_map[i] = true; | 136 | 6 | result_column->insert_default(); | 137 | 65 | } else { | 138 | 65 | Impl::calculate_cell(context, data_column, src_base, dst_base, result_column, | 139 | 65 | result_null_map, i); | 140 | 65 | } | 141 | 71 | } | 142 | 37 | } |
|
143 | | static void execute_scalar_args(FunctionContext* context, |
144 | | const typename Impl::DataType::ColumnType* data_column, |
145 | | const Int8 src_base, const Int8 dst_base, |
146 | | ColumnString* result_column, NullMap& result_null_map, |
147 | 2 | size_t input_rows_count) { |
148 | 2 | if (_check_oob(src_base, dst_base)) { |
149 | 0 | result_null_map.assign(input_rows_count, UInt8 {true}); |
150 | 0 | result_column->insert_many_defaults(input_rows_count); |
151 | 0 | return; |
152 | 0 | } |
153 | 10 | for (size_t i = 0; i < input_rows_count; i++) { |
154 | 8 | Impl::calculate_cell(context, data_column, src_base, dst_base, result_column, |
155 | 8 | result_null_map, i); |
156 | 8 | } |
157 | 2 | } Unexecuted instantiation: _ZN5doris12FunctionConvINS_13ConvInt64ImplEE19execute_scalar_argsEPNS_15FunctionContextEPKNS_12ColumnVectorILNS_13PrimitiveTypeE6EEEaaPNS_9ColumnStrIjEERNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEEm _ZN5doris12FunctionConvINS_14ConvStringImplEE19execute_scalar_argsEPNS_15FunctionContextEPKNS_9ColumnStrIjEEaaPS6_RNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEEm Line | Count | Source | 147 | 2 | size_t input_rows_count) { | 148 | 2 | if (_check_oob(src_base, dst_base)) { | 149 | 0 | result_null_map.assign(input_rows_count, UInt8 {true}); | 150 | 0 | result_column->insert_many_defaults(input_rows_count); | 151 | 0 | return; | 152 | 0 | } | 153 | 10 | for (size_t i = 0; i < input_rows_count; i++) { | 154 | 8 | Impl::calculate_cell(context, data_column, src_base, dst_base, result_column, | 155 | 8 | result_null_map, i); | 156 | 8 | } | 157 | 2 | } |
|
158 | | }; |
159 | | |
160 | | struct ConvInt64Impl { |
161 | | using DataType = DataTypeInt64; |
162 | | |
163 | | static void calculate_cell(FunctionContext* context, const DataType::ColumnType* data_column, |
164 | | const Int8 src_base, const Int8 dst_base, |
165 | | ColumnString* result_column, NullMap& result_null_map, |
166 | 37 | size_t index) { |
167 | 37 | Int64 num = data_column->get_element(index); |
168 | 37 | if (src_base < 0 && num >= 0) { |
169 | 0 | result_null_map[index] = true; |
170 | 0 | result_column->insert_default(); |
171 | 0 | return; |
172 | 0 | } |
173 | | |
174 | 37 | int64_t decimal_num = num; |
175 | 37 | if (src_base != 10) { |
176 | 22 | if (!MathFunctions::decimal_in_base_to_decimal(num, src_base, &decimal_num)) { |
177 | 0 | MathFunctions::handle_parse_result(dst_base, &decimal_num, |
178 | 0 | StringParser::PARSE_OVERFLOW); |
179 | 0 | } |
180 | 22 | } |
181 | 37 | StringRef str = MathFunctions::decimal_to_base(context, decimal_num, dst_base); |
182 | 37 | result_column->insert_data(reinterpret_cast<const char*>(str.data), str.size); |
183 | 37 | } |
184 | | }; |
185 | | |
186 | | struct ConvStringImpl { |
187 | | using DataType = DataTypeString; |
188 | | |
189 | | static void calculate_cell(FunctionContext* context, const DataType::ColumnType* data_column, |
190 | | const Int8 src_base, const Int8 dst_base, |
191 | | ColumnString* result_column, NullMap& result_null_map, |
192 | 73 | size_t index) { |
193 | 73 | StringRef str = data_column->get_data_at(index); |
194 | 73 | auto new_size = str.size; |
195 | | // eg: select conv('1.464868',10,2); the result should be return 1. |
196 | | // But StringParser::string_to_int will PARSE_FAILURE and return 0, |
197 | | // so should handle the point part of number firstly if need convert '1.464868' to number 1 |
198 | 73 | if (auto pos = str.to_string_view().find_first_of('.'); pos != std::string::npos) { |
199 | 3 | new_size = pos; |
200 | 3 | } |
201 | 73 | StringParser::ParseResult parse_res; |
202 | | // select conv('ffffffffffffff', 24, 2); |
203 | | // if 'ffffffffffffff' parse as int64_t will be overflow, will be get max value: std::numeric_limits<int64_t>::max() |
204 | | // so change it parse as uint64_t, and return value could still use int64_t, in function decimal_to_base could handle it. |
205 | | // But if the value is still overflow in uint64_t, will get max value of uint64_t |
206 | 73 | int64_t decimal_num = |
207 | 73 | StringParser::string_to_int<uint64_t>(str.data, new_size, src_base, &parse_res); |
208 | 73 | if (src_base < 0 && decimal_num >= 0) { |
209 | 0 | result_null_map[index] = true; |
210 | 0 | result_column->insert_default(); |
211 | 0 | return; |
212 | 0 | } |
213 | | |
214 | 73 | if (!MathFunctions::handle_parse_result(dst_base, &decimal_num, parse_res)) { |
215 | 2 | result_column->insert_data("0", 1); |
216 | 71 | } else { |
217 | 71 | StringRef str_base = MathFunctions::decimal_to_base(context, decimal_num, dst_base); |
218 | 71 | result_column->insert_data(reinterpret_cast<const char*>(str_base.data), str_base.size); |
219 | 71 | } |
220 | 73 | } |
221 | | }; |
222 | | |
223 | 8 | void register_function_conv(SimpleFunctionFactory& factory) { |
224 | 8 | factory.register_function<FunctionConv<ConvInt64Impl>>(); |
225 | 8 | factory.register_function<FunctionConv<ConvStringImpl>>(); |
226 | 8 | } |
227 | | |
228 | | } // namespace doris |