1 | #include <Parsers/ASTCreateQuotaQuery.h> |
2 | #include <Parsers/ASTRoleList.h> |
3 | #include <Common/quoteString.h> |
4 | #include <Common/IntervalKind.h> |
5 | #include <ext/range.h> |
6 | |
7 | |
8 | namespace DB |
9 | { |
10 | namespace |
11 | { |
12 | using KeyType = Quota::KeyType; |
13 | using ResourceType = Quota::ResourceType; |
14 | using ResourceAmount = Quota::ResourceAmount; |
15 | |
16 | |
17 | void formatKeyType(const KeyType & key_type, const IAST::FormatSettings & settings) |
18 | { |
19 | settings.ostr << (settings.hilite ? IAST::hilite_keyword : "" ) << " KEYED BY " << (settings.hilite ? IAST::hilite_none : "" ) << "'" |
20 | << Quota::getNameOfKeyType(key_type) << "'" ; |
21 | } |
22 | |
23 | |
24 | void formatRenameTo(const String & new_name, const IAST::FormatSettings & settings) |
25 | { |
26 | settings.ostr << (settings.hilite ? IAST::hilite_keyword : "" ) << " RENAME TO " << (settings.hilite ? IAST::hilite_none : "" ) |
27 | << backQuote(new_name); |
28 | } |
29 | |
30 | |
31 | void formatLimit(ResourceType resource_type, ResourceAmount max, const IAST::FormatSettings & settings) |
32 | { |
33 | settings.ostr << (settings.hilite ? IAST::hilite_keyword : "" ) << " MAX " << Quota::resourceTypeToKeyword(resource_type) |
34 | << (settings.hilite ? IAST::hilite_none : "" ); |
35 | |
36 | settings.ostr << (settings.hilite ? IAST::hilite_operator : "" ) << " = " << (settings.hilite ? IAST::hilite_none : "" ); |
37 | |
38 | if (max == Quota::UNLIMITED) |
39 | settings.ostr << (settings.hilite ? IAST::hilite_keyword : "" ) << "ANY" << (settings.hilite ? IAST::hilite_none : "" ); |
40 | else if (resource_type == Quota::EXECUTION_TIME) |
41 | settings.ostr << Quota::executionTimeToSeconds(max); |
42 | else |
43 | settings.ostr << max; |
44 | } |
45 | |
46 | |
47 | void formatLimits(const ASTCreateQuotaQuery::Limits & limits, const IAST::FormatSettings & settings) |
48 | { |
49 | auto interval_kind = IntervalKind::fromAvgSeconds(limits.duration.count()); |
50 | Int64 num_intervals = limits.duration.count() / interval_kind.toAvgSeconds(); |
51 | |
52 | settings.ostr << (settings.hilite ? IAST::hilite_keyword : "" ) |
53 | << " FOR" |
54 | << (limits.randomize_interval ? " RANDOMIZED" : "" ) |
55 | << " INTERVAL " |
56 | << (settings.hilite ? IAST::hilite_none : "" ) |
57 | << num_intervals << " " |
58 | << (settings.hilite ? IAST::hilite_keyword : "" ) |
59 | << interval_kind.toKeyword() |
60 | << (settings.hilite ? IAST::hilite_none : "" ); |
61 | |
62 | if (limits.unset_tracking) |
63 | { |
64 | settings.ostr << (settings.hilite ? IAST::hilite_keyword : "" ) << " UNSET TRACKING" << (settings.hilite ? IAST::hilite_none : "" ); |
65 | } |
66 | else |
67 | { |
68 | bool limit_found = false; |
69 | for (auto resource_type : ext::range_with_static_cast<ResourceType>(Quota::MAX_RESOURCE_TYPE)) |
70 | { |
71 | if (limits.max[resource_type]) |
72 | { |
73 | if (limit_found) |
74 | settings.ostr << "," ; |
75 | limit_found = true; |
76 | formatLimit(resource_type, *limits.max[resource_type], settings); |
77 | } |
78 | } |
79 | if (!limit_found) |
80 | settings.ostr << (settings.hilite ? IAST::hilite_keyword : "" ) << " TRACKING" << (settings.hilite ? IAST::hilite_none : "" ); |
81 | } |
82 | } |
83 | |
84 | void formatAllLimits(const std::vector<ASTCreateQuotaQuery::Limits> & all_limits, const IAST::FormatSettings & settings) |
85 | { |
86 | bool need_comma = false; |
87 | for (auto & limits : all_limits) |
88 | { |
89 | if (need_comma) |
90 | settings.ostr << "," ; |
91 | need_comma = true; |
92 | |
93 | formatLimits(limits, settings); |
94 | } |
95 | } |
96 | |
97 | void formatRoles(const ASTRoleList & roles, const IAST::FormatSettings & settings) |
98 | { |
99 | settings.ostr << (settings.hilite ? IAST::hilite_keyword : "" ) << " TO " << (settings.hilite ? IAST::hilite_none : "" ); |
100 | roles.format(settings); |
101 | } |
102 | } |
103 | |
104 | |
105 | String ASTCreateQuotaQuery::getID(char) const |
106 | { |
107 | return "CreateQuotaQuery" ; |
108 | } |
109 | |
110 | |
111 | ASTPtr ASTCreateQuotaQuery::clone() const |
112 | { |
113 | return std::make_shared<ASTCreateQuotaQuery>(*this); |
114 | } |
115 | |
116 | |
117 | void ASTCreateQuotaQuery::formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const |
118 | { |
119 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << (alter ? "ALTER QUOTA" : "CREATE QUOTA" ) |
120 | << (settings.hilite ? hilite_none : "" ); |
121 | |
122 | if (if_exists) |
123 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << " IF EXISTS" << (settings.hilite ? hilite_none : "" ); |
124 | else if (if_not_exists) |
125 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << " IF NOT EXISTS" << (settings.hilite ? hilite_none : "" ); |
126 | else if (or_replace) |
127 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << " OR REPLACE" << (settings.hilite ? hilite_none : "" ); |
128 | |
129 | settings.ostr << " " << backQuoteIfNeed(name); |
130 | |
131 | if (!new_name.empty()) |
132 | formatRenameTo(new_name, settings); |
133 | |
134 | if (key_type) |
135 | formatKeyType(*key_type, settings); |
136 | |
137 | formatAllLimits(all_limits, settings); |
138 | |
139 | if (roles) |
140 | formatRoles(*roles, settings); |
141 | } |
142 | } |
143 | |