aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Functions/visitParamExtractRaw.cpp
blob: 74a8317054576dd8745a33eaa50183d9863bb33e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <Functions/FunctionFactory.h>
#include <Functions/FunctionsVisitParam.h>
#include <Functions/FunctionsStringSearchToString.h>


namespace DB
{

struct ExtractRaw
{
    using ExpectChars = PODArrayWithStackMemory<char, 64>;

    static void extract(const UInt8 * pos, const UInt8 * end, ColumnString::Chars & res_data)
    {
        ExpectChars expects_end;
        UInt8 current_expect_end = 0;

        for (const auto * extract_begin = pos; pos != end; ++pos)
        {
            if (current_expect_end && *pos == current_expect_end)
            {
                expects_end.pop_back();
                current_expect_end = expects_end.empty() ? 0 : expects_end.back();
            }
            else if (current_expect_end == '"')
            {
                /// skip backslash
                if (*pos == '\\' && pos + 1 < end && pos[1] == '"')
                    ++pos;
            }
            else
            {
                switch (*pos)
                {
                    case '[':
                        current_expect_end = ']';
                        expects_end.push_back(current_expect_end);
                        break;
                    case '{':
                        current_expect_end = '}';
                        expects_end.push_back(current_expect_end);
                        break;
                    case '"' :
                        current_expect_end = '"';
                        expects_end.push_back(current_expect_end);
                        break;
                    default:
                        if (!current_expect_end && (*pos == ',' || *pos == '}'))
                        {
                            res_data.insert(extract_begin, pos);
                            return;
                        }
                }
            }
        }
    }
};

struct NameSimpleJSONExtractRaw    { static constexpr auto name = "simpleJSONExtractRaw"; };
using FunctionSimpleJSONExtractRaw = FunctionsStringSearchToString<ExtractParamToStringImpl<ExtractRaw>, NameSimpleJSONExtractRaw>;

REGISTER_FUNCTION(VisitParamExtractRaw)
{
    factory.registerFunction<FunctionSimpleJSONExtractRaw>();
    factory.registerAlias("visitParamExtractRaw", "simpleJSONExtractRaw");
}

}