Coverage Report

Created: 2026-05-18 11:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/function/function_string.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 <ctype.h>
19
#include <math.h>
20
#include <re2/stringpiece.h>
21
#include <unicode/schriter.h>
22
#include <unicode/uchar.h>
23
#include <unicode/unistr.h>
24
#include <unicode/ustream.h>
25
26
#include <bitset>
27
#include <cstddef>
28
#include <cstdint>
29
#include <string_view>
30
31
#include "common/cast_set.h"
32
#include "common/status.h"
33
#include "core/column/column.h"
34
#include "core/column/column_string.h"
35
#include "core/pod_array_fwd.h"
36
#include "core/string_ref.h"
37
#include "exprs/function/function_reverse.h"
38
#include "exprs/function/function_string_concat.h"
39
#include "exprs/function/function_string_format.h"
40
#include "exprs/function/function_string_replace.h"
41
#include "exprs/function/function_string_to_string.h"
42
#include "exprs/function/function_totype.h"
43
#include "exprs/function/simple_function_factory.h"
44
#include "exprs/function/string_hex_util.h"
45
#include "util/string_search.hpp"
46
#include "util/url_coding.h"
47
#include "util/utf8_check.h"
48
49
namespace doris {
50
struct NameStringASCII {
51
    static constexpr auto name = "ascii";
52
};
53
54
struct StringASCII {
55
    using ReturnType = DataTypeInt32;
56
    static constexpr auto PrimitiveTypeImpl = PrimitiveType::TYPE_STRING;
57
    using Type = String;
58
    using ReturnColumnType = ColumnInt32;
59
60
    static Status vector(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
61
13
                         PaddedPODArray<Int32>& res) {
62
13
        auto size = offsets.size();
63
13
        res.resize(size);
64
58
        for (int i = 0; i < size; ++i) {
65
45
            const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
66
45
            res[i] = (offsets[i] == offsets[i - 1]) ? 0 : static_cast<uint8_t>(raw_str[0]);
67
45
        }
68
13
        return Status::OK();
69
13
    }
70
};
71
72
struct NameParseDataSize {
73
    static constexpr auto name = "parse_data_size";
74
};
75
76
static const std::map<std::string_view, Int128> UNITS = {
77
        {"B", static_cast<Int128>(1)},        {"kB", static_cast<Int128>(1) << 10},
78
        {"MB", static_cast<Int128>(1) << 20}, {"GB", static_cast<Int128>(1) << 30},
79
        {"TB", static_cast<Int128>(1) << 40}, {"PB", static_cast<Int128>(1) << 50},
80
        {"EB", static_cast<Int128>(1) << 60}, {"ZB", static_cast<Int128>(1) << 70},
81
        {"YB", static_cast<Int128>(1) << 80}};
82
83
struct ParseDataSize {
84
    using ReturnType = DataTypeInt128;
85
    static constexpr auto PrimitiveTypeImpl = PrimitiveType::TYPE_STRING;
86
    using Type = String;
87
    using ReturnColumnType = ColumnInt128;
88
89
    static Status vector(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
90
0
                         PaddedPODArray<Int128>& res) {
91
0
        auto size = offsets.size();
92
0
        res.resize(size);
93
0
        for (int i = 0; i < size; ++i) {
94
0
            const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
95
0
            int str_size = offsets[i] - offsets[i - 1];
96
0
            res[i] = parse_data_size(std::string_view(raw_str, str_size));
97
0
        }
98
0
        return Status::OK();
99
0
    }
100
101
0
    static Int128 parse_data_size(const std::string_view& dataSize) {
102
0
        int digit_length = 0;
103
0
        for (char c : dataSize) {
104
0
            if (isdigit(c) || c == '.') {
105
0
                digit_length++;
106
0
            } else {
107
0
                break;
108
0
            }
109
0
        }
110
111
0
        if (digit_length == 0) {
112
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
113
0
                                   "Invalid Input argument \"{}\" of function parse_data_size",
114
0
                                   dataSize);
115
0
        }
116
        // 123.45MB--->123.45 : MB
117
0
        double value = 0.0;
118
0
        try {
119
0
            value = std::stod(std::string(dataSize.substr(0, digit_length)));
120
0
        } catch (const std::exception& e) {
121
0
            throw doris::Exception(
122
0
                    ErrorCode::INVALID_ARGUMENT,
123
0
                    "Invalid Input argument \"{}\" of function parse_data_size, error: {}",
124
0
                    dataSize, e.what());
125
0
        }
126
0
        auto unit = dataSize.substr(digit_length);
127
0
        auto it = UNITS.find(unit);
128
0
        if (it != UNITS.end()) {
129
0
            return static_cast<__int128>(static_cast<long double>(it->second) * value);
130
0
        } else {
131
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
132
0
                                   "Invalid Input argument \"{}\" of function parse_data_size",
133
0
                                   dataSize);
134
0
        }
135
0
    }
136
};
137
138
struct NameQuote {
139
    static constexpr auto name = "quote";
140
};
141
142
struct NameQuoteImpl {
143
    static Status vector(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
144
12
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
145
12
        size_t offset_size = offsets.size();
146
12
        ColumnString::Offset pos = 0;
147
12
        res_offsets.resize(offset_size);
148
12
        res_data.resize(data.size() + offset_size * 2);
149
35
        for (int i = 0; i < offset_size; i++) {
150
23
            const unsigned char* raw_str = &data[offsets[i - 1]];
151
23
            ColumnString::Offset size = offsets[i] - offsets[i - 1];
152
23
            res_data[pos] = '\'';
153
23
            std::memcpy(res_data.data() + pos + 1, raw_str, size);
154
23
            res_data[pos + size + 1] = '\'';
155
23
            pos += size + 2;
156
23
            res_offsets[i] = pos;
157
23
        }
158
12
        return Status::OK();
159
12
    }
160
};
161
162
struct NameStringLength {
163
    static constexpr auto name = "length";
164
};
165
166
struct StringLengthImpl {
167
    using ReturnType = DataTypeInt32;
168
    static constexpr auto PrimitiveTypeImpl = PrimitiveType::TYPE_STRING;
169
    using Type = String;
170
    using ReturnColumnType = ColumnInt32;
171
172
    static Status vector(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
173
5.86k
                         PaddedPODArray<Int32>& res) {
174
5.86k
        auto size = offsets.size();
175
5.86k
        res.resize(size);
176
276k
        for (int i = 0; i < size; ++i) {
177
270k
            int str_size = offsets[i] - offsets[i - 1];
178
270k
            res[i] = str_size;
179
270k
        }
180
5.86k
        return Status::OK();
181
5.86k
    }
182
};
183
184
struct NameCrc32 {
185
    static constexpr auto name = "crc32";
186
};
187
188
struct Crc32Impl {
189
    using ReturnType = DataTypeInt64;
190
    static constexpr auto PrimitiveTypeImpl = PrimitiveType::TYPE_STRING;
191
    using Type = String;
192
    using ReturnColumnType = ColumnInt64;
193
194
    static Status vector(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
195
0
                         PaddedPODArray<Int64>& res) {
196
0
        auto size = offsets.size();
197
0
        res.resize(size);
198
0
        for (int i = 0; i < size; ++i) {
199
0
            res[i] = crc32_z(0L, (const unsigned char*)data.data() + offsets[i - 1],
200
0
                             offsets[i] - offsets[i - 1]);
201
0
        }
202
0
        return Status::OK();
203
0
    }
204
};
205
206
struct NameStringUtf8Length {
207
    static constexpr auto name = "char_length";
208
};
209
210
struct StringUtf8LengthImpl {
211
    using ReturnType = DataTypeInt32;
212
    static constexpr auto PrimitiveTypeImpl = PrimitiveType::TYPE_STRING;
213
    using Type = String;
214
    using ReturnColumnType = ColumnInt32;
215
216
    static Status vector(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
217
17
                         PaddedPODArray<Int32>& res) {
218
17
        auto size = offsets.size();
219
17
        res.resize(size);
220
74
        for (int i = 0; i < size; ++i) {
221
57
            const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
222
57
            int str_size = offsets[i] - offsets[i - 1];
223
57
            res[i] = simd::VStringFunctions::get_char_len(raw_str, str_size);
224
57
        }
225
17
        return Status::OK();
226
17
    }
227
};
228
229
struct NameIsValidUTF8 {
230
    static constexpr auto name = "is_valid_utf8";
231
};
232
233
struct IsValidUTF8Impl {
234
    using ReturnType = DataTypeUInt8;
235
    static constexpr auto PrimitiveTypeImpl = PrimitiveType::TYPE_STRING;
236
    using Type = String;
237
    using ReturnColumnType = ColumnUInt8;
238
239
    static Status vector(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
240
16
                         PaddedPODArray<UInt8>& res) {
241
16
        auto size = offsets.size();
242
16
        res.resize(size);
243
47
        for (size_t i = 0; i < size; ++i) {
244
31
            const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
245
31
            size_t str_size = offsets[i] - offsets[i - 1];
246
31
            res[i] = validate_utf8(raw_str, str_size) ? 1 : 0;
247
31
        }
248
16
        return Status::OK();
249
16
    }
250
};
251
252
struct NameStartsWith {
253
    static constexpr auto name = "starts_with";
254
};
255
256
struct StartsWithOp {
257
    using ResultDataType = DataTypeUInt8;
258
    using ResultPaddedPODArray = PaddedPODArray<UInt8>;
259
260
48
    static void execute(const std::string_view& strl, const std::string_view& strr, uint8_t& res) {
261
48
        res = strl.starts_with(strr);
262
48
    }
263
};
264
265
struct NameEndsWith {
266
    static constexpr auto name = "ends_with";
267
};
268
269
struct EndsWithOp {
270
    using ResultDataType = DataTypeUInt8;
271
    using ResultPaddedPODArray = PaddedPODArray<UInt8>;
272
273
86
    static void execute(const std::string_view& strl, const std::string_view& strr, uint8_t& res) {
274
86
        res = strl.ends_with(strr);
275
86
    }
276
};
277
278
struct NameFindInSet {
279
    static constexpr auto name = "find_in_set";
280
};
281
282
struct FindInSetOp {
283
    using ResultDataType = DataTypeInt32;
284
    using ResultPaddedPODArray = PaddedPODArray<Int32>;
285
93
    static void execute(const std::string_view& strl, const std::string_view& strr, int32_t& res) {
286
105
        for (const auto& c : strl) {
287
105
            if (c == ',') {
288
17
                res = 0;
289
17
                return;
290
17
            }
291
105
        }
292
293
76
        int32_t token_index = 1;
294
76
        int32_t start = 0;
295
76
        int32_t end;
296
297
226
        do {
298
226
            end = start;
299
            // Position end.
300
385
            while (end < strr.length() && strr[end] != ',') {
301
159
                ++end;
302
159
            }
303
304
226
            if (strl == std::string_view {strr.data() + start, (size_t)end - start}) {
305
41
                res = token_index;
306
41
                return;
307
41
            }
308
309
            // Re-position start and end past ','
310
185
            start = end + 1;
311
185
            ++token_index;
312
185
        } while (start < strr.length());
313
35
        res = 0;
314
35
    }
315
};
316
317
struct NameInstr {
318
    static constexpr auto name = "instr";
319
};
320
321
// LeftDataType and RightDataType are DataTypeString
322
template <typename LeftDataType, typename RightDataType>
323
struct StringInStrImpl {
324
    using ResultDataType = DataTypeInt32;
325
    using ResultPaddedPODArray = PaddedPODArray<Int32>;
326
327
    static Status scalar_vector(const StringRef& ldata, const ColumnString::Chars& rdata,
328
72
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
329
72
        StringRef lstr_ref(ldata.data, ldata.size);
330
331
72
        auto size = roffsets.size();
332
72
        res.resize(size);
333
144
        for (int i = 0; i < size; ++i) {
334
72
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
335
72
            int r_str_size = roffsets[i] - roffsets[i - 1];
336
337
72
            StringRef rstr_ref(r_raw_str, r_str_size);
338
339
72
            res[i] = execute(lstr_ref, rstr_ref);
340
72
        }
341
342
72
        return Status::OK();
343
72
    }
344
345
    static Status vector_scalar(const ColumnString::Chars& ldata,
346
                                const ColumnString::Offsets& loffsets, const StringRef& rdata,
347
102
                                ResultPaddedPODArray& res) {
348
102
        auto size = loffsets.size();
349
102
        res.resize(size);
350
351
102
        if (rdata.size == 0) {
352
12
            std::fill(res.begin(), res.end(), 1);
353
12
            return Status::OK();
354
12
        }
355
356
90
        const UInt8* begin = ldata.data();
357
90
        const UInt8* end = begin + ldata.size();
358
90
        const UInt8* pos = begin;
359
360
        /// Current index in the array of strings.
361
90
        size_t i = 0;
362
90
        std::fill(res.begin(), res.end(), 0);
363
364
90
        StringRef rstr_ref(rdata.data, rdata.size);
365
90
        StringSearch search(&rstr_ref);
366
367
132
        while (pos < end) {
368
            // search return matched substring start offset
369
104
            pos = (UInt8*)search.search((char*)pos, end - pos);
370
104
            if (pos >= end) {
371
62
                break;
372
62
            }
373
374
            /// Determine which index it refers to.
375
            /// begin + value_offsets[i] is the start offset of string at i+1
376
48
            while (begin + loffsets[i] < pos) {
377
6
                ++i;
378
6
            }
379
380
            /// We check that the entry does not pass through the boundaries of strings.
381
42
            if (pos + rdata.size <= begin + loffsets[i]) {
382
40
                int loc = (int)(pos - begin) - loffsets[i - 1];
383
40
                int l_str_size = loffsets[i] - loffsets[i - 1];
384
40
                auto len = std::min(l_str_size, loc);
385
40
                loc = simd::VStringFunctions::get_char_len((char*)(begin + loffsets[i - 1]), len);
386
40
                res[i] = loc + 1;
387
40
            }
388
389
            // move to next string offset
390
42
            pos = begin + loffsets[i];
391
42
            ++i;
392
42
        }
393
394
90
        return Status::OK();
395
102
    }
396
397
    static Status vector_vector(const ColumnString::Chars& ldata,
398
                                const ColumnString::Offsets& loffsets,
399
                                const ColumnString::Chars& rdata,
400
74
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
401
74
        DCHECK_EQ(loffsets.size(), roffsets.size());
402
403
74
        auto size = loffsets.size();
404
74
        res.resize(size);
405
259
        for (int i = 0; i < size; ++i) {
406
185
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
407
185
            int l_str_size = loffsets[i] - loffsets[i - 1];
408
185
            StringRef lstr_ref(l_raw_str, l_str_size);
409
410
185
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
411
185
            int r_str_size = roffsets[i] - roffsets[i - 1];
412
185
            StringRef rstr_ref(r_raw_str, r_str_size);
413
414
185
            res[i] = execute(lstr_ref, rstr_ref);
415
185
        }
416
417
74
        return Status::OK();
418
74
    }
419
420
257
    static int execute(const StringRef& strl, const StringRef& strr) {
421
257
        if (strr.size == 0) {
422
62
            return 1;
423
62
        }
424
425
195
        StringSearch search(&strr);
426
        // Hive returns positions starting from 1.
427
195
        int loc = search.search(&strl);
428
195
        if (loc > 0) {
429
12
            int len = std::min(loc, (int)strl.size);
430
12
            loc = simd::VStringFunctions::get_char_len(strl.data, len);
431
12
        }
432
433
195
        return loc + 1;
434
257
    }
435
};
436
437
// the same impl as instr
438
struct NameLocate {
439
    static constexpr auto name = "locate";
440
};
441
442
// LeftDataType and RightDataType are DataTypeString
443
template <typename LeftDataType, typename RightDataType>
444
struct StringLocateImpl {
445
    using ResultDataType = DataTypeInt32;
446
    using ResultPaddedPODArray = PaddedPODArray<Int32>;
447
448
    static Status scalar_vector(const StringRef& ldata, const ColumnString::Chars& rdata,
449
38
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
450
38
        return StringInStrImpl<LeftDataType, RightDataType>::vector_scalar(rdata, roffsets, ldata,
451
38
                                                                           res);
452
38
    }
453
454
    static Status vector_scalar(const ColumnString::Chars& ldata,
455
                                const ColumnString::Offsets& loffsets, const StringRef& rdata,
456
36
                                ResultPaddedPODArray& res) {
457
36
        return StringInStrImpl<LeftDataType, RightDataType>::scalar_vector(rdata, ldata, loffsets,
458
36
                                                                           res);
459
36
    }
460
461
    static Status vector_vector(const ColumnString::Chars& ldata,
462
                                const ColumnString::Offsets& loffsets,
463
                                const ColumnString::Chars& rdata,
464
37
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
465
37
        return StringInStrImpl<LeftDataType, RightDataType>::vector_vector(rdata, roffsets, ldata,
466
37
                                                                           loffsets, res);
467
37
    }
468
};
469
470
// LeftDataType and RightDataType are DataTypeString
471
template <typename LeftDataType, typename RightDataType, typename OP>
472
struct StringFunctionImpl {
473
    using ResultDataType = typename OP::ResultDataType;
474
    using ResultPaddedPODArray = typename OP::ResultPaddedPODArray;
475
476
    static Status vector_vector(const ColumnString::Chars& ldata,
477
                                const ColumnString::Offsets& loffsets,
478
                                const ColumnString::Chars& rdata,
479
37
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
480
37
        DCHECK_EQ(loffsets.size(), roffsets.size());
481
482
37
        auto size = loffsets.size();
483
37
        res.resize(size);
484
122
        for (int i = 0; i < size; ++i) {
485
85
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
486
85
            int l_str_size = loffsets[i] - loffsets[i - 1];
487
488
85
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
489
85
            int r_str_size = roffsets[i] - roffsets[i - 1];
490
491
85
            std::string_view lview(l_raw_str, l_str_size);
492
85
            std::string_view rview(r_raw_str, r_str_size);
493
494
85
            OP::execute(lview, rview, res[i]);
495
85
        }
496
37
        return Status::OK();
497
37
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_12StartsWithOpEE13vector_vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEESA_SD_RS8_
Line
Count
Source
479
5
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
480
5
        DCHECK_EQ(loffsets.size(), roffsets.size());
481
482
5
        auto size = loffsets.size();
483
5
        res.resize(size);
484
15
        for (int i = 0; i < size; ++i) {
485
10
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
486
10
            int l_str_size = loffsets[i] - loffsets[i - 1];
487
488
10
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
489
10
            int r_str_size = roffsets[i] - roffsets[i - 1];
490
491
10
            std::string_view lview(l_raw_str, l_str_size);
492
10
            std::string_view rview(r_raw_str, r_str_size);
493
494
10
            OP::execute(lview, rview, res[i]);
495
10
        }
496
5
        return Status::OK();
497
5
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_10EndsWithOpEE13vector_vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEESA_SD_RS8_
Line
Count
Source
479
15
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
480
15
        DCHECK_EQ(loffsets.size(), roffsets.size());
481
482
15
        auto size = loffsets.size();
483
15
        res.resize(size);
484
49
        for (int i = 0; i < size; ++i) {
485
34
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
486
34
            int l_str_size = loffsets[i] - loffsets[i - 1];
487
488
34
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
489
34
            int r_str_size = roffsets[i] - roffsets[i - 1];
490
491
34
            std::string_view lview(l_raw_str, l_str_size);
492
34
            std::string_view rview(r_raw_str, r_str_size);
493
494
34
            OP::execute(lview, rview, res[i]);
495
34
        }
496
15
        return Status::OK();
497
15
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_11FindInSetOpEE13vector_vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEESA_SD_RNS4_IiLm4096ES7_Lm16ELm15EEE
Line
Count
Source
479
17
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
480
17
        DCHECK_EQ(loffsets.size(), roffsets.size());
481
482
17
        auto size = loffsets.size();
483
17
        res.resize(size);
484
58
        for (int i = 0; i < size; ++i) {
485
41
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
486
41
            int l_str_size = loffsets[i] - loffsets[i - 1];
487
488
41
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
489
41
            int r_str_size = roffsets[i] - roffsets[i - 1];
490
491
41
            std::string_view lview(l_raw_str, l_str_size);
492
41
            std::string_view rview(r_raw_str, r_str_size);
493
494
41
            OP::execute(lview, rview, res[i]);
495
41
        }
496
17
        return Status::OK();
497
17
    }
498
    static Status vector_scalar(const ColumnString::Chars& ldata,
499
                                const ColumnString::Offsets& loffsets, const StringRef& rdata,
500
40
                                ResultPaddedPODArray& res) {
501
40
        auto size = loffsets.size();
502
40
        res.resize(size);
503
40
        std::string_view rview(rdata.data, rdata.size);
504
148
        for (int i = 0; i < size; ++i) {
505
108
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
506
108
            int l_str_size = loffsets[i] - loffsets[i - 1];
507
108
            std::string_view lview(l_raw_str, l_str_size);
508
509
108
            OP::execute(lview, rview, res[i]);
510
108
        }
511
40
        return Status::OK();
512
40
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_12StartsWithOpEE13vector_scalarERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEERKNS_9StringRefERS8_
Line
Count
Source
500
6
                                ResultPaddedPODArray& res) {
501
6
        auto size = loffsets.size();
502
6
        res.resize(size);
503
6
        std::string_view rview(rdata.data, rdata.size);
504
40
        for (int i = 0; i < size; ++i) {
505
34
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
506
34
            int l_str_size = loffsets[i] - loffsets[i - 1];
507
34
            std::string_view lview(l_raw_str, l_str_size);
508
509
34
            OP::execute(lview, rview, res[i]);
510
34
        }
511
6
        return Status::OK();
512
6
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_10EndsWithOpEE13vector_scalarERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEERKNS_9StringRefERS8_
Line
Count
Source
500
16
                                ResultPaddedPODArray& res) {
501
16
        auto size = loffsets.size();
502
16
        res.resize(size);
503
16
        std::string_view rview(rdata.data, rdata.size);
504
54
        for (int i = 0; i < size; ++i) {
505
38
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
506
38
            int l_str_size = loffsets[i] - loffsets[i - 1];
507
38
            std::string_view lview(l_raw_str, l_str_size);
508
509
38
            OP::execute(lview, rview, res[i]);
510
38
        }
511
16
        return Status::OK();
512
16
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_11FindInSetOpEE13vector_scalarERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEERKNS_9StringRefERNS4_IiLm4096ES7_Lm16ELm15EEE
Line
Count
Source
500
18
                                ResultPaddedPODArray& res) {
501
18
        auto size = loffsets.size();
502
18
        res.resize(size);
503
18
        std::string_view rview(rdata.data, rdata.size);
504
54
        for (int i = 0; i < size; ++i) {
505
36
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
506
36
            int l_str_size = loffsets[i] - loffsets[i - 1];
507
36
            std::string_view lview(l_raw_str, l_str_size);
508
509
36
            OP::execute(lview, rview, res[i]);
510
36
        }
511
18
        return Status::OK();
512
18
    }
513
    static Status scalar_vector(const StringRef& ldata, const ColumnString::Chars& rdata,
514
34
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
515
34
        auto size = roffsets.size();
516
34
        res.resize(size);
517
34
        std::string_view lview(ldata.data, ldata.size);
518
68
        for (int i = 0; i < size; ++i) {
519
34
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
520
34
            int r_str_size = roffsets[i] - roffsets[i - 1];
521
34
            std::string_view rview(r_raw_str, r_str_size);
522
523
34
            OP::execute(lview, rview, res[i]);
524
34
        }
525
34
        return Status::OK();
526
34
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_12StartsWithOpEE13scalar_vectorERKNS_9StringRefERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS7_IjLm4096ESA_Lm16ELm15EEERSB_
Line
Count
Source
514
4
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
515
4
        auto size = roffsets.size();
516
4
        res.resize(size);
517
4
        std::string_view lview(ldata.data, ldata.size);
518
8
        for (int i = 0; i < size; ++i) {
519
4
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
520
4
            int r_str_size = roffsets[i] - roffsets[i - 1];
521
4
            std::string_view rview(r_raw_str, r_str_size);
522
523
4
            OP::execute(lview, rview, res[i]);
524
4
        }
525
4
        return Status::OK();
526
4
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_10EndsWithOpEE13scalar_vectorERKNS_9StringRefERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS7_IjLm4096ESA_Lm16ELm15EEERSB_
Line
Count
Source
514
14
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
515
14
        auto size = roffsets.size();
516
14
        res.resize(size);
517
14
        std::string_view lview(ldata.data, ldata.size);
518
28
        for (int i = 0; i < size; ++i) {
519
14
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
520
14
            int r_str_size = roffsets[i] - roffsets[i - 1];
521
14
            std::string_view rview(r_raw_str, r_str_size);
522
523
14
            OP::execute(lview, rview, res[i]);
524
14
        }
525
14
        return Status::OK();
526
14
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_11FindInSetOpEE13scalar_vectorERKNS_9StringRefERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS7_IjLm4096ESA_Lm16ELm15EEERNS7_IiLm4096ESA_Lm16ELm15EEE
Line
Count
Source
514
16
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
515
16
        auto size = roffsets.size();
516
16
        res.resize(size);
517
16
        std::string_view lview(ldata.data, ldata.size);
518
32
        for (int i = 0; i < size; ++i) {
519
16
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
520
16
            int r_str_size = roffsets[i] - roffsets[i - 1];
521
16
            std::string_view rview(r_raw_str, r_str_size);
522
523
16
            OP::execute(lview, rview, res[i]);
524
16
        }
525
16
        return Status::OK();
526
16
    }
527
};
528
529
struct NameToLower {
530
    static constexpr auto name = "lower";
531
};
532
533
struct NameToUpper {
534
    static constexpr auto name = "upper";
535
};
536
537
template <typename OpName>
538
struct TransferImpl {
539
    static Status vector(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
540
190
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
541
190
        size_t offset_size = offsets.size();
542
190
        if (UNLIKELY(!offset_size)) {
543
0
            return Status::OK();
544
0
        }
545
546
190
        const bool is_ascii = simd::VStringFunctions::is_ascii({data.data(), data.size()});
547
190
        res_offsets.resize(offset_size);
548
190
        if (is_ascii) {
549
144
            memcpy_small_allow_read_write_overflow15(
550
144
                    res_offsets.data(), offsets.data(),
551
144
                    offset_size * sizeof(ColumnString::Offsets::value_type));
552
553
144
            size_t data_length = data.size();
554
144
            res_data.resize(data_length);
555
144
            if constexpr (std::is_same_v<OpName, NameToUpper>) {
556
22
                simd::VStringFunctions::to_upper(data.data(), data_length, res_data.data());
557
122
            } else if constexpr (std::is_same_v<OpName, NameToLower>) {
558
122
                simd::VStringFunctions::to_lower(data.data(), data_length, res_data.data());
559
122
            }
560
144
        } else {
561
46
            execute_utf8(data, offsets, res_data, res_offsets);
562
46
        }
563
564
190
        return Status::OK();
565
190
    }
_ZN5doris12TransferImplINS_11NameToLowerEE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS3_IjLm4096ES6_Lm16ELm15EEERS7_RSA_
Line
Count
Source
540
136
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
541
136
        size_t offset_size = offsets.size();
542
136
        if (UNLIKELY(!offset_size)) {
543
0
            return Status::OK();
544
0
        }
545
546
136
        const bool is_ascii = simd::VStringFunctions::is_ascii({data.data(), data.size()});
547
136
        res_offsets.resize(offset_size);
548
136
        if (is_ascii) {
549
122
            memcpy_small_allow_read_write_overflow15(
550
122
                    res_offsets.data(), offsets.data(),
551
122
                    offset_size * sizeof(ColumnString::Offsets::value_type));
552
553
122
            size_t data_length = data.size();
554
122
            res_data.resize(data_length);
555
            if constexpr (std::is_same_v<OpName, NameToUpper>) {
556
                simd::VStringFunctions::to_upper(data.data(), data_length, res_data.data());
557
122
            } else if constexpr (std::is_same_v<OpName, NameToLower>) {
558
122
                simd::VStringFunctions::to_lower(data.data(), data_length, res_data.data());
559
122
            }
560
122
        } else {
561
14
            execute_utf8(data, offsets, res_data, res_offsets);
562
14
        }
563
564
136
        return Status::OK();
565
136
    }
_ZN5doris12TransferImplINS_11NameToUpperEE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS3_IjLm4096ES6_Lm16ELm15EEERS7_RSA_
Line
Count
Source
540
54
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
541
54
        size_t offset_size = offsets.size();
542
54
        if (UNLIKELY(!offset_size)) {
543
0
            return Status::OK();
544
0
        }
545
546
54
        const bool is_ascii = simd::VStringFunctions::is_ascii({data.data(), data.size()});
547
54
        res_offsets.resize(offset_size);
548
54
        if (is_ascii) {
549
22
            memcpy_small_allow_read_write_overflow15(
550
22
                    res_offsets.data(), offsets.data(),
551
22
                    offset_size * sizeof(ColumnString::Offsets::value_type));
552
553
22
            size_t data_length = data.size();
554
22
            res_data.resize(data_length);
555
22
            if constexpr (std::is_same_v<OpName, NameToUpper>) {
556
22
                simd::VStringFunctions::to_upper(data.data(), data_length, res_data.data());
557
            } else if constexpr (std::is_same_v<OpName, NameToLower>) {
558
                simd::VStringFunctions::to_lower(data.data(), data_length, res_data.data());
559
            }
560
32
        } else {
561
32
            execute_utf8(data, offsets, res_data, res_offsets);
562
32
        }
563
564
54
        return Status::OK();
565
54
    }
566
567
    static void execute_utf8(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
568
46
                             ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
569
46
        std::string result;
570
170
        for (int64_t i = 0; i < offsets.size(); ++i) {
571
124
            const char* begin = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
572
124
            uint32_t size = offsets[i] - offsets[i - 1];
573
574
124
            result.clear();
575
124
            if constexpr (std::is_same_v<OpName, NameToUpper>) {
576
84
                to_upper_utf8(begin, size, result);
577
84
            } else if constexpr (std::is_same_v<OpName, NameToLower>) {
578
40
                to_lower_utf8(begin, size, result);
579
40
            }
580
124
            StringOP::push_value_string(result, i, res_data, res_offsets);
581
124
        }
582
46
    }
_ZN5doris12TransferImplINS_11NameToLowerEE12execute_utf8ERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS3_IjLm4096ES6_Lm16ELm15EEERS7_RSA_
Line
Count
Source
568
14
                             ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
569
14
        std::string result;
570
54
        for (int64_t i = 0; i < offsets.size(); ++i) {
571
40
            const char* begin = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
572
40
            uint32_t size = offsets[i] - offsets[i - 1];
573
574
40
            result.clear();
575
            if constexpr (std::is_same_v<OpName, NameToUpper>) {
576
                to_upper_utf8(begin, size, result);
577
40
            } else if constexpr (std::is_same_v<OpName, NameToLower>) {
578
40
                to_lower_utf8(begin, size, result);
579
40
            }
580
40
            StringOP::push_value_string(result, i, res_data, res_offsets);
581
40
        }
582
14
    }
_ZN5doris12TransferImplINS_11NameToUpperEE12execute_utf8ERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS3_IjLm4096ES6_Lm16ELm15EEERS7_RSA_
Line
Count
Source
568
32
                             ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
569
32
        std::string result;
570
116
        for (int64_t i = 0; i < offsets.size(); ++i) {
571
84
            const char* begin = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
572
84
            uint32_t size = offsets[i] - offsets[i - 1];
573
574
84
            result.clear();
575
84
            if constexpr (std::is_same_v<OpName, NameToUpper>) {
576
84
                to_upper_utf8(begin, size, result);
577
            } else if constexpr (std::is_same_v<OpName, NameToLower>) {
578
                to_lower_utf8(begin, size, result);
579
            }
580
84
            StringOP::push_value_string(result, i, res_data, res_offsets);
581
84
        }
582
32
    }
583
584
84
    static void to_upper_utf8(const char* data, uint32_t size, std::string& result) {
585
84
        icu::StringPiece sp;
586
84
        sp.set(data, size);
587
84
        icu::UnicodeString unicode_str = icu::UnicodeString::fromUTF8(sp);
588
84
        unicode_str.toUpper();
589
84
        unicode_str.toUTF8String(result);
590
84
    }
591
592
40
    static void to_lower_utf8(const char* data, uint32_t size, std::string& result) {
593
40
        icu::StringPiece sp;
594
40
        sp.set(data, size);
595
40
        icu::UnicodeString unicode_str = icu::UnicodeString::fromUTF8(sp);
596
40
        unicode_str.toLower();
597
40
        unicode_str.toUTF8String(result);
598
40
    }
599
};
600
601
// Capitalize first letter
602
struct NameToInitcap {
603
    static constexpr auto name = "initcap";
604
};
605
606
struct InitcapImpl {
607
    static Status vector(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
608
8
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
609
8
        res_offsets.resize(offsets.size());
610
611
8
        const bool is_ascii = simd::VStringFunctions::is_ascii({data.data(), data.size()});
612
8
        if (is_ascii) {
613
6
            impl_vectors_ascii(data, offsets, res_data, res_offsets);
614
6
        } else {
615
2
            impl_vectors_utf8(data, offsets, res_data, res_offsets);
616
2
        }
617
8
        return Status::OK();
618
8
    }
619
620
    static void impl_vectors_ascii(const ColumnString::Chars& data,
621
                                   const ColumnString::Offsets& offsets,
622
                                   ColumnString::Chars& res_data,
623
6
                                   ColumnString::Offsets& res_offsets) {
624
6
        size_t offset_size = offsets.size();
625
6
        memcpy_small_allow_read_write_overflow15(
626
6
                res_offsets.data(), offsets.data(),
627
6
                offset_size * sizeof(ColumnString::Offsets::value_type));
628
629
6
        size_t data_length = data.size();
630
6
        res_data.resize(data_length);
631
6
        simd::VStringFunctions::to_lower(data.data(), data_length, res_data.data());
632
633
6
        bool need_capitalize = true;
634
12
        for (size_t offset_index = 0, start_index = 0; offset_index < offset_size; ++offset_index) {
635
6
            auto end_index = res_offsets[offset_index];
636
6
            need_capitalize = true;
637
638
78
            for (size_t i = start_index; i < end_index; ++i) {
639
72
                if (!::isalnum(res_data[i])) {
640
23
                    need_capitalize = true;
641
49
                } else if (need_capitalize) {
642
                    /*
643
                    https://en.cppreference.com/w/cpp/string/byte/toupper
644
                    Like all other functions from <cctype>, the behavior of std::toupper is undefined if the argument's value is neither representable as unsigned char nor equal to EOF. 
645
                    To use these functions safely with plain chars (or signed chars), the argument should first be converted to unsigned char:
646
                    char my_toupper(char ch)
647
                    {
648
                        return static_cast<char>(std::toupper(static_cast<unsigned char>(ch)));
649
                    }
650
                    */
651
18
                    res_data[i] = static_cast<unsigned char>(::toupper(res_data[i]));
652
18
                    need_capitalize = false;
653
18
                }
654
72
            }
655
656
6
            start_index = end_index;
657
6
        }
658
6
    }
659
660
    static void impl_vectors_utf8(const ColumnString::Chars& data,
661
                                  const ColumnString::Offsets& offsets,
662
                                  ColumnString::Chars& res_data,
663
2
                                  ColumnString::Offsets& res_offsets) {
664
2
        std::string result;
665
11
        for (int64_t i = 0; i < offsets.size(); ++i) {
666
9
            const char* begin = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
667
9
            uint32_t size = offsets[i] - offsets[i - 1];
668
9
            result.clear();
669
9
            to_initcap_utf8(begin, size, result);
670
9
            StringOP::push_value_string(result, i, res_data, res_offsets);
671
9
        }
672
2
    }
673
674
9
    static void to_initcap_utf8(const char* data, uint32_t size, std::string& result) {
675
9
        icu::StringPiece sp;
676
9
        sp.set(data, size);
677
9
        icu::UnicodeString unicode_str = icu::UnicodeString::fromUTF8(sp);
678
9
        unicode_str.toLower();
679
9
        icu::UnicodeString output_str;
680
9
        bool need_capitalize = true;
681
9
        icu::StringCharacterIterator iter(unicode_str);
682
157
        for (UChar32 ch = iter.first32(); ch != icu::CharacterIterator::DONE; ch = iter.next32()) {
683
148
            if (!u_isalnum(ch)) {
684
47
                need_capitalize = true;
685
101
            } else if (need_capitalize) {
686
26
                ch = u_toupper(ch);
687
26
                need_capitalize = false;
688
26
            }
689
148
            output_str.append(ch);
690
148
        }
691
9
        output_str.toUTF8String(result);
692
9
    }
693
};
694
695
struct NameTrim {
696
    static constexpr auto name = "trim";
697
};
698
struct NameLTrim {
699
    static constexpr auto name = "ltrim";
700
};
701
struct NameRTrim {
702
    static constexpr auto name = "rtrim";
703
};
704
struct NameTrimIn {
705
    static constexpr auto name = "trim_in";
706
};
707
struct NameLTrimIn {
708
    static constexpr auto name = "ltrim_in";
709
};
710
struct NameRTrimIn {
711
    static constexpr auto name = "rtrim_in";
712
};
713
template <bool is_ltrim, bool is_rtrim, bool trim_single>
714
struct TrimUtil {
715
    static Status vector(const ColumnString::Chars& str_data,
716
                         const ColumnString::Offsets& str_offsets, const StringRef& remove_str,
717
52
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
718
52
        const size_t offset_size = str_offsets.size();
719
52
        res_offsets.resize(offset_size);
720
52
        res_data.reserve(str_data.size());
721
168
        for (size_t i = 0; i < offset_size; ++i) {
722
116
            const auto* str_begin = str_data.data() + str_offsets[i - 1];
723
116
            const auto* str_end = str_data.data() + str_offsets[i];
724
725
116
            if constexpr (is_ltrim) {
726
95
                str_begin =
727
95
                        simd::VStringFunctions::ltrim<trim_single>(str_begin, str_end, remove_str);
728
95
            }
729
116
            if constexpr (is_rtrim) {
730
75
                str_end =
731
75
                        simd::VStringFunctions::rtrim<trim_single>(str_begin, str_end, remove_str);
732
75
            }
733
734
116
            res_data.insert_assume_reserved(str_begin, str_end);
735
            // The length of the result of the trim function will never exceed the length of the input.
736
116
            res_offsets[i] = (ColumnString::Offset)res_data.size();
737
116
        }
738
52
        return Status::OK();
739
52
    }
_ZN5doris8TrimUtilILb1ELb1ELb1EE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
Line
Count
Source
717
28
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
718
28
        const size_t offset_size = str_offsets.size();
719
28
        res_offsets.resize(offset_size);
720
28
        res_data.reserve(str_data.size());
721
82
        for (size_t i = 0; i < offset_size; ++i) {
722
54
            const auto* str_begin = str_data.data() + str_offsets[i - 1];
723
54
            const auto* str_end = str_data.data() + str_offsets[i];
724
725
54
            if constexpr (is_ltrim) {
726
54
                str_begin =
727
54
                        simd::VStringFunctions::ltrim<trim_single>(str_begin, str_end, remove_str);
728
54
            }
729
54
            if constexpr (is_rtrim) {
730
54
                str_end =
731
54
                        simd::VStringFunctions::rtrim<trim_single>(str_begin, str_end, remove_str);
732
54
            }
733
734
54
            res_data.insert_assume_reserved(str_begin, str_end);
735
            // The length of the result of the trim function will never exceed the length of the input.
736
54
            res_offsets[i] = (ColumnString::Offset)res_data.size();
737
54
        }
738
28
        return Status::OK();
739
28
    }
_ZN5doris8TrimUtilILb1ELb0ELb1EE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
Line
Count
Source
717
13
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
718
13
        const size_t offset_size = str_offsets.size();
719
13
        res_offsets.resize(offset_size);
720
13
        res_data.reserve(str_data.size());
721
54
        for (size_t i = 0; i < offset_size; ++i) {
722
41
            const auto* str_begin = str_data.data() + str_offsets[i - 1];
723
41
            const auto* str_end = str_data.data() + str_offsets[i];
724
725
41
            if constexpr (is_ltrim) {
726
41
                str_begin =
727
41
                        simd::VStringFunctions::ltrim<trim_single>(str_begin, str_end, remove_str);
728
41
            }
729
            if constexpr (is_rtrim) {
730
                str_end =
731
                        simd::VStringFunctions::rtrim<trim_single>(str_begin, str_end, remove_str);
732
            }
733
734
41
            res_data.insert_assume_reserved(str_begin, str_end);
735
            // The length of the result of the trim function will never exceed the length of the input.
736
41
            res_offsets[i] = (ColumnString::Offset)res_data.size();
737
41
        }
738
13
        return Status::OK();
739
13
    }
_ZN5doris8TrimUtilILb0ELb1ELb1EE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
Line
Count
Source
717
11
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
718
11
        const size_t offset_size = str_offsets.size();
719
11
        res_offsets.resize(offset_size);
720
11
        res_data.reserve(str_data.size());
721
32
        for (size_t i = 0; i < offset_size; ++i) {
722
21
            const auto* str_begin = str_data.data() + str_offsets[i - 1];
723
21
            const auto* str_end = str_data.data() + str_offsets[i];
724
725
            if constexpr (is_ltrim) {
726
                str_begin =
727
                        simd::VStringFunctions::ltrim<trim_single>(str_begin, str_end, remove_str);
728
            }
729
21
            if constexpr (is_rtrim) {
730
21
                str_end =
731
21
                        simd::VStringFunctions::rtrim<trim_single>(str_begin, str_end, remove_str);
732
21
            }
733
734
21
            res_data.insert_assume_reserved(str_begin, str_end);
735
            // The length of the result of the trim function will never exceed the length of the input.
736
21
            res_offsets[i] = (ColumnString::Offset)res_data.size();
737
21
        }
738
11
        return Status::OK();
739
11
    }
Unexecuted instantiation: _ZN5doris8TrimUtilILb1ELb1ELb0EE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
Unexecuted instantiation: _ZN5doris8TrimUtilILb1ELb0ELb0EE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
Unexecuted instantiation: _ZN5doris8TrimUtilILb0ELb1ELb0EE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
740
};
741
template <bool is_ltrim, bool is_rtrim, bool trim_single>
742
struct TrimInUtil {
743
    static Status vector(const ColumnString::Chars& str_data,
744
                         const ColumnString::Offsets& str_offsets, const StringRef& remove_str,
745
0
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
746
0
        const size_t offset_size = str_offsets.size();
747
0
        res_offsets.resize(offset_size);
748
0
        res_data.reserve(str_data.size());
749
0
        bool all_ascii = simd::VStringFunctions::is_ascii(remove_str) &&
750
0
                         simd::VStringFunctions::is_ascii(StringRef(
751
0
                                 reinterpret_cast<const char*>(str_data.data()), str_data.size()));
752
753
0
        if (all_ascii) {
754
0
            return impl_vectors_ascii(str_data, str_offsets, remove_str, res_data, res_offsets);
755
0
        } else {
756
0
            return impl_vectors_utf8(str_data, str_offsets, remove_str, res_data, res_offsets);
757
0
        }
758
0
    }
Unexecuted instantiation: _ZN5doris10TrimInUtilILb1ELb1ELb0EE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
Unexecuted instantiation: _ZN5doris10TrimInUtilILb1ELb0ELb0EE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
Unexecuted instantiation: _ZN5doris10TrimInUtilILb0ELb1ELb0EE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
759
760
private:
761
    static Status impl_vectors_ascii(const ColumnString::Chars& str_data,
762
                                     const ColumnString::Offsets& str_offsets,
763
                                     const StringRef& remove_str, ColumnString::Chars& res_data,
764
0
                                     ColumnString::Offsets& res_offsets) {
765
0
        const size_t offset_size = str_offsets.size();
766
0
        std::bitset<128> char_lookup;
767
0
        const char* remove_begin = remove_str.data;
768
0
        const char* remove_end = remove_str.data + remove_str.size;
769
770
0
        while (remove_begin < remove_end) {
771
0
            char_lookup.set(static_cast<unsigned char>(*remove_begin));
772
0
            remove_begin += 1;
773
0
        }
774
775
0
        for (size_t i = 0; i < offset_size; ++i) {
776
0
            const char* str_begin =
777
0
                    reinterpret_cast<const char*>(str_data.data() + str_offsets[i - 1]);
778
0
            const char* str_end = reinterpret_cast<const char*>(str_data.data() + str_offsets[i]);
779
0
            const char* left_trim_pos = str_begin;
780
0
            const char* right_trim_pos = str_end;
781
782
0
            if constexpr (is_ltrim) {
783
0
                while (left_trim_pos < str_end) {
784
0
                    if (!char_lookup.test(static_cast<unsigned char>(*left_trim_pos))) {
785
0
                        break;
786
0
                    }
787
0
                    ++left_trim_pos;
788
0
                }
789
0
            }
790
791
0
            if constexpr (is_rtrim) {
792
0
                while (right_trim_pos > left_trim_pos) {
793
0
                    --right_trim_pos;
794
0
                    if (!char_lookup.test(static_cast<unsigned char>(*right_trim_pos))) {
795
0
                        ++right_trim_pos;
796
0
                        break;
797
0
                    }
798
0
                }
799
0
            }
800
801
0
            res_data.insert_assume_reserved(left_trim_pos, right_trim_pos);
802
            // The length of the result of the trim function will never exceed the length of the input.
803
0
            res_offsets[i] = (ColumnString::Offset)res_data.size();
804
0
        }
805
806
0
        return Status::OK();
807
0
    }
Unexecuted instantiation: _ZN5doris10TrimInUtilILb1ELb1ELb0EE18impl_vectors_asciiERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
Unexecuted instantiation: _ZN5doris10TrimInUtilILb1ELb0ELb0EE18impl_vectors_asciiERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
Unexecuted instantiation: _ZN5doris10TrimInUtilILb0ELb1ELb0EE18impl_vectors_asciiERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
808
809
    static Status impl_vectors_utf8(const ColumnString::Chars& str_data,
810
                                    const ColumnString::Offsets& str_offsets,
811
                                    const StringRef& remove_str, ColumnString::Chars& res_data,
812
0
                                    ColumnString::Offsets& res_offsets) {
813
0
        const size_t offset_size = str_offsets.size();
814
0
        res_offsets.resize(offset_size);
815
0
        res_data.reserve(str_data.size());
816
817
0
        std::unordered_set<std::string_view> char_lookup;
818
0
        const char* remove_begin = remove_str.data;
819
0
        const char* remove_end = remove_str.data + remove_str.size;
820
821
0
        while (remove_begin < remove_end) {
822
0
            size_t byte_len, char_len;
823
0
            std::tie(byte_len, char_len) = simd::VStringFunctions::iterate_utf8_with_limit_length(
824
0
                    remove_begin, remove_end, 1);
825
0
            char_lookup.insert(std::string_view(remove_begin, byte_len));
826
0
            remove_begin += byte_len;
827
0
        }
828
829
0
        for (size_t i = 0; i < offset_size; ++i) {
830
0
            const char* str_begin =
831
0
                    reinterpret_cast<const char*>(str_data.data() + str_offsets[i - 1]);
832
0
            const char* str_end = reinterpret_cast<const char*>(str_data.data() + str_offsets[i]);
833
0
            const char* left_trim_pos = str_begin;
834
0
            const char* right_trim_pos = str_end;
835
836
0
            if constexpr (is_ltrim) {
837
0
                while (left_trim_pos < str_end) {
838
0
                    size_t byte_len, char_len;
839
0
                    std::tie(byte_len, char_len) =
840
0
                            simd::VStringFunctions::iterate_utf8_with_limit_length(left_trim_pos,
841
0
                                                                                   str_end, 1);
842
0
                    if (char_lookup.find(std::string_view(left_trim_pos, byte_len)) ==
843
0
                        char_lookup.end()) {
844
0
                        break;
845
0
                    }
846
0
                    left_trim_pos += byte_len;
847
0
                }
848
0
            }
849
850
0
            if constexpr (is_rtrim) {
851
0
                while (right_trim_pos > left_trim_pos) {
852
0
                    const char* prev_char_pos = right_trim_pos;
853
0
                    do {
854
0
                        --prev_char_pos;
855
0
                    } while ((*prev_char_pos & 0xC0) == 0x80);
856
0
                    size_t byte_len = right_trim_pos - prev_char_pos;
857
0
                    if (char_lookup.find(std::string_view(prev_char_pos, byte_len)) ==
858
0
                        char_lookup.end()) {
859
0
                        break;
860
0
                    }
861
0
                    right_trim_pos = prev_char_pos;
862
0
                }
863
0
            }
864
865
0
            res_data.insert_assume_reserved(left_trim_pos, right_trim_pos);
866
            // The length of the result of the trim function will never exceed the length of the input.
867
0
            res_offsets[i] = (ColumnString::Offset)res_data.size();
868
0
        }
869
0
        return Status::OK();
870
0
    }
Unexecuted instantiation: _ZN5doris10TrimInUtilILb1ELb1ELb0EE17impl_vectors_utf8ERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
Unexecuted instantiation: _ZN5doris10TrimInUtilILb1ELb0ELb0EE17impl_vectors_utf8ERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
Unexecuted instantiation: _ZN5doris10TrimInUtilILb0ELb1ELb0EE17impl_vectors_utf8ERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
871
};
872
// This is an implementation of a parameter for the Trim function.
873
template <bool is_ltrim, bool is_rtrim, typename Name>
874
struct Trim1Impl {
875
    static constexpr auto name = Name::name;
876
877
96
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb1ELb1ENS_8NameTrimEE27get_variadic_argument_typesEv
Line
Count
Source
877
35
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb1ELb0ENS_9NameLTrimEE27get_variadic_argument_typesEv
Line
Count
Source
877
21
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb0ELb1ENS_9NameRTrimEE27get_variadic_argument_typesEv
Line
Count
Source
877
19
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb1ELb1ENS_10NameTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
877
7
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb1ELb0ENS_11NameLTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
877
7
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb0ELb1ENS_11NameRTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
877
7
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
878
879
    static Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
880
52
                          uint32_t result, size_t input_rows_count) {
881
52
        const ColumnPtr column = block.get_by_position(arguments[0]).column;
882
52
        if (const auto* col = assert_cast<const ColumnString*>(column.get())) {
883
52
            auto col_res = ColumnString::create();
884
52
            char blank[] = " ";
885
52
            const StringRef remove_str(blank, 1);
886
52
            RETURN_IF_ERROR((TrimUtil<is_ltrim, is_rtrim, true>::vector(
887
52
                    col->get_chars(), col->get_offsets(), remove_str, col_res->get_chars(),
888
52
                    col_res->get_offsets())));
889
52
            block.replace_by_position(result, std::move(col_res));
890
52
        } else {
891
0
            return Status::RuntimeError("Illegal column {} of argument of function {}",
892
0
                                        block.get_by_position(arguments[0]).column->get_name(),
893
0
                                        name);
894
0
        }
895
52
        return Status::OK();
896
52
    }
_ZN5doris9Trim1ImplILb1ELb1ENS_8NameTrimEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
880
28
                          uint32_t result, size_t input_rows_count) {
881
28
        const ColumnPtr column = block.get_by_position(arguments[0]).column;
882
28
        if (const auto* col = assert_cast<const ColumnString*>(column.get())) {
883
28
            auto col_res = ColumnString::create();
884
28
            char blank[] = " ";
885
28
            const StringRef remove_str(blank, 1);
886
28
            RETURN_IF_ERROR((TrimUtil<is_ltrim, is_rtrim, true>::vector(
887
28
                    col->get_chars(), col->get_offsets(), remove_str, col_res->get_chars(),
888
28
                    col_res->get_offsets())));
889
28
            block.replace_by_position(result, std::move(col_res));
890
28
        } else {
891
0
            return Status::RuntimeError("Illegal column {} of argument of function {}",
892
0
                                        block.get_by_position(arguments[0]).column->get_name(),
893
0
                                        name);
894
0
        }
895
28
        return Status::OK();
896
28
    }
_ZN5doris9Trim1ImplILb1ELb0ENS_9NameLTrimEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
880
13
                          uint32_t result, size_t input_rows_count) {
881
13
        const ColumnPtr column = block.get_by_position(arguments[0]).column;
882
13
        if (const auto* col = assert_cast<const ColumnString*>(column.get())) {
883
13
            auto col_res = ColumnString::create();
884
13
            char blank[] = " ";
885
13
            const StringRef remove_str(blank, 1);
886
13
            RETURN_IF_ERROR((TrimUtil<is_ltrim, is_rtrim, true>::vector(
887
13
                    col->get_chars(), col->get_offsets(), remove_str, col_res->get_chars(),
888
13
                    col_res->get_offsets())));
889
13
            block.replace_by_position(result, std::move(col_res));
890
13
        } else {
891
0
            return Status::RuntimeError("Illegal column {} of argument of function {}",
892
0
                                        block.get_by_position(arguments[0]).column->get_name(),
893
0
                                        name);
894
0
        }
895
13
        return Status::OK();
896
13
    }
_ZN5doris9Trim1ImplILb0ELb1ENS_9NameRTrimEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
880
11
                          uint32_t result, size_t input_rows_count) {
881
11
        const ColumnPtr column = block.get_by_position(arguments[0]).column;
882
11
        if (const auto* col = assert_cast<const ColumnString*>(column.get())) {
883
11
            auto col_res = ColumnString::create();
884
11
            char blank[] = " ";
885
11
            const StringRef remove_str(blank, 1);
886
11
            RETURN_IF_ERROR((TrimUtil<is_ltrim, is_rtrim, true>::vector(
887
11
                    col->get_chars(), col->get_offsets(), remove_str, col_res->get_chars(),
888
11
                    col_res->get_offsets())));
889
11
            block.replace_by_position(result, std::move(col_res));
890
11
        } else {
891
0
            return Status::RuntimeError("Illegal column {} of argument of function {}",
892
0
                                        block.get_by_position(arguments[0]).column->get_name(),
893
0
                                        name);
894
0
        }
895
11
        return Status::OK();
896
11
    }
Unexecuted instantiation: _ZN5doris9Trim1ImplILb1ELb1ENS_10NameTrimInEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZN5doris9Trim1ImplILb1ELb0ENS_11NameLTrimInEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZN5doris9Trim1ImplILb0ELb1ENS_11NameRTrimInEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
897
};
898
899
// This is an implementation of two parameters for the Trim function.
900
template <bool is_ltrim, bool is_rtrim, typename Name>
901
struct Trim2Impl {
902
    static constexpr auto name = Name::name;
903
904
42
    static DataTypes get_variadic_argument_types() {
905
42
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
906
42
    }
_ZN5doris9Trim2ImplILb1ELb1ENS_8NameTrimEE27get_variadic_argument_typesEv
Line
Count
Source
904
7
    static DataTypes get_variadic_argument_types() {
905
7
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
906
7
    }
_ZN5doris9Trim2ImplILb1ELb0ENS_9NameLTrimEE27get_variadic_argument_typesEv
Line
Count
Source
904
7
    static DataTypes get_variadic_argument_types() {
905
7
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
906
7
    }
_ZN5doris9Trim2ImplILb0ELb1ENS_9NameRTrimEE27get_variadic_argument_typesEv
Line
Count
Source
904
7
    static DataTypes get_variadic_argument_types() {
905
7
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
906
7
    }
_ZN5doris9Trim2ImplILb1ELb1ENS_10NameTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
904
7
    static DataTypes get_variadic_argument_types() {
905
7
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
906
7
    }
_ZN5doris9Trim2ImplILb1ELb0ENS_11NameLTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
904
7
    static DataTypes get_variadic_argument_types() {
905
7
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
906
7
    }
_ZN5doris9Trim2ImplILb0ELb1ENS_11NameRTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
904
7
    static DataTypes get_variadic_argument_types() {
905
7
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
906
7
    }
907
908
    static Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
909
0
                          uint32_t result, size_t input_rows_count) {
910
0
        const ColumnPtr column = block.get_by_position(arguments[0]).column;
911
0
        const auto& rcol =
912
0
                assert_cast<const ColumnConst*>(block.get_by_position(arguments[1]).column.get())
913
0
                        ->get_data_column_ptr();
914
0
        if (const auto* col = assert_cast<const ColumnString*>(column.get())) {
915
0
            if (const auto* col_right = assert_cast<const ColumnString*>(rcol.get())) {
916
0
                auto col_res = ColumnString::create();
917
0
                const auto* remove_str_raw = col_right->get_chars().data();
918
0
                const ColumnString::Offset remove_str_size = col_right->get_offsets()[0];
919
0
                const StringRef remove_str(remove_str_raw, remove_str_size);
920
921
0
                if (remove_str.size == 1) {
922
0
                    RETURN_IF_ERROR((TrimUtil<is_ltrim, is_rtrim, true>::vector(
923
0
                            col->get_chars(), col->get_offsets(), remove_str, col_res->get_chars(),
924
0
                            col_res->get_offsets())));
925
0
                } else {
926
                    if constexpr (std::is_same<Name, NameTrimIn>::value ||
927
                                  std::is_same<Name, NameLTrimIn>::value ||
928
0
                                  std::is_same<Name, NameRTrimIn>::value) {
929
0
                        RETURN_IF_ERROR((TrimInUtil<is_ltrim, is_rtrim, false>::vector(
930
0
                                col->get_chars(), col->get_offsets(), remove_str,
931
0
                                col_res->get_chars(), col_res->get_offsets())));
932
0
                    } else {
933
0
                        RETURN_IF_ERROR((TrimUtil<is_ltrim, is_rtrim, false>::vector(
934
0
                                col->get_chars(), col->get_offsets(), remove_str,
935
0
                                col_res->get_chars(), col_res->get_offsets())));
936
0
                    }
937
0
                }
938
0
                block.replace_by_position(result, std::move(col_res));
939
0
            } else {
940
0
                return Status::RuntimeError("Illegal column {} of argument of function {}",
941
0
                                            block.get_by_position(arguments[1]).column->get_name(),
942
0
                                            name);
943
0
            }
944
945
0
        } else {
946
0
            return Status::RuntimeError("Illegal column {} of argument of function {}",
947
0
                                        block.get_by_position(arguments[0]).column->get_name(),
948
0
                                        name);
949
0
        }
950
0
        return Status::OK();
951
0
    }
Unexecuted instantiation: _ZN5doris9Trim2ImplILb1ELb1ENS_8NameTrimEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZN5doris9Trim2ImplILb1ELb0ENS_9NameLTrimEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZN5doris9Trim2ImplILb0ELb1ENS_9NameRTrimEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZN5doris9Trim2ImplILb1ELb1ENS_10NameTrimInEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZN5doris9Trim2ImplILb1ELb0ENS_11NameLTrimInEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZN5doris9Trim2ImplILb0ELb1ENS_11NameRTrimInEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
952
};
953
954
template <typename impl>
955
class FunctionTrim : public IFunction {
956
public:
957
    static constexpr auto name = impl::name;
958
150
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE6createEv
Line
Count
Source
958
36
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE6createEv
Line
Count
Source
958
22
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE6createEv
Line
Count
Source
958
20
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE6createEv
Line
Count
Source
958
8
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE6createEv
Line
Count
Source
958
8
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE6createEv
Line
Count
Source
958
8
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE6createEv
Line
Count
Source
958
8
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE6createEv
Line
Count
Source
958
8
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE6createEv
Line
Count
Source
958
8
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE6createEv
Line
Count
Source
958
8
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE6createEv
Line
Count
Source
958
8
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE6createEv
Line
Count
Source
958
8
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
959
12
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE8get_nameB5cxx11Ev
Line
Count
Source
959
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE8get_nameB5cxx11Ev
Line
Count
Source
959
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE8get_nameB5cxx11Ev
Line
Count
Source
959
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE8get_nameB5cxx11Ev
Line
Count
Source
959
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE8get_nameB5cxx11Ev
Line
Count
Source
959
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE8get_nameB5cxx11Ev
Line
Count
Source
959
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE8get_nameB5cxx11Ev
Line
Count
Source
959
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE8get_nameB5cxx11Ev
Line
Count
Source
959
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE8get_nameB5cxx11Ev
Line
Count
Source
959
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE8get_nameB5cxx11Ev
Line
Count
Source
959
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE8get_nameB5cxx11Ev
Line
Count
Source
959
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE8get_nameB5cxx11Ev
Line
Count
Source
959
1
    String get_name() const override { return impl::name; }
960
961
54
    size_t get_number_of_arguments() const override {
962
54
        return get_variadic_argument_types_impl().size();
963
54
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE23get_number_of_argumentsEv
Line
Count
Source
961
28
    size_t get_number_of_arguments() const override {
962
28
        return get_variadic_argument_types_impl().size();
963
28
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE23get_number_of_argumentsEv
Line
Count
Source
961
14
    size_t get_number_of_arguments() const override {
962
14
        return get_variadic_argument_types_impl().size();
963
14
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE23get_number_of_argumentsEv
Line
Count
Source
961
12
    size_t get_number_of_arguments() const override {
962
12
        return get_variadic_argument_types_impl().size();
963
12
    }
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE23get_number_of_argumentsEv
964
965
54
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
966
54
        if (!is_string_type(arguments[0]->get_primitive_type())) {
967
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
968
0
                                   "Illegal type {} of argument of function {}",
969
0
                                   arguments[0]->get_name(), get_name());
970
0
        }
971
54
        return arguments[0];
972
54
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Line
Count
Source
965
28
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
966
28
        if (!is_string_type(arguments[0]->get_primitive_type())) {
967
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
968
0
                                   "Illegal type {} of argument of function {}",
969
0
                                   arguments[0]->get_name(), get_name());
970
0
        }
971
28
        return arguments[0];
972
28
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Line
Count
Source
965
14
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
966
14
        if (!is_string_type(arguments[0]->get_primitive_type())) {
967
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
968
0
                                   "Illegal type {} of argument of function {}",
969
0
                                   arguments[0]->get_name(), get_name());
970
0
        }
971
14
        return arguments[0];
972
14
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Line
Count
Source
965
12
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
966
12
        if (!is_string_type(arguments[0]->get_primitive_type())) {
967
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
968
0
                                   "Illegal type {} of argument of function {}",
969
0
                                   arguments[0]->get_name(), get_name());
970
0
        }
971
12
        return arguments[0];
972
12
    }
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
973
    // The second parameter of "trim" is a constant.
974
104
    ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE38get_arguments_that_are_always_constantEv
Line
Count
Source
974
56
    ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE38get_arguments_that_are_always_constantEv
Line
Count
Source
974
25
    ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE38get_arguments_that_are_always_constantEv
Line
Count
Source
974
23
    ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE38get_arguments_that_are_always_constantEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE38get_arguments_that_are_always_constantEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE38get_arguments_that_are_always_constantEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE38get_arguments_that_are_always_constantEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE38get_arguments_that_are_always_constantEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE38get_arguments_that_are_always_constantEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE38get_arguments_that_are_always_constantEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE38get_arguments_that_are_always_constantEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE38get_arguments_that_are_always_constantEv
975
976
138
    DataTypes get_variadic_argument_types_impl() const override {
977
138
        return impl::get_variadic_argument_types();
978
138
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
35
    DataTypes get_variadic_argument_types_impl() const override {
977
35
        return impl::get_variadic_argument_types();
978
35
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
21
    DataTypes get_variadic_argument_types_impl() const override {
977
21
        return impl::get_variadic_argument_types();
978
21
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
19
    DataTypes get_variadic_argument_types_impl() const override {
977
19
        return impl::get_variadic_argument_types();
978
19
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
7
    DataTypes get_variadic_argument_types_impl() const override {
977
7
        return impl::get_variadic_argument_types();
978
7
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
7
    DataTypes get_variadic_argument_types_impl() const override {
977
7
        return impl::get_variadic_argument_types();
978
7
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
7
    DataTypes get_variadic_argument_types_impl() const override {
977
7
        return impl::get_variadic_argument_types();
978
7
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
7
    DataTypes get_variadic_argument_types_impl() const override {
977
7
        return impl::get_variadic_argument_types();
978
7
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
7
    DataTypes get_variadic_argument_types_impl() const override {
977
7
        return impl::get_variadic_argument_types();
978
7
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
7
    DataTypes get_variadic_argument_types_impl() const override {
977
7
        return impl::get_variadic_argument_types();
978
7
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
7
    DataTypes get_variadic_argument_types_impl() const override {
977
7
        return impl::get_variadic_argument_types();
978
7
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
7
    DataTypes get_variadic_argument_types_impl() const override {
977
7
        return impl::get_variadic_argument_types();
978
7
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
7
    DataTypes get_variadic_argument_types_impl() const override {
977
7
        return impl::get_variadic_argument_types();
978
7
    }
979
980
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
981
52
                        uint32_t result, size_t input_rows_count) const override {
982
52
        return impl::execute(context, block, arguments, result, input_rows_count);
983
52
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
981
28
                        uint32_t result, size_t input_rows_count) const override {
982
28
        return impl::execute(context, block, arguments, result, input_rows_count);
983
28
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
981
13
                        uint32_t result, size_t input_rows_count) const override {
982
13
        return impl::execute(context, block, arguments, result, input_rows_count);
983
13
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
981
11
                        uint32_t result, size_t input_rows_count) const override {
982
11
        return impl::execute(context, block, arguments, result, input_rows_count);
983
11
    }
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
984
};
985
986
struct UnHexImplEmpty {
987
    static constexpr auto name = "unhex";
988
};
989
990
struct UnHexImplNull {
991
    static constexpr auto name = "unhex_null";
992
};
993
994
template <typename Name>
995
struct UnHexImpl {
996
    static constexpr auto name = Name::name;
997
    using ReturnType = DataTypeString;
998
    using ColumnType = ColumnString;
999
    static constexpr auto PrimitiveTypeImpl = PrimitiveType::TYPE_STRING;
1000
1001
    static Status vector(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
1002
17
                         ColumnString::Chars& dst_data, ColumnString::Offsets& dst_offsets) {
1003
17
        auto rows_count = offsets.size();
1004
17
        dst_offsets.resize(rows_count);
1005
1006
17
        int64_t total_size = 0;
1007
106
        for (size_t i = 0; i < rows_count; i++) {
1008
89
            size_t len = offsets[i] - offsets[i - 1];
1009
89
            total_size += len / 2;
1010
89
        }
1011
17
        ColumnString::check_chars_length(total_size, rows_count);
1012
17
        dst_data.resize(total_size);
1013
17
        char* dst_data_ptr = reinterpret_cast<char*>(dst_data.data());
1014
17
        size_t offset = 0;
1015
1016
106
        for (int i = 0; i < rows_count; ++i) {
1017
89
            const auto* source = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
1018
89
            ColumnString::Offset srclen = offsets[i] - offsets[i - 1];
1019
1020
89
            if (UNLIKELY(srclen == 0)) {
1021
3
                dst_offsets[i] = cast_set<uint32_t>(offset);
1022
3
                continue;
1023
3
            }
1024
1025
86
            int outlen = string_hex::hex_decode(source, srclen, dst_data_ptr + offset);
1026
1027
86
            offset += outlen;
1028
86
            dst_offsets[i] = cast_set<uint32_t>(offset);
1029
86
        }
1030
17
        dst_data.pop_back(total_size - offset);
1031
17
        return Status::OK();
1032
17
    }
1033
1034
    static Status vector(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
1035
                         ColumnString::Chars& dst_data, ColumnString::Offsets& dst_offsets,
1036
19
                         ColumnUInt8::Container* null_map_data) {
1037
19
        auto rows_count = offsets.size();
1038
19
        dst_offsets.resize(rows_count);
1039
1040
19
        int64_t total_size = 0;
1041
56
        for (size_t i = 0; i < rows_count; i++) {
1042
37
            size_t len = offsets[i] - offsets[i - 1];
1043
37
            total_size += len / 2;
1044
37
        }
1045
19
        ColumnString::check_chars_length(total_size, rows_count);
1046
19
        dst_data.resize(total_size);
1047
19
        char* dst_data_ptr = reinterpret_cast<char*>(dst_data.data());
1048
19
        size_t offset = 0;
1049
1050
56
        for (int i = 0; i < rows_count; ++i) {
1051
37
            const auto* source = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
1052
37
            ColumnString::Offset srclen = offsets[i] - offsets[i - 1];
1053
1054
37
            if (UNLIKELY(srclen == 0)) {
1055
3
                (*null_map_data)[i] = 1;
1056
3
                dst_offsets[i] = cast_set<uint32_t>(offset);
1057
3
                continue;
1058
3
            }
1059
1060
34
            int outlen = string_hex::hex_decode(source, srclen, dst_data_ptr + offset);
1061
1062
34
            if (outlen == 0) {
1063
6
                (*null_map_data)[i] = 1;
1064
6
                dst_offsets[i] = cast_set<uint32_t>(offset);
1065
6
                continue;
1066
6
            }
1067
1068
28
            offset += outlen;
1069
28
            dst_offsets[i] = cast_set<uint32_t>(offset);
1070
28
        }
1071
19
        dst_data.pop_back(total_size - offset);
1072
19
        return Status::OK();
1073
19
    }
1074
};
1075
1076
struct NameStringSpace {
1077
    static constexpr auto name = "space";
1078
};
1079
1080
struct StringSpace {
1081
    using ReturnType = DataTypeString;
1082
    static constexpr auto PrimitiveTypeImpl = PrimitiveType::TYPE_INT;
1083
    using Type = Int32;
1084
    using ReturnColumnType = ColumnString;
1085
1086
    static Status vector(const ColumnInt32::Container& data, ColumnString::Chars& res_data,
1087
0
                         ColumnString::Offsets& res_offsets) {
1088
0
        res_offsets.resize(data.size());
1089
0
        size_t input_size = res_offsets.size();
1090
0
        int64_t total_size = 0;
1091
0
        for (size_t i = 0; i < input_size; ++i) {
1092
0
            if (data[i] > 0) {
1093
0
                total_size += data[i];
1094
0
            }
1095
0
        }
1096
0
        ColumnString::check_chars_length(total_size, input_size);
1097
0
        res_data.reserve(total_size);
1098
1099
0
        for (size_t i = 0; i < input_size; ++i) {
1100
0
            if (data[i] > 0) [[likely]] {
1101
0
                res_data.resize_fill(res_data.size() + data[i], ' ');
1102
0
                cast_set(res_offsets[i], res_data.size());
1103
0
            } else {
1104
0
                StringOP::push_empty_string(i, res_data, res_offsets);
1105
0
            }
1106
0
        }
1107
0
        return Status::OK();
1108
0
    }
1109
};
1110
1111
struct ToBase64Impl {
1112
    static constexpr auto name = "to_base64";
1113
    using ReturnType = DataTypeString;
1114
    using ColumnType = ColumnString;
1115
    static constexpr auto PrimitiveTypeImpl = PrimitiveType::TYPE_STRING;
1116
1117
    static Status vector(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
1118
14
                         ColumnString::Chars& dst_data, ColumnString::Offsets& dst_offsets) {
1119
14
        auto rows_count = offsets.size();
1120
14
        dst_offsets.resize(rows_count);
1121
1122
14
        size_t total_size = 0;
1123
50
        for (size_t i = 0; i < rows_count; i++) {
1124
36
            size_t len = offsets[i] - offsets[i - 1];
1125
36
            total_size += 4 * ((len + 2) / 3);
1126
36
        }
1127
14
        ColumnString::check_chars_length(total_size, rows_count);
1128
14
        dst_data.resize(total_size);
1129
14
        auto* dst_data_ptr = dst_data.data();
1130
14
        size_t offset = 0;
1131
1132
50
        for (int i = 0; i < rows_count; ++i) {
1133
36
            const auto* source = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
1134
36
            size_t srclen = offsets[i] - offsets[i - 1];
1135
1136
36
            if (UNLIKELY(srclen == 0)) {
1137
6
                dst_offsets[i] = cast_set<uint32_t>(offset);
1138
6
                continue;
1139
6
            }
1140
1141
30
            auto outlen = doris::base64_encode((const unsigned char*)source, srclen,
1142
30
                                               (unsigned char*)(dst_data_ptr + offset));
1143
1144
30
            offset += outlen;
1145
30
            dst_offsets[i] = cast_set<uint32_t>(offset);
1146
30
        }
1147
14
        dst_data.pop_back(total_size - offset);
1148
14
        return Status::OK();
1149
14
    }
1150
};
1151
1152
struct FromBase64Impl {
1153
    static constexpr auto name = "from_base64";
1154
    using ReturnType = DataTypeString;
1155
    using ColumnType = ColumnString;
1156
1157
    static Status vector(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
1158
                         ColumnString::Chars& dst_data, ColumnString::Offsets& dst_offsets,
1159
11
                         NullMap& null_map) {
1160
11
        auto rows_count = offsets.size();
1161
11
        dst_offsets.resize(rows_count);
1162
1163
11
        size_t total_size = 0;
1164
42
        for (size_t i = 0; i < rows_count; i++) {
1165
31
            auto len = offsets[i] - offsets[i - 1];
1166
31
            total_size += len / 4 * 3;
1167
31
        }
1168
11
        ColumnString::check_chars_length(total_size, rows_count);
1169
11
        dst_data.resize(total_size);
1170
11
        char* dst_data_ptr = reinterpret_cast<char*>(dst_data.data());
1171
11
        size_t offset = 0;
1172
1173
42
        for (int i = 0; i < rows_count; ++i) {
1174
31
            if (UNLIKELY(null_map[i])) {
1175
0
                null_map[i] = 1;
1176
0
                dst_offsets[i] = cast_set<uint32_t>(offset);
1177
0
                continue;
1178
0
            }
1179
1180
31
            const auto* source = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
1181
31
            ColumnString::Offset srclen = offsets[i] - offsets[i - 1];
1182
1183
31
            if (UNLIKELY(srclen == 0)) {
1184
5
                dst_offsets[i] = cast_set<uint32_t>(offset);
1185
5
                continue;
1186
5
            }
1187
1188
26
            auto outlen = base64_decode(source, srclen, dst_data_ptr + offset);
1189
1190
26
            if (outlen < 0) {
1191
14
                null_map[i] = 1;
1192
14
                dst_offsets[i] = cast_set<uint32_t>(offset);
1193
14
            } else {
1194
12
                offset += outlen;
1195
12
                dst_offsets[i] = cast_set<uint32_t>(offset);
1196
12
            }
1197
26
        }
1198
11
        dst_data.pop_back(total_size - offset);
1199
11
        return Status::OK();
1200
11
    }
1201
};
1202
1203
struct StringAppendTrailingCharIfAbsent {
1204
    static constexpr auto name = "append_trailing_char_if_absent";
1205
    using Chars = ColumnString::Chars;
1206
    using Offsets = ColumnString::Offsets;
1207
    using ReturnType = DataTypeString;
1208
    using ColumnType = ColumnString;
1209
1210
44
    static bool str_end_with(const StringRef& str, const StringRef& end) {
1211
44
        if (str.size < end.size) {
1212
8
            return false;
1213
8
        }
1214
        // The end_with method of StringRef needs to ensure that the size of end is less than or equal to the size of str.
1215
36
        return str.end_with(end);
1216
44
    }
1217
1218
    static void vector_vector(FunctionContext* context, const Chars& ldata, const Offsets& loffsets,
1219
                              const Chars& rdata, const Offsets& roffsets, Chars& res_data,
1220
9
                              Offsets& res_offsets, NullMap& null_map_data) {
1221
9
        DCHECK_EQ(loffsets.size(), roffsets.size());
1222
9
        size_t input_rows_count = loffsets.size();
1223
9
        res_offsets.resize(input_rows_count);
1224
9
        fmt::memory_buffer buffer;
1225
1226
30
        for (size_t i = 0; i < input_rows_count; ++i) {
1227
21
            buffer.clear();
1228
1229
21
            StringRef lstr = StringRef(reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]),
1230
21
                                       loffsets[i] - loffsets[i - 1]);
1231
21
            StringRef rstr = StringRef(reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]),
1232
21
                                       roffsets[i] - roffsets[i - 1]);
1233
            // The iterate_utf8_with_limit_length function iterates over a maximum of two UTF-8 characters.
1234
21
            auto [byte_len, char_len] = simd::VStringFunctions::iterate_utf8_with_limit_length(
1235
21
                    rstr.begin(), rstr.end(), 2);
1236
1237
21
            if (char_len != 1) {
1238
9
                StringOP::push_null_string(i, res_data, res_offsets, null_map_data);
1239
9
                continue;
1240
9
            }
1241
12
            if (str_end_with(lstr, rstr)) {
1242
4
                StringOP::push_value_string(lstr, i, res_data, res_offsets);
1243
4
                continue;
1244
4
            }
1245
1246
8
            buffer.append(lstr.begin(), lstr.end());
1247
8
            buffer.append(rstr.begin(), rstr.end());
1248
8
            StringOP::push_value_string(std::string_view(buffer.data(), buffer.size()), i, res_data,
1249
8
                                        res_offsets);
1250
8
        }
1251
9
    }
1252
    static void vector_scalar(FunctionContext* context, const Chars& ldata, const Offsets& loffsets,
1253
                              const StringRef& rstr, Chars& res_data, Offsets& res_offsets,
1254
10
                              NullMap& null_map_data) {
1255
10
        size_t input_rows_count = loffsets.size();
1256
10
        res_offsets.resize(input_rows_count);
1257
10
        fmt::memory_buffer buffer;
1258
        // The iterate_utf8_with_limit_length function iterates over a maximum of two UTF-8 characters.
1259
10
        auto [byte_len, char_len] =
1260
10
                simd::VStringFunctions::iterate_utf8_with_limit_length(rstr.begin(), rstr.end(), 2);
1261
10
        if (char_len != 1) {
1262
4
            for (size_t i = 0; i < input_rows_count; ++i) {
1263
2
                StringOP::push_null_string(i, res_data, res_offsets, null_map_data);
1264
2
            }
1265
2
            return;
1266
2
        }
1267
1268
34
        for (size_t i = 0; i < input_rows_count; ++i) {
1269
26
            buffer.clear();
1270
26
            StringRef lstr = StringRef(reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]),
1271
26
                                       loffsets[i] - loffsets[i - 1]);
1272
1273
26
            if (str_end_with(lstr, rstr)) {
1274
2
                StringOP::push_value_string(lstr, i, res_data, res_offsets);
1275
2
                continue;
1276
2
            }
1277
1278
24
            buffer.append(lstr.begin(), lstr.end());
1279
24
            buffer.append(rstr.begin(), rstr.end());
1280
24
            StringOP::push_value_string(std::string_view(buffer.data(), buffer.size()), i, res_data,
1281
24
                                        res_offsets);
1282
24
        }
1283
8
    }
1284
    static void scalar_vector(FunctionContext* context, const StringRef& lstr, const Chars& rdata,
1285
                              const Offsets& roffsets, Chars& res_data, Offsets& res_offsets,
1286
8
                              NullMap& null_map_data) {
1287
8
        size_t input_rows_count = roffsets.size();
1288
8
        res_offsets.resize(input_rows_count);
1289
8
        fmt::memory_buffer buffer;
1290
1291
16
        for (size_t i = 0; i < input_rows_count; ++i) {
1292
8
            buffer.clear();
1293
1294
8
            StringRef rstr = StringRef(reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]),
1295
8
                                       roffsets[i] - roffsets[i - 1]);
1296
            // The iterate_utf8_with_limit_length function iterates over a maximum of two UTF-8 characters.
1297
8
            auto [byte_len, char_len] = simd::VStringFunctions::iterate_utf8_with_limit_length(
1298
8
                    rstr.begin(), rstr.end(), 2);
1299
1300
8
            if (char_len != 1) {
1301
2
                StringOP::push_null_string(i, res_data, res_offsets, null_map_data);
1302
2
                continue;
1303
2
            }
1304
6
            if (str_end_with(lstr, rstr)) {
1305
2
                StringOP::push_value_string(lstr, i, res_data, res_offsets);
1306
2
                continue;
1307
2
            }
1308
1309
4
            buffer.append(lstr.begin(), lstr.end());
1310
4
            buffer.append(rstr.begin(), rstr.end());
1311
4
            StringOP::push_value_string(std::string_view(buffer.data(), buffer.size()), i, res_data,
1312
4
                                        res_offsets);
1313
4
        }
1314
8
    }
1315
};
1316
1317
struct StringLPad {
1318
    static constexpr auto name = "lpad";
1319
    static constexpr auto is_lpad = true;
1320
};
1321
1322
struct StringRPad {
1323
    static constexpr auto name = "rpad";
1324
    static constexpr auto is_lpad = false;
1325
};
1326
1327
template <typename LeftDataType, typename RightDataType>
1328
using StringStartsWithImpl = StringFunctionImpl<LeftDataType, RightDataType, StartsWithOp>;
1329
1330
template <typename LeftDataType, typename RightDataType>
1331
using StringEndsWithImpl = StringFunctionImpl<LeftDataType, RightDataType, EndsWithOp>;
1332
1333
template <typename LeftDataType, typename RightDataType>
1334
using StringFindInSetImpl = StringFunctionImpl<LeftDataType, RightDataType, FindInSetOp>;
1335
1336
// ready for regist function
1337
using FunctionStringParseDataSize = FunctionUnaryToType<ParseDataSize, NameParseDataSize>;
1338
using FunctionStringASCII = FunctionUnaryToType<StringASCII, NameStringASCII>;
1339
using FunctionStringLength = FunctionUnaryToType<StringLengthImpl, NameStringLength>;
1340
using FunctionCrc32 = FunctionUnaryToType<Crc32Impl, NameCrc32>;
1341
using FunctionStringUTF8Length = FunctionUnaryToType<StringUtf8LengthImpl, NameStringUtf8Length>;
1342
using FunctionStringSpace = FunctionUnaryToType<StringSpace, NameStringSpace>;
1343
using FunctionIsValidUTF8 = FunctionUnaryToType<IsValidUTF8Impl, NameIsValidUTF8>;
1344
using FunctionStringStartsWith =
1345
        FunctionBinaryToType<DataTypeString, DataTypeString, StringStartsWithImpl, NameStartsWith>;
1346
using FunctionStringEndsWith =
1347
        FunctionBinaryToType<DataTypeString, DataTypeString, StringEndsWithImpl, NameEndsWith>;
1348
using FunctionStringInstr =
1349
        FunctionBinaryToType<DataTypeString, DataTypeString, StringInStrImpl, NameInstr>;
1350
using FunctionStringLocate =
1351
        FunctionBinaryToType<DataTypeString, DataTypeString, StringLocateImpl, NameLocate>;
1352
using FunctionStringFindInSet =
1353
        FunctionBinaryToType<DataTypeString, DataTypeString, StringFindInSetImpl, NameFindInSet>;
1354
1355
using FunctionQuote = FunctionStringToString<NameQuoteImpl, NameQuote>;
1356
1357
using FunctionToLower = FunctionStringToString<TransferImpl<NameToLower>, NameToLower>;
1358
1359
using FunctionToUpper = FunctionStringToString<TransferImpl<NameToUpper>, NameToUpper>;
1360
1361
using FunctionToInitcap = FunctionStringToString<InitcapImpl, NameToInitcap>;
1362
1363
using FunctionUnHex = FunctionStringEncode<UnHexImpl<UnHexImplEmpty>, false>;
1364
using FunctionUnHexNullable = FunctionStringEncode<UnHexImpl<UnHexImplNull>, true>;
1365
using FunctionToBase64 = FunctionStringEncode<ToBase64Impl, false>;
1366
using FunctionFromBase64 = FunctionStringOperateToNullType<FromBase64Impl>;
1367
1368
using FunctionStringAppendTrailingCharIfAbsent =
1369
        FunctionBinaryStringOperateToNullType<StringAppendTrailingCharIfAbsent>;
1370
1371
using FunctionStringLPad = FunctionStringPad<StringLPad>;
1372
using FunctionStringRPad = FunctionStringPad<StringRPad>;
1373
1374
extern void register_function_string_basic(SimpleFunctionFactory& factory);
1375
extern void register_function_string_digest(SimpleFunctionFactory& factory);
1376
extern void register_function_string_mask(SimpleFunctionFactory& factory);
1377
extern void register_function_string_misc(SimpleFunctionFactory& factory);
1378
extern void register_function_string_search(SimpleFunctionFactory& factory);
1379
extern void register_function_string_url(SimpleFunctionFactory& factory);
1380
1381
7
void register_function_string(SimpleFunctionFactory& factory) {
1382
7
    register_function_string_basic(factory);
1383
7
    register_function_string_digest(factory);
1384
7
    register_function_string_mask(factory);
1385
7
    register_function_string_misc(factory);
1386
7
    register_function_string_search(factory);
1387
7
    register_function_string_url(factory);
1388
1389
7
    factory.register_function<FunctionStringParseDataSize>();
1390
7
    factory.register_function<FunctionStringASCII>();
1391
7
    factory.register_function<FunctionStringLength>();
1392
7
    factory.register_function<FunctionCrc32>();
1393
7
    factory.register_function<FunctionStringUTF8Length>();
1394
7
    factory.register_function<FunctionStringSpace>();
1395
7
    factory.register_function<FunctionStringStartsWith>();
1396
7
    factory.register_function<FunctionStringEndsWith>();
1397
7
    factory.register_function<FunctionStringInstr>();
1398
7
    factory.register_function<FunctionStringFindInSet>();
1399
7
    factory.register_function<FunctionStringLocate>();
1400
7
    factory.register_function<FunctionQuote>();
1401
7
    factory.register_function<FunctionReverseCommon>();
1402
7
    factory.register_function<FunctionUnHex>();
1403
7
    factory.register_function<FunctionUnHexNullable>();
1404
7
    factory.register_function<FunctionToLower>();
1405
7
    factory.register_function<FunctionToUpper>();
1406
7
    factory.register_function<FunctionToInitcap>();
1407
7
    factory.register_function<FunctionTrim<Trim1Impl<true, true, NameTrim>>>();
1408
7
    factory.register_function<FunctionTrim<Trim1Impl<true, false, NameLTrim>>>();
1409
7
    factory.register_function<FunctionTrim<Trim1Impl<false, true, NameRTrim>>>();
1410
7
    factory.register_function<FunctionTrim<Trim2Impl<true, true, NameTrim>>>();
1411
7
    factory.register_function<FunctionTrim<Trim2Impl<true, false, NameLTrim>>>();
1412
7
    factory.register_function<FunctionTrim<Trim2Impl<false, true, NameRTrim>>>();
1413
7
    factory.register_function<FunctionTrim<Trim1Impl<true, true, NameTrimIn>>>();
1414
7
    factory.register_function<FunctionTrim<Trim1Impl<true, false, NameLTrimIn>>>();
1415
7
    factory.register_function<FunctionTrim<Trim1Impl<false, true, NameRTrimIn>>>();
1416
7
    factory.register_function<FunctionTrim<Trim2Impl<true, true, NameTrimIn>>>();
1417
7
    factory.register_function<FunctionTrim<Trim2Impl<true, false, NameLTrimIn>>>();
1418
7
    factory.register_function<FunctionTrim<Trim2Impl<false, true, NameRTrimIn>>>();
1419
7
    factory.register_function<FunctionStringConcat>();
1420
7
    factory.register_function<FunctionStringElt>();
1421
7
    factory.register_function<FunctionStringConcatWs>();
1422
7
    factory.register_function<FunctionStringAppendTrailingCharIfAbsent>();
1423
7
    factory.register_function<FunctionStringRepeat>();
1424
7
    factory.register_function<FunctionStringLPad>();
1425
7
    factory.register_function<FunctionStringRPad>();
1426
7
    factory.register_function<FunctionToBase64>();
1427
7
    factory.register_function<FunctionFromBase64>();
1428
7
    factory.register_function<FunctionMoneyFormat<MoneyFormatDoubleImpl>>();
1429
7
    factory.register_function<FunctionMoneyFormat<MoneyFormatInt64Impl>>();
1430
7
    factory.register_function<FunctionMoneyFormat<MoneyFormatInt128Impl>>();
1431
7
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMALV2>>>();
1432
7
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMAL32>>>();
1433
7
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMAL64>>>();
1434
7
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMAL128I>>>();
1435
7
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMAL256>>>();
1436
7
    factory.register_function<FunctionStringFormatRound<FormatRoundDoubleImpl>>();
1437
7
    factory.register_function<FunctionStringFormatRound<FormatRoundInt64Impl>>();
1438
7
    factory.register_function<FunctionStringFormatRound<FormatRoundInt128Impl>>();
1439
7
    factory.register_function<FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMALV2>>>();
1440
7
    factory.register_function<FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMAL32>>>();
1441
7
    factory.register_function<FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMAL64>>>();
1442
7
    factory.register_function<
1443
7
            FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMAL128I>>>();
1444
7
    factory.register_function<FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMAL256>>>();
1445
7
    factory.register_function<FunctionReplace<ReplaceImpl, true>>();
1446
7
    factory.register_function<FunctionReplace<ReplaceEmptyImpl, false>>();
1447
7
    factory.register_function<FunctionSubReplace<SubReplaceThreeImpl>>();
1448
7
    factory.register_function<FunctionSubReplace<SubReplaceFourImpl>>();
1449
7
    factory.register_function<FunctionOverlay>();
1450
7
    factory.register_function<FunctionIsValidUTF8>();
1451
1452
7
    factory.register_alias(FunctionIsValidUTF8::name, "isValidUTF8");
1453
7
    factory.register_alias(FunctionToLower::name, "lcase");
1454
7
    factory.register_alias(FunctionToUpper::name, "ucase");
1455
7
    factory.register_alias(FunctionStringUTF8Length::name, "character_length");
1456
7
    factory.register_alias(FunctionStringLength::name, "octet_length");
1457
7
    factory.register_alias(FunctionOverlay::name, "insert");
1458
7
}
1459
1460
} // namespace doris