ClickHouse

Форк
0
/
splitByWhitespace.cpp 
103 строки · 2.4 Кб
1
#include <Functions/FunctionTokens.h>
2
#include <Functions/FunctionFactory.h>
3
#include <Common/StringUtils/StringUtils.h>
4

5

6
namespace DB
7
{
8

9
/** Functions that split strings into an array of strings or vice versa.
10
  *
11
  * splitByWhitespace(s[, max_substrings])      - split the string by whitespace characters
12
  */
13
namespace
14
{
15

16
using Pos = const char *;
17

18
class SplitByWhitespaceImpl
19
{
20
private:
21
    Pos pos;
22
    Pos end;
23
    std::optional<size_t> max_splits;
24
    size_t splits;
25
    bool max_substrings_includes_remaining_string;
26

27
public:
28
    static constexpr auto name = "splitByWhitespace";
29

30
    static bool isVariadic() { return true; }
31
    static size_t getNumberOfArguments() { return 0; }
32

33
    static ColumnNumbers getArgumentsThatAreAlwaysConstant() { return {1}; }
34

35
    static void checkArguments(const IFunction & func, const ColumnsWithTypeAndName & arguments)
36
    {
37
        checkArgumentsWithOptionalMaxSubstrings(func, arguments);
38
    }
39

40
    static constexpr auto strings_argument_position = 0uz;
41

42
    void init(const ColumnsWithTypeAndName & arguments, bool max_substrings_includes_remaining_string_)
43
    {
44
        max_substrings_includes_remaining_string = max_substrings_includes_remaining_string_;
45
        max_splits = extractMaxSplits(arguments, 1);
46
    }
47

48
    /// Called for each next string.
49
    void set(Pos pos_, Pos end_)
50
    {
51
        pos = pos_;
52
        end = end_;
53
        splits = 0;
54
    }
55

56
    /// Get the next token, if any, or return false.
57
    bool get(Pos & token_begin, Pos & token_end)
58
    {
59
        /// Skip garbage
60
        while (pos < end && isWhitespaceASCII(*pos))
61
            ++pos;
62

63
        if (pos == end)
64
            return false;
65

66
        token_begin = pos;
67

68
        if (max_splits)
69
        {
70
            if (max_substrings_includes_remaining_string)
71
            {
72
                if (splits == *max_splits - 1)
73
                {
74
                    token_end = end;
75
                    pos = end;
76
                    return true;
77
                }
78
            }
79
            else
80
                if (splits == *max_splits)
81
                    return false;
82
        }
83

84
        while (pos < end && !isWhitespaceASCII(*pos))
85
            ++pos;
86

87
        token_end = pos;
88
        splits++;
89

90
        return true;
91
    }
92
};
93

94
using FunctionSplitByWhitespace = FunctionTokens<SplitByWhitespaceImpl>;
95

96
}
97

98
REGISTER_FUNCTION(SplitByWhitespace)
99
{
100
    factory.registerFunction<FunctionSplitByWhitespace>();
101
}
102

103
}
104

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.