Coverage Report

Created: 2026-03-15 17:28

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 "exprs/function/function_string.h"
19
20
#include <ctype.h>
21
#include <math.h>
22
#include <re2/stringpiece.h>
23
#include <unicode/schriter.h>
24
#include <unicode/uchar.h>
25
#include <unicode/unistr.h>
26
#include <unicode/ustream.h>
27
28
#include <bitset>
29
#include <cstddef>
30
#include <cstdint>
31
#include <string_view>
32
33
#include "common/cast_set.h"
34
#include "common/status.h"
35
#include "core/column/column.h"
36
#include "core/column/column_string.h"
37
#include "core/pod_array_fwd.h"
38
#include "core/string_ref.h"
39
#include "exprs/function/function_reverse.h"
40
#include "exprs/function/function_string_to_string.h"
41
#include "exprs/function/function_totype.h"
42
#include "exprs/function/simple_function_factory.h"
43
#include "exprs/function/string_hex_util.h"
44
#include "util/string_search.hpp"
45
#include "util/url_coding.h"
46
47
namespace doris {
48
#include "common/compile_check_begin.h"
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
11
                         PaddedPODArray<Int32>& res) {
61
11
        auto size = offsets.size();
62
11
        res.resize(size);
63
32
        for (int i = 0; i < size; ++i) {
64
21
            const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
65
21
            res[i] = (offsets[i] == offsets[i - 1]) ? 0 : static_cast<uint8_t>(raw_str[0]);
66
21
        }
67
11
        return Status::OK();
68
11
    }
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
12
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
144
12
        size_t offset_size = offsets.size();
145
12
        ColumnString::Offset pos = 0;
146
12
        res_offsets.resize(offset_size);
147
12
        res_data.resize(data.size() + offset_size * 2);
148
35
        for (int i = 0; i < offset_size; i++) {
149
23
            const unsigned char* raw_str = &data[offsets[i - 1]];
150
23
            ColumnString::Offset size = offsets[i] - offsets[i - 1];
151
23
            res_data[pos] = '\'';
152
23
            std::memcpy(res_data.data() + pos + 1, raw_str, size);
153
23
            res_data[pos + size + 1] = '\'';
154
23
            pos += size + 2;
155
23
            res_offsets[i] = pos;
156
23
        }
157
12
        return Status::OK();
158
12
    }
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
32
                         PaddedPODArray<Int32>& res) {
173
32
        auto size = offsets.size();
174
32
        res.resize(size);
175
96
        for (int i = 0; i < size; ++i) {
176
64
            int str_size = offsets[i] - offsets[i - 1];
177
64
            res[i] = str_size;
178
64
        }
179
32
        return Status::OK();
180
32
    }
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
11
                         PaddedPODArray<Int32>& res) {
217
11
        auto size = offsets.size();
218
11
        res.resize(size);
219
32
        for (int i = 0; i < size; ++i) {
220
21
            const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
221
21
            int str_size = offsets[i] - offsets[i - 1];
222
21
            res[i] = simd::VStringFunctions::get_char_len(raw_str, str_size);
223
21
        }
224
11
        return Status::OK();
225
11
    }
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
18
    static void execute(const std::string_view& strl, const std::string_view& strr, uint8_t& res) {
237
18
        res = strl.starts_with(strr);
238
18
    }
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
62
    static void execute(const std::string_view& strl, const std::string_view& strr, uint8_t& res) {
250
62
        res = strl.ends_with(strr);
251
62
    }
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
73
    static void execute(const std::string_view& strl, const std::string_view& strr, int32_t& res) {
262
85
        for (const auto& c : strl) {
263
85
            if (c == ',') {
264
17
                res = 0;
265
17
                return;
266
17
            }
267
85
        }
268
269
56
        int32_t token_index = 1;
270
56
        int32_t start = 0;
271
56
        int32_t end;
272
273
122
        do {
274
122
            end = start;
275
            // Position end.
276
177
            while (end < strr.length() && strr[end] != ',') {
277
55
                ++end;
278
55
            }
279
280
122
            if (strl == std::string_view {strr.data() + start, (size_t)end - start}) {
281
25
                res = token_index;
282
25
                return;
283
25
            }
284
285
            // Re-position start and end past ','
286
97
            start = end + 1;
287
97
            ++token_index;
288
97
        } while (start < strr.length());
289
31
        res = 0;
290
31
    }
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
72
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
305
72
        StringRef lstr_ref(ldata.data, ldata.size);
306
307
72
        auto size = roffsets.size();
308
72
        res.resize(size);
309
144
        for (int i = 0; i < size; ++i) {
310
72
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
311
72
            int r_str_size = roffsets[i] - roffsets[i - 1];
312
313
72
            StringRef rstr_ref(r_raw_str, r_str_size);
314
315
72
            res[i] = execute(lstr_ref, rstr_ref);
316
72
        }
317
318
72
        return Status::OK();
319
72
    }
320
321
    static Status vector_scalar(const ColumnString::Chars& ldata,
322
                                const ColumnString::Offsets& loffsets, const StringRef& rdata,
323
72
                                ResultPaddedPODArray& res) {
324
72
        auto size = loffsets.size();
325
72
        res.resize(size);
326
327
72
        if (rdata.size == 0) {
328
12
            std::fill(res.begin(), res.end(), 1);
329
12
            return Status::OK();
330
12
        }
331
332
60
        const UInt8* begin = ldata.data();
333
60
        const UInt8* end = begin + ldata.size();
334
60
        const UInt8* pos = begin;
335
336
        /// Current index in the array of strings.
337
60
        size_t i = 0;
338
60
        std::fill(res.begin(), res.end(), 0);
339
340
60
        StringRef rstr_ref(rdata.data, rdata.size);
341
60
        StringSearch search(&rstr_ref);
342
343
76
        while (pos < end) {
344
            // search return matched substring start offset
345
50
            pos = (UInt8*)search.search((char*)pos, end - pos);
346
50
            if (pos >= end) {
347
34
                break;
348
34
            }
349
350
            /// Determine which index it refers to.
351
            /// begin + value_offsets[i] is the start offset of string at i+1
352
16
            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
16
            if (pos + rdata.size <= begin + loffsets[i]) {
358
16
                int loc = (int)(pos - begin) - loffsets[i - 1];
359
16
                int l_str_size = loffsets[i] - loffsets[i - 1];
360
16
                auto len = std::min(l_str_size, loc);
361
16
                loc = simd::VStringFunctions::get_char_len((char*)(begin + loffsets[i - 1]), len);
362
16
                res[i] = loc + 1;
363
16
            }
364
365
            // move to next string offset
366
16
            pos = begin + loffsets[i];
367
16
            ++i;
368
16
        }
369
370
60
        return Status::OK();
371
72
    }
372
373
    static Status vector_vector(const ColumnString::Chars& ldata,
374
                                const ColumnString::Offsets& loffsets,
375
                                const ColumnString::Chars& rdata,
376
74
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
377
74
        DCHECK_EQ(loffsets.size(), roffsets.size());
378
379
74
        auto size = loffsets.size();
380
74
        res.resize(size);
381
259
        for (int i = 0; i < size; ++i) {
382
185
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
383
185
            int l_str_size = loffsets[i] - loffsets[i - 1];
384
185
            StringRef lstr_ref(l_raw_str, l_str_size);
385
386
185
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
387
185
            int r_str_size = roffsets[i] - roffsets[i - 1];
388
185
            StringRef rstr_ref(r_raw_str, r_str_size);
389
390
185
            res[i] = execute(lstr_ref, rstr_ref);
391
185
        }
392
393
74
        return Status::OK();
394
74
    }
395
396
257
    static int execute(const StringRef& strl, const StringRef& strr) {
397
257
        if (strr.size == 0) {
398
62
            return 1;
399
62
        }
400
401
195
        StringSearch search(&strr);
402
        // Hive returns positions starting from 1.
403
195
        int loc = search.search(&strl);
404
195
        if (loc > 0) {
405
12
            int len = std::min(loc, (int)strl.size);
406
12
            loc = simd::VStringFunctions::get_char_len(strl.data, len);
407
12
        }
408
409
195
        return loc + 1;
410
257
    }
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
36
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
426
36
        return StringInStrImpl<LeftDataType, RightDataType>::vector_scalar(rdata, roffsets, ldata,
427
36
                                                                           res);
428
36
    }
429
430
    static Status vector_scalar(const ColumnString::Chars& ldata,
431
                                const ColumnString::Offsets& loffsets, const StringRef& rdata,
432
36
                                ResultPaddedPODArray& res) {
433
36
        return StringInStrImpl<LeftDataType, RightDataType>::scalar_vector(rdata, ldata, loffsets,
434
36
                                                                           res);
435
36
    }
436
437
    static Status vector_vector(const ColumnString::Chars& ldata,
438
                                const ColumnString::Offsets& loffsets,
439
                                const ColumnString::Chars& rdata,
440
37
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
441
37
        return StringInStrImpl<LeftDataType, RightDataType>::vector_vector(rdata, roffsets, ldata,
442
37
                                                                           loffsets, res);
443
37
    }
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
37
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
456
37
        DCHECK_EQ(loffsets.size(), roffsets.size());
457
458
37
        auto size = loffsets.size();
459
37
        res.resize(size);
460
122
        for (int i = 0; i < size; ++i) {
461
85
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
462
85
            int l_str_size = loffsets[i] - loffsets[i - 1];
463
464
85
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
465
85
            int r_str_size = roffsets[i] - roffsets[i - 1];
466
467
85
            std::string_view lview(l_raw_str, l_str_size);
468
85
            std::string_view rview(r_raw_str, r_str_size);
469
470
85
            OP::execute(lview, rview, res[i]);
471
85
        }
472
37
        return Status::OK();
473
37
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_12StartsWithOpEE13vector_vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEESA_SD_RS8_
Line
Count
Source
455
5
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
456
5
        DCHECK_EQ(loffsets.size(), roffsets.size());
457
458
5
        auto size = loffsets.size();
459
5
        res.resize(size);
460
15
        for (int i = 0; i < size; ++i) {
461
10
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
462
10
            int l_str_size = loffsets[i] - loffsets[i - 1];
463
464
10
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
465
10
            int r_str_size = roffsets[i] - roffsets[i - 1];
466
467
10
            std::string_view lview(l_raw_str, l_str_size);
468
10
            std::string_view rview(r_raw_str, r_str_size);
469
470
10
            OP::execute(lview, rview, res[i]);
471
10
        }
472
5
        return Status::OK();
473
5
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_10EndsWithOpEE13vector_vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEESA_SD_RS8_
Line
Count
Source
455
15
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
456
15
        DCHECK_EQ(loffsets.size(), roffsets.size());
457
458
15
        auto size = loffsets.size();
459
15
        res.resize(size);
460
49
        for (int i = 0; i < size; ++i) {
461
34
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
462
34
            int l_str_size = loffsets[i] - loffsets[i - 1];
463
464
34
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
465
34
            int r_str_size = roffsets[i] - roffsets[i - 1];
466
467
34
            std::string_view lview(l_raw_str, l_str_size);
468
34
            std::string_view rview(r_raw_str, r_str_size);
469
470
34
            OP::execute(lview, rview, res[i]);
471
34
        }
472
15
        return Status::OK();
473
15
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_11FindInSetOpEE13vector_vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEESA_SD_RNS4_IiLm4096ES7_Lm16ELm15EEE
Line
Count
Source
455
17
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
456
17
        DCHECK_EQ(loffsets.size(), roffsets.size());
457
458
17
        auto size = loffsets.size();
459
17
        res.resize(size);
460
58
        for (int i = 0; i < size; ++i) {
461
41
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
462
41
            int l_str_size = loffsets[i] - loffsets[i - 1];
463
464
41
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
465
41
            int r_str_size = roffsets[i] - roffsets[i - 1];
466
467
41
            std::string_view lview(l_raw_str, l_str_size);
468
41
            std::string_view rview(r_raw_str, r_str_size);
469
470
41
            OP::execute(lview, rview, res[i]);
471
41
        }
472
17
        return Status::OK();
473
17
    }
474
    static Status vector_scalar(const ColumnString::Chars& ldata,
475
                                const ColumnString::Offsets& loffsets, const StringRef& rdata,
476
34
                                ResultPaddedPODArray& res) {
477
34
        auto size = loffsets.size();
478
34
        res.resize(size);
479
34
        std::string_view rview(rdata.data, rdata.size);
480
68
        for (int i = 0; i < size; ++i) {
481
34
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
482
34
            int l_str_size = loffsets[i] - loffsets[i - 1];
483
34
            std::string_view lview(l_raw_str, l_str_size);
484
485
34
            OP::execute(lview, rview, res[i]);
486
34
        }
487
34
        return Status::OK();
488
34
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_12StartsWithOpEE13vector_scalarERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEERKNS_9StringRefERS8_
Line
Count
Source
476
4
                                ResultPaddedPODArray& res) {
477
4
        auto size = loffsets.size();
478
4
        res.resize(size);
479
4
        std::string_view rview(rdata.data, rdata.size);
480
8
        for (int i = 0; i < size; ++i) {
481
4
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
482
4
            int l_str_size = loffsets[i] - loffsets[i - 1];
483
4
            std::string_view lview(l_raw_str, l_str_size);
484
485
4
            OP::execute(lview, rview, res[i]);
486
4
        }
487
4
        return Status::OK();
488
4
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_10EndsWithOpEE13vector_scalarERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEERKNS_9StringRefERS8_
Line
Count
Source
476
14
                                ResultPaddedPODArray& res) {
477
14
        auto size = loffsets.size();
478
14
        res.resize(size);
479
14
        std::string_view rview(rdata.data, rdata.size);
480
28
        for (int i = 0; i < size; ++i) {
481
14
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
482
14
            int l_str_size = loffsets[i] - loffsets[i - 1];
483
14
            std::string_view lview(l_raw_str, l_str_size);
484
485
14
            OP::execute(lview, rview, res[i]);
486
14
        }
487
14
        return Status::OK();
488
14
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_11FindInSetOpEE13vector_scalarERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS4_IjLm4096ES7_Lm16ELm15EEERKNS_9StringRefERNS4_IiLm4096ES7_Lm16ELm15EEE
Line
Count
Source
476
16
                                ResultPaddedPODArray& res) {
477
16
        auto size = loffsets.size();
478
16
        res.resize(size);
479
16
        std::string_view rview(rdata.data, rdata.size);
480
32
        for (int i = 0; i < size; ++i) {
481
16
            const char* l_raw_str = reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]);
482
16
            int l_str_size = loffsets[i] - loffsets[i - 1];
483
16
            std::string_view lview(l_raw_str, l_str_size);
484
485
16
            OP::execute(lview, rview, res[i]);
486
16
        }
487
16
        return Status::OK();
488
16
    }
489
    static Status scalar_vector(const StringRef& ldata, const ColumnString::Chars& rdata,
490
34
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
491
34
        auto size = roffsets.size();
492
34
        res.resize(size);
493
34
        std::string_view lview(ldata.data, ldata.size);
494
68
        for (int i = 0; i < size; ++i) {
495
34
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
496
34
            int r_str_size = roffsets[i] - roffsets[i - 1];
497
34
            std::string_view rview(r_raw_str, r_str_size);
498
499
34
            OP::execute(lview, rview, res[i]);
500
34
        }
501
34
        return Status::OK();
502
34
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_12StartsWithOpEE13scalar_vectorERKNS_9StringRefERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS7_IjLm4096ESA_Lm16ELm15EEERSB_
Line
Count
Source
490
4
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
491
4
        auto size = roffsets.size();
492
4
        res.resize(size);
493
4
        std::string_view lview(ldata.data, ldata.size);
494
8
        for (int i = 0; i < size; ++i) {
495
4
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
496
4
            int r_str_size = roffsets[i] - roffsets[i - 1];
497
4
            std::string_view rview(r_raw_str, r_str_size);
498
499
4
            OP::execute(lview, rview, res[i]);
500
4
        }
501
4
        return Status::OK();
502
4
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_10EndsWithOpEE13scalar_vectorERKNS_9StringRefERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS7_IjLm4096ESA_Lm16ELm15EEERSB_
Line
Count
Source
490
14
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
491
14
        auto size = roffsets.size();
492
14
        res.resize(size);
493
14
        std::string_view lview(ldata.data, ldata.size);
494
28
        for (int i = 0; i < size; ++i) {
495
14
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
496
14
            int r_str_size = roffsets[i] - roffsets[i - 1];
497
14
            std::string_view rview(r_raw_str, r_str_size);
498
499
14
            OP::execute(lview, rview, res[i]);
500
14
        }
501
14
        return Status::OK();
502
14
    }
_ZN5doris18StringFunctionImplINS_14DataTypeStringES1_NS_11FindInSetOpEE13scalar_vectorERKNS_9StringRefERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS7_IjLm4096ESA_Lm16ELm15EEERNS7_IiLm4096ESA_Lm16ELm15EEE
Line
Count
Source
490
16
                                const ColumnString::Offsets& roffsets, ResultPaddedPODArray& res) {
491
16
        auto size = roffsets.size();
492
16
        res.resize(size);
493
16
        std::string_view lview(ldata.data, ldata.size);
494
32
        for (int i = 0; i < size; ++i) {
495
16
            const char* r_raw_str = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
496
16
            int r_str_size = roffsets[i] - roffsets[i - 1];
497
16
            std::string_view rview(r_raw_str, r_str_size);
498
499
16
            OP::execute(lview, rview, res[i]);
500
16
        }
501
16
        return Status::OK();
502
16
    }
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
82
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
517
82
        size_t offset_size = offsets.size();
518
82
        if (UNLIKELY(!offset_size)) {
519
0
            return Status::OK();
520
0
        }
521
522
82
        const bool is_ascii = simd::VStringFunctions::is_ascii({data.data(), data.size()});
523
82
        res_offsets.resize(offset_size);
524
82
        if (is_ascii) {
525
36
            memcpy_small_allow_read_write_overflow15(
526
36
                    res_offsets.data(), offsets.data(),
527
36
                    offset_size * sizeof(ColumnString::Offsets::value_type));
528
529
36
            size_t data_length = data.size();
530
36
            res_data.resize(data_length);
531
36
            if constexpr (std::is_same_v<OpName, NameToUpper>) {
532
22
                simd::VStringFunctions::to_upper(data.data(), data_length, res_data.data());
533
22
            } else if constexpr (std::is_same_v<OpName, NameToLower>) {
534
14
                simd::VStringFunctions::to_lower(data.data(), data_length, res_data.data());
535
14
            }
536
46
        } else {
537
46
            execute_utf8(data, offsets, res_data, res_offsets);
538
46
        }
539
540
82
        return Status::OK();
541
82
    }
_ZN5doris12TransferImplINS_11NameToLowerEE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS3_IjLm4096ES6_Lm16ELm15EEERS7_RSA_
Line
Count
Source
516
28
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
517
28
        size_t offset_size = offsets.size();
518
28
        if (UNLIKELY(!offset_size)) {
519
0
            return Status::OK();
520
0
        }
521
522
28
        const bool is_ascii = simd::VStringFunctions::is_ascii({data.data(), data.size()});
523
28
        res_offsets.resize(offset_size);
524
28
        if (is_ascii) {
525
14
            memcpy_small_allow_read_write_overflow15(
526
14
                    res_offsets.data(), offsets.data(),
527
14
                    offset_size * sizeof(ColumnString::Offsets::value_type));
528
529
14
            size_t data_length = data.size();
530
14
            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
14
            } else if constexpr (std::is_same_v<OpName, NameToLower>) {
534
14
                simd::VStringFunctions::to_lower(data.data(), data_length, res_data.data());
535
14
            }
536
14
        } else {
537
14
            execute_utf8(data, offsets, res_data, res_offsets);
538
14
        }
539
540
28
        return Status::OK();
541
28
    }
_ZN5doris12TransferImplINS_11NameToUpperEE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS3_IjLm4096ES6_Lm16ELm15EEERS7_RSA_
Line
Count
Source
516
54
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
517
54
        size_t offset_size = offsets.size();
518
54
        if (UNLIKELY(!offset_size)) {
519
0
            return Status::OK();
520
0
        }
521
522
54
        const bool is_ascii = simd::VStringFunctions::is_ascii({data.data(), data.size()});
523
54
        res_offsets.resize(offset_size);
524
54
        if (is_ascii) {
525
22
            memcpy_small_allow_read_write_overflow15(
526
22
                    res_offsets.data(), offsets.data(),
527
22
                    offset_size * sizeof(ColumnString::Offsets::value_type));
528
529
22
            size_t data_length = data.size();
530
22
            res_data.resize(data_length);
531
22
            if constexpr (std::is_same_v<OpName, NameToUpper>) {
532
22
                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
32
        } else {
537
32
            execute_utf8(data, offsets, res_data, res_offsets);
538
32
        }
539
540
54
        return Status::OK();
541
54
    }
542
543
    static void execute_utf8(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
544
46
                             ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
545
46
        std::string result;
546
170
        for (int64_t i = 0; i < offsets.size(); ++i) {
547
124
            const char* begin = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
548
124
            uint32_t size = offsets[i] - offsets[i - 1];
549
550
124
            result.clear();
551
124
            if constexpr (std::is_same_v<OpName, NameToUpper>) {
552
84
                to_upper_utf8(begin, size, result);
553
84
            } else if constexpr (std::is_same_v<OpName, NameToLower>) {
554
40
                to_lower_utf8(begin, size, result);
555
40
            }
556
124
            StringOP::push_value_string(result, i, res_data, res_offsets);
557
124
        }
558
46
    }
_ZN5doris12TransferImplINS_11NameToLowerEE12execute_utf8ERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS3_IjLm4096ES6_Lm16ELm15EEERS7_RSA_
Line
Count
Source
544
14
                             ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
545
14
        std::string result;
546
54
        for (int64_t i = 0; i < offsets.size(); ++i) {
547
40
            const char* begin = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
548
40
            uint32_t size = offsets[i] - offsets[i - 1];
549
550
40
            result.clear();
551
            if constexpr (std::is_same_v<OpName, NameToUpper>) {
552
                to_upper_utf8(begin, size, result);
553
40
            } else if constexpr (std::is_same_v<OpName, NameToLower>) {
554
40
                to_lower_utf8(begin, size, result);
555
40
            }
556
40
            StringOP::push_value_string(result, i, res_data, res_offsets);
557
40
        }
558
14
    }
_ZN5doris12TransferImplINS_11NameToUpperEE12execute_utf8ERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS3_IjLm4096ES6_Lm16ELm15EEERS7_RSA_
Line
Count
Source
544
32
                             ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
545
32
        std::string result;
546
116
        for (int64_t i = 0; i < offsets.size(); ++i) {
547
84
            const char* begin = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
548
84
            uint32_t size = offsets[i] - offsets[i - 1];
549
550
84
            result.clear();
551
84
            if constexpr (std::is_same_v<OpName, NameToUpper>) {
552
84
                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
84
            StringOP::push_value_string(result, i, res_data, res_offsets);
557
84
        }
558
32
    }
559
560
84
    static void to_upper_utf8(const char* data, uint32_t size, std::string& result) {
561
84
        icu::StringPiece sp;
562
84
        sp.set(data, size);
563
84
        icu::UnicodeString unicode_str = icu::UnicodeString::fromUTF8(sp);
564
84
        unicode_str.toUpper();
565
84
        unicode_str.toUTF8String(result);
566
84
    }
567
568
40
    static void to_lower_utf8(const char* data, uint32_t size, std::string& result) {
569
40
        icu::StringPiece sp;
570
40
        sp.set(data, size);
571
40
        icu::UnicodeString unicode_str = icu::UnicodeString::fromUTF8(sp);
572
40
        unicode_str.toLower();
573
40
        unicode_str.toUTF8String(result);
574
40
    }
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
8
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
585
8
        res_offsets.resize(offsets.size());
586
587
8
        const bool is_ascii = simd::VStringFunctions::is_ascii({data.data(), data.size()});
588
8
        if (is_ascii) {
589
6
            impl_vectors_ascii(data, offsets, res_data, res_offsets);
590
6
        } else {
591
2
            impl_vectors_utf8(data, offsets, res_data, res_offsets);
592
2
        }
593
8
        return Status::OK();
594
8
    }
595
596
    static void impl_vectors_ascii(const ColumnString::Chars& data,
597
                                   const ColumnString::Offsets& offsets,
598
                                   ColumnString::Chars& res_data,
599
6
                                   ColumnString::Offsets& res_offsets) {
600
6
        size_t offset_size = offsets.size();
601
6
        memcpy_small_allow_read_write_overflow15(
602
6
                res_offsets.data(), offsets.data(),
603
6
                offset_size * sizeof(ColumnString::Offsets::value_type));
604
605
6
        size_t data_length = data.size();
606
6
        res_data.resize(data_length);
607
6
        simd::VStringFunctions::to_lower(data.data(), data_length, res_data.data());
608
609
6
        bool need_capitalize = true;
610
12
        for (size_t offset_index = 0, start_index = 0; offset_index < offset_size; ++offset_index) {
611
6
            auto end_index = res_offsets[offset_index];
612
6
            need_capitalize = true;
613
614
78
            for (size_t i = start_index; i < end_index; ++i) {
615
72
                if (!::isalnum(res_data[i])) {
616
23
                    need_capitalize = true;
617
49
                } 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
18
                    res_data[i] = static_cast<unsigned char>(::toupper(res_data[i]));
628
18
                    need_capitalize = false;
629
18
                }
630
72
            }
631
632
6
            start_index = end_index;
633
6
        }
634
6
    }
635
636
    static void impl_vectors_utf8(const ColumnString::Chars& data,
637
                                  const ColumnString::Offsets& offsets,
638
                                  ColumnString::Chars& res_data,
639
2
                                  ColumnString::Offsets& res_offsets) {
640
2
        std::string result;
641
11
        for (int64_t i = 0; i < offsets.size(); ++i) {
642
9
            const char* begin = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
643
9
            uint32_t size = offsets[i] - offsets[i - 1];
644
9
            result.clear();
645
9
            to_initcap_utf8(begin, size, result);
646
9
            StringOP::push_value_string(result, i, res_data, res_offsets);
647
9
        }
648
2
    }
649
650
9
    static void to_initcap_utf8(const char* data, uint32_t size, std::string& result) {
651
9
        icu::StringPiece sp;
652
9
        sp.set(data, size);
653
9
        icu::UnicodeString unicode_str = icu::UnicodeString::fromUTF8(sp);
654
9
        unicode_str.toLower();
655
9
        icu::UnicodeString output_str;
656
9
        bool need_capitalize = true;
657
9
        icu::StringCharacterIterator iter(unicode_str);
658
157
        for (UChar32 ch = iter.first32(); ch != icu::CharacterIterator::DONE; ch = iter.next32()) {
659
148
            if (!u_isalnum(ch)) {
660
47
                need_capitalize = true;
661
101
            } else if (need_capitalize) {
662
26
                ch = u_toupper(ch);
663
26
                need_capitalize = false;
664
26
            }
665
148
            output_str.append(ch);
666
148
        }
667
9
        output_str.toUTF8String(result);
668
9
    }
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
50
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
694
50
        const size_t offset_size = str_offsets.size();
695
50
        res_offsets.resize(offset_size);
696
50
        res_data.reserve(str_data.size());
697
146
        for (size_t i = 0; i < offset_size; ++i) {
698
96
            const auto* str_begin = str_data.data() + str_offsets[i - 1];
699
96
            const auto* str_end = str_data.data() + str_offsets[i];
700
701
96
            if constexpr (is_ltrim) {
702
75
                str_begin =
703
75
                        simd::VStringFunctions::ltrim<trim_single>(str_begin, str_end, remove_str);
704
75
            }
705
96
            if constexpr (is_rtrim) {
706
75
                str_end =
707
75
                        simd::VStringFunctions::rtrim<trim_single>(str_begin, str_end, remove_str);
708
75
            }
709
710
96
            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
96
            res_offsets[i] = (ColumnString::Offset)res_data.size();
713
96
        }
714
50
        return Status::OK();
715
50
    }
_ZN5doris8TrimUtilILb1ELb1ELb1EE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
Line
Count
Source
693
28
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
694
28
        const size_t offset_size = str_offsets.size();
695
28
        res_offsets.resize(offset_size);
696
28
        res_data.reserve(str_data.size());
697
82
        for (size_t i = 0; i < offset_size; ++i) {
698
54
            const auto* str_begin = str_data.data() + str_offsets[i - 1];
699
54
            const auto* str_end = str_data.data() + str_offsets[i];
700
701
54
            if constexpr (is_ltrim) {
702
54
                str_begin =
703
54
                        simd::VStringFunctions::ltrim<trim_single>(str_begin, str_end, remove_str);
704
54
            }
705
54
            if constexpr (is_rtrim) {
706
54
                str_end =
707
54
                        simd::VStringFunctions::rtrim<trim_single>(str_begin, str_end, remove_str);
708
54
            }
709
710
54
            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
54
            res_offsets[i] = (ColumnString::Offset)res_data.size();
713
54
        }
714
28
        return Status::OK();
715
28
    }
_ZN5doris8TrimUtilILb1ELb0ELb1EE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
Line
Count
Source
693
11
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
694
11
        const size_t offset_size = str_offsets.size();
695
11
        res_offsets.resize(offset_size);
696
11
        res_data.reserve(str_data.size());
697
32
        for (size_t i = 0; i < offset_size; ++i) {
698
21
            const auto* str_begin = str_data.data() + str_offsets[i - 1];
699
21
            const auto* str_end = str_data.data() + str_offsets[i];
700
701
21
            if constexpr (is_ltrim) {
702
21
                str_begin =
703
21
                        simd::VStringFunctions::ltrim<trim_single>(str_begin, str_end, remove_str);
704
21
            }
705
            if constexpr (is_rtrim) {
706
                str_end =
707
                        simd::VStringFunctions::rtrim<trim_single>(str_begin, str_end, remove_str);
708
            }
709
710
21
            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
21
            res_offsets[i] = (ColumnString::Offset)res_data.size();
713
21
        }
714
11
        return Status::OK();
715
11
    }
_ZN5doris8TrimUtilILb0ELb1ELb1EE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
Line
Count
Source
693
11
                         ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets) {
694
11
        const size_t offset_size = str_offsets.size();
695
11
        res_offsets.resize(offset_size);
696
11
        res_data.reserve(str_data.size());
697
32
        for (size_t i = 0; i < offset_size; ++i) {
698
21
            const auto* str_begin = str_data.data() + str_offsets[i - 1];
699
21
            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
21
            if constexpr (is_rtrim) {
706
21
                str_end =
707
21
                        simd::VStringFunctions::rtrim<trim_single>(str_begin, str_end, remove_str);
708
21
            }
709
710
21
            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
21
            res_offsets[i] = (ColumnString::Offset)res_data.size();
713
21
        }
714
11
        return Status::OK();
715
11
    }
Unexecuted instantiation: _ZN5doris8TrimUtilILb1ELb1ELb0EE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
Unexecuted instantiation: _ZN5doris8TrimUtilILb1ELb0ELb0EE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
Unexecuted instantiation: _ZN5doris8TrimUtilILb0ELb1ELb0EE6vectorERKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS2_IjLm4096ES5_Lm16ELm15EEERKNS_9StringRefERS6_RS9_
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
58
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb1ELb1ENS_8NameTrimEE27get_variadic_argument_typesEv
Line
Count
Source
853
29
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb1ELb0ENS_9NameLTrimEE27get_variadic_argument_typesEv
Line
Count
Source
853
13
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb0ELb1ENS_9NameRTrimEE27get_variadic_argument_typesEv
Line
Count
Source
853
13
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb1ELb1ENS_10NameTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
853
1
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb1ELb0ENS_11NameLTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
853
1
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
_ZN5doris9Trim1ImplILb0ELb1ENS_11NameRTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
853
1
    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeString>()}; }
854
855
    static Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
856
50
                          uint32_t result, size_t input_rows_count) {
857
50
        const ColumnPtr column = block.get_by_position(arguments[0]).column;
858
50
        if (const auto* col = assert_cast<const ColumnString*>(column.get())) {
859
50
            auto col_res = ColumnString::create();
860
50
            char blank[] = " ";
861
50
            const StringRef remove_str(blank, 1);
862
50
            RETURN_IF_ERROR((TrimUtil<is_ltrim, is_rtrim, true>::vector(
863
50
                    col->get_chars(), col->get_offsets(), remove_str, col_res->get_chars(),
864
50
                    col_res->get_offsets())));
865
50
            block.replace_by_position(result, std::move(col_res));
866
50
        } 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
50
        return Status::OK();
872
50
    }
_ZN5doris9Trim1ImplILb1ELb1ENS_8NameTrimEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
856
28
                          uint32_t result, size_t input_rows_count) {
857
28
        const ColumnPtr column = block.get_by_position(arguments[0]).column;
858
28
        if (const auto* col = assert_cast<const ColumnString*>(column.get())) {
859
28
            auto col_res = ColumnString::create();
860
28
            char blank[] = " ";
861
28
            const StringRef remove_str(blank, 1);
862
28
            RETURN_IF_ERROR((TrimUtil<is_ltrim, is_rtrim, true>::vector(
863
28
                    col->get_chars(), col->get_offsets(), remove_str, col_res->get_chars(),
864
28
                    col_res->get_offsets())));
865
28
            block.replace_by_position(result, std::move(col_res));
866
28
        } 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
28
        return Status::OK();
872
28
    }
_ZN5doris9Trim1ImplILb1ELb0ENS_9NameLTrimEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
856
11
                          uint32_t result, size_t input_rows_count) {
857
11
        const ColumnPtr column = block.get_by_position(arguments[0]).column;
858
11
        if (const auto* col = assert_cast<const ColumnString*>(column.get())) {
859
11
            auto col_res = ColumnString::create();
860
11
            char blank[] = " ";
861
11
            const StringRef remove_str(blank, 1);
862
11
            RETURN_IF_ERROR((TrimUtil<is_ltrim, is_rtrim, true>::vector(
863
11
                    col->get_chars(), col->get_offsets(), remove_str, col_res->get_chars(),
864
11
                    col_res->get_offsets())));
865
11
            block.replace_by_position(result, std::move(col_res));
866
11
        } 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
11
        return Status::OK();
872
11
    }
_ZN5doris9Trim1ImplILb0ELb1ENS_9NameRTrimEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
856
11
                          uint32_t result, size_t input_rows_count) {
857
11
        const ColumnPtr column = block.get_by_position(arguments[0]).column;
858
11
        if (const auto* col = assert_cast<const ColumnString*>(column.get())) {
859
11
            auto col_res = ColumnString::create();
860
11
            char blank[] = " ";
861
11
            const StringRef remove_str(blank, 1);
862
11
            RETURN_IF_ERROR((TrimUtil<is_ltrim, is_rtrim, true>::vector(
863
11
                    col->get_chars(), col->get_offsets(), remove_str, col_res->get_chars(),
864
11
                    col_res->get_offsets())));
865
11
            block.replace_by_position(result, std::move(col_res));
866
11
        } 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
11
        return Status::OK();
872
11
    }
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
6
    static DataTypes get_variadic_argument_types() {
881
6
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
882
6
    }
_ZN5doris9Trim2ImplILb1ELb1ENS_8NameTrimEE27get_variadic_argument_typesEv
Line
Count
Source
880
1
    static DataTypes get_variadic_argument_types() {
881
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
882
1
    }
_ZN5doris9Trim2ImplILb1ELb0ENS_9NameLTrimEE27get_variadic_argument_typesEv
Line
Count
Source
880
1
    static DataTypes get_variadic_argument_types() {
881
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
882
1
    }
_ZN5doris9Trim2ImplILb0ELb1ENS_9NameRTrimEE27get_variadic_argument_typesEv
Line
Count
Source
880
1
    static DataTypes get_variadic_argument_types() {
881
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
882
1
    }
_ZN5doris9Trim2ImplILb1ELb1ENS_10NameTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
880
1
    static DataTypes get_variadic_argument_types() {
881
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
882
1
    }
_ZN5doris9Trim2ImplILb1ELb0ENS_11NameLTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
880
1
    static DataTypes get_variadic_argument_types() {
881
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
882
1
    }
_ZN5doris9Trim2ImplILb0ELb1ENS_11NameRTrimInEE27get_variadic_argument_typesEv
Line
Count
Source
880
1
    static DataTypes get_variadic_argument_types() {
881
1
        return {std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()};
882
1
    }
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
76
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE6createEv
Line
Count
Source
934
30
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE6createEv
Line
Count
Source
934
14
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE6createEv
Line
Count
Source
934
14
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE6createEv
Line
Count
Source
934
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE6createEv
Line
Count
Source
934
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE6createEv
Line
Count
Source
934
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE6createEv
Line
Count
Source
934
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE6createEv
Line
Count
Source
934
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE6createEv
Line
Count
Source
934
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE6createEv
Line
Count
Source
934
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE6createEv
Line
Count
Source
934
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
_ZN5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE6createEv
Line
Count
Source
934
2
    static FunctionPtr create() { return std::make_shared<FunctionTrim<impl>>(); }
935
12
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE8get_nameB5cxx11Ev
Line
Count
Source
935
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE8get_nameB5cxx11Ev
Line
Count
Source
935
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE8get_nameB5cxx11Ev
Line
Count
Source
935
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE8get_nameB5cxx11Ev
Line
Count
Source
935
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE8get_nameB5cxx11Ev
Line
Count
Source
935
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE8get_nameB5cxx11Ev
Line
Count
Source
935
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE8get_nameB5cxx11Ev
Line
Count
Source
935
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE8get_nameB5cxx11Ev
Line
Count
Source
935
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE8get_nameB5cxx11Ev
Line
Count
Source
935
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE8get_nameB5cxx11Ev
Line
Count
Source
935
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE8get_nameB5cxx11Ev
Line
Count
Source
935
1
    String get_name() const override { return impl::name; }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE8get_nameB5cxx11Ev
Line
Count
Source
935
1
    String get_name() const override { return impl::name; }
936
937
52
    size_t get_number_of_arguments() const override {
938
52
        return get_variadic_argument_types_impl().size();
939
52
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE23get_number_of_argumentsEv
Line
Count
Source
937
28
    size_t get_number_of_arguments() const override {
938
28
        return get_variadic_argument_types_impl().size();
939
28
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE23get_number_of_argumentsEv
Line
Count
Source
937
12
    size_t get_number_of_arguments() const override {
938
12
        return get_variadic_argument_types_impl().size();
939
12
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE23get_number_of_argumentsEv
Line
Count
Source
937
12
    size_t get_number_of_arguments() const override {
938
12
        return get_variadic_argument_types_impl().size();
939
12
    }
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE23get_number_of_argumentsEv
940
941
52
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
942
52
        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
52
        return arguments[0];
948
52
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Line
Count
Source
941
28
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
942
28
        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
28
        return arguments[0];
948
28
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Line
Count
Source
941
12
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
942
12
        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
12
        return arguments[0];
948
12
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Line
Count
Source
941
12
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
942
12
        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
12
        return arguments[0];
948
12
    }
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE
949
    // The second parameter of "trim" is a constant.
950
102
    ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE38get_arguments_that_are_always_constantEv
Line
Count
Source
950
56
    ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE38get_arguments_that_are_always_constantEv
Line
Count
Source
950
23
    ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE38get_arguments_that_are_always_constantEv
Line
Count
Source
950
23
    ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE38get_arguments_that_are_always_constantEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE38get_arguments_that_are_always_constantEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE38get_arguments_that_are_always_constantEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE38get_arguments_that_are_always_constantEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE38get_arguments_that_are_always_constantEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE38get_arguments_that_are_always_constantEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE38get_arguments_that_are_always_constantEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE38get_arguments_that_are_always_constantEv
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE38get_arguments_that_are_always_constantEv
951
952
64
    DataTypes get_variadic_argument_types_impl() const override {
953
64
        return impl::get_variadic_argument_types();
954
64
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
952
29
    DataTypes get_variadic_argument_types_impl() const override {
953
29
        return impl::get_variadic_argument_types();
954
29
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
952
13
    DataTypes get_variadic_argument_types_impl() const override {
953
13
        return impl::get_variadic_argument_types();
954
13
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
952
13
    DataTypes get_variadic_argument_types_impl() const override {
953
13
        return impl::get_variadic_argument_types();
954
13
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
952
1
    DataTypes get_variadic_argument_types_impl() const override {
953
1
        return impl::get_variadic_argument_types();
954
1
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
952
1
    DataTypes get_variadic_argument_types_impl() const override {
953
1
        return impl::get_variadic_argument_types();
954
1
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE32get_variadic_argument_types_implEv
Line
Count
Source
952
1
    DataTypes get_variadic_argument_types_impl() const override {
953
1
        return impl::get_variadic_argument_types();
954
1
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
952
1
    DataTypes get_variadic_argument_types_impl() const override {
953
1
        return impl::get_variadic_argument_types();
954
1
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
952
1
    DataTypes get_variadic_argument_types_impl() const override {
953
1
        return impl::get_variadic_argument_types();
954
1
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
952
1
    DataTypes get_variadic_argument_types_impl() const override {
953
1
        return impl::get_variadic_argument_types();
954
1
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
952
1
    DataTypes get_variadic_argument_types_impl() const override {
953
1
        return impl::get_variadic_argument_types();
954
1
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
952
1
    DataTypes get_variadic_argument_types_impl() const override {
953
1
        return impl::get_variadic_argument_types();
954
1
    }
_ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE32get_variadic_argument_types_implEv
Line
Count
Source
952
1
    DataTypes get_variadic_argument_types_impl() const override {
953
1
        return impl::get_variadic_argument_types();
954
1
    }
955
956
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
957
50
                        uint32_t result, size_t input_rows_count) const override {
958
50
        return impl::execute(context, block, arguments, result, input_rows_count);
959
50
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_8NameTrimEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
957
28
                        uint32_t result, size_t input_rows_count) const override {
958
28
        return impl::execute(context, block, arguments, result, input_rows_count);
959
28
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_9NameLTrimEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
957
11
                        uint32_t result, size_t input_rows_count) const override {
958
11
        return impl::execute(context, block, arguments, result, input_rows_count);
959
11
    }
_ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_9NameRTrimEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
957
11
                        uint32_t result, size_t input_rows_count) const override {
958
11
        return impl::execute(context, block, arguments, result, input_rows_count);
959
11
    }
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_8NameTrimEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_9NameLTrimEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_9NameRTrimEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb1ENS_10NameTrimInEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb1ELb0ENS_11NameLTrimInEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim1ImplILb0ELb1ENS_11NameRTrimInEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb1ENS_10NameTrimInEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb1ELb0ENS_11NameLTrimInEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris12FunctionTrimINS_9Trim2ImplILb0ELb1ENS_11NameRTrimInEEEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
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
15
                         ColumnString::Chars& dst_data, ColumnString::Offsets& dst_offsets) {
979
15
        auto rows_count = offsets.size();
980
15
        dst_offsets.resize(rows_count);
981
982
15
        int64_t total_size = 0;
983
44
        for (size_t i = 0; i < rows_count; i++) {
984
29
            size_t len = offsets[i] - offsets[i - 1];
985
29
            total_size += len / 2;
986
29
        }
987
15
        ColumnString::check_chars_length(total_size, rows_count);
988
15
        dst_data.resize(total_size);
989
15
        char* dst_data_ptr = reinterpret_cast<char*>(dst_data.data());
990
15
        size_t offset = 0;
991
992
44
        for (int i = 0; i < rows_count; ++i) {
993
29
            const auto* source = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
994
29
            ColumnString::Offset srclen = offsets[i] - offsets[i - 1];
995
996
29
            if (UNLIKELY(srclen == 0)) {
997
3
                dst_offsets[i] = cast_set<uint32_t>(offset);
998
3
                continue;
999
3
            }
1000
1001
26
            int outlen = string_hex::hex_decode(source, srclen, dst_data_ptr + offset);
1002
1003
26
            offset += outlen;
1004
26
            dst_offsets[i] = cast_set<uint32_t>(offset);
1005
26
        }
1006
15
        dst_data.pop_back(total_size - offset);
1007
15
        return Status::OK();
1008
15
    }
1009
1010
    static Status vector(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
1011
                         ColumnString::Chars& dst_data, ColumnString::Offsets& dst_offsets,
1012
19
                         ColumnUInt8::Container* null_map_data) {
1013
19
        auto rows_count = offsets.size();
1014
19
        dst_offsets.resize(rows_count);
1015
1016
19
        int64_t total_size = 0;
1017
56
        for (size_t i = 0; i < rows_count; i++) {
1018
37
            size_t len = offsets[i] - offsets[i - 1];
1019
37
            total_size += len / 2;
1020
37
        }
1021
19
        ColumnString::check_chars_length(total_size, rows_count);
1022
19
        dst_data.resize(total_size);
1023
19
        char* dst_data_ptr = reinterpret_cast<char*>(dst_data.data());
1024
19
        size_t offset = 0;
1025
1026
56
        for (int i = 0; i < rows_count; ++i) {
1027
37
            const auto* source = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
1028
37
            ColumnString::Offset srclen = offsets[i] - offsets[i - 1];
1029
1030
37
            if (UNLIKELY(srclen == 0)) {
1031
3
                (*null_map_data)[i] = 1;
1032
3
                dst_offsets[i] = cast_set<uint32_t>(offset);
1033
3
                continue;
1034
3
            }
1035
1036
34
            int outlen = string_hex::hex_decode(source, srclen, dst_data_ptr + offset);
1037
1038
34
            if (outlen == 0) {
1039
6
                (*null_map_data)[i] = 1;
1040
6
                dst_offsets[i] = cast_set<uint32_t>(offset);
1041
6
                continue;
1042
6
            }
1043
1044
28
            offset += outlen;
1045
28
            dst_offsets[i] = cast_set<uint32_t>(offset);
1046
28
        }
1047
19
        dst_data.pop_back(total_size - offset);
1048
19
        return Status::OK();
1049
19
    }
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
12
                         ColumnString::Chars& dst_data, ColumnString::Offsets& dst_offsets) {
1095
12
        auto rows_count = offsets.size();
1096
12
        dst_offsets.resize(rows_count);
1097
1098
12
        size_t total_size = 0;
1099
34
        for (size_t i = 0; i < rows_count; i++) {
1100
22
            size_t len = offsets[i] - offsets[i - 1];
1101
22
            total_size += 4 * ((len + 2) / 3);
1102
22
        }
1103
12
        ColumnString::check_chars_length(total_size, rows_count);
1104
12
        dst_data.resize(total_size);
1105
12
        auto* dst_data_ptr = dst_data.data();
1106
12
        size_t offset = 0;
1107
1108
34
        for (int i = 0; i < rows_count; ++i) {
1109
22
            const auto* source = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
1110
22
            size_t srclen = offsets[i] - offsets[i - 1];
1111
1112
22
            if (UNLIKELY(srclen == 0)) {
1113
4
                dst_offsets[i] = cast_set<uint32_t>(offset);
1114
4
                continue;
1115
4
            }
1116
1117
18
            auto outlen = doris::base64_encode((const unsigned char*)source, srclen,
1118
18
                                               (unsigned char*)(dst_data_ptr + offset));
1119
1120
18
            offset += outlen;
1121
18
            dst_offsets[i] = cast_set<uint32_t>(offset);
1122
18
        }
1123
12
        dst_data.pop_back(total_size - offset);
1124
12
        return Status::OK();
1125
12
    }
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
9
                         NullMap& null_map) {
1136
9
        auto rows_count = offsets.size();
1137
9
        dst_offsets.resize(rows_count);
1138
1139
9
        size_t total_size = 0;
1140
26
        for (size_t i = 0; i < rows_count; i++) {
1141
17
            auto len = offsets[i] - offsets[i - 1];
1142
17
            total_size += len / 4 * 3;
1143
17
        }
1144
9
        ColumnString::check_chars_length(total_size, rows_count);
1145
9
        dst_data.resize(total_size);
1146
9
        char* dst_data_ptr = reinterpret_cast<char*>(dst_data.data());
1147
9
        size_t offset = 0;
1148
1149
26
        for (int i = 0; i < rows_count; ++i) {
1150
17
            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
17
            const auto* source = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
1157
17
            ColumnString::Offset srclen = offsets[i] - offsets[i - 1];
1158
1159
17
            if (UNLIKELY(srclen == 0)) {
1160
3
                dst_offsets[i] = cast_set<uint32_t>(offset);
1161
3
                continue;
1162
3
            }
1163
1164
14
            auto outlen = base64_decode(source, srclen, dst_data_ptr + offset);
1165
1166
14
            if (outlen < 0) {
1167
6
                null_map[i] = 1;
1168
6
                dst_offsets[i] = cast_set<uint32_t>(offset);
1169
8
            } else {
1170
8
                offset += outlen;
1171
8
                dst_offsets[i] = cast_set<uint32_t>(offset);
1172
8
            }
1173
14
        }
1174
9
        dst_data.pop_back(total_size - offset);
1175
9
        return Status::OK();
1176
9
    }
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
24
    static bool str_end_with(const StringRef& str, const StringRef& end) {
1187
24
        if (str.size < end.size) {
1188
8
            return false;
1189
8
        }
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
16
        return str.end_with(end);
1192
24
    }
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
9
                              Offsets& res_offsets, NullMap& null_map_data) {
1197
9
        DCHECK_EQ(loffsets.size(), roffsets.size());
1198
9
        size_t input_rows_count = loffsets.size();
1199
9
        res_offsets.resize(input_rows_count);
1200
9
        fmt::memory_buffer buffer;
1201
1202
30
        for (size_t i = 0; i < input_rows_count; ++i) {
1203
21
            buffer.clear();
1204
1205
21
            StringRef lstr = StringRef(reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]),
1206
21
                                       loffsets[i] - loffsets[i - 1]);
1207
21
            StringRef rstr = StringRef(reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]),
1208
21
                                       roffsets[i] - roffsets[i - 1]);
1209
            // The iterate_utf8_with_limit_length function iterates over a maximum of two UTF-8 characters.
1210
21
            auto [byte_len, char_len] = simd::VStringFunctions::iterate_utf8_with_limit_length(
1211
21
                    rstr.begin(), rstr.end(), 2);
1212
1213
21
            if (char_len != 1) {
1214
9
                StringOP::push_null_string(i, res_data, res_offsets, null_map_data);
1215
9
                continue;
1216
9
            }
1217
12
            if (str_end_with(lstr, rstr)) {
1218
4
                StringOP::push_value_string(lstr, i, res_data, res_offsets);
1219
4
                continue;
1220
4
            }
1221
1222
8
            buffer.append(lstr.begin(), lstr.end());
1223
8
            buffer.append(rstr.begin(), rstr.end());
1224
8
            StringOP::push_value_string(std::string_view(buffer.data(), buffer.size()), i, res_data,
1225
8
                                        res_offsets);
1226
8
        }
1227
9
    }
1228
    static void vector_scalar(FunctionContext* context, const Chars& ldata, const Offsets& loffsets,
1229
                              const StringRef& rstr, Chars& res_data, Offsets& res_offsets,
1230
8
                              NullMap& null_map_data) {
1231
8
        size_t input_rows_count = loffsets.size();
1232
8
        res_offsets.resize(input_rows_count);
1233
8
        fmt::memory_buffer buffer;
1234
        // The iterate_utf8_with_limit_length function iterates over a maximum of two UTF-8 characters.
1235
8
        auto [byte_len, char_len] =
1236
8
                simd::VStringFunctions::iterate_utf8_with_limit_length(rstr.begin(), rstr.end(), 2);
1237
8
        if (char_len != 1) {
1238
4
            for (size_t i = 0; i < input_rows_count; ++i) {
1239
2
                StringOP::push_null_string(i, res_data, res_offsets, null_map_data);
1240
2
            }
1241
2
            return;
1242
2
        }
1243
1244
12
        for (size_t i = 0; i < input_rows_count; ++i) {
1245
6
            buffer.clear();
1246
6
            StringRef lstr = StringRef(reinterpret_cast<const char*>(&ldata[loffsets[i - 1]]),
1247
6
                                       loffsets[i] - loffsets[i - 1]);
1248
1249
6
            if (str_end_with(lstr, rstr)) {
1250
2
                StringOP::push_value_string(lstr, i, res_data, res_offsets);
1251
2
                continue;
1252
2
            }
1253
1254
4
            buffer.append(lstr.begin(), lstr.end());
1255
4
            buffer.append(rstr.begin(), rstr.end());
1256
4
            StringOP::push_value_string(std::string_view(buffer.data(), buffer.size()), i, res_data,
1257
4
                                        res_offsets);
1258
4
        }
1259
6
    }
1260
    static void scalar_vector(FunctionContext* context, const StringRef& lstr, const Chars& rdata,
1261
                              const Offsets& roffsets, Chars& res_data, Offsets& res_offsets,
1262
8
                              NullMap& null_map_data) {
1263
8
        size_t input_rows_count = roffsets.size();
1264
8
        res_offsets.resize(input_rows_count);
1265
8
        fmt::memory_buffer buffer;
1266
1267
16
        for (size_t i = 0; i < input_rows_count; ++i) {
1268
8
            buffer.clear();
1269
1270
8
            StringRef rstr = StringRef(reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]),
1271
8
                                       roffsets[i] - roffsets[i - 1]);
1272
            // The iterate_utf8_with_limit_length function iterates over a maximum of two UTF-8 characters.
1273
8
            auto [byte_len, char_len] = simd::VStringFunctions::iterate_utf8_with_limit_length(
1274
8
                    rstr.begin(), rstr.end(), 2);
1275
1276
8
            if (char_len != 1) {
1277
2
                StringOP::push_null_string(i, res_data, res_offsets, null_map_data);
1278
2
                continue;
1279
2
            }
1280
6
            if (str_end_with(lstr, rstr)) {
1281
2
                StringOP::push_value_string(lstr, i, res_data, res_offsets);
1282
2
                continue;
1283
2
            }
1284
1285
4
            buffer.append(lstr.begin(), lstr.end());
1286
4
            buffer.append(rstr.begin(), rstr.end());
1287
4
            StringOP::push_value_string(std::string_view(buffer.data(), buffer.size()), i, res_data,
1288
4
                                        res_offsets);
1289
4
        }
1290
8
    }
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
using FunctionMakeSet = FunctionNeedsToHandleNull<MakeSetImpl, PrimitiveType::TYPE_STRING>;
1350
1351
1
void register_function_string(SimpleFunctionFactory& factory) {
1352
1
    factory.register_function<FunctionStringParseDataSize>();
1353
1
    factory.register_function<FunctionStringASCII>();
1354
1
    factory.register_function<FunctionStringLength>();
1355
1
    factory.register_function<FunctionCrc32>();
1356
1
    factory.register_function<FunctionStringUTF8Length>();
1357
1
    factory.register_function<FunctionStringSpace>();
1358
1
    factory.register_function<FunctionStringStartsWith>();
1359
1
    factory.register_function<FunctionStringEndsWith>();
1360
1
    factory.register_function<FunctionStringInstr>();
1361
1
    factory.register_function<FunctionStringFindInSet>();
1362
1
    factory.register_function<FunctionStringLocate>();
1363
1
    factory.register_function<FunctionStringLocatePos>();
1364
1
    factory.register_function<FunctionQuote>();
1365
1
    factory.register_function<FunctionAutoPartitionName>();
1366
1
    factory.register_function<FunctionReverseCommon>();
1367
1
    factory.register_function<FunctionUnHex>();
1368
1
    factory.register_function<FunctionUnHexNullable>();
1369
1
    factory.register_function<FunctionToLower>();
1370
1
    factory.register_function<FunctionToUpper>();
1371
1
    factory.register_function<FunctionToInitcap>();
1372
1
    factory.register_function<FunctionTrim<Trim1Impl<true, true, NameTrim>>>();
1373
1
    factory.register_function<FunctionTrim<Trim1Impl<true, false, NameLTrim>>>();
1374
1
    factory.register_function<FunctionTrim<Trim1Impl<false, true, NameRTrim>>>();
1375
1
    factory.register_function<FunctionTrim<Trim2Impl<true, true, NameTrim>>>();
1376
1
    factory.register_function<FunctionTrim<Trim2Impl<true, false, NameLTrim>>>();
1377
1
    factory.register_function<FunctionTrim<Trim2Impl<false, true, NameRTrim>>>();
1378
1
    factory.register_function<FunctionTrim<Trim1Impl<true, true, NameTrimIn>>>();
1379
1
    factory.register_function<FunctionTrim<Trim1Impl<true, false, NameLTrimIn>>>();
1380
1
    factory.register_function<FunctionTrim<Trim1Impl<false, true, NameRTrimIn>>>();
1381
1
    factory.register_function<FunctionTrim<Trim2Impl<true, true, NameTrimIn>>>();
1382
1
    factory.register_function<FunctionTrim<Trim2Impl<true, false, NameLTrimIn>>>();
1383
1
    factory.register_function<FunctionTrim<Trim2Impl<false, true, NameRTrimIn>>>();
1384
1
    factory.register_function<FunctionConvertTo>();
1385
1
    factory.register_function<FunctionSubstring<Substr3Impl>>();
1386
1
    factory.register_function<FunctionSubstring<Substr2Impl>>();
1387
1
    factory.register_function<FunctionLeft>();
1388
1
    factory.register_function<FunctionRight>();
1389
1
    factory.register_function<FunctionNullOrEmpty>();
1390
1
    factory.register_function<FunctionNotNullOrEmpty>();
1391
1
    factory.register_function<FunctionStringConcat>();
1392
1
    factory.register_function<FunctionIntToChar>();
1393
1
    factory.register_function<FunctionStringElt>();
1394
1
    factory.register_function<FunctionStringConcatWs>();
1395
1
    factory.register_function<FunctionStringAppendTrailingCharIfAbsent>();
1396
1
    factory.register_function<FunctionStringRepeat>();
1397
1
    factory.register_function<FunctionStringLPad>();
1398
1
    factory.register_function<FunctionStringRPad>();
1399
1
    factory.register_function<FunctionToBase64>();
1400
1
    factory.register_function<FunctionFromBase64>();
1401
1
    factory.register_function<FunctionSplitPart>();
1402
1
    factory.register_function<FunctionSplitByString>();
1403
1
    factory.register_function<FunctionCountSubString<FunctionCountSubStringType::TWO_ARGUMENTS>>();
1404
1
    factory.register_function<
1405
1
            FunctionCountSubString<FunctionCountSubStringType::THREE_ARGUMENTS>>();
1406
1
    factory.register_function<FunctionSubstringIndex>();
1407
1
    factory.register_function<FunctionExtractURLParameter>();
1408
1
    factory.register_function<FunctionStringParseUrl>();
1409
1
    factory.register_function<FunctionUrlDecode>();
1410
1
    factory.register_function<FunctionUrlEncode>();
1411
1
    factory.register_function<FunctionRandomBytes>();
1412
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDoubleImpl>>();
1413
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatInt64Impl>>();
1414
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatInt128Impl>>();
1415
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMALV2>>>();
1416
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMAL32>>>();
1417
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMAL64>>>();
1418
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMAL128I>>>();
1419
1
    factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl<TYPE_DECIMAL256>>>();
1420
1
    factory.register_function<FunctionStringFormatRound<FormatRoundDoubleImpl>>();
1421
1
    factory.register_function<FunctionStringFormatRound<FormatRoundInt64Impl>>();
1422
1
    factory.register_function<FunctionStringFormatRound<FormatRoundInt128Impl>>();
1423
1
    factory.register_function<FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMALV2>>>();
1424
1
    factory.register_function<FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMAL32>>>();
1425
1
    factory.register_function<FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMAL64>>>();
1426
1
    factory.register_function<
1427
1
            FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMAL128I>>>();
1428
1
    factory.register_function<FunctionStringFormatRound<FormatRoundDecimalImpl<TYPE_DECIMAL256>>>();
1429
1
    factory.register_function<FunctionStringDigestMulti<SM3Sum>>();
1430
1
    factory.register_function<FunctionStringDigestMulti<MD5Sum>>();
1431
1
    factory.register_function<FunctionStringDigestSHA1>();
1432
1
    factory.register_function<FunctionStringDigestSHA2>();
1433
1
    factory.register_function<FunctionReplace<ReplaceImpl, true>>();
1434
1
    factory.register_function<FunctionReplace<ReplaceEmptyImpl, false>>();
1435
1
    factory.register_function<FunctionTranslate>();
1436
1
    factory.register_function<FunctionMask>();
1437
1
    factory.register_function<FunctionMaskPartial<true>>();
1438
1
    factory.register_function<FunctionMaskPartial<false>>();
1439
1
    factory.register_function<FunctionSubReplace<SubReplaceThreeImpl>>();
1440
1
    factory.register_function<FunctionSubReplace<SubReplaceFourImpl>>();
1441
1
    factory.register_function<FunctionOverlay>();
1442
1
    factory.register_function<FunctionStrcmp>();
1443
1
    factory.register_function<FunctionNgramSearch>();
1444
1
    factory.register_function<FunctionXPathString>();
1445
1
    factory.register_function<FunctionCrc32Internal>();
1446
1
    factory.register_function<FunctionMakeSet>();
1447
1
    factory.register_function<FunctionExportSet>();
1448
1
    factory.register_function<FunctionUnicodeNormalize>();
1449
1450
1
    factory.register_alias(FunctionLeft::name, "strleft");
1451
1
    factory.register_alias(FunctionRight::name, "strright");
1452
1
    factory.register_alias(SubstringUtil::name, "substr");
1453
1
    factory.register_alias(SubstringUtil::name, "mid");
1454
1
    factory.register_alias(FunctionToLower::name, "lcase");
1455
1
    factory.register_alias(FunctionToUpper::name, "ucase");
1456
1
    factory.register_alias(FunctionStringDigestMulti<MD5Sum>::name, "md5");
1457
1
    factory.register_alias(FunctionStringUTF8Length::name, "character_length");
1458
1
    factory.register_alias(FunctionStringDigestMulti<SM3Sum>::name, "sm3");
1459
1
    factory.register_alias(FunctionStringDigestSHA1::name, "sha");
1460
1
    factory.register_alias(FunctionStringLocatePos::name, "position");
1461
1
    factory.register_alias(FunctionStringLength::name, "octet_length");
1462
1
    factory.register_alias(FunctionOverlay::name, "insert");
1463
1
}
1464
1465
} // namespace doris