ParserRolesOrUsersSet.cpp 4.3 KB
Newer Older
1
#include <Parsers/ParserRolesOrUsersSet.h>
V
Vitaly Baranov 已提交
2
#include <Parsers/CommonParsers.h>
3 4
#include <Parsers/ExpressionElementParsers.h>
#include <Parsers/ASTLiteral.h>
5
#include <Parsers/ASTRolesOrUsersSet.h>
6
#include <Parsers/parseUserName.h>
V
Vitaly Baranov 已提交
7 8 9 10 11
#include <boost/range/algorithm/find.hpp>


namespace DB
{
12
namespace
V
Vitaly Baranov 已提交
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
    bool parseRoleNameOrID(IParserBase::Pos & pos, Expected & expected, bool parse_id, String & res)
    {
        return IParserBase::wrapParseImpl(pos, [&]
        {
            if (!parse_id)
                return parseRoleName(pos, expected, res);

            if (!ParserKeyword{"ID"}.ignore(pos, expected))
                return false;
            if (!ParserToken(TokenType::OpeningRoundBracket).ignore(pos, expected))
                return false;
            ASTPtr ast;
            if (!ParserStringLiteral{}.parse(pos, ast, expected))
                return false;
            String id = ast->as<ASTLiteral &>().value.safeGet<String>();
            if (!ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
                return false;

            res = std::move(id);
            return true;
        });
    }


    bool parseBeforeExcept(
        IParserBase::Pos & pos,
        Expected & expected,
        bool id_mode,
42 43
        bool allow_all,
        bool allow_current_user_tag,
44 45 46
        Strings & names,
        bool & all,
        bool & current_user)
V
Vitaly Baranov 已提交
47
    {
48
        return IParserBase::wrapParseImpl(pos, [&]
V
Vitaly Baranov 已提交
49
        {
50 51 52 53
            bool res_all = false;
            bool res_current_user = false;
            Strings res_names;
            while (true)
V
Vitaly Baranov 已提交
54
            {
55 56 57 58
                if (ParserKeyword{"NONE"}.ignore(pos, expected))
                {
                }
                else if (
59
                    allow_current_user_tag
60
                    && (ParserKeyword{"CURRENT_USER"}.ignore(pos, expected) || ParserKeyword{"currentUser"}.ignore(pos, expected)))
61 62 63 64 65 66 67 68
                {
                    if (ParserToken{TokenType::OpeningRoundBracket}.ignore(pos, expected))
                    {
                        if (!ParserToken{TokenType::ClosingRoundBracket}.ignore(pos, expected))
                            return false;
                    }
                    res_current_user = true;
                }
69
                else if (allow_all && ParserKeyword{"ALL"}.ignore(pos, expected))
70 71 72 73 74 75
                {
                    res_all = true;
                }
                else
                {
                    String name;
76
                    if (!parseRoleNameOrID(pos, expected, id_mode, name))
77 78 79 80 81 82
                        return false;
                    res_names.push_back(name);
                }

                if (!ParserToken{TokenType::Comma}.ignore(pos, expected))
                    break;
V
Vitaly Baranov 已提交
83 84
            }

85 86
            all = res_all;
            current_user = res_current_user;
87 88 89
            names = std::move(res_names);
            return true;
        });
V
Vitaly Baranov 已提交
90 91
    }

92 93 94 95
    bool parseExceptAndAfterExcept(
        IParserBase::Pos & pos,
        Expected & expected,
        bool id_mode,
96
        bool allow_current_user_tag,
97 98
        Strings & except_names,
        bool & except_current_user)
V
Vitaly Baranov 已提交
99
    {
100 101 102 103 104
        return IParserBase::wrapParseImpl(pos, [&]
        {
            if (!ParserKeyword{"EXCEPT"}.ignore(pos, expected))
                return false;

105
            bool dummy;
106
            return parseBeforeExcept(pos, expected, id_mode, false, allow_current_user_tag, except_names, dummy, except_current_user);
107
        });
V
Vitaly Baranov 已提交
108
    }
109 110 111
}


112
bool ParserRolesOrUsersSet::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
113 114 115 116 117 118 119
{
    Strings names;
    bool current_user = false;
    bool all = false;
    Strings except_names;
    bool except_current_user = false;

120
    if (!parseBeforeExcept(pos, expected, id_mode, allow_all, allow_current_user, names, all, current_user))
121 122
        return false;

123
    parseExceptAndAfterExcept(pos, expected, id_mode, allow_current_user, except_names, except_current_user);
124 125 126

    if (all)
        names.clear();
V
Vitaly Baranov 已提交
127

128
    auto result = std::make_shared<ASTRolesOrUsersSet>();
129
    result->names = std::move(names);
V
Vitaly Baranov 已提交
130
    result->current_user = current_user;
131 132
    result->all = all;
    result->except_names = std::move(except_names);
V
Vitaly Baranov 已提交
133
    result->except_current_user = except_current_user;
134
    result->id_mode = id_mode;
135 136
    result->allow_user_names = allow_user_names;
    result->allow_role_names = allow_role_names;
V
Vitaly Baranov 已提交
137 138 139 140 141
    node = result;
    return true;
}

}