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
8namespace DB
9{
10namespace
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
105String ASTCreateQuotaQuery::getID(char) const
106{
107 return "CreateQuotaQuery";
108}
109
110
111ASTPtr ASTCreateQuotaQuery::clone() const
112{
113 return std::make_shared<ASTCreateQuotaQuery>(*this);
114}
115
116
117void 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