Coverage Report

Created: 2026-07-07 22:17

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
114k
    static inline int _fast_to_buffer(T value, char* buffer) {
97
114k
        char* end = nullptr;
98
        // output NaN and Infinity to be compatible with most of the implementations
99
114k
        if (std::isnan(value)) {
100
28
            static constexpr char nan_str[] = "NaN";
101
28
            static constexpr int nan_str_len = sizeof(nan_str) - 1;
102
28
            memcpy(buffer, nan_str, nan_str_len);
103
28
            end = buffer + nan_str_len;
104
114k
        } else if (std::isinf(value)) {
105
54
            static constexpr char inf_str[] = "Infinity";
106
54
            static constexpr int inf_str_len = sizeof(inf_str) - 1;
107
54
            static constexpr char neg_inf_str[] = "-Infinity";
108
54
            static constexpr int neg_inf_str_len = sizeof(neg_inf_str) - 1;
109
54
            if (value > 0) {
110
28
                memcpy(buffer, inf_str, inf_str_len);
111
28
                end = buffer + inf_str_len;
112
28
            } else {
113
26
                memcpy(buffer, neg_inf_str, neg_inf_str_len);
114
26
                end = buffer + neg_inf_str_len;
115
26
            }
116
114k
        } else {
117
114k
            if constexpr (std::is_same_v<T, float>) {
118
53.8k
                end = fmt::format_to(buffer, FMT_COMPILE("{:.{}g}"), value,
119
53.8k
                                     std::numeric_limits<float>::digits10 + 1);
120
60.5k
            } else {
121
60.5k
                end = fmt::format_to(buffer, FMT_COMPILE("{:.{}g}"), value,
122
60.5k
                                     std::numeric_limits<double>::digits10 + 1);
123
60.5k
            }
124
114k
        }
125
114k
        *end = '\0';
126
114k
        return int(end - buffer);
127
114k
    }
_ZN5doris12CastToString15_fast_to_bufferIfQoosr3stdE9is_same_vIT_fEsr3stdE9is_same_vIS2_dEEEiS2_Pc
Line
Count
Source
96
53.9k
    static inline int _fast_to_buffer(T value, char* buffer) {
97
53.9k
        char* end = nullptr;
98
        // output NaN and Infinity to be compatible with most of the implementations
99
53.9k
        if (std::isnan(value)) {
100
12
            static constexpr char nan_str[] = "NaN";
101
12
            static constexpr int nan_str_len = sizeof(nan_str) - 1;
102
12
            memcpy(buffer, nan_str, nan_str_len);
103
12
            end = buffer + nan_str_len;
104
53.9k
        } else if (std::isinf(value)) {
105
24
            static constexpr char inf_str[] = "Infinity";
106
24
            static constexpr int inf_str_len = sizeof(inf_str) - 1;
107
24
            static constexpr char neg_inf_str[] = "-Infinity";
108
24
            static constexpr int neg_inf_str_len = sizeof(neg_inf_str) - 1;
109
24
            if (value > 0) {
110
12
                memcpy(buffer, inf_str, inf_str_len);
111
12
                end = buffer + inf_str_len;
112
12
            } else {
113
12
                memcpy(buffer, neg_inf_str, neg_inf_str_len);
114
12
                end = buffer + neg_inf_str_len;
115
12
            }
116
53.8k
        } else {
117
53.8k
            if constexpr (std::is_same_v<T, float>) {
118
53.8k
                end = fmt::format_to(buffer, FMT_COMPILE("{:.{}g}"), value,
119
53.8k
                                     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
53.8k
        }
125
53.9k
        *end = '\0';
126
53.9k
        return int(end - buffer);
127
53.9k
    }
_ZN5doris12CastToString15_fast_to_bufferIdQoosr3stdE9is_same_vIT_fEsr3stdE9is_same_vIS2_dEEEiS2_Pc
Line
Count
Source
96
60.5k
    static inline int _fast_to_buffer(T value, char* buffer) {
97
60.5k
        char* end = nullptr;
98
        // output NaN and Infinity to be compatible with most of the implementations
99
60.5k
        if (std::isnan(value)) {
100
16
            static constexpr char nan_str[] = "NaN";
101
16
            static constexpr int nan_str_len = sizeof(nan_str) - 1;
102
16
            memcpy(buffer, nan_str, nan_str_len);
103
16
            end = buffer + nan_str_len;
104
60.5k
        } else if (std::isinf(value)) {
105
30
            static constexpr char inf_str[] = "Infinity";
106
30
            static constexpr int inf_str_len = sizeof(inf_str) - 1;
107
30
            static constexpr char neg_inf_str[] = "-Infinity";
108
30
            static constexpr int neg_inf_str_len = sizeof(neg_inf_str) - 1;
109
30
            if (value > 0) {
110
16
                memcpy(buffer, inf_str, inf_str_len);
111
16
                end = buffer + inf_str_len;
112
16
            } else {
113
14
                memcpy(buffer, neg_inf_str, neg_inf_str_len);
114
14
                end = buffer + neg_inf_str_len;
115
14
            }
116
60.5k
        } 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
60.5k
            } else {
121
                end = fmt::format_to(buffer, FMT_COMPILE("{:.{}g}"), value,
122
60.5k
                                     std::numeric_limits<double>::digits10 + 1);
123
60.5k
            }
124
60.5k
        }
125
60.5k
        *end = '\0';
126
60.5k
        return int(end - buffer);
127
60.5k
    }
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
2
inline std::string CastToString::from_number(const UInt8& num) {
176
2
    auto f = fmt::format_int(num);
177
2
    return std::string(f.data(), f.data() + f.size());
178
2
}
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
702
inline void CastToString::push_number(const UInt8& num, BufferWritable& bw) {
188
702
    auto f = fmt::format_int(num);
189
702
    bw.write(f.data(), f.size());
190
702
}
191
192
// TINYINT
193
template <>
194
4.85k
inline std::string CastToString::from_number(const Int8& num) {
195
4.85k
    auto f = fmt::format_int(num);
196
4.85k
    return std::string(f.data(), f.data() + f.size());
197
4.85k
}
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
13.3k
inline void CastToString::push_number(const Int8& num, BufferWritable& bw) {
207
13.3k
    auto f = fmt::format_int(num);
208
13.3k
    bw.write(f.data(), f.size());
209
13.3k
}
210
211
// SMALLINT
212
template <>
213
60
inline std::string CastToString::from_number(const Int16& num) {
214
60
    auto f = fmt::format_int(num);
215
60
    return std::string(f.data(), f.data() + f.size());
216
60
}
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
12.1k
inline void CastToString::push_number(const Int16& num, BufferWritable& bw) {
226
12.1k
    auto f = fmt::format_int(num);
227
12.1k
    bw.write(f.data(), f.size());
228
12.1k
}
229
230
// INT
231
template <>
232
56.1k
inline std::string CastToString::from_number(const Int32& num) {
233
56.1k
    auto f = fmt::format_int(num);
234
56.1k
    return std::string(f.data(), f.data() + f.size());
235
56.1k
}
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
18.8k
inline void CastToString::push_number(const Int32& num, BufferWritable& bw) {
245
18.8k
    auto f = fmt::format_int(num);
246
18.8k
    bw.write(f.data(), f.size());
247
18.8k
}
248
249
// BIGINT
250
template <>
251
3.00k
inline std::string CastToString::from_number(const Int64& num) {
252
3.00k
    auto f = fmt::format_int(num);
253
3.00k
    return std::string(f.data(), f.data() + f.size());
254
3.00k
}
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
30.8k
inline void CastToString::push_number(const Int64& num, BufferWritable& bw) {
264
30.8k
    auto f = fmt::format_int(num);
265
30.8k
    bw.write(f.data(), f.size());
266
30.8k
}
267
268
// LARGEINT
269
642
inline std::string CastToString::from_int128(int128_t value) {
270
642
    fmt::memory_buffer buffer;
271
642
    fmt::format_to(buffer, "{}", value);
272
642
    return std::string(buffer.data(), buffer.size());
273
642
}
274
275
4
inline std::string CastToString::from_uint128(uint128_t value) {
276
4
    fmt::memory_buffer buffer;
277
4
    fmt::format_to(buffer, "{}", value);
278
4
    return std::string(buffer.data(), buffer.size());
279
4
}
280
281
2
inline std::string CastToString::from_uint128(UInt128 value) {
282
2
    return value.to_hex_string();
283
2
}
284
285
template <>
286
2
inline std::string CastToString::from_number(const Int128& num) {
287
2
    return from_int128(num);
288
2
}
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
9.55k
inline void CastToString::push_number(const Int128& num, BufferWritable& bw) {
299
9.55k
    fmt::memory_buffer buffer;
300
9.55k
    fmt::format_to(buffer, "{}", num);
301
9.55k
    bw.write(buffer.data(), buffer.size());
302
9.55k
}
303
304
// FLOAT
305
306
template <>
307
42.9k
inline std::string CastToString::from_number(const Float32& num) {
308
42.9k
    char buf[MAX_FLOAT_STR_LENGTH + 2];
309
42.9k
    int len = _fast_to_buffer(num, buf);
310
42.9k
    return std::string(buf, buf + len);
311
42.9k
}
312
313
template <typename T>
314
    requires(std::is_same_v<T, Float32> || std::is_same_v<T, Float64>)
315
162
inline int CastToString::from_number(const T& from, char* buffer) {
316
162
    return _fast_to_buffer(from, buffer);
317
162
}
_ZN5doris12CastToString11from_numberIfQoosr3stdE9is_same_vIT_fEsr3stdE9is_same_vIS2_dEEEiRKS2_Pc
Line
Count
Source
315
76
inline int CastToString::from_number(const T& from, char* buffer) {
316
76
    return _fast_to_buffer(from, buffer);
317
76
}
_ZN5doris12CastToString11from_numberIdQoosr3stdE9is_same_vIT_fEsr3stdE9is_same_vIS2_dEEEiRKS2_Pc
Line
Count
Source
315
86
inline int CastToString::from_number(const T& from, char* buffer) {
316
86
    return _fast_to_buffer(from, buffer);
317
86
}
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
10.8k
inline void CastToString::push_number(const Float32& num, BufferWritable& bw) {
328
10.8k
    char buf[MAX_FLOAT_STR_LENGTH + 2];
329
10.8k
    int len = _fast_to_buffer(num, buf);
330
10.8k
    bw.write(buf, len);
331
10.8k
}
332
333
// DOUBLE
334
template <>
335
48.4k
inline std::string CastToString::from_number(const Float64& num) {
336
48.4k
    char buf[MAX_DOUBLE_STR_LENGTH + 2];
337
48.4k
    int len = _fast_to_buffer(num, buf);
338
48.4k
    return std::string(buf, len);
339
48.4k
}
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
12.0k
inline void CastToString::push_number(const Float64& num, BufferWritable& bw) {
350
12.0k
    char buf[MAX_DOUBLE_STR_LENGTH + 2];
351
12.0k
    int len = _fast_to_buffer(num, buf);
352
12.0k
    bw.write(buf, len);
353
12.0k
}
354
355
// DECIMAL32
356
template <>
357
4
inline std::string CastToString::from_decimal(const Decimal32& from, UInt32 scale) {
358
4
    return from.to_string(scale);
359
4
}
360
361
template <>
362
9.70k
inline void CastToString::push_decimal(const Decimal32& from, UInt32 scale, BufferWritable& bw) {
363
9.70k
    std::string str = from.to_string(scale);
364
9.70k
    bw.write(str.data(), str.size());
365
9.70k
}
366
367
// DECIMAL64
368
template <>
369
4
inline std::string CastToString::from_decimal(const Decimal64& from, UInt32 scale) {
370
4
    return from.to_string(scale);
371
4
}
372
373
template <>
374
25.2k
inline void CastToString::push_decimal(const Decimal64& from, UInt32 scale, BufferWritable& bw) {
375
25.2k
    std::string str = from.to_string(scale);
376
25.2k
    bw.write(str.data(), str.size());
377
25.2k
}
378
379
// DECIMAL128
380
template <>
381
4
inline std::string CastToString::from_decimal(const Decimal128V3& from, UInt32 scale) {
382
4
    return from.to_string(scale);
383
4
}
384
385
template <>
386
27.9k
inline void CastToString::push_decimal(const Decimal128V3& from, UInt32 scale, BufferWritable& bw) {
387
27.9k
    std::string str = from.to_string(scale);
388
27.9k
    bw.write(str.data(), str.size());
389
27.9k
}
390
391
// DECIMAL256
392
template <>
393
4
inline std::string CastToString::from_decimal(const Decimal256& from, UInt32 scale) {
394
4
    return from.to_string(scale);
395
4
}
396
397
template <>
398
29.4k
inline void CastToString::push_decimal(const Decimal256& from, UInt32 scale, BufferWritable& bw) {
399
29.4k
    std::string str = from.to_string(scale);
400
29.4k
    bw.write(str.data(), str.size());
401
29.4k
}
402
403
// DECIMALV2
404
template <>
405
2
inline std::string CastToString::from_decimal(const Decimal128V2& from, UInt32 scale) {
406
2
    auto value = (DecimalV2Value)from;
407
2
    auto str = value.to_string(scale);
408
2
    return str;
409
2
}
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
16.2k
                                       BufferWritable& bw) {
421
16.2k
    std::string str = from.to_string(scale);
422
16.2k
    bw.write(str.data(), str.size());
423
16.2k
}
424
425
// DATEV1 DATETIMEV1
426
4
inline std::string CastToString::from_date_or_datetime(const VecDateTimeValue& from) {
427
4
    char buf[64];
428
4
    char* pos = from.to_string(buf);
429
    // DateTime to_string the end is /0
430
4
    return std::string(buf, pos - 1);
431
4
}
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
13.1k
inline void CastToString::push_date_or_datetime(const VecDateTimeValue& from, BufferWritable& bw) {
442
13.1k
    char buf[64];
443
13.1k
    char* pos = from.to_string(buf);
444
    // DateTime to_string the end is /0
445
13.1k
    bw.write(buf, pos - buf - 1);
446
13.1k
}
447
448
// DATEV2
449
50
inline std::string CastToString::from_datev2(const DateV2Value<DateV2ValueType>& from) {
450
50
    char buf[64];
451
50
    char* pos = from.to_string(buf);
452
    // DateTime to_string the end is /0
453
50
    return std::string(buf, pos - 1);
454
50
}
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
5.46k
                                      BufferWritable& bw) {
466
5.46k
    char buf[64];
467
5.46k
    char* pos = from.to_string(buf);
468
    // DateTime to_string the end is /0
469
5.46k
    bw.write(buf, pos - buf - 1);
470
5.46k
}
471
472
// DATETIMEV2
473
inline std::string CastToString::from_datetimev2(const DateV2Value<DateTimeV2ValueType>& from,
474
116
                                                 UInt32 scale) {
475
116
    char buf[64];
476
116
    char* pos = from.to_string(buf, scale);
477
    // DateTime to_string the end is /0
478
116
    return std::string(buf, pos - 1);
479
116
}
480
481
inline std::string CastToString::from_timestamptz(const TimestampTzValue& from, UInt32 scale,
482
46
                                                  const cctz::time_zone* timezone) {
483
46
    cctz::time_zone tz;
484
46
    if (timezone == nullptr) {
485
46
        tz = cctz::utc_time_zone();
486
46
    } else {
487
0
        tz = *timezone;
488
0
    }
489
46
    return from.to_string(tz, scale);
490
46
}
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
28.7k
                                          UInt32 scale, BufferWritable& bw) {
501
28.7k
    char buf[64];
502
28.7k
    char* pos = from.to_string(buf, scale);
503
    // DateTime to_string the end is /0
504
28.7k
    bw.write(buf, pos - buf - 1);
505
28.7k
}
506
507
inline void CastToString::push_timestamptz(const TimestampTzValue& from, UInt32 scale,
508
                                           BufferWritable& bw,
509
6
                                           const DataTypeSerDe::FormatOptions& options) {
510
6
    auto str = from.to_string(*options.timezone, scale);
511
6
    bw.write(str.data(), str.size());
512
6
}
513
514
// IPv4
515
template <>
516
10
inline std::string CastToString::from_ip(const IPv4& from) {
517
10
    auto value = IPv4Value(from);
518
10
    return value.to_string();
519
10
}
520
521
template <>
522
20.3k
inline void CastToString::push_ip(const IPv4& from, BufferWritable& bw) {
523
20.3k
    auto value = IPv4Value(from);
524
20.3k
    std::string str = value.to_string();
525
20.3k
    bw.write(str.data(), str.size());
526
20.3k
}
527
528
//IPv6
529
530
template <>
531
20
inline std::string CastToString::from_ip(const IPv6& from) {
532
20
    auto value = IPv6Value(from);
533
20
    return value.to_string();
534
20
}
535
536
template <>
537
14.3k
inline void CastToString::push_ip(const IPv6& from, BufferWritable& bw) {
538
14.3k
    auto value = IPv6Value(from);
539
14.3k
    std::string str = value.to_string();
540
14.3k
    bw.write(str.data(), str.size());
541
14.3k
}
542
543
// Time
544
2
inline std::string CastToString::from_time(const TimeValue::TimeType& from, UInt32 scale) {
545
2
    return timev2_to_buffer_from_double(from, scale);
546
2
}
547
548
inline void CastToString::push_time(const TimeValue::TimeType& from, UInt32 scale,
549
558
                                    BufferWritable& bw) {
550
558
    std::string str = timev2_to_buffer_from_double(from, scale);
551
558
    bw.write(str.data(), str.size());
552
558
}
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
38
                               const NullMap::value_type* null_map = nullptr) {
560
38
        const auto& col_with_type_and_name = block.get_by_position(arguments[0]);
561
38
        const IDataType& type = *col_with_type_and_name.type;
562
38
        const IColumn& col_from = *col_with_type_and_name.column;
563
564
38
        auto col_to = ColumnString::create();
565
566
38
        DataTypeSerDe::FormatOptions options;
567
38
        auto time_zone = cctz::utc_time_zone();
568
38
        options.timezone =
569
38
                (context && context->state()) ? &context->state()->timezone_obj() : &time_zone;
570
38
        ColumnPtr limited_col;
571
38
        const IColumn* col_to_serialize = &col_from;
572
38
        if (col_from.size() != input_rows_count) {
573
4
            DORIS_CHECK(col_from.size() >= input_rows_count);
574
4
            limited_col = col_from.cut(0, input_rows_count);
575
4
            col_to_serialize = limited_col.get();
576
4
        }
577
38
        type.get_serde()->to_string_batch(*col_to_serialize, *col_to, options);
578
579
38
        block.replace_by_position(result, std::move(col_to));
580
38
        return Status::OK();
581
38
    }
582
};
583
584
namespace CastWrapper {
585
586
30
inline WrapperType create_string_wrapper(const DataTypePtr& from_type) {
587
30
    return [](FunctionContext* context, Block& block, const ColumnNumbers& arguments,
588
30
              uint32_t result, size_t input_rows_count,
589
30
              const NullMap::value_type* null_map = nullptr) {
590
30
        return CastToStringFunction::execute_impl(context, block, arguments, result,
591
30
                                                  input_rows_count, null_map);
592
30
    };
593
30
}
594
595
}; // namespace CastWrapper
596
} // namespace doris