Coverage Report

Created: 2026-07-03 18:10

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
11
                         PaddedPODArray<Int32>& res) {
70
11
        auto size = offsets.size();
71
11
        res.resize(size);
72
32
        for (int i = 0; i < size; ++i) {
73
21
            const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
74
21
            res[i] = (offsets[i] == offsets[i - 1]) ? 0 : static_cast<uint8_t>(raw_str[0]);
75
21
        }
76
11
        return Status::OK();
77
11
    }
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
32
                         PaddedPODArray<Int32>& res) {
182
32
        auto size = offsets.size();
183
32
        res.resize(size);
184
96
        for (int i = 0; i < size; ++i) {
185
64
            int str_size = offsets[i] - offsets[i - 1];
186
64
            res[i] = str_size;
187
64
        }
188
32
        return Status::OK();
189
32
    }
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
11
                         PaddedPODArray<Int32>& res) {
226
11
        auto size = offsets.size();
227
11
        res.resize(size);
228
32
        for (int i = 0; i < size; ++i) {
229
21
            const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
230
21
            int str_size = offsets[i] - offsets[i - 1];
231
21
            res[i] = simd::VStringFunctions::get_char_len(raw_str, str_size);
232
21
        }
233
11
        return Status::OK();
234
11
    }
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
18
    static void execute(const std::string_view& strl, const std::string_view& strr, uint8_t& res) {
269
18
        res = strl.starts_with(strr);
270
18
    }
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
62
    static void execute(const std::string_view& strl, const std::string_view& strr, uint8_t& res) {
282
62
        res = strl.ends_with(strr);
283
62
    }
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
73
    static void execute(const std::string_view& strl, const std::string_view& strr, int32_t& res) {
294
85
        for (const auto& c : strl) {
295
85
            if (c == ',') {
296
17
                res = 0;
297
17
                return;
298
17
            }
299
85
        }
300
301
56
        int32_t token_index = 1;
302
56
        int32_t start = 0;
303
56
        int32_t end;
304
305
122
        do {
306
122
            end = start;
307
            // Position end.
308
177
            while (end < strr.length() && strr[end] != ',') {
309
55
                ++end;
310
55
            }
311
312
122
            if (strl == std::string_view {strr.data() + start, (size_t)end - start}) {
313
25
                res = token_index;
314
25
                return;
315
25
            }
316
317
            // Re-position start and end past ','
318
97
            start = end + 1;
319
97
            ++token_index;
320
97
        } while (start < strr.length());
321
31
        res = 0;
322
31
    }
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
72
                                ResultPaddedPODArray& res) {
356
72
        auto size = loffsets.size();
357
72
        res.resize(size);
358
359
72
        if (rdata.size == 0) {
360
12
            std::fill(res.begin(), res.end(), 1);
361
12
            return Status::OK();
362
12
        }
363
364
60
        const UInt8* begin = ldata.data();
365
60
        const UInt8* end = begin + ldata.size();
366
60
        const UInt8* pos = begin;
367
368
        /// Current index in the array of strings.
369
60
        size_t i = 0;
370
60
        std::fill(res.begin(), res.end(), 0);
371
372
60
        StringRef rstr_ref(rdata.data, rdata.size);
373
60
        StringSearch search(&rstr_ref);
374
375
76
        while (pos < end) {
376
            // search return matched substring start offset
377
50
            pos = (UInt8*)search.search((char*)pos, end - pos);
378
50
            if (pos >= end) {
379
34
                break;
380
34
            }
381
382
            /// Determine which index it refers to.
383
            /// begin + value_offsets[i] is the start offset of string at i+1
384
16
            while (begin + loffsets[i] < pos) {
385
0
                ++i;
386
0
            }
387
388
            /// We check that the entry does not pass through the boundaries of strings.
389
16
            if (pos + rdata.size <= begin + loffsets[i]) {
390
16
                int loc = (int)(pos - begin) - loffsets[i - 1];
391
16
                int l_str_size = loffsets[i] - loffsets[i - 1];
392
16
                auto len = std::min(l_str_size, loc);
393
16
                loc = simd::VStringFunctions::get_char_len((char*)(begin + loffsets[i - 1]), len);
394
16
                res[i] = loc + 1;
395
16
            }
396
397
            // move to next string offset
398
16
            pos = begin + loffsets[i];
399
16
            ++i;
400
16
        }
401
402
60
        return Status::OK();
403
72
    }
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
36
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
458
36
        return StringInStrImpl<LeftDataType, RightDataType>::vector_scalar(rdata, roffsets, ldata,
459
36
                                                                           res);
460
36
    }
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
34
                                ResultPaddedPODArray& res) {
509
34
        auto size = loffsets.size();
510
34
        res.resize(size);
511
34
        std::string_view rview(rdata.data, rdata.size);
512
68
        for (int i = 0; i < size; ++i) {
513
34
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
514
34
            int l_str_size = loffsets[i] - loffsets[i - 1];
515
34
            std::string_view lview(l_raw_str, l_str_size);
516
517
34
            OP::execute(lview, rview, res[i]);
518
34
        }
519
34
        return Status::OK();
520
34
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_12StartsWithOpEE13vector_scalarERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEERKNS_9StringRefERS8_
Line
Count
Source
508
4
                                ResultPaddedPODArray& res) {
509
4
        auto size = loffsets.size();
510
4
        res.resize(size);
511
4
        std::string_view rview(rdata.data, rdata.size);
512
8
        for (int i = 0; i < size; ++i) {
513
4
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
514
4
            int l_str_size = loffsets[i] - loffsets[i - 1];
515
4
            std::string_view lview(l_raw_str, l_str_size);
516
517
4
            OP::execute(lview, rview, res[i]);
518
4
        }
519
4
        return Status::OK();
520
4
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_10EndsWithOpEE13vector_scalarERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEERKNS_9StringRefERS8_
Line
Count
Source
508
14
                                ResultPaddedPODArray& res) {
509
14
        auto size = loffsets.size();
510
14
        res.resize(size);
511
14
        std::string_view rview(rdata.data, rdata.size);
512
28
        for (int i = 0; i < size; ++i) {
513
14
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
514
14
            int l_str_size = loffsets[i] - loffsets[i - 1];
515
14
            std::string_view lview(l_raw_str, l_str_size);
516
517
14
            OP::execute(lview, rview, res[i]);
518
14
        }
519
14
        return Status::OK();
520
14
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_11FindInSetOpEE13vector_scalarERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEERKNS_9StringRefERNS4_IiLm4096ES7_Lm16ELm15EEE
Line
Count
Source
508
16
                                ResultPaddedPODArray& res) {
509
16
        auto size = loffsets.size();
510
16
        res.resize(size);
511
16
        std::string_view rview(rdata.data, rdata.size);
512
32
        for (int i = 0; i < size; ++i) {
513
16
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
514
16
            int l_str_size = loffsets[i] - loffsets[i - 1];
515
16
            std::string_view lview(l_raw_str, l_str_size);
516
517
16
            OP::execute(lview, rview, res[i]);
518
16
        }
519
16
        return Status::OK();
520
16
    }
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
82
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
549
82
        size_t offset_size = offsets.size();
550
82
        if (UNLIKELY(!offset_size)) {
551
0
            return Status::OK();
552
0
        }
553
554
82
        const bool is_ascii = simd::VStringFunctions::is_ascii({data.data(), data.size()});
555
82
        res_offsets.resize(offset_size);
556
82
        if (is_ascii) {
557
36
            memcpy_small_allow_read_write_overflow15(
558
36
                    res_offsets.data(), offsets.data(),
559
36
                    offset_size * sizeof(ColumnString::Offsets::value_type));
560
561
36
            size_t data_length = data.size();
562
36
            res_data.resize(data_length);
563
36
            if constexpr (std::is_same_v<OpName, NameToUpper>) {
564
22
                simd::VStringFunctions::to_upper(data.data(), data_length, res_data.data());
565
22
            } else if constexpr (std::is_same_v<OpName, NameToLower>) {
566
14
                simd::VStringFunctions::to_lower(data.data(), data_length, res_data.data());
567
14
            }
568
46
        } else {
569
46
            execute_utf8(data, offsets, res_data, res_offsets);
570
46
        }
571
572
82
        return Status::OK();
573
82
    }
_ZN5doris12TransferImplINS_11NameToLowerEE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS3_IjLm4096ES6_Lm16ELm15EEERS7_RSA_
Line
Count
Source
548
28
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
549
28
        size_t offset_size = offsets.size();
550
28
        if (UNLIKELY(!offset_size)) {
551
0
            return Status::OK();
552
0
        }
553
554
28
        const bool is_ascii = simd::VStringFunctions::is_ascii({data.data(), data.size()});
555
28
        res_offsets.resize(offset_size);
556
28
        if (is_ascii) {
557
14
            memcpy_small_allow_read_write_overflow15(
558
14
                    res_offsets.data(), offsets.data(),
559
14
                    offset_size * sizeof(ColumnString::Offsets::value_type));
560
561
14
            size_t data_length = data.size();
562
14
            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
14
            } else if constexpr (std::is_same_v<OpName, NameToLower>) {
566
14
                simd::VStringFunctions::to_lower(data.data(), data_length, res_data.data());
567
14
            }
568
14
        } else {
569
14
            execute_utf8(data, offsets, res_data, res_offsets);
570
14
        }
571
572
28
        return Status::OK();
573
28
    }
_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
50
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
726
50
        const size_t offset_size = str_offsets.size();
727
50
        res_offsets.resize(offset_size);
728
50
        res_data.reserve(str_data.size());
729
146
        for (size_t i = 0; i < offset_size; ++i) {
730
96
            const auto* str_begin = str_data.data() + str_offsets[i - 1];
731
96
            const auto* str_end = str_data.data() + str_offsets[i];
732
733
96
            if constexpr (is_ltrim) {
734
75
                str_begin =
735
75
                        simd::VStringFunctions::ltrim<trim_single>(str_begin, str_end, remove_str);
736
75
            }
737
96
            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
96
            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
96
            res_offsets[i] = (ColumnString::Offset)res_data.size();
745
96
        }
746
50
        return Status::OK();
747
50
    }
_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
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
21
            if constexpr (is_ltrim) {
734
21
                str_begin =
735
21
                        simd::VStringFunctions::ltrim<trim_single>(str_begin, str_end, remove_str);
736
21
            }
737
            if constexpr (is_rtrim) {
738
                str_end =
739
                        simd::VStringFunctions::rtrim<trim_single>(str_begin, str_end, remove_str);
740
            }
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
    }
_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
58
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb1ELb1ENS_8NameTrimEE27get_variadic_argument_typesEv
Line
Count
Source
885
29
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb1ELb0ENS_9NameLTrimEE27get_variadic_argument_typesEv
Line
Count
Source
885
13
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb0ELb1ENS_9NameRTrimEE27get_variadic_argument_typesEv
Line
Count
Source
885
13
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb1ELb1ENS_10NameTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
885
1
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb1ELb0ENS_11NameLTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
885
1
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb0ELb1ENS_11NameRTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
885
1
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
886
887
    static Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
888
50
                          uint32_t result, size_t input_rows_count) {
889
50
        const ColumnPtr column = block.get_by_position(arguments[0]).column;
890
50
        if (const auto* col = assert_cast<const ColumnString*>(column.get())) {
891
50
            auto col_res = ColumnString::create();
892
50
            char blank[] = " ";
893
50
            const StringRef remove_str(blank, 1);
894
50
            RETURN_IF_ERROR((TrimUtil<is_ltrim, is_rtrim, true>::vector(
895
50
                    col->get_chars(), col->get_offsets(), remove_str, col_res->get_chars(),
896
50
                    col_res->get_offsets())));
897
50
            block.replace_by_position(result, std::move(col_res));
898
50
        } 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
50
        return Status::OK();
904
50
    }
_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
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
    }
_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
6
    static DataTypes get_variadic_argument_types() {
913
6
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
914
6
    }
_ZN5doris9Trim2ImplILb1ELb1ENS_8NameTrimEE27get_variadic_argument_typesEv
Line
Count
Source
912
1
    static DataTypes get_variadic_argument_types() {
913
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
914
1
    }
_ZN5doris9Trim2ImplILb1ELb0ENS_9NameLTrimEE27get_variadic_argument_typesEv
Line
Count
Source
912
1
    static DataTypes get_variadic_argument_types() {
913
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
914
1
    }
_ZN5doris9Trim2ImplILb0ELb1ENS_9NameRTrimEE27get_variadic_argument_typesEv
Line
Count
Source
912
1
    static DataTypes get_variadic_argument_types() {
913
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
914
1
    }
_ZN5doris9Trim2ImplILb1ELb1ENS_10NameTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
912
1
    static DataTypes get_variadic_argument_types() {
913
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
914
1
    }
_ZN5doris9Trim2ImplILb1ELb0ENS_11NameLTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
912
1
    static DataTypes get_variadic_argument_types() {
913
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
914
1
    }
_ZN5doris9Trim2ImplILb0ELb1ENS_11NameRTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
912
1
    static DataTypes get_variadic_argument_types() {
913
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
914
1
    }
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
76
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE6createEv
Line
Count
Source
966
30
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE6createEv
Line
Count
Source
966
14
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE6createEv
Line
Count
Source
966
14
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE6createEv
Line
Count
Source
966
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE6createEv
Line
Count
Source
966
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE6createEv
Line
Count
Source
966
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE6createEv
Line
Count
Source
966
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE6createEv
Line
Count
Source
966
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE6createEv
Line
Count
Source
966
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE6createEv
Line
Count
Source
966
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE6createEv
Line
Count
Source
966
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE6createEv
Line
Count
Source
966
2
    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
52
    size_t get_number_of_arguments() const override {
970
52
        return get_variadic_argument_types_impl().size();
971
52
    }
_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
12
    size_t get_number_of_arguments() const override {
970
12
        return get_variadic_argument_types_impl().size();
971
12
    }
_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
52
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
974
52
        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
52
        return arguments[0];
980
52
    }
_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
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
    }
_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
102
    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
23
    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
64
    DataTypes get_variadic_argument_types_impl() const override {
985
64
        return impl::get_variadic_argument_types();
986
64
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
984
29
    DataTypes get_variadic_argument_types_impl() const override {
985
29
        return impl::get_variadic_argument_types();
986
29
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
984
13
    DataTypes get_variadic_argument_types_impl() const override {
985
13
        return impl::get_variadic_argument_types();
986
13
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
984
13
    DataTypes get_variadic_argument_types_impl() const override {
985
13
        return impl::get_variadic_argument_types();
986
13
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
984
1
    DataTypes get_variadic_argument_types_impl() const override {
985
1
        return impl::get_variadic_argument_types();
986
1
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
984
1
    DataTypes get_variadic_argument_types_impl() const override {
985
1
        return impl::get_variadic_argument_types();
986
1
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
984
1
    DataTypes get_variadic_argument_types_impl() const override {
985
1
        return impl::get_variadic_argument_types();
986
1
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
984
1
    DataTypes get_variadic_argument_types_impl() const override {
985
1
        return impl::get_variadic_argument_types();
986
1
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
984
1
    DataTypes get_variadic_argument_types_impl() const override {
985
1
        return impl::get_variadic_argument_types();
986
1
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
984
1
    DataTypes get_variadic_argument_types_impl() const override {
985
1
        return impl::get_variadic_argument_types();
986
1
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
984
1
    DataTypes get_variadic_argument_types_impl() const override {
985
1
        return impl::get_variadic_argument_types();
986
1
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
984
1
    DataTypes get_variadic_argument_types_impl() const override {
985
1
        return impl::get_variadic_argument_types();
986
1
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
984
1
    DataTypes get_variadic_argument_types_impl() const override {
985
1
        return impl::get_variadic_argument_types();
986
1
    }
987
988
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
989
50
                        uint32_t result, size_t input_rows_count) const override {
990
50
        return impl::execute(context, block, arguments, result, input_rows_count);
991
50
    }
_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
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
    }
_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
15
                         ColumnString::Chars& dst_data, ColumnString::Offsets& dst_offsets) {
1011
15
        auto rows_count = offsets.size();
1012
15
        dst_offsets.resize(rows_count);
1013
1014
15
        int64_t total_size = 0;
1015
44
        for (size_t i = 0; i < rows_count; i++) {
1016
29
            size_t len = offsets[i] - offsets[i - 1];
1017
29
            total_size += len / 2;
1018
29
        }
1019
15
        ColumnString::check_chars_length(total_size, rows_count);
1020
15
        dst_data.resize(total_size);
1021
15
        char* dst_data_ptr = reinterpret_cast<char*>(dst_data.data());
1022
15
        size_t offset = 0;
1023
1024
44
        for (int i = 0; i < rows_count; ++i) {
1025
29
            const auto* source = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
1026
29
            ColumnString::Offset srclen = offsets[i] - offsets[i - 1];
1027
1028
29
            if (UNLIKELY(srclen == 0)) {
1029
3
                dst_offsets[i] = cast_set<uint32_t>(offset);
1030
3
                continue;
1031
3
            }
1032
1033
26
            int outlen = string_hex::hex_decode(source, srclen, dst_data_ptr + offset);
1034
1035
26
            offset += outlen;
1036
26
            dst_offsets[i] = cast_set<uint32_t>(offset);
1037
26
        }
1038
15
        dst_data.pop_back(total_size - offset);
1039
15
        return Status::OK();
1040
15
    }
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
12
                         ColumnString::Chars& dst_data, ColumnString::Offsets& dst_offsets) {
1127
12
        auto rows_count = offsets.size();
1128
12
        dst_offsets.resize(rows_count);
1129
1130
12
        size_t total_size = 0;
1131
34
        for (size_t i = 0; i < rows_count; i++) {
1132
22
            size_t len = offsets[i] - offsets[i - 1];
1133
22
            total_size += 4 * ((len + 2) / 3);
1134
22
        }
1135
12
        ColumnString::check_chars_length(total_size, rows_count);
1136
12
        dst_data.resize(total_size);
1137
12
        auto* dst_data_ptr = dst_data.data();
1138
12
        size_t offset = 0;
1139
1140
34
        for (int i = 0; i < rows_count; ++i) {
1141
22
            const auto* source = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
1142
22
            size_t srclen = offsets[i] - offsets[i - 1];
1143
1144
22
            if (UNLIKELY(srclen == 0)) {
1145
4
                dst_offsets[i] = cast_set<uint32_t>(offset);
1146
4
                continue;
1147
4
            }
1148
1149
18
            auto outlen = doris::base64_encode((const unsigned char*)source, srclen,
1150
18
                                               (unsigned char*)(dst_data_ptr + offset));
1151
1152
18
            offset += outlen;
1153
18
            dst_offsets[i] = cast_set<uint32_t>(offset);
1154
18
        }
1155
12
        dst_data.pop_back(total_size - offset);
1156
12
        return Status::OK();
1157
12
    }
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
12
                         NullMap& null_map) {
1168
12
        auto rows_count = offsets.size();
1169
12
        dst_offsets.resize(rows_count);
1170
1171
12
        size_t total_size = 0;
1172
35
        for (size_t i = 0; i < rows_count; i++) {
1173
23
            auto len = offsets[i] - offsets[i - 1];
1174
23
            total_size += len / 4 * 3;
1175
23
        }
1176
12
        ColumnString::check_chars_length(total_size, rows_count);
1177
12
        dst_data.resize(total_size);
1178
12
        char* dst_data_ptr = reinterpret_cast<char*>(dst_data.data());
1179
12
        size_t offset = 0;
1180
1181
35
        for (int i = 0; i < rows_count; ++i) {
1182
23
            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
23
            const auto* source = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
1189
23
            ColumnString::Offset srclen = offsets[i] - offsets[i - 1];
1190
1191
23
            if (UNLIKELY(srclen == 0)) {
1192
3
                dst_offsets[i] = cast_set<uint32_t>(offset);
1193
3
                continue;
1194
3
            }
1195
1196
20
            if (UNLIKELY(srclen % 4 != 0)) {
1197
8
                null_map[i] = 1;
1198
8
                dst_offsets[i] = cast_set<uint32_t>(offset);
1199
8
                continue;
1200
8
            }
1201
1202
12
            auto outlen = base64_decode(source, srclen, dst_data_ptr + offset);
1203
1204
12
            if (outlen < 0) {
1205
4
                null_map[i] = 1;
1206
4
                dst_offsets[i] = cast_set<uint32_t>(offset);
1207
8
            } else {
1208
8
                offset += outlen;
1209
8
                dst_offsets[i] = cast_set<uint32_t>(offset);
1210
8
            }
1211
12
        }
1212
12
        dst_data.pop_back(total_size - offset);
1213
12
        return Status::OK();
1214
12
    }
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
24
    static bool str_end_with(const StringRef& str, const StringRef& end) {
1225
24
        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
16
        return str.end_with(end);
1230
24
    }
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
8
                              NullMap& null_map_data) {
1269
8
        size_t input_rows_count = loffsets.size();
1270
8
        res_offsets.resize(input_rows_count);
1271
8
        fmt::memory_buffer buffer;
1272
        // The iterate_utf8_with_limit_length function iterates over a maximum of two UTF-8 characters.
1273
8
        auto [byte_len, char_len] =
1274
8
                simd::VStringFunctions::iterate_utf8_with_limit_length(rstr.begin(), rstr.end(), 2);
1275
8
        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
12
        for (size_t i = 0; i < input_rows_count; ++i) {
1283
6
            buffer.clear();
1284
6
            StringRef lstr = StringRef(reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]),
1285
6
                                       loffsets[i] - loffsets[i - 1]);
1286
1287
6
            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
4
            buffer.append(lstr.begin(), lstr.end());
1293
4
            buffer.append(rstr.begin(), rstr.end());
1294
4
            StringOP::push_value_string(std::string_view(buffer.data(), buffer.size()), i, res_data,
1295
4
                                        res_offsets);
1296
4
        }
1297
6
    }
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
24
    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
1
void register_function_string(SimpleFunctionFactory& factory) {
1475
1
    register_function_string_basic(factory);
1476
1
    register_function_string_digest(factory);
1477
1
    register_function_string_mask(factory);
1478
1
    register_function_string_misc(factory);
1479
1
    register_function_string_search(factory);
1480
1
    register_function_string_url(factory);
1481
1482
1
    factory.register_function<FunctionStringParseDataSize>();
1483
1
    factory.register_function<FunctionStringASCII>();
1484
1
    factory.register_function<FunctionStringLength>();
1485
1
    factory.register_function<FunctionCrc32>();
1486
1
    factory.register_function<FunctionStringUTF8Length>();
1487
1
    factory.register_function<FunctionStringSpace>();
1488
1
    factory.register_function<FunctionStringStartsWith>();
1489
1
    factory.register_function<FunctionStringEndsWith>();
1490
1
    factory.register_function<FunctionStringInstr>();
1491
1
    factory.register_function<FunctionStringFindInSet>();
1492
1
    factory.register_function<FunctionStringLocate>();
1493
1
    factory.register_function<FunctionQuote>();
1494
1
    factory.register_function<FunctionReverseCommon>();
1495
1
    factory.register_function<FunctionUnHex>();
1496
1
    factory.register_function<FunctionUnHexNullable>();
1497
1
    factory.register_function<FunctionToLower>();
1498
1
    factory.register_function<FunctionToUpper>();
1499
1
    factory.register_function<FunctionToInitcap>();
1500
1
    factory.register_function<FunctionTrim<Trim1Impl<true, true, NameTrim>>>();
1501
1
    factory.register_function<FunctionTrim<Trim1Impl<true, false, NameLTrim>>>();
1502
1
    factory.register_function<FunctionTrim<Trim1Impl<false, true, NameRTrim>>>();
1503
1
    factory.register_function<FunctionTrim<Trim2Impl<true, true, NameTrim>>>();
1504
1
    factory.register_function<FunctionTrim<Trim2Impl<true, false, NameLTrim>>>();
1505
1
    factory.register_function<FunctionTrim<Trim2Impl<false, true, NameRTrim>>>();
1506
1
    factory.register_function<FunctionTrim<Trim1Impl<true, true, NameTrimIn>>>();
1507
1
    factory.register_function<FunctionTrim<Trim1Impl<true, false, NameLTrimIn>>>();
1508
1
    factory.register_function<FunctionTrim<Trim1Impl<false, true, NameRTrimIn>>>();
1509
1
    factory.register_function<FunctionTrim<Trim2Impl<true, true, NameTrimIn>>>();
1510
1
    factory.register_function<FunctionTrim<Trim2Impl<true, false, NameLTrimIn>>>();
1511
1
    factory.register_function<FunctionTrim<Trim2Impl<false, true, NameRTrimIn>>>();
1512
1
    factory.register_function<FunctionStringConcat>();
1513
1
    factory.register_function<FunctionStringElt>();
1514
1
    factory.register_function<FunctionStringConcatWs>();
1515
1
    factory.register_function<FunctionStringAppendTrailingCharIfAbsent>();
1516
1
    factory.register_function<FunctionStringRepeat>();
1517
1
    factory.register_function<FunctionStringLPad>();
1518
1
    factory.register_function<FunctionStringRPad>();
1519
1
    factory.register_function<FunctionToBase64>();
1520
1
    factory.register_function<FunctionFromBase64>();
1521
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDoubleImpl>>();
1522
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatInt64Impl>>();
1523
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatInt128Impl>>();
1524
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMALV2>>>();
1525
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMAL32>>>();
1526
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMAL64>>>();
1527
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMAL128I>>>();
1528
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMAL256>>>();
1529
1
    factory.register_function<FunctionStringFormatRound<FormatRoundDoubleImpl>>();
1530
1
    factory.register_function<FunctionStringFormatRound<FormatRoundInt64Impl>>();
1531
1
    factory.register_function<FunctionStringFormatRound<FormatRoundInt128Impl>>();
1532
1
    factory.register_function<FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMALV2>>>();
1533
1
    factory.register_function<FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMAL32>>>();
1534
1
    factory.register_function<FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMAL64>>>();
1535
1
    factory.register_function<
1536
1
            FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMAL128I>>>();
1537
1
    factory.register_function<FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMAL256>>>();
1538
1
    factory.register_function<FunctionReplace<ReplaceImpl, true>>();
1539
1
    factory.register_function<FunctionReplace<ReplaceEmptyImpl, false>>();
1540
1
    factory.register_function<FunctionSubReplace<SubReplaceThreeImpl>>();
1541
1
    factory.register_function<FunctionSubReplace<SubReplaceFourImpl>>();
1542
1
    factory.register_function<FunctionOverlay>();
1543
1
    factory.register_function<FunctionIsValidUTF8>();
1544
1545
1
    factory.register_alias(FunctionIsValidUTF8::name, "isValidUTF8");
1546
1
    factory.register_alias(FunctionToLower::name, "lcase");
1547
1
    factory.register_alias(FunctionToUpper::name, "ucase");
1548
1
    factory.register_alias(FunctionStringUTF8Length::name, "character_length");
1549
1
    factory.register_alias(FunctionStringLength::name, "octet_length");
1550
1
    factory.register_alias(FunctionOverlay::name, "insert");
1551
1
}
1552
1553
} // namespace doris