Coverage Report

Created: 2026-07-16 17:31

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