1#include <Interpreters/InterpreterShowQuotasQuery.h>
2#include <Interpreters/executeQuery.h>
3#include <Parsers/ASTShowQuotasQuery.h>
4#include <Parsers/formatAST.h>
5#include <Access/Quota.h>
6#include <Common/quoteString.h>
7#include <Common/StringUtils/StringUtils.h>
8#include <ext/range.h>
9
10
11namespace DB
12{
13InterpreterShowQuotasQuery::InterpreterShowQuotasQuery(const ASTPtr & query_ptr_, Context & context_)
14 : query_ptr(query_ptr_), context(context_)
15{
16}
17
18
19String InterpreterShowQuotasQuery::getRewrittenQuery()
20{
21 const auto & query = query_ptr->as<ASTShowQuotasQuery &>();
22
23 /// Transform the query into some kind of "SELECT from system.quotas" query.
24 String expr;
25 String filter;
26 String table_name;
27 String order_by;
28 if (query.usage)
29 {
30 expr = "name || ' key=\\'' || key || '\\'' || if(isNull(end_of_interval), '', ' interval=[' || "
31 "toString(end_of_interval - duration) || ' .. ' || "
32 "toString(end_of_interval) || ']'";
33 for (auto resource_type : ext::range_with_static_cast<Quota::ResourceType>(Quota::MAX_RESOURCE_TYPE))
34 {
35 String column_name = Quota::resourceTypeToColumnName(resource_type);
36 expr += String{" || ' "} + column_name + "=' || toString(" + column_name + ")";
37 expr += String{" || if(max_"} + column_name + "=0, '', '/' || toString(max_" + column_name + "))";
38 }
39 expr += ")";
40
41 if (query.current)
42 filter = "(id = currentQuotaID()) AND (key = currentQuotaKey())";
43
44 table_name = "system.quota_usage";
45 order_by = "name, key, duration";
46 }
47 else
48 {
49 expr = "name";
50 table_name = "system.quotas";
51 order_by = "name";
52 }
53
54 /// Prepare description of the result column.
55 std::stringstream ss;
56 formatAST(query, ss, false, true);
57 String desc = ss.str();
58 String prefix = "SHOW ";
59 if (startsWith(desc, prefix))
60 desc = desc.substr(prefix.length()); /// `desc` always starts with "SHOW ", so we can trim this prefix.
61
62 /// Build a new query.
63 return "SELECT " + expr + " AS " + backQuote(desc) + " FROM " + table_name + (filter.empty() ? "" : (" WHERE " + filter))
64 + (order_by.empty() ? "" : (" ORDER BY " + order_by));
65}
66
67
68BlockIO InterpreterShowQuotasQuery::execute()
69{
70 return executeQuery(getRewrittenQuery(), context, true);
71}
72
73}
74