aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Functions/initcap.cpp
blob: 5460ee067920d097afa2d497151e669a1be8dc79 (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
#include <Functions/FunctionFactory.h>
#include <Functions/FunctionStringToString.h>
#include <Common/StringUtils/StringUtils.h>

namespace DB
{
namespace
{

struct InitcapImpl
{
    static void vector(const ColumnString::Chars & data,
        const ColumnString::Offsets & offsets,
        ColumnString::Chars & res_data,
        ColumnString::Offsets & res_offsets)
    {
        if (data.empty())
            return;
        res_data.resize(data.size());
        res_offsets.assign(offsets);
        array(data.data(), data.data() + data.size(), res_data.data());
    }

    static void vectorFixed(const ColumnString::Chars & data, size_t /*n*/, ColumnString::Chars & res_data)
    {
        res_data.resize(data.size());
        array(data.data(), data.data() + data.size(), res_data.data());
    }

private:
    static void array(const UInt8 * src, const UInt8 * src_end, UInt8 * dst)
    {
        bool prev_alphanum = false;

        for (; src < src_end; ++src, ++dst)
        {
            char c = *src;
            bool alphanum = isAlphaNumericASCII(c);
            if (alphanum && !prev_alphanum)
                if (isAlphaASCII(c))
                    *dst = toUpperIfAlphaASCII(c);
                else
                    *dst = c;
            else if (isAlphaASCII(c))
                *dst = toLowerIfAlphaASCII(c);
            else
                *dst = c;
            prev_alphanum = alphanum;
        }
    }
};

struct NameInitcap
{
    static constexpr auto name = "initcap";
};
using FunctionInitcap = FunctionStringToString<InitcapImpl, NameInitcap>;

}

REGISTER_FUNCTION(Initcap)
{
    factory.registerFunction<FunctionInitcap>({}, FunctionFactory::CaseInsensitive);
}

}