Coverage Report

Created: 2026-04-20 20:34

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
11
                         PaddedPODArray<Int32>& res) {
62
11
        auto size = offsets.size();
63
11
        res.resize(size);
64
32
        for (int i = 0; i < size; ++i) {
65
21
            const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
66
21
            res[i] = (offsets[i] == offsets[i - 1]) ? 0 : static_cast<uint8_t>(raw_str[0]);
67
21
        }
68
11
        return Status::OK();
69
11
    }
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
32
                         PaddedPODArray<Int32>& res) {
174
32
        auto size = offsets.size();
175
32
        res.resize(size);
176
96
        for (int i = 0; i < size; ++i) {
177
64
            int str_size = offsets[i] - offsets[i - 1];
178
64
            res[i] = str_size;
179
64
        }
180
32
        return Status::OK();
181
32
    }
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
11
                         PaddedPODArray<Int32>& res) {
218
11
        auto size = offsets.size();
219
11
        res.resize(size);
220
32
        for (int i = 0; i < size; ++i) {
221
21
            const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
222
21
            int str_size = offsets[i] - offsets[i - 1];
223
21
            res[i] = simd::VStringFunctions::get_char_len(raw_str, str_size);
224
21
        }
225
11
        return Status::OK();
226
11
    }
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
18
    static void execute(const std::string_view& strl, const std::string_view& strr, uint8_t& res) {
261
18
        res = strl.starts_with(strr);
262
18
    }
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
62
    static void execute(const std::string_view& strl, const std::string_view& strr, uint8_t& res) {
274
62
        res = strl.ends_with(strr);
275
62
    }
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
73
    static void execute(const std::string_view& strl, const std::string_view& strr, int32_t& res) {
286
85
        for (const auto& c : strl) {
287
85
            if (c == ',') {
288
17
                res = 0;
289
17
                return;
290
17
            }
291
85
        }
292
293
56
        int32_t token_index = 1;
294
56
        int32_t start = 0;
295
56
        int32_t end;
296
297
122
        do {
298
122
            end = start;
299
            // Position end.
300
177
            while (end < strr.length() && strr[end] != ',') {
301
55
                ++end;
302
55
            }
303
304
122
            if (strl == std::string_view {strr.data() + start, (size_t)end - start}) {
305
25
                res = token_index;
306
25
                return;
307
25
            }
308
309
            // Re-position start and end past ','
310
97
            start = end + 1;
311
97
            ++token_index;
312
97
        } while (start < strr.length());
313
31
        res = 0;
314
31
    }
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
72
                                ResultPaddedPODArray& res) {
348
72
        auto size = loffsets.size();
349
72
        res.resize(size);
350
351
72
        if (rdata.size == 0) {
352
12
            std::fill(res.begin(), res.end(), 1);
353
12
            return Status::OK();
354
12
        }
355
356
60
        const UInt8* begin = ldata.data();
357
60
        const UInt8* end = begin + ldata.size();
358
60
        const UInt8* pos = begin;
359
360
        /// Current index in the array of strings.
361
60
        size_t i = 0;
362
60
        std::fill(res.begin(), res.end(), 0);
363
364
60
        StringRef rstr_ref(rdata.data, rdata.size);
365
60
        StringSearch search(&rstr_ref);
366
367
76
        while (pos < end) {
368
            // search return matched substring start offset
369
50
            pos = (UInt8*)search.search((char*)pos, end - pos);
370
50
            if (pos >= end) {
371
34
                break;
372
34
            }
373
374
            /// Determine which index it refers to.
375
            /// begin + value_offsets[i] is the start offset of string at i+1
376
16
            while (begin + loffsets[i] < pos) {
377
0
                ++i;
378
0
            }
379
380
            /// We check that the entry does not pass through the boundaries of strings.
381
16
            if (pos + rdata.size <= begin + loffsets[i]) {
382
16
                int loc = (int)(pos - begin) - loffsets[i - 1];
383
16
                int l_str_size = loffsets[i] - loffsets[i - 1];
384
16
                auto len = std::min(l_str_size, loc);
385
16
                loc = simd::VStringFunctions::get_char_len((char*)(begin + loffsets[i - 1]), len);
386
16
                res[i] = loc + 1;
387
16
            }
388
389
            // move to next string offset
390
16
            pos = begin + loffsets[i];
391
16
            ++i;
392
16
        }
393
394
60
        return Status::OK();
395
72
    }
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
36
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
450
36
        return StringInStrImpl<LeftDataType, RightDataType>::vector_scalar(rdata, roffsets, ldata,
451
36
                                                                           res);
452
36
    }
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
34
                                ResultPaddedPODArray& res) {
501
34
        auto size = loffsets.size();
502
34
        res.resize(size);
503
34
        std::string_view rview(rdata.data, rdata.size);
504
68
        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
34
        return Status::OK();
512
34
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_12StartsWithOpEE13vector_scalarERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEERKNS_9StringRefERS8_
Line
Count
Source
500
4
                                ResultPaddedPODArray& res) {
501
4
        auto size = loffsets.size();
502
4
        res.resize(size);
503
4
        std::string_view rview(rdata.data, rdata.size);
504
8
        for (int i = 0; i < size; ++i) {
505
4
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
506
4
            int l_str_size = loffsets[i] - loffsets[i - 1];
507
4
            std::string_view lview(l_raw_str, l_str_size);
508
509
4
            OP::execute(lview, rview, res[i]);
510
4
        }
511
4
        return Status::OK();
512
4
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_10EndsWithOpEE13vector_scalarERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEERKNS_9StringRefERS8_
Line
Count
Source
500
14
                                ResultPaddedPODArray& res) {
501
14
        auto size = loffsets.size();
502
14
        res.resize(size);
503
14
        std::string_view rview(rdata.data, rdata.size);
504
28
        for (int i = 0; i < size; ++i) {
505
14
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
506
14
            int l_str_size = loffsets[i] - loffsets[i - 1];
507
14
            std::string_view lview(l_raw_str, l_str_size);
508
509
14
            OP::execute(lview, rview, res[i]);
510
14
        }
511
14
        return Status::OK();
512
14
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_11FindInSetOpEE13vector_scalarERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEERKNS_9StringRefERNS4_IiLm4096ES7_Lm16ELm15EEE
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
32
        for (int i = 0; i < size; ++i) {
505
16
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
506
16
            int l_str_size = loffsets[i] - loffsets[i - 1];
507
16
            std::string_view lview(l_raw_str, l_str_size);
508
509
16
            OP::execute(lview, rview, res[i]);
510
16
        }
511
16
        return Status::OK();
512
16
    }
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
82
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
541
82
        size_t offset_size = offsets.size();
542
82
        if (UNLIKELY(!offset_size)) {
543
0
            return Status::OK();
544
0
        }
545
546
82
        const bool is_ascii = simd::VStringFunctions::is_ascii({data.data(), data.size()});
547
82
        res_offsets.resize(offset_size);
548
82
        if (is_ascii) {
549
36
            memcpy_small_allow_read_write_overflow15(
550
36
                    res_offsets.data(), offsets.data(),
551
36
                    offset_size * sizeof(ColumnString::Offsets::value_type));
552
553
36
            size_t data_length = data.size();
554
36
            res_data.resize(data_length);
555
36
            if constexpr (std::is_same_v<OpName, NameToUpper>) {
556
22
                simd::VStringFunctions::to_upper(data.data(), data_length, res_data.data());
557
22
            } else if constexpr (std::is_same_v<OpName, NameToLower>) {
558
14
                simd::VStringFunctions::to_lower(data.data(), data_length, res_data.data());
559
14
            }
560
46
        } else {
561
46
            execute_utf8(data, offsets, res_data, res_offsets);
562
46
        }
563
564
82
        return Status::OK();
565
82
    }
_ZN5doris12TransferImplINS_11NameToLowerEE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS3_IjLm4096ES6_Lm16ELm15EEERS7_RSA_
Line
Count
Source
540
28
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
541
28
        size_t offset_size = offsets.size();
542
28
        if (UNLIKELY(!offset_size)) {
543
0
            return Status::OK();
544
0
        }
545
546
28
        const bool is_ascii = simd::VStringFunctions::is_ascii({data.data(), data.size()});
547
28
        res_offsets.resize(offset_size);
548
28
        if (is_ascii) {
549
14
            memcpy_small_allow_read_write_overflow15(
550
14
                    res_offsets.data(), offsets.data(),
551
14
                    offset_size * sizeof(ColumnString::Offsets::value_type));
552
553
14
            size_t data_length = data.size();
554
14
            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
14
            } else if constexpr (std::is_same_v<OpName, NameToLower>) {
558
14
                simd::VStringFunctions::to_lower(data.data(), data_length, res_data.data());
559
14
            }
560
14
        } else {
561
14
            execute_utf8(data, offsets, res_data, res_offsets);
562
14
        }
563
564
28
        return Status::OK();
565
28
    }
_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
50
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
718
50
        const size_t offset_size = str_offsets.size();
719
50
        res_offsets.resize(offset_size);
720
50
        res_data.reserve(str_data.size());
721
146
        for (size_t i = 0; i < offset_size; ++i) {
722
96
            const auto* str_begin = str_data.data() + str_offsets[i - 1];
723
96
            const auto* str_end = str_data.data() + str_offsets[i];
724
725
96
            if constexpr (is_ltrim) {
726
75
                str_begin =
727
75
                        simd::VStringFunctions::ltrim<trim_single>(str_begin, str_end, remove_str);
728
75
            }
729
96
            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
96
            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
96
            res_offsets[i] = (ColumnString::Offset)res_data.size();
737
96
        }
738
50
        return Status::OK();
739
50
    }
_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
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
21
            if constexpr (is_ltrim) {
726
21
                str_begin =
727
21
                        simd::VStringFunctions::ltrim<trim_single>(str_begin, str_end, remove_str);
728
21
            }
729
            if constexpr (is_rtrim) {
730
                str_end =
731
                        simd::VStringFunctions::rtrim<trim_single>(str_begin, str_end, remove_str);
732
            }
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
    }
_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
58
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb1ELb1ENS_8NameTrimEE27get_variadic_argument_typesEv
Line
Count
Source
877
29
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb1ELb0ENS_9NameLTrimEE27get_variadic_argument_typesEv
Line
Count
Source
877
13
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb0ELb1ENS_9NameRTrimEE27get_variadic_argument_typesEv
Line
Count
Source
877
13
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb1ELb1ENS_10NameTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
877
1
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb1ELb0ENS_11NameLTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
877
1
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb0ELb1ENS_11NameRTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
877
1
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
878
879
    static Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
880
50
                          uint32_t result, size_t input_rows_count) {
881
50
        const ColumnPtr column = block.get_by_position(arguments[0]).column;
882
50
        if (const auto* col = assert_cast<const ColumnString*>(column.get())) {
883
50
            auto col_res = ColumnString::create();
884
50
            char blank[] = " ";
885
50
            const StringRef remove_str(blank, 1);
886
50
            RETURN_IF_ERROR((TrimUtil<is_ltrim, is_rtrim, true>::vector(
887
50
                    col->get_chars(), col->get_offsets(), remove_str, col_res->get_chars(),
888
50
                    col_res->get_offsets())));
889
50
            block.replace_by_position(result, std::move(col_res));
890
50
        } 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
50
        return Status::OK();
896
50
    }
_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
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
    }
_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
6
    static DataTypes get_variadic_argument_types() {
905
6
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
906
6
    }
_ZN5doris9Trim2ImplILb1ELb1ENS_8NameTrimEE27get_variadic_argument_typesEv
Line
Count
Source
904
1
    static DataTypes get_variadic_argument_types() {
905
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
906
1
    }
_ZN5doris9Trim2ImplILb1ELb0ENS_9NameLTrimEE27get_variadic_argument_typesEv
Line
Count
Source
904
1
    static DataTypes get_variadic_argument_types() {
905
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
906
1
    }
_ZN5doris9Trim2ImplILb0ELb1ENS_9NameRTrimEE27get_variadic_argument_typesEv
Line
Count
Source
904
1
    static DataTypes get_variadic_argument_types() {
905
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
906
1
    }
_ZN5doris9Trim2ImplILb1ELb1ENS_10NameTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
904
1
    static DataTypes get_variadic_argument_types() {
905
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
906
1
    }
_ZN5doris9Trim2ImplILb1ELb0ENS_11NameLTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
904
1
    static DataTypes get_variadic_argument_types() {
905
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
906
1
    }
_ZN5doris9Trim2ImplILb0ELb1ENS_11NameRTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
904
1
    static DataTypes get_variadic_argument_types() {
905
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
906
1
    }
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
76
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE6createEv
Line
Count
Source
958
30
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE6createEv
Line
Count
Source
958
14
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE6createEv
Line
Count
Source
958
14
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE6createEv
Line
Count
Source
958
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE6createEv
Line
Count
Source
958
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE6createEv
Line
Count
Source
958
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE6createEv
Line
Count
Source
958
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE6createEv
Line
Count
Source
958
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE6createEv
Line
Count
Source
958
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE6createEv
Line
Count
Source
958
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE6createEv
Line
Count
Source
958
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE6createEv
Line
Count
Source
958
2
    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
52
    size_t get_number_of_arguments() const override {
962
52
        return get_variadic_argument_types_impl().size();
963
52
    }
_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
12
    size_t get_number_of_arguments() const override {
962
12
        return get_variadic_argument_types_impl().size();
963
12
    }
_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
52
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
966
52
        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
52
        return arguments[0];
972
52
    }
_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
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
    }
_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
102
    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
23
    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
64
    DataTypes get_variadic_argument_types_impl() const override {
977
64
        return impl::get_variadic_argument_types();
978
64
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
29
    DataTypes get_variadic_argument_types_impl() const override {
977
29
        return impl::get_variadic_argument_types();
978
29
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
13
    DataTypes get_variadic_argument_types_impl() const override {
977
13
        return impl::get_variadic_argument_types();
978
13
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
13
    DataTypes get_variadic_argument_types_impl() const override {
977
13
        return impl::get_variadic_argument_types();
978
13
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
1
    DataTypes get_variadic_argument_types_impl() const override {
977
1
        return impl::get_variadic_argument_types();
978
1
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
1
    DataTypes get_variadic_argument_types_impl() const override {
977
1
        return impl::get_variadic_argument_types();
978
1
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
1
    DataTypes get_variadic_argument_types_impl() const override {
977
1
        return impl::get_variadic_argument_types();
978
1
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
1
    DataTypes get_variadic_argument_types_impl() const override {
977
1
        return impl::get_variadic_argument_types();
978
1
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
1
    DataTypes get_variadic_argument_types_impl() const override {
977
1
        return impl::get_variadic_argument_types();
978
1
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
1
    DataTypes get_variadic_argument_types_impl() const override {
977
1
        return impl::get_variadic_argument_types();
978
1
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
1
    DataTypes get_variadic_argument_types_impl() const override {
977
1
        return impl::get_variadic_argument_types();
978
1
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
1
    DataTypes get_variadic_argument_types_impl() const override {
977
1
        return impl::get_variadic_argument_types();
978
1
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
976
1
    DataTypes get_variadic_argument_types_impl() const override {
977
1
        return impl::get_variadic_argument_types();
978
1
    }
979
980
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
981
50
                        uint32_t result, size_t input_rows_count) const override {
982
50
        return impl::execute(context, block, arguments, result, input_rows_count);
983
50
    }
_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
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
    }
_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
15
                         ColumnString::Chars& dst_data, ColumnString::Offsets& dst_offsets) {
1003
15
        auto rows_count = offsets.size();
1004
15
        dst_offsets.resize(rows_count);
1005
1006
15
        int64_t total_size = 0;
1007
44
        for (size_t i = 0; i < rows_count; i++) {
1008
29
            size_t len = offsets[i] - offsets[i - 1];
1009
29
            total_size += len / 2;
1010
29
        }
1011
15
        ColumnString::check_chars_length(total_size, rows_count);
1012
15
        dst_data.resize(total_size);
1013
15
        char* dst_data_ptr = reinterpret_cast<char*>(dst_data.data());
1014
15
        size_t offset = 0;
1015
1016
44
        for (int i = 0; i < rows_count; ++i) {
1017
29
            const auto* source = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
1018
29
            ColumnString::Offset srclen = offsets[i] - offsets[i - 1];
1019
1020
29
            if (UNLIKELY(srclen == 0)) {
1021
3
                dst_offsets[i] = cast_set<uint32_t>(offset);
1022
3
                continue;
1023
3
            }
1024
1025
26
            int outlen = string_hex::hex_decode(source, srclen, dst_data_ptr + offset);
1026
1027
26
            offset += outlen;
1028
26
            dst_offsets[i] = cast_set<uint32_t>(offset);
1029
26
        }
1030
15
        dst_data.pop_back(total_size - offset);
1031
15
        return Status::OK();
1032
15
    }
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
12
                         ColumnString::Chars& dst_data, ColumnString::Offsets& dst_offsets) {
1119
12
        auto rows_count = offsets.size();
1120
12
        dst_offsets.resize(rows_count);
1121
1122
12
        size_t total_size = 0;
1123
34
        for (size_t i = 0; i < rows_count; i++) {
1124
22
            size_t len = offsets[i] - offsets[i - 1];
1125
22
            total_size += 4 * ((len + 2) / 3);
1126
22
        }
1127
12
        ColumnString::check_chars_length(total_size, rows_count);
1128
12
        dst_data.resize(total_size);
1129
12
        auto* dst_data_ptr = dst_data.data();
1130
12
        size_t offset = 0;
1131
1132
34
        for (int i = 0; i < rows_count; ++i) {
1133
22
            const auto* source = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
1134
22
            size_t srclen = offsets[i] - offsets[i - 1];
1135
1136
22
            if (UNLIKELY(srclen == 0)) {
1137
4
                dst_offsets[i] = cast_set<uint32_t>(offset);
1138
4
                continue;
1139
4
            }
1140
1141
18
            auto outlen = doris::base64_encode((const unsigned char*)source, srclen,
1142
18
                                               (unsigned char*)(dst_data_ptr + offset));
1143
1144
18
            offset += outlen;
1145
18
            dst_offsets[i] = cast_set<uint32_t>(offset);
1146
18
        }
1147
12
        dst_data.pop_back(total_size - offset);
1148
12
        return Status::OK();
1149
12
    }
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
9
                         NullMap& null_map) {
1160
9
        auto rows_count = offsets.size();
1161
9
        dst_offsets.resize(rows_count);
1162
1163
9
        size_t total_size = 0;
1164
26
        for (size_t i = 0; i < rows_count; i++) {
1165
17
            auto len = offsets[i] - offsets[i - 1];
1166
17
            total_size += len / 4 * 3;
1167
17
        }
1168
9
        ColumnString::check_chars_length(total_size, rows_count);
1169
9
        dst_data.resize(total_size);
1170
9
        char* dst_data_ptr = reinterpret_cast<char*>(dst_data.data());
1171
9
        size_t offset = 0;
1172
1173
26
        for (int i = 0; i < rows_count; ++i) {
1174
17
            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
17
            const auto* source = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
1181
17
            ColumnString::Offset srclen = offsets[i] - offsets[i - 1];
1182
1183
17
            if (UNLIKELY(srclen == 0)) {
1184
3
                dst_offsets[i] = cast_set<uint32_t>(offset);
1185
3
                continue;
1186
3
            }
1187
1188
14
            auto outlen = base64_decode(source, srclen, dst_data_ptr + offset);
1189
1190
14
            if (outlen < 0) {
1191
6
                null_map[i] = 1;
1192
6
                dst_offsets[i] = cast_set<uint32_t>(offset);
1193
8
            } else {
1194
8
                offset += outlen;
1195
8
                dst_offsets[i] = cast_set<uint32_t>(offset);
1196
8
            }
1197
14
        }
1198
9
        dst_data.pop_back(total_size - offset);
1199
9
        return Status::OK();
1200
9
    }
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
24
    static bool str_end_with(const StringRef& str, const StringRef& end) {
1211
24
        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
16
        return str.end_with(end);
1216
24
    }
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
8
                              NullMap& null_map_data) {
1255
8
        size_t input_rows_count = loffsets.size();
1256
8
        res_offsets.resize(input_rows_count);
1257
8
        fmt::memory_buffer buffer;
1258
        // The iterate_utf8_with_limit_length function iterates over a maximum of two UTF-8 characters.
1259
8
        auto [byte_len, char_len] =
1260
8
                simd::VStringFunctions::iterate_utf8_with_limit_length(rstr.begin(), rstr.end(), 2);
1261
8
        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
12
        for (size_t i = 0; i < input_rows_count; ++i) {
1269
6
            buffer.clear();
1270
6
            StringRef lstr = StringRef(reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]),
1271
6
                                       loffsets[i] - loffsets[i - 1]);
1272
1273
6
            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
4
            buffer.append(lstr.begin(), lstr.end());
1279
4
            buffer.append(rstr.begin(), rstr.end());
1280
4
            StringOP::push_value_string(std::string_view(buffer.data(), buffer.size()), i, res_data,
1281
4
                                        res_offsets);
1282
4
        }
1283
6
    }
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
1
void register_function_string(SimpleFunctionFactory& factory) {
1382
1
    register_function_string_basic(factory);
1383
1
    register_function_string_digest(factory);
1384
1
    register_function_string_mask(factory);
1385
1
    register_function_string_misc(factory);
1386
1
    register_function_string_search(factory);
1387
1
    register_function_string_url(factory);
1388
1389
1
    factory.register_function<FunctionStringParseDataSize>();
1390
1
    factory.register_function<FunctionStringASCII>();
1391
1
    factory.register_function<FunctionStringLength>();
1392
1
    factory.register_function<FunctionCrc32>();
1393
1
    factory.register_function<FunctionStringUTF8Length>();
1394
1
    factory.register_function<FunctionStringSpace>();
1395
1
    factory.register_function<FunctionStringStartsWith>();
1396
1
    factory.register_function<FunctionStringEndsWith>();
1397
1
    factory.register_function<FunctionStringInstr>();
1398
1
    factory.register_function<FunctionStringFindInSet>();
1399
1
    factory.register_function<FunctionStringLocate>();
1400
1
    factory.register_function<FunctionQuote>();
1401
1
    factory.register_function<FunctionReverseCommon>();
1402
1
    factory.register_function<FunctionUnHex>();
1403
1
    factory.register_function<FunctionUnHexNullable>();
1404
1
    factory.register_function<FunctionToLower>();
1405
1
    factory.register_function<FunctionToUpper>();
1406
1
    factory.register_function<FunctionToInitcap>();
1407
1
    factory.register_function<FunctionTrim<Trim1Impl<true, true, NameTrim>>>();
1408
1
    factory.register_function<FunctionTrim<Trim1Impl<true, false, NameLTrim>>>();
1409
1
    factory.register_function<FunctionTrim<Trim1Impl<false, true, NameRTrim>>>();
1410
1
    factory.register_function<FunctionTrim<Trim2Impl<true, true, NameTrim>>>();
1411
1
    factory.register_function<FunctionTrim<Trim2Impl<true, false, NameLTrim>>>();
1412
1
    factory.register_function<FunctionTrim<Trim2Impl<false, true, NameRTrim>>>();
1413
1
    factory.register_function<FunctionTrim<Trim1Impl<true, true, NameTrimIn>>>();
1414
1
    factory.register_function<FunctionTrim<Trim1Impl<true, false, NameLTrimIn>>>();
1415
1
    factory.register_function<FunctionTrim<Trim1Impl<false, true, NameRTrimIn>>>();
1416
1
    factory.register_function<FunctionTrim<Trim2Impl<true, true, NameTrimIn>>>();
1417
1
    factory.register_function<FunctionTrim<Trim2Impl<true, false, NameLTrimIn>>>();
1418
1
    factory.register_function<FunctionTrim<Trim2Impl<false, true, NameRTrimIn>>>();
1419
1
    factory.register_function<FunctionStringConcat>();
1420
1
    factory.register_function<FunctionStringElt>();
1421
1
    factory.register_function<FunctionStringConcatWs>();
1422
1
    factory.register_function<FunctionStringAppendTrailingCharIfAbsent>();
1423
1
    factory.register_function<FunctionStringRepeat>();
1424
1
    factory.register_function<FunctionStringLPad>();
1425
1
    factory.register_function<FunctionStringRPad>();
1426
1
    factory.register_function<FunctionToBase64>();
1427
1
    factory.register_function<FunctionFromBase64>();
1428
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDoubleImpl>>();
1429
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatInt64Impl>>();
1430
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatInt128Impl>>();
1431
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMALV2>>>();
1432
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMAL32>>>();
1433
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMAL64>>>();
1434
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMAL128I>>>();
1435
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMAL256>>>();
1436
1
    factory.register_function<FunctionStringFormatRound<FormatRoundDoubleImpl>>();
1437
1
    factory.register_function<FunctionStringFormatRound<FormatRoundInt64Impl>>();
1438
1
    factory.register_function<FunctionStringFormatRound<FormatRoundInt128Impl>>();
1439
1
    factory.register_function<FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMALV2>>>();
1440
1
    factory.register_function<FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMAL32>>>();
1441
1
    factory.register_function<FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMAL64>>>();
1442
1
    factory.register_function<
1443
1
            FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMAL128I>>>();
1444
1
    factory.register_function<FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMAL256>>>();
1445
1
    factory.register_function<FunctionReplace<ReplaceImpl, true>>();
1446
1
    factory.register_function<FunctionReplace<ReplaceEmptyImpl, false>>();
1447
1
    factory.register_function<FunctionSubReplace<SubReplaceThreeImpl>>();
1448
1
    factory.register_function<FunctionSubReplace<SubReplaceFourImpl>>();
1449
1
    factory.register_function<FunctionOverlay>();
1450
1
    factory.register_function<FunctionIsValidUTF8>();
1451
1452
1
    factory.register_alias(FunctionIsValidUTF8::name, "isValidUTF8");
1453
1
    factory.register_alias(FunctionToLower::name, "lcase");
1454
1
    factory.register_alias(FunctionToUpper::name, "ucase");
1455
1
    factory.register_alias(FunctionStringUTF8Length::name, "character_length");
1456
1
    factory.register_alias(FunctionStringLength::name, "octet_length");
1457
1
    factory.register_alias(FunctionOverlay::name, "insert");
1458
1
}
1459
1460
} // namespace doris