Coverage Report

Created: 2026-04-15 18:59

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