Coverage Report

Created: 2026-04-16 21:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/function/cast/cast_to_string.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#pragma once
19
20
#include "core/data_type_serde/data_type_serde.h"
21
#include "core/types.h"
22
#include "core/value/time_value.h"
23
#include "exprs/function/cast/cast_base.h"
24
#include "util/mysql_global.h"
25
#include "util/to_string.h"
26
namespace doris {
27
struct CastToString {
28
    static inline std::string from_int128(int128_t value);
29
    static inline std::string from_uint128(uint128_t value);
30
    static inline std::string from_uint128(UInt128 value);
31
32
    template <class SRC>
33
    static inline std::string from_number(const SRC& from);
34
35
    // Caller is responsible for ensuring that `buffer` has enough space.
36
    template <class SRC>
37
    static inline int from_number(const SRC& from, char* buffer);
38
39
    template <typename T>
40
        requires(std::is_same_v<T, Float32> || std::is_same_v<T, Float64>)
41
    static inline int from_number(const T& from, char* buffer);
42
43
    template <class SRC>
44
    static inline void push_number(const SRC& from, ColumnString::Chars& chars);
45
46
    template <class SRC>
47
    static inline void push_number(const SRC& from, BufferWritable& bw);
48
49
    template <class SRC>
50
    static inline std::string from_decimal(const SRC& from, UInt32 scale);
51
52
    template <class SRC>
53
    static inline void push_decimal(const SRC& from, UInt32 scale, BufferWritable& bw);
54
55
    static inline std::string from_date_or_datetime(const VecDateTimeValue& from);
56
57
    static inline void push_date_or_datetime(const VecDateTimeValue& from,
58
                                             ColumnString::Chars& chars);
59
    static inline void push_date_or_datetime(const VecDateTimeValue& from, BufferWritable& bw);
60
61
    static inline std::string from_datev2(const DateV2Value<DateV2ValueType>& from);
62
    static inline void push_datev2(const DateV2Value<DateV2ValueType>& from,
63
                                   ColumnString::Chars& chars);
64
    static inline void push_datev2(const DateV2Value<DateV2ValueType>& from, BufferWritable& bw);
65
66
    static inline std::string from_datetimev2(const DateV2Value<DateTimeV2ValueType>& from,
67
                                              UInt32 scale);
68
    static inline std::string from_timestamptz(const TimestampTzValue& from, UInt32 scale,
69
                                               const cctz::time_zone* timezone = nullptr);
70
    static inline void push_datetimev2(const DateV2Value<DateTimeV2ValueType>& from, UInt32 scale,
71
                                       ColumnString::Chars& chars);
72
73
    static inline void push_datetimev2(const DateV2Value<DateTimeV2ValueType>& from, UInt32 scale,
74
                                       BufferWritable& bw);
75
    static inline void push_timestamptz(const TimestampTzValue& from, UInt32 scale,
76
                                        BufferWritable& bw,
77
                                        const DataTypeSerDe::FormatOptions& options);
78
79
    template <class SRC>
80
    static inline std::string from_ip(const SRC& from);
81
82
    template <class SRC>
83
    static inline void push_ip(const SRC& from, BufferWritable& bw);
84
85
    static inline std::string from_time(const TimeValue::TimeType& from, UInt32 scale);
86
87
    static inline void push_time(const TimeValue::TimeType& from, UInt32 scale, BufferWritable& bw);
88
89
    template <PrimitiveType T>
90
    static constexpr size_t string_length = 1;
91
92
private:
93
    // refer to: https://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10.html
94
    template <typename T>
95
        requires(std::is_same_v<T, float> || std::is_same_v<T, double>)
96
58.7k
    static inline int _fast_to_buffer(T value, char* buffer) {
97
58.7k
        char* end = nullptr;
98
        // output NaN and Infinity to be compatible with most of the implementations
99
58.7k
        if (std::isnan(value)) {
100
14
            static constexpr char nan_str[] = "NaN";
101
14
            static constexpr int nan_str_len = sizeof(nan_str) - 1;
102
14
            memcpy(buffer, nan_str, nan_str_len);
103
14
            end = buffer + nan_str_len;
104
58.7k
        } else if (std::isinf(value)) {
105
27
            static constexpr char inf_str[] = "Infinity";
106
27
            static constexpr int inf_str_len = sizeof(inf_str) - 1;
107
27
            static constexpr char neg_inf_str[] = "-Infinity";
108
27
            static constexpr int neg_inf_str_len = sizeof(neg_inf_str) - 1;
109
27
            if (value > 0) {
110
14
                memcpy(buffer, inf_str, inf_str_len);
111
14
                end = buffer + inf_str_len;
112
14
            } else {
113
13
                memcpy(buffer, neg_inf_str, neg_inf_str_len);
114
13
                end = buffer + neg_inf_str_len;
115
13
            }
116
58.7k
        } else {
117
58.7k
            if constexpr (std::is_same_v<T, float>) {
118
27.6k
                end = fmt::format_to(buffer, FMT_COMPILE("{:.{}g}"), value,
119
27.6k
                                     std::numeric_limits<float>::digits10 + 1);
120
31.0k
            } else {
121
31.0k
                end = fmt::format_to(buffer, FMT_COMPILE("{:.{}g}"), value,
122
31.0k
                                     std::numeric_limits<double>::digits10 + 1);
123
31.0k
            }
124
58.7k
        }
125
58.7k
        *end = '\0';
126
58.7k
        return int(end - buffer);
127
58.7k
    }
_ZN5doris12CastToString15_fast_to_bufferIfQoosr3stdE9is_same_vIT_fEsr3stdE9is_same_vIS2_dEEEiS2_Pc
Line
Count
Source
96
27.6k
    static inline int _fast_to_buffer(T value, char* buffer) {
97
27.6k
        char* end = nullptr;
98
        // output NaN and Infinity to be compatible with most of the implementations
99
27.6k
        if (std::isnan(value)) {
100
6
            static constexpr char nan_str[] = "NaN";
101
6
            static constexpr int nan_str_len = sizeof(nan_str) - 1;
102
6
            memcpy(buffer, nan_str, nan_str_len);
103
6
            end = buffer + nan_str_len;
104
27.6k
        } else if (std::isinf(value)) {
105
12
            static constexpr char inf_str[] = "Infinity";
106
12
            static constexpr int inf_str_len = sizeof(inf_str) - 1;
107
12
            static constexpr char neg_inf_str[] = "-Infinity";
108
12
            static constexpr int neg_inf_str_len = sizeof(neg_inf_str) - 1;
109
12
            if (value > 0) {
110
6
                memcpy(buffer, inf_str, inf_str_len);
111
6
                end = buffer + inf_str_len;
112
6
            } else {
113
6
                memcpy(buffer, neg_inf_str, neg_inf_str_len);
114
6
                end = buffer + neg_inf_str_len;
115
6
            }
116
27.6k
        } else {
117
27.6k
            if constexpr (std::is_same_v<T, float>) {
118
27.6k
                end = fmt::format_to(buffer, FMT_COMPILE("{:.{}g}"), value,
119
27.6k
                                     std::numeric_limits<float>::digits10 + 1);
120
            } else {
121
                end = fmt::format_to(buffer, FMT_COMPILE("{:.{}g}"), value,
122
                                     std::numeric_limits<double>::digits10 + 1);
123
            }
124
27.6k
        }
125
27.6k
        *end = '\0';
126
27.6k
        return int(end - buffer);
127
27.6k
    }
_ZN5doris12CastToString15_fast_to_bufferIdQoosr3stdE9is_same_vIT_fEsr3stdE9is_same_vIS2_dEEEiS2_Pc
Line
Count
Source
96
31.0k
    static inline int _fast_to_buffer(T value, char* buffer) {
97
31.0k
        char* end = nullptr;
98
        // output NaN and Infinity to be compatible with most of the implementations
99
31.0k
        if (std::isnan(value)) {
100
8
            static constexpr char nan_str[] = "NaN";
101
8
            static constexpr int nan_str_len = sizeof(nan_str) - 1;
102
8
            memcpy(buffer, nan_str, nan_str_len);
103
8
            end = buffer + nan_str_len;
104
31.0k
        } else if (std::isinf(value)) {
105
15
            static constexpr char inf_str[] = "Infinity";
106
15
            static constexpr int inf_str_len = sizeof(inf_str) - 1;
107
15
            static constexpr char neg_inf_str[] = "-Infinity";
108
15
            static constexpr int neg_inf_str_len = sizeof(neg_inf_str) - 1;
109
15
            if (value > 0) {
110
8
                memcpy(buffer, inf_str, inf_str_len);
111
8
                end = buffer + inf_str_len;
112
8
            } else {
113
7
                memcpy(buffer, neg_inf_str, neg_inf_str_len);
114
7
                end = buffer + neg_inf_str_len;
115
7
            }
116
31.0k
        } else {
117
            if constexpr (std::is_same_v<T, float>) {
118
                end = fmt::format_to(buffer, FMT_COMPILE("{:.{}g}"), value,
119
                                     std::numeric_limits<float>::digits10 + 1);
120
31.0k
            } else {
121
                end = fmt::format_to(buffer, FMT_COMPILE("{:.{}g}"), value,
122
31.0k
                                     std::numeric_limits<double>::digits10 + 1);
123
31.0k
            }
124
31.0k
        }
125
31.0k
        *end = '\0';
126
31.0k
        return int(end - buffer);
127
31.0k
    }
128
};
129
130
template <>
131
constexpr size_t CastToString::string_length<TYPE_BOOLEAN> = 1;
132
template <>
133
constexpr size_t CastToString::string_length<TYPE_TINYINT> = 4;
134
template <>
135
constexpr size_t CastToString::string_length<TYPE_SMALLINT> = 6;
136
template <>
137
constexpr size_t CastToString::string_length<TYPE_INT> = 11;
138
template <>
139
constexpr size_t CastToString::string_length<TYPE_BIGINT> = 20;
140
template <>
141
constexpr size_t CastToString::string_length<TYPE_LARGEINT> = 40;
142
template <>
143
constexpr size_t CastToString::string_length<TYPE_FLOAT> = MAX_FLOAT_STR_LENGTH;
144
template <>
145
constexpr size_t CastToString::string_length<TYPE_DOUBLE> = MAX_DOUBLE_STR_LENGTH;
146
template <>
147
constexpr size_t CastToString::string_length<TYPE_DECIMAL32> = 14;
148
template <>
149
constexpr size_t CastToString::string_length<TYPE_DECIMAL64> = 24;
150
template <>
151
constexpr size_t CastToString::string_length<TYPE_DECIMALV2> = 24;
152
template <>
153
constexpr size_t CastToString::string_length<TYPE_DECIMAL128I> = 39;
154
template <>
155
constexpr size_t CastToString::string_length<TYPE_DECIMAL256> = 78;
156
template <>
157
constexpr size_t CastToString::string_length<TYPE_DATE> = sizeof("YYYY-MM-DD") - 1;
158
template <>
159
constexpr size_t CastToString::string_length<TYPE_DATETIME> = sizeof("YYYY-MM-DD HH:MM:SS") - 1;
160
template <>
161
constexpr size_t CastToString::string_length<TYPE_DATEV2> = sizeof("YYYY-MM-DD") - 1;
162
template <>
163
constexpr size_t CastToString::string_length<TYPE_DATETIMEV2> =
164
        sizeof("YYYY-MM-DD HH:MM:SS.ssssss") - 1;
165
template <>
166
constexpr size_t CastToString::string_length<TYPE_TIMEV2> = sizeof("-838:59:59.999999") - 1;
167
template <>
168
constexpr size_t CastToString::string_length<TYPE_IPV4> = sizeof("255.255 .255.255") - 1;
169
template <>
170
constexpr size_t CastToString::string_length<TYPE_IPV6> =
171
        sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff") - 1;
172
173
// BOOLEAN
174
template <>
175
1
inline std::string CastToString::from_number(const UInt8& num) {
176
1
    auto f = fmt::format_int(num);
177
1
    return std::string(f.data(), f.data() + f.size());
178
1
}
179
180
template <>
181
0
inline void CastToString::push_number(const UInt8& num, ColumnString::Chars& chars) {
182
0
    auto f = fmt::format_int(num);
183
0
    chars.insert(f.data(), f.data() + f.size());
184
0
}
185
186
template <>
187
351
inline void CastToString::push_number(const UInt8& num, BufferWritable& bw) {
188
351
    auto f = fmt::format_int(num);
189
351
    bw.write(f.data(), f.size());
190
351
}
191
192
// TINYINT
193
template <>
194
2.46k
inline std::string CastToString::from_number(const Int8& num) {
195
2.46k
    auto f = fmt::format_int(num);
196
2.46k
    return std::string(f.data(), f.data() + f.size());
197
2.46k
}
198
199
template <>
200
0
inline void CastToString::push_number(const Int8& num, ColumnString::Chars& chars) {
201
0
    auto f = fmt::format_int(num);
202
0
    chars.insert(f.data(), f.data() + f.size());
203
0
}
204
205
template <>
206
6.66k
inline void CastToString::push_number(const Int8& num, BufferWritable& bw) {
207
6.66k
    auto f = fmt::format_int(num);
208
6.66k
    bw.write(f.data(), f.size());
209
6.66k
}
210
211
// SMALLINT
212
template <>
213
30
inline std::string CastToString::from_number(const Int16& num) {
214
30
    auto f = fmt::format_int(num);
215
30
    return std::string(f.data(), f.data() + f.size());
216
30
}
217
218
template <>
219
0
inline void CastToString::push_number(const Int16& num, ColumnString::Chars& chars) {
220
0
    auto f = fmt::format_int(num);
221
0
    chars.insert(f.data(), f.data() + f.size());
222
0
}
223
224
template <>
225
6.07k
inline void CastToString::push_number(const Int16& num, BufferWritable& bw) {
226
6.07k
    auto f = fmt::format_int(num);
227
6.07k
    bw.write(f.data(), f.size());
228
6.07k
}
229
230
// INT
231
template <>
232
48.8k
inline std::string CastToString::from_number(const Int32& num) {
233
48.8k
    auto f = fmt::format_int(num);
234
48.8k
    return std::string(f.data(), f.data() + f.size());
235
48.8k
}
236
237
template <>
238
0
inline void CastToString::push_number(const Int32& num, ColumnString::Chars& chars) {
239
0
    auto f = fmt::format_int(num);
240
0
    chars.insert(f.data(), f.data() + f.size());
241
0
}
242
243
template <>
244
9.41k
inline void CastToString::push_number(const Int32& num, BufferWritable& bw) {
245
9.41k
    auto f = fmt::format_int(num);
246
9.41k
    bw.write(f.data(), f.size());
247
9.41k
}
248
249
// BIGINT
250
template <>
251
1.56k
inline std::string CastToString::from_number(const Int64& num) {
252
1.56k
    auto f = fmt::format_int(num);
253
1.56k
    return std::string(f.data(), f.data() + f.size());
254
1.56k
}
255
256
template <>
257
0
inline void CastToString::push_number(const Int64& num, ColumnString::Chars& chars) {
258
0
    auto f = fmt::format_int(num);
259
0
    chars.insert(f.data(), f.data() + f.size());
260
0
}
261
262
template <>
263
15.4k
inline void CastToString::push_number(const Int64& num, BufferWritable& bw) {
264
15.4k
    auto f = fmt::format_int(num);
265
15.4k
    bw.write(f.data(), f.size());
266
15.4k
}
267
268
// LARGEINT
269
321
inline std::string CastToString::from_int128(int128_t value) {
270
321
    fmt::memory_buffer buffer;
271
321
    fmt::format_to(buffer, "{}", value);
272
321
    return std::string(buffer.data(), buffer.size());
273
321
}
274
275
2
inline std::string CastToString::from_uint128(uint128_t value) {
276
2
    fmt::memory_buffer buffer;
277
2
    fmt::format_to(buffer, "{}", value);
278
2
    return std::string(buffer.data(), buffer.size());
279
2
}
280
281
1
inline std::string CastToString::from_uint128(UInt128 value) {
282
1
    return value.to_hex_string();
283
1
}
284
285
template <>
286
1
inline std::string CastToString::from_number(const Int128& num) {
287
1
    return from_int128(num);
288
1
}
289
290
template <>
291
0
inline void CastToString::push_number(const Int128& num, ColumnString::Chars& chars) {
292
0
    fmt::memory_buffer buffer;
293
0
    fmt::format_to(buffer, "{}", num);
294
0
    chars.insert(buffer.data(), buffer.data() + buffer.size());
295
0
}
296
297
template <>
298
4.77k
inline void CastToString::push_number(const Int128& num, BufferWritable& bw) {
299
4.77k
    fmt::memory_buffer buffer;
300
4.77k
    fmt::format_to(buffer, "{}", num);
301
4.77k
    bw.write(buffer.data(), buffer.size());
302
4.77k
}
303
304
// FLOAT
305
306
template <>
307
22.2k
inline std::string CastToString::from_number(const Float32& num) {
308
22.2k
    char buf[MAX_FLOAT_STR_LENGTH + 2];
309
22.2k
    int len = _fast_to_buffer(num, buf);
310
22.2k
    return std::string(buf, buf + len);
311
22.2k
}
312
313
template <typename T>
314
    requires(std::is_same_v<T, Float32> || std::is_same_v<T, Float64>)
315
81
inline int CastToString::from_number(const T& from, char* buffer) {
316
81
    return _fast_to_buffer(from, buffer);
317
81
}
_ZN5doris12CastToString11from_numberIfQoosr3stdE9is_same_vIT_fEsr3stdE9is_same_vIS2_dEEEiRKS2_Pc
Line
Count
Source
315
38
inline int CastToString::from_number(const T& from, char* buffer) {
316
38
    return _fast_to_buffer(from, buffer);
317
38
}
_ZN5doris12CastToString11from_numberIdQoosr3stdE9is_same_vIT_fEsr3stdE9is_same_vIS2_dEEEiRKS2_Pc
Line
Count
Source
315
43
inline int CastToString::from_number(const T& from, char* buffer) {
316
43
    return _fast_to_buffer(from, buffer);
317
43
}
318
319
template <>
320
0
inline void CastToString::push_number(const Float32& num, ColumnString::Chars& chars) {
321
0
    char buf[MAX_FLOAT_STR_LENGTH + 2];
322
0
    int len = _fast_to_buffer(num, buf);
323
0
    chars.insert(buf, buf + len);
324
0
}
325
326
template <>
327
5.42k
inline void CastToString::push_number(const Float32& num, BufferWritable& bw) {
328
5.42k
    char buf[MAX_FLOAT_STR_LENGTH + 2];
329
5.42k
    int len = _fast_to_buffer(num, buf);
330
5.42k
    bw.write(buf, len);
331
5.42k
}
332
333
// DOUBLE
334
template <>
335
25.0k
inline std::string CastToString::from_number(const Float64& num) {
336
25.0k
    char buf[MAX_DOUBLE_STR_LENGTH + 2];
337
25.0k
    int len = _fast_to_buffer(num, buf);
338
25.0k
    return std::string(buf, len);
339
25.0k
}
340
341
template <>
342
0
inline void CastToString::push_number(const Float64& num, ColumnString::Chars& chars) {
343
0
    char buf[MAX_DOUBLE_STR_LENGTH + 2];
344
0
    int len = _fast_to_buffer(num, buf);
345
0
    chars.insert(buf, buf + len);
346
0
}
347
348
template <>
349
6.02k
inline void CastToString::push_number(const Float64& num, BufferWritable& bw) {
350
6.02k
    char buf[MAX_DOUBLE_STR_LENGTH + 2];
351
6.02k
    int len = _fast_to_buffer(num, buf);
352
6.02k
    bw.write(buf, len);
353
6.02k
}
354
355
// DECIMAL32
356
template <>
357
1
inline std::string CastToString::from_decimal(const Decimal32& from, UInt32 scale) {
358
1
    return from.to_string(scale);
359
1
}
360
361
template <>
362
4.84k
inline void CastToString::push_decimal(const Decimal32& from, UInt32 scale, BufferWritable& bw) {
363
4.84k
    std::string str = from.to_string(scale);
364
4.84k
    bw.write(str.data(), str.size());
365
4.84k
}
366
367
// DECIMAL64
368
template <>
369
1
inline std::string CastToString::from_decimal(const Decimal64& from, UInt32 scale) {
370
1
    return from.to_string(scale);
371
1
}
372
373
template <>
374
12.6k
inline void CastToString::push_decimal(const Decimal64& from, UInt32 scale, BufferWritable& bw) {
375
12.6k
    std::string str = from.to_string(scale);
376
12.6k
    bw.write(str.data(), str.size());
377
12.6k
}
378
379
// DECIMAL128
380
template <>
381
1
inline std::string CastToString::from_decimal(const Decimal128V3& from, UInt32 scale) {
382
1
    return from.to_string(scale);
383
1
}
384
385
template <>
386
13.9k
inline void CastToString::push_decimal(const Decimal128V3& from, UInt32 scale, BufferWritable& bw) {
387
13.9k
    std::string str = from.to_string(scale);
388
13.9k
    bw.write(str.data(), str.size());
389
13.9k
}
390
391
// DECIMAL256
392
template <>
393
1
inline std::string CastToString::from_decimal(const Decimal256& from, UInt32 scale) {
394
1
    return from.to_string(scale);
395
1
}
396
397
template <>
398
14.7k
inline void CastToString::push_decimal(const Decimal256& from, UInt32 scale, BufferWritable& bw) {
399
14.7k
    std::string str = from.to_string(scale);
400
14.7k
    bw.write(str.data(), str.size());
401
14.7k
}
402
403
// DECIMALV2
404
template <>
405
1
inline std::string CastToString::from_decimal(const Decimal128V2& from, UInt32 scale) {
406
1
    auto value = (DecimalV2Value)from;
407
1
    auto str = value.to_string(scale);
408
1
    return str;
409
1
}
410
411
template <>
412
0
inline void CastToString::push_decimal(const Decimal128V2& from, UInt32 scale, BufferWritable& bw) {
413
0
    auto value = (DecimalV2Value)from;
414
0
    std::string str = value.to_string(scale);
415
0
    bw.write(str.data(), str.size());
416
0
}
417
418
template <>
419
inline void CastToString::push_decimal(const DecimalV2Value& from, UInt32 scale,
420
8.14k
                                       BufferWritable& bw) {
421
8.14k
    std::string str = from.to_string(scale);
422
8.14k
    bw.write(str.data(), str.size());
423
8.14k
}
424
425
// DATEV1 DATETIMEV1
426
2
inline std::string CastToString::from_date_or_datetime(const VecDateTimeValue& from) {
427
2
    char buf[64];
428
2
    char* pos = from.to_string(buf);
429
    // DateTime to_string the end is /0
430
2
    return std::string(buf, pos - 1);
431
2
}
432
433
inline void CastToString::push_date_or_datetime(const VecDateTimeValue& from,
434
0
                                                ColumnString::Chars& chars) {
435
0
    char buf[64];
436
0
    char* pos = from.to_string(buf);
437
0
    // DateTime to_string the end is /0
438
0
    chars.insert(buf, pos - 1);
439
0
}
440
441
6.55k
inline void CastToString::push_date_or_datetime(const VecDateTimeValue& from, BufferWritable& bw) {
442
6.55k
    char buf[64];
443
6.55k
    char* pos = from.to_string(buf);
444
    // DateTime to_string the end is /0
445
6.55k
    bw.write(buf, pos - buf - 1);
446
6.55k
}
447
448
// DATEV2
449
22
inline std::string CastToString::from_datev2(const DateV2Value<DateV2ValueType>& from) {
450
22
    char buf[64];
451
22
    char* pos = from.to_string(buf);
452
    // DateTime to_string the end is /0
453
22
    return std::string(buf, pos - 1);
454
22
}
455
456
inline void CastToString::push_datev2(const DateV2Value<DateV2ValueType>& from,
457
0
                                      ColumnString::Chars& chars) {
458
0
    char buf[64];
459
0
    char* pos = from.to_string(buf);
460
0
    // DateTime to_string the end is /0
461
0
    chars.insert(buf, pos - 1);
462
0
}
463
464
inline void CastToString::push_datev2(const DateV2Value<DateV2ValueType>& from,
465
2.72k
                                      BufferWritable& bw) {
466
2.72k
    char buf[64];
467
2.72k
    char* pos = from.to_string(buf);
468
    // DateTime to_string the end is /0
469
2.72k
    bw.write(buf, pos - buf - 1);
470
2.72k
}
471
472
// DATETIMEV2
473
inline std::string CastToString::from_datetimev2(const DateV2Value<DateTimeV2ValueType>& from,
474
53
                                                 UInt32 scale) {
475
53
    char buf[64];
476
53
    char* pos = from.to_string(buf, scale);
477
    // DateTime to_string the end is /0
478
53
    return std::string(buf, pos - 1);
479
53
}
480
481
inline std::string CastToString::from_timestamptz(const TimestampTzValue& from, UInt32 scale,
482
23
                                                  const cctz::time_zone* timezone) {
483
23
    cctz::time_zone tz;
484
23
    if (timezone == nullptr) {
485
23
        tz = cctz::utc_time_zone();
486
23
    } else {
487
0
        tz = *timezone;
488
0
    }
489
23
    return from.to_string(tz, scale);
490
23
}
491
inline void CastToString::push_datetimev2(const DateV2Value<DateTimeV2ValueType>& from,
492
0
                                          UInt32 scale, ColumnString::Chars& chars) {
493
0
    char buf[64];
494
0
    char* pos = from.to_string(buf, scale);
495
0
    // DateTime to_string the end is /0
496
0
    chars.insert(buf, pos - 1);
497
0
}
498
499
inline void CastToString::push_datetimev2(const DateV2Value<DateTimeV2ValueType>& from,
500
14.3k
                                          UInt32 scale, BufferWritable& bw) {
501
14.3k
    char buf[64];
502
14.3k
    char* pos = from.to_string(buf, scale);
503
    // DateTime to_string the end is /0
504
14.3k
    bw.write(buf, pos - buf - 1);
505
14.3k
}
506
507
inline void CastToString::push_timestamptz(const TimestampTzValue& from, UInt32 scale,
508
                                           BufferWritable& bw,
509
3
                                           const DataTypeSerDe::FormatOptions& options) {
510
3
    auto str = from.to_string(*options.timezone, scale);
511
3
    bw.write(str.data(), str.size());
512
3
}
513
514
// IPv4
515
template <>
516
8
inline std::string CastToString::from_ip(const IPv4& from) {
517
8
    auto value = IPv4Value(from);
518
8
    return value.to_string();
519
8
}
520
521
template <>
522
10.1k
inline void CastToString::push_ip(const IPv4& from, BufferWritable& bw) {
523
10.1k
    auto value = IPv4Value(from);
524
10.1k
    std::string str = value.to_string();
525
10.1k
    bw.write(str.data(), str.size());
526
10.1k
}
527
528
//IPv6
529
530
template <>
531
4
inline std::string CastToString::from_ip(const IPv6& from) {
532
4
    auto value = IPv6Value(from);
533
4
    return value.to_string();
534
4
}
535
536
template <>
537
7.17k
inline void CastToString::push_ip(const IPv6& from, BufferWritable& bw) {
538
7.17k
    auto value = IPv6Value(from);
539
7.17k
    std::string str = value.to_string();
540
7.17k
    bw.write(str.data(), str.size());
541
7.17k
}
542
543
// Time
544
1
inline std::string CastToString::from_time(const TimeValue::TimeType& from, UInt32 scale) {
545
1
    return timev2_to_buffer_from_double(from, scale);
546
1
}
547
548
inline void CastToString::push_time(const TimeValue::TimeType& from, UInt32 scale,
549
258
                                    BufferWritable& bw) {
550
258
    std::string str = timev2_to_buffer_from_double(from, scale);
551
258
    bw.write(str.data(), str.size());
552
258
}
553
554
class CastToStringFunction {
555
public:
556
    static Status execute_impl(FunctionContext* context, Block& block,
557
                               const ColumnNumbers& arguments, uint32_t result,
558
                               size_t input_rows_count,
559
16
                               const NullMap::value_type* null_map = nullptr) {
560
16
        const auto& col_with_type_and_name = block.get_by_position(arguments[0]);
561
16
        const IDataType& type = *col_with_type_and_name.type;
562
16
        const IColumn& col_from = *col_with_type_and_name.column;
563
564
16
        auto col_to = ColumnString::create();
565
566
16
        DataTypeSerDe::FormatOptions options;
567
16
        auto time_zone = cctz::utc_time_zone();
568
16
        options.timezone =
569
16
                (context && context->state()) ? &context->state()->timezone_obj() : &time_zone;
570
16
        type.get_serde()->to_string_batch(col_from, *col_to, options);
571
572
16
        block.replace_by_position(result, std::move(col_to));
573
16
        return Status::OK();
574
16
    }
575
};
576
577
namespace CastWrapper {
578
579
14
inline WrapperType create_string_wrapper(const DataTypePtr& from_type) {
580
14
    return [](FunctionContext* context, Block& block, const ColumnNumbers& arguments,
581
14
              uint32_t result, size_t input_rows_count,
582
14
              const NullMap::value_type* null_map = nullptr) {
583
14
        return CastToStringFunction::execute_impl(context, block, arguments, result,
584
14
                                                  input_rows_count, null_map);
585
14
    };
586
14
}
587
588
}; // namespace CastWrapper
589
} // namespace doris