1#include <Parsers/ParserRoleList.h>
2#include <Parsers/CommonParsers.h>
3#include <Parsers/ASTRoleList.h>
4#include <Parsers/parseIdentifierOrStringLiteral.h>
5#include <boost/range/algorithm/find.hpp>
6
7
8namespace DB
9{
10
11bool ParserRoleList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
12{
13 Strings roles;
14 bool current_user = false;
15 bool all_roles = false;
16 Strings except_roles;
17 bool except_current_user = false;
18
19 bool except_mode = false;
20 while (true)
21 {
22 if (ParserKeyword{"NONE"}.ignore(pos, expected))
23 {
24 }
25 else if (ParserKeyword{"CURRENT_USER"}.ignore(pos, expected) ||
26 ParserKeyword{"currentUser"}.ignore(pos, expected))
27 {
28 if (ParserToken{TokenType::OpeningRoundBracket}.ignore(pos, expected))
29 {
30 if (!ParserToken{TokenType::ClosingRoundBracket}.ignore(pos, expected))
31 return false;
32 }
33 if (except_mode && !current_user)
34 except_current_user = true;
35 else
36 current_user = true;
37 }
38 else if (ParserKeyword{"ALL"}.ignore(pos, expected))
39 {
40 all_roles = true;
41 if (ParserKeyword{"EXCEPT"}.ignore(pos, expected))
42 {
43 except_mode = true;
44 continue;
45 }
46 }
47 else
48 {
49 String name;
50 if (!parseIdentifierOrStringLiteral(pos, expected, name))
51 return false;
52 if (except_mode && (boost::range::find(roles, name) == roles.end()))
53 except_roles.push_back(name);
54 else
55 roles.push_back(name);
56 }
57
58 if (!ParserToken{TokenType::Comma}.ignore(pos, expected))
59 break;
60 }
61
62 if (all_roles)
63 {
64 current_user = false;
65 roles.clear();
66 }
67
68 auto result = std::make_shared<ASTRoleList>();
69 result->roles = std::move(roles);
70 result->current_user = current_user;
71 result->all_roles = all_roles;
72 result->except_roles = std::move(except_roles);
73 result->except_current_user = except_current_user;
74 node = result;
75 return true;
76}
77
78}
79