Coverage Report

Created: 2026-09-29 04:23

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 <algorithm>
21
22
#include "core/data_type_serde/data_type_serde.h"
23
#include "core/types.h"
24
#include "core/value/time_value.h"
25
#include "core/value/timestamp_ns_value.h"
26
#include "core/value/uuid_value.h"
27
#include "exprs/function/cast/cast_base.h"
28
#include "runtime/runtime_state.h"
29
#include "util/mysql_global.h"
30
#include "util/to_string.h"
31
namespace doris {
32
struct CastToString {
33
    static inline std::string from_int128(int128_t value);
34
    static inline std::string from_uint128(uint128_t value);
35
    static inline std::string from_uint128(UInt128 value);
36
    static inline std::string from_uuid(UUIDValueType value);
37
    static inline void push_uuid(UUIDValueType value, BufferWritable& bw);
38
39
    template <class SRC>
40
    static inline std::string from_number(const SRC& from);
41
42
    // Caller is responsible for ensuring that `buffer` has enough space.
43
    template <class SRC>
44
    static inline int from_number(const SRC& from, char* buffer);
45
46
    template <typename T>
47
        requires(std::is_same_v<T, Float32> || std::is_same_v<T, Float64>)
48
    static inline int from_number(const T& from, char* buffer);
49
50
    template <class SRC>
51
    static inline void push_number(const SRC& from, ColumnString::Chars& chars);
52
53
    template <class SRC>
54
    static inline void push_number(const SRC& from, BufferWritable& bw);
55
56
    template <class SRC>
57
    static inline std::string from_decimal(const SRC& from, UInt32 scale);
58
59
    template <class SRC>
60
    static inline void push_decimal(const SRC& from, UInt32 scale, BufferWritable& bw);
61
62
    static inline std::string from_date_or_datetime(const VecDateTimeValue& from);
63
64
    static inline void push_date_or_datetime(const VecDateTimeValue& from,
65
                                             ColumnString::Chars& chars);
66
    static inline void push_date_or_datetime(const VecDateTimeValue& from, BufferWritable& bw);
67
68
    static inline std::string from_datev2(const DateV2Value<DateV2ValueType>& from);
69
    static inline void push_datev2(const DateV2Value<DateV2ValueType>& from,
70
                                   ColumnString::Chars& chars);
71
    static inline void push_datev2(const DateV2Value<DateV2ValueType>& from, BufferWritable& bw);
72
73
    static inline std::string from_datetimev2(const DateV2Value<DateTimeV2ValueType>& from,
74
                                              UInt32 scale);
75
    static inline std::string from_timestamp_ns(const TimeStampNsValue& from);
76
    static inline std::string from_timestamptz(const TimestampTzValue& from, UInt32 scale,
77
                                               const cctz::time_zone* timezone = nullptr);
78
    static inline void push_datetimev2(const DateV2Value<DateTimeV2ValueType>& from, UInt32 scale,
79
                                       ColumnString::Chars& chars);
80
81
    static inline void push_datetimev2(const DateV2Value<DateTimeV2ValueType>& from, UInt32 scale,
82
                                       BufferWritable& bw);
83
    static inline void push_timestamp_ns(const TimeStampNsValue& from, BufferWritable& bw);
84
    static inline void push_timestamptz(const TimestampTzValue& from, UInt32 scale,
85
                                        BufferWritable& bw,
86
                                        const DataTypeSerDe::FormatOptions& options);
87
88
    template <class SRC>
89
    static inline std::string from_ip(const SRC& from);
90
91
    template <class SRC>
92
    static inline void push_ip(const SRC& from, BufferWritable& bw);
93
94
    static inline std::string from_time(const TimeValue::TimeType& from, UInt32 scale);
95
96
    static inline void push_time(const TimeValue::TimeType& from, UInt32 scale, BufferWritable& bw);
97
98
    template <PrimitiveType T>
99
    static constexpr size_t string_length = 1;
100
101
private:
102
    template <typename T>
103
        requires(std::is_same_v<T, float> || std::is_same_v<T, double>)
104
58.5k
    static inline int _fast_to_buffer(T value, char* buffer) {
105
58.5k
        char* end = nullptr;
106
        // output NaN and Infinity to be compatible with most of the implementations
107
58.5k
        if (std::isnan(value)) {
108
14
            static constexpr char nan_str[] = "NaN";
109
14
            static constexpr int nan_str_len = sizeof(nan_str) - 1;
110
14
            memcpy(buffer, nan_str, nan_str_len);
111
14
            end = buffer + nan_str_len;
112
58.5k
        } else if (std::isinf(value)) {
113
27
            static constexpr char inf_str[] = "Infinity";
114
27
            static constexpr int inf_str_len = sizeof(inf_str) - 1;
115
27
            static constexpr char neg_inf_str[] = "-Infinity";
116
27
            static constexpr int neg_inf_str_len = sizeof(neg_inf_str) - 1;
117
27
            if (value > 0) {
118
14
                memcpy(buffer, inf_str, inf_str_len);
119
14
                end = buffer + inf_str_len;
120
14
            } else {
121
13
                memcpy(buffer, neg_inf_str, neg_inf_str_len);
122
13
                end = buffer + neg_inf_str_len;
123
13
            }
124
58.5k
        } else {
125
58.5k
            end = fmt::format_to(buffer, FMT_COMPILE("{}"), value);
Unexecuted instantiation: _ZZZN5doris12CastToString15_fast_to_bufferIfQoosr3stdE9is_same_vIT_fEsr3stdE9is_same_vIS2_dEEEiS2_PcENKUlvE_clEvENK18FMT_COMPILE_STRINGcvN3fmt2v717basic_string_viewIcEEEv
Unexecuted instantiation: _ZZZN5doris12CastToString15_fast_to_bufferIdQoosr3stdE9is_same_vIT_fEsr3stdE9is_same_vIS2_dEEEiS2_PcENKUlvE_clEvENK18FMT_COMPILE_STRINGcvN3fmt2v717basic_string_viewIcEEEv
126
58.5k
        }
127
58.5k
        *end = '\0';
128
58.5k
        return int(end - buffer);
129
58.5k
    }
_ZN5doris12CastToString15_fast_to_bufferIfQoosr3stdE9is_same_vIT_fEsr3stdE9is_same_vIS2_dEEEiS2_Pc
Line
Count
Source
104
27.5k
    static inline int _fast_to_buffer(T value, char* buffer) {
105
27.5k
        char* end = nullptr;
106
        // output NaN and Infinity to be compatible with most of the implementations
107
27.5k
        if (std::isnan(value)) {
108
6
            static constexpr char nan_str[] = "NaN";
109
6
            static constexpr int nan_str_len = sizeof(nan_str) - 1;
110
6
            memcpy(buffer, nan_str, nan_str_len);
111
6
            end = buffer + nan_str_len;
112
27.5k
        } else if (std::isinf(value)) {
113
12
            static constexpr char inf_str[] = "Infinity";
114
12
            static constexpr int inf_str_len = sizeof(inf_str) - 1;
115
12
            static constexpr char neg_inf_str[] = "-Infinity";
116
12
            static constexpr int neg_inf_str_len = sizeof(neg_inf_str) - 1;
117
12
            if (value > 0) {
118
6
                memcpy(buffer, inf_str, inf_str_len);
119
6
                end = buffer + inf_str_len;
120
6
            } else {
121
6
                memcpy(buffer, neg_inf_str, neg_inf_str_len);
122
6
                end = buffer + neg_inf_str_len;
123
6
            }
124
27.5k
        } else {
125
            end = fmt::format_to(buffer, FMT_COMPILE("{}"), value);
126
27.5k
        }
127
27.5k
        *end = '\0';
128
27.5k
        return int(end - buffer);
129
27.5k
    }
_ZN5doris12CastToString15_fast_to_bufferIdQoosr3stdE9is_same_vIT_fEsr3stdE9is_same_vIS2_dEEEiS2_Pc
Line
Count
Source
104
31.0k
    static inline int _fast_to_buffer(T value, char* buffer) {
105
31.0k
        char* end = nullptr;
106
        // output NaN and Infinity to be compatible with most of the implementations
107
31.0k
        if (std::isnan(value)) {
108
8
            static constexpr char nan_str[] = "NaN";
109
8
            static constexpr int nan_str_len = sizeof(nan_str) - 1;
110
8
            memcpy(buffer, nan_str, nan_str_len);
111
8
            end = buffer + nan_str_len;
112
31.0k
        } else if (std::isinf(value)) {
113
15
            static constexpr char inf_str[] = "Infinity";
114
15
            static constexpr int inf_str_len = sizeof(inf_str) - 1;
115
15
            static constexpr char neg_inf_str[] = "-Infinity";
116
15
            static constexpr int neg_inf_str_len = sizeof(neg_inf_str) - 1;
117
15
            if (value > 0) {
118
8
                memcpy(buffer, inf_str, inf_str_len);
119
8
                end = buffer + inf_str_len;
120
8
            } else {
121
7
                memcpy(buffer, neg_inf_str, neg_inf_str_len);
122
7
                end = buffer + neg_inf_str_len;
123
7
            }
124
31.0k
        } else {
125
            end = fmt::format_to(buffer, FMT_COMPILE("{}"), value);
126
31.0k
        }
127
31.0k
        *end = '\0';
128
31.0k
        return int(end - buffer);
129
31.0k
    }
130
};
131
132
template <>
133
constexpr size_t CastToString::string_length<TYPE_BOOLEAN> = 1;
134
template <>
135
constexpr size_t CastToString::string_length<TYPE_TINYINT> = 4;
136
template <>
137
constexpr size_t CastToString::string_length<TYPE_SMALLINT> = 6;
138
template <>
139
constexpr size_t CastToString::string_length<TYPE_INT> = 11;
140
template <>
141
constexpr size_t CastToString::string_length<TYPE_BIGINT> = 20;
142
template <>
143
constexpr size_t CastToString::string_length<TYPE_LARGEINT> = 40;
144
template <>
145
constexpr size_t CastToString::string_length<TYPE_FLOAT> = MAX_FLOAT_STR_LENGTH;
146
template <>
147
constexpr size_t CastToString::string_length<TYPE_DOUBLE> = MAX_DOUBLE_STR_LENGTH;
148
template <>
149
constexpr size_t CastToString::string_length<TYPE_DECIMAL32> = 14;
150
template <>
151
constexpr size_t CastToString::string_length<TYPE_DECIMAL64> = 24;
152
template <>
153
constexpr size_t CastToString::string_length<TYPE_DECIMALV2> = 24;
154
template <>
155
constexpr size_t CastToString::string_length<TYPE_DECIMAL128I> = 39;
156
template <>
157
constexpr size_t CastToString::string_length<TYPE_DECIMAL256> = 78;
158
template <>
159
constexpr size_t CastToString::string_length<TYPE_DATE> = sizeof("YYYY-MM-DD") - 1;
160
template <>
161
constexpr size_t CastToString::string_length<TYPE_DATETIME> = sizeof("YYYY-MM-DD HH:MM:SS") - 1;
162
template <>
163
constexpr size_t CastToString::string_length<TYPE_DATEV2> = sizeof("YYYY-MM-DD") - 1;
164
template <>
165
constexpr size_t CastToString::string_length<TYPE_DATETIMEV2> =
166
        sizeof("YYYY-MM-DD HH:MM:SS.ssssss") - 1;
167
template <>
168
constexpr size_t CastToString::string_length<TYPE_TIMEV2> = sizeof("-838:59:59.999999") - 1;
169
template <>
170
constexpr size_t CastToString::string_length<TYPE_IPV4> = sizeof("255.255 .255.255") - 1;
171
template <>
172
constexpr size_t CastToString::string_length<TYPE_IPV6> =
173
        sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff") - 1;
174
template <>
175
constexpr size_t CastToString::string_length<TYPE_UUID> = 36;
176
177
// BOOLEAN
178
template <>
179
1
inline std::string CastToString::from_number(const UInt8& num) {
180
1
    auto f = fmt::format_int(num);
181
1
    return std::string(f.data(), f.data() + f.size());
182
1
}
183
184
template <>
185
0
inline void CastToString::push_number(const UInt8& num, ColumnString::Chars& chars) {
186
0
    auto f = fmt::format_int(num);
187
0
    chars.insert(f.data(), f.data() + f.size());
188
0
}
189
190
template <>
191
567
inline void CastToString::push_number(const UInt8& num, BufferWritable& bw) {
192
567
    auto f = fmt::format_int(num);
193
567
    bw.write(f.data(), f.size());
194
567
}
195
196
// TINYINT
197
template <>
198
5.66k
inline std::string CastToString::from_number(const Int8& num) {
199
5.66k
    auto f = fmt::format_int(num);
200
5.66k
    return std::string(f.data(), f.data() + f.size());
201
5.66k
}
202
203
template <>
204
0
inline void CastToString::push_number(const Int8& num, ColumnString::Chars& chars) {
205
0
    auto f = fmt::format_int(num);
206
0
    chars.insert(f.data(), f.data() + f.size());
207
0
}
208
209
template <>
210
6.73k
inline void CastToString::push_number(const Int8& num, BufferWritable& bw) {
211
6.73k
    auto f = fmt::format_int(num);
212
6.73k
    bw.write(f.data(), f.size());
213
6.73k
}
214
215
// SMALLINT
216
template <>
217
304
inline std::string CastToString::from_number(const Int16& num) {
218
304
    auto f = fmt::format_int(num);
219
304
    return std::string(f.data(), f.data() + f.size());
220
304
}
221
222
template <>
223
0
inline void CastToString::push_number(const Int16& num, ColumnString::Chars& chars) {
224
0
    auto f = fmt::format_int(num);
225
0
    chars.insert(f.data(), f.data() + f.size());
226
0
}
227
228
template <>
229
6.14k
inline void CastToString::push_number(const Int16& num, BufferWritable& bw) {
230
6.14k
    auto f = fmt::format_int(num);
231
6.14k
    bw.write(f.data(), f.size());
232
6.14k
}
233
234
// INT
235
template <>
236
33.2k
inline std::string CastToString::from_number(const Int32& num) {
237
33.2k
    auto f = fmt::format_int(num);
238
33.2k
    return std::string(f.data(), f.data() + f.size());
239
33.2k
}
240
241
template <>
242
0
inline void CastToString::push_number(const Int32& num, ColumnString::Chars& chars) {
243
0
    auto f = fmt::format_int(num);
244
0
    chars.insert(f.data(), f.data() + f.size());
245
0
}
246
247
template <>
248
41.7k
inline void CastToString::push_number(const Int32& num, BufferWritable& bw) {
249
41.7k
    auto f = fmt::format_int(num);
250
41.7k
    bw.write(f.data(), f.size());
251
41.7k
}
252
253
// BIGINT
254
template <>
255
2.59k
inline std::string CastToString::from_number(const Int64& num) {
256
2.59k
    auto f = fmt::format_int(num);
257
2.59k
    return std::string(f.data(), f.data() + f.size());
258
2.59k
}
259
260
template <>
261
0
inline void CastToString::push_number(const Int64& num, ColumnString::Chars& chars) {
262
0
    auto f = fmt::format_int(num);
263
0
    chars.insert(f.data(), f.data() + f.size());
264
0
}
265
266
template <>
267
15.8k
inline void CastToString::push_number(const Int64& num, BufferWritable& bw) {
268
15.8k
    auto f = fmt::format_int(num);
269
15.8k
    bw.write(f.data(), f.size());
270
15.8k
}
271
272
// LARGEINT
273
321
inline std::string CastToString::from_int128(int128_t value) {
274
321
    fmt::memory_buffer buffer;
275
321
    fmt::format_to(buffer, "{}", value);
276
321
    return std::string(buffer.data(), buffer.size());
277
321
}
278
279
2
inline std::string CastToString::from_uint128(uint128_t value) {
280
2
    fmt::memory_buffer buffer;
281
2
    fmt::format_to(buffer, "{}", value);
282
2
    return std::string(buffer.data(), buffer.size());
283
2
}
284
285
1
inline std::string CastToString::from_uint128(UInt128 value) {
286
1
    return value.to_hex_string();
287
1
}
288
289
template <>
290
1
inline std::string CastToString::from_number(const Int128& num) {
291
1
    return from_int128(num);
292
1
}
293
294
template <>
295
0
inline void CastToString::push_number(const Int128& num, ColumnString::Chars& chars) {
296
0
    fmt::memory_buffer buffer;
297
0
    fmt::format_to(buffer, "{}", num);
298
0
    chars.insert(buffer.data(), buffer.data() + buffer.size());
299
0
}
300
301
template <>
302
4.74k
inline void CastToString::push_number(const Int128& num, BufferWritable& bw) {
303
4.74k
    fmt::memory_buffer buffer;
304
4.74k
    fmt::format_to(buffer, "{}", num);
305
4.74k
    bw.write(buffer.data(), buffer.size());
306
4.74k
}
307
308
// FLOAT
309
310
template <>
311
22.0k
inline std::string CastToString::from_number(const Float32& num) {
312
22.0k
    char buf[MAX_FLOAT_STR_LENGTH + 2];
313
22.0k
    int len = _fast_to_buffer(num, buf);
314
22.0k
    return std::string(buf, buf + len);
315
22.0k
}
316
317
template <typename T>
318
    requires(std::is_same_v<T, Float32> || std::is_same_v<T, Float64>)
319
85
inline int CastToString::from_number(const T& from, char* buffer) {
320
85
    return _fast_to_buffer(from, buffer);
321
85
}
_ZN5doris12CastToString11from_numberIfQoosr3stdE9is_same_vIT_fEsr3stdE9is_same_vIS2_dEEEiRKS2_Pc
Line
Count
Source
319
40
inline int CastToString::from_number(const T& from, char* buffer) {
320
40
    return _fast_to_buffer(from, buffer);
321
40
}
_ZN5doris12CastToString11from_numberIdQoosr3stdE9is_same_vIT_fEsr3stdE9is_same_vIS2_dEEEiRKS2_Pc
Line
Count
Source
319
45
inline int CastToString::from_number(const T& from, char* buffer) {
320
45
    return _fast_to_buffer(from, buffer);
321
45
}
322
323
template <>
324
0
inline void CastToString::push_number(const Float32& num, ColumnString::Chars& chars) {
325
0
    char buf[MAX_FLOAT_STR_LENGTH + 2];
326
0
    int len = _fast_to_buffer(num, buf);
327
0
    chars.insert(buf, buf + len);
328
0
}
329
330
template <>
331
5.49k
inline void CastToString::push_number(const Float32& num, BufferWritable& bw) {
332
5.49k
    char buf[MAX_FLOAT_STR_LENGTH + 2];
333
5.49k
    int len = _fast_to_buffer(num, buf);
334
5.49k
    bw.write(buf, len);
335
5.49k
}
336
337
// DOUBLE
338
template <>
339
24.8k
inline std::string CastToString::from_number(const Float64& num) {
340
24.8k
    char buf[MAX_DOUBLE_STR_LENGTH + 2];
341
24.8k
    int len = _fast_to_buffer(num, buf);
342
24.8k
    return std::string(buf, len);
343
24.8k
}
344
345
template <>
346
0
inline void CastToString::push_number(const Float64& num, ColumnString::Chars& chars) {
347
0
    char buf[MAX_DOUBLE_STR_LENGTH + 2];
348
0
    int len = _fast_to_buffer(num, buf);
349
0
    chars.insert(buf, buf + len);
350
0
}
351
352
template <>
353
6.08k
inline void CastToString::push_number(const Float64& num, BufferWritable& bw) {
354
6.08k
    char buf[MAX_DOUBLE_STR_LENGTH + 2];
355
6.08k
    int len = _fast_to_buffer(num, buf);
356
6.08k
    bw.write(buf, len);
357
6.08k
}
358
359
// DECIMAL32
360
template <>
361
2
inline std::string CastToString::from_decimal(const Decimal32& from, UInt32 scale) {
362
2
    return from.to_string(scale);
363
2
}
364
365
template <>
366
4.85k
inline void CastToString::push_decimal(const Decimal32& from, UInt32 scale, BufferWritable& bw) {
367
4.85k
    std::string str = from.to_string(scale);
368
4.85k
    bw.write(str.data(), str.size());
369
4.85k
}
370
371
// DECIMAL64
372
template <>
373
2
inline std::string CastToString::from_decimal(const Decimal64& from, UInt32 scale) {
374
2
    return from.to_string(scale);
375
2
}
376
377
template <>
378
12.6k
inline void CastToString::push_decimal(const Decimal64& from, UInt32 scale, BufferWritable& bw) {
379
12.6k
    std::string str = from.to_string(scale);
380
12.6k
    bw.write(str.data(), str.size());
381
12.6k
}
382
383
// DECIMAL128
384
template <>
385
2
inline std::string CastToString::from_decimal(const Decimal128V3& from, UInt32 scale) {
386
2
    return from.to_string(scale);
387
2
}
388
389
template <>
390
14.0k
inline void CastToString::push_decimal(const Decimal128V3& from, UInt32 scale, BufferWritable& bw) {
391
14.0k
    std::string str = from.to_string(scale);
392
14.0k
    bw.write(str.data(), str.size());
393
14.0k
}
394
395
// DECIMAL256
396
template <>
397
2
inline std::string CastToString::from_decimal(const Decimal256& from, UInt32 scale) {
398
2
    return from.to_string(scale);
399
2
}
400
401
template <>
402
14.7k
inline void CastToString::push_decimal(const Decimal256& from, UInt32 scale, BufferWritable& bw) {
403
14.7k
    std::string str = from.to_string(scale);
404
14.7k
    bw.write(str.data(), str.size());
405
14.7k
}
406
407
// DECIMALV2
408
template <>
409
1
inline std::string CastToString::from_decimal(const Decimal128V2& from, UInt32 scale) {
410
1
    auto value = (DecimalV2Value)from;
411
1
    auto str = value.to_string(scale);
412
1
    return str;
413
1
}
414
415
template <>
416
0
inline void CastToString::push_decimal(const Decimal128V2& from, UInt32 scale, BufferWritable& bw) {
417
0
    auto value = (DecimalV2Value)from;
418
0
    std::string str = value.to_string(scale);
419
0
    bw.write(str.data(), str.size());
420
0
}
421
422
template <>
423
inline void CastToString::push_decimal(const DecimalV2Value& from, UInt32 scale,
424
8.14k
                                       BufferWritable& bw) {
425
8.14k
    std::string str = from.to_string(scale);
426
8.14k
    bw.write(str.data(), str.size());
427
8.14k
}
428
429
// DATEV1 DATETIMEV1
430
2
inline std::string CastToString::from_date_or_datetime(const VecDateTimeValue& from) {
431
2
    char buf[64];
432
2
    char* pos = from.to_string(buf);
433
    // DateTime to_string the end is /0
434
2
    return std::string(buf, pos - 1);
435
2
}
436
437
inline void CastToString::push_date_or_datetime(const VecDateTimeValue& from,
438
0
                                                ColumnString::Chars& chars) {
439
0
    char buf[64];
440
0
    char* pos = from.to_string(buf);
441
0
    // DateTime to_string the end is /0
442
0
    chars.insert(buf, pos - 1);
443
0
}
444
445
6.55k
inline void CastToString::push_date_or_datetime(const VecDateTimeValue& from, BufferWritable& bw) {
446
6.55k
    char buf[64];
447
6.55k
    char* pos = from.to_string(buf);
448
    // DateTime to_string the end is /0
449
6.55k
    bw.write(buf, pos - buf - 1);
450
6.55k
}
451
452
// DATEV2
453
300
inline std::string CastToString::from_datev2(const DateV2Value<DateV2ValueType>& from) {
454
300
    char buf[64];
455
300
    char* pos = from.to_string(buf);
456
    // DateTime to_string the end is /0
457
300
    return std::string(buf, pos - 1);
458
300
}
459
460
inline void CastToString::push_datev2(const DateV2Value<DateV2ValueType>& from,
461
0
                                      ColumnString::Chars& chars) {
462
0
    char buf[64];
463
0
    char* pos = from.to_string(buf);
464
0
    // DateTime to_string the end is /0
465
0
    chars.insert(buf, pos - 1);
466
0
}
467
468
inline void CastToString::push_datev2(const DateV2Value<DateV2ValueType>& from,
469
2.74k
                                      BufferWritable& bw) {
470
2.74k
    char buf[64];
471
2.74k
    char* pos = from.to_string(buf);
472
    // DateTime to_string the end is /0
473
2.74k
    bw.write(buf, pos - buf - 1);
474
2.74k
}
475
476
// DATETIMEV2
477
inline std::string CastToString::from_datetimev2(const DateV2Value<DateTimeV2ValueType>& from,
478
333
                                                 UInt32 scale) {
479
333
    char buf[64];
480
333
    char* pos = from.to_string(buf, scale);
481
    // DateTime to_string the end is /0
482
333
    return std::string(buf, pos - 1);
483
333
}
484
485
4
inline std::string CastToString::from_timestamp_ns(const TimeStampNsValue& from) {
486
4
    return from.to_string();
487
4
}
488
489
inline std::string CastToString::from_timestamptz(const TimestampTzValue& from, UInt32 scale,
490
298
                                                  const cctz::time_zone* timezone) {
491
298
    cctz::time_zone tz;
492
298
    if (timezone == nullptr) {
493
298
        tz = cctz::utc_time_zone();
494
298
    } else {
495
0
        tz = *timezone;
496
0
    }
497
298
    return from.to_string(tz, scale);
498
298
}
499
inline void CastToString::push_datetimev2(const DateV2Value<DateTimeV2ValueType>& from,
500
0
                                          UInt32 scale, ColumnString::Chars& chars) {
501
0
    char buf[64];
502
0
    char* pos = from.to_string(buf, scale);
503
0
    // DateTime to_string the end is /0
504
0
    chars.insert(buf, pos - 1);
505
0
}
506
507
inline void CastToString::push_datetimev2(const DateV2Value<DateTimeV2ValueType>& from,
508
14.4k
                                          UInt32 scale, BufferWritable& bw) {
509
14.4k
    char buf[64];
510
14.4k
    char* pos = from.to_string(buf, scale);
511
    // DateTime to_string the end is /0
512
14.4k
    bw.write(buf, pos - buf - 1);
513
14.4k
}
514
515
60
inline void CastToString::push_timestamp_ns(const TimeStampNsValue& from, BufferWritable& bw) {
516
60
    char buf[40];
517
60
    const int32_t length = from.to_buffer(buf);
518
60
    bw.write(buf, length);
519
60
}
520
521
inline void CastToString::push_timestamptz(const TimestampTzValue& from, UInt32 scale,
522
                                           BufferWritable& bw,
523
17
                                           const DataTypeSerDe::FormatOptions& options) {
524
17
    auto str = from.to_string(*options.timezone, scale);
525
17
    bw.write(str.data(), str.size());
526
17
}
527
528
// IPv4
529
template <>
530
271
inline std::string CastToString::from_ip(const IPv4& from) {
531
271
    auto value = IPv4Value(from);
532
271
    return value.to_string();
533
271
}
534
535
template <>
536
10.1k
inline void CastToString::push_ip(const IPv4& from, BufferWritable& bw) {
537
10.1k
    auto value = IPv4Value(from);
538
10.1k
    std::string str = value.to_string();
539
10.1k
    bw.write(str.data(), str.size());
540
10.1k
}
541
542
//IPv6
543
544
template <>
545
276
inline std::string CastToString::from_ip(const IPv6& from) {
546
276
    auto value = IPv6Value(from);
547
276
    return value.to_string();
548
276
}
549
550
template <>
551
7.17k
inline void CastToString::push_ip(const IPv6& from, BufferWritable& bw) {
552
7.17k
    auto value = IPv6Value(from);
553
7.17k
    std::string str = value.to_string();
554
7.17k
    bw.write(str.data(), str.size());
555
7.17k
}
556
557
// Time
558
1
inline std::string CastToString::from_time(const TimeValue::TimeType& from, UInt32 scale) {
559
1
    return timev2_to_buffer_from_double(from, scale);
560
1
}
561
562
inline void CastToString::push_time(const TimeValue::TimeType& from, UInt32 scale,
563
279
                                    BufferWritable& bw) {
564
279
    std::string str = timev2_to_buffer_from_double(from, scale);
565
279
    bw.write(str.data(), str.size());
566
279
}
567
568
1
inline std::string CastToString::from_uuid(UUIDValueType value) {
569
1
    return UUIDValue::to_string(value);
570
1
}
571
572
828
inline void CastToString::push_uuid(UUIDValueType value, BufferWritable& bw) {
573
828
    bw.resize(UUIDValue::TEXT_LENGTH);
574
828
    UUIDValue::to_string(value, bw.data());
575
828
    bw.add_offset(UUIDValue::TEXT_LENGTH);
576
828
}
577
578
class CastToStringFunction {
579
public:
580
    static Status execute_impl(FunctionContext* context, Block& block,
581
                               const ColumnNumbers& arguments, uint32_t result,
582
                               size_t input_rows_count,
583
28
                               const NullMap::value_type* null_map = nullptr) {
584
28
        const auto& col_with_type_and_name = block.get_by_position(arguments[0]);
585
28
        const IDataType& type = *col_with_type_and_name.type;
586
28
        const IColumn& col_from = *col_with_type_and_name.column;
587
588
28
        auto col_to = ColumnString::create();
589
590
28
        DataTypeSerDe::FormatOptions options;
591
28
        auto time_zone = cctz::utc_time_zone();
592
28
        options.timezone =
593
28
                (context && context->state()) ? &context->state()->timezone_obj() : &time_zone;
594
28
        ColumnPtr limited_col;
595
28
        const IColumn* col_to_serialize = &col_from;
596
28
        if (col_from.size() != input_rows_count) {
597
4
            DORIS_CHECK(col_from.size() >= input_rows_count);
598
4
            limited_col = col_from.cut(0, input_rows_count);
599
4
            col_to_serialize = limited_col.get();
600
4
        }
601
28
        const auto serde = type.get_serde();
602
28
        if (null_map != nullptr && std::any_of(null_map, null_map + input_rows_count,
603
2.02k
                                               [](auto value) { return value != 0; })) {
604
            // Nested payloads of NULL rows may be uninitialized or outside the type's
605
            // domain. Do not format them before the nullable wrapper restores the mask.
606
3
            col_to->reserve(input_rows_count);
607
3
            VectorBufferWriter write_buffer(*col_to);
608
12
            for (size_t row = 0; row < input_rows_count; ++row) {
609
9
                if (!null_map[row]) {
610
5
                    serde->to_string(*col_to_serialize, row, write_buffer, options);
611
5
                }
612
9
                write_buffer.commit();
613
9
            }
614
25
        } else {
615
25
            serde->to_string_batch(*col_to_serialize, *col_to, options);
616
25
        }
617
618
28
        block.replace_by_position(result, std::move(col_to));
619
28
        return Status::OK();
620
28
    }
621
};
622
623
namespace CastWrapper {
624
625
22
inline WrapperType create_string_wrapper(const DataTypePtr& from_type) {
626
22
    return [](FunctionContext* context, Block& block, const ColumnNumbers& arguments,
627
22
              uint32_t result, size_t input_rows_count,
628
22
              const NullMap::value_type* null_map = nullptr) {
629
22
        return CastToStringFunction::execute_impl(context, block, arguments, result,
630
22
                                                  input_rows_count, null_map);
631
22
    };
632
22
}
633
634
}; // namespace CastWrapper
635
} // namespace doris