1#include <Interpreters/InterpreterShowCreateAccessEntityQuery.h>
2#include <Interpreters/Context.h>
3#include <Parsers/ASTCreateQuotaQuery.h>
4#include <Parsers/ASTCreateRowPolicyQuery.h>
5#include <Parsers/ASTShowCreateAccessEntityQuery.h>
6#include <Parsers/ASTRoleList.h>
7#include <Parsers/ExpressionListParsers.h>
8#include <Parsers/formatAST.h>
9#include <Parsers/parseQuery.h>
10#include <Access/AccessControlManager.h>
11#include <Access/QuotaContext.h>
12#include <Columns/ColumnString.h>
13#include <DataStreams/OneBlockInputStream.h>
14#include <DataTypes/DataTypeString.h>
15#include <ext/range.h>
16#include <sstream>
17
18
19namespace DB
20{
21BlockIO InterpreterShowCreateAccessEntityQuery::execute()
22{
23 BlockIO res;
24 res.in = executeImpl();
25 return res;
26}
27
28
29BlockInputStreamPtr InterpreterShowCreateAccessEntityQuery::executeImpl()
30{
31 const auto & show_query = query_ptr->as<ASTShowCreateAccessEntityQuery &>();
32
33 /// Build a create query.
34 ASTPtr create_query = getCreateQuery(show_query);
35
36 /// Build the result column.
37 std::stringstream create_query_ss;
38 formatAST(*create_query, create_query_ss, false, true);
39 String create_query_str = create_query_ss.str();
40 MutableColumnPtr column = ColumnString::create();
41 column->insert(create_query_str);
42
43 /// Prepare description of the result column.
44 std::stringstream desc_ss;
45 formatAST(show_query, desc_ss, false, true);
46 String desc = desc_ss.str();
47 String prefix = "SHOW ";
48 if (startsWith(desc, prefix))
49 desc = desc.substr(prefix.length()); /// `desc` always starts with "SHOW ", so we can trim this prefix.
50
51 return std::make_shared<OneBlockInputStream>(Block{{std::move(column), std::make_shared<DataTypeString>(), desc}});
52}
53
54
55ASTPtr InterpreterShowCreateAccessEntityQuery::getCreateQuery(const ASTShowCreateAccessEntityQuery & show_query) const
56{
57 using Kind = ASTShowCreateAccessEntityQuery::Kind;
58 switch (show_query.kind)
59 {
60 case Kind::QUOTA: return getCreateQuotaQuery(show_query);
61 case Kind::ROW_POLICY: return getCreateRowPolicyQuery(show_query);
62 }
63 __builtin_unreachable();
64}
65
66
67ASTPtr InterpreterShowCreateAccessEntityQuery::getCreateQuotaQuery(const ASTShowCreateAccessEntityQuery & show_query) const
68{
69 auto & access_control = context.getAccessControlManager();
70
71 QuotaPtr quota;
72 if (show_query.current_quota)
73 quota = access_control.read<Quota>(context.getQuota()->getUsageInfo().quota_id);
74 else
75 quota = access_control.read<Quota>(show_query.name);
76
77 auto create_query = std::make_shared<ASTCreateQuotaQuery>();
78 create_query->name = quota->getName();
79 create_query->key_type = quota->key_type;
80 create_query->all_limits.reserve(quota->all_limits.size());
81
82 for (const auto & limits : quota->all_limits)
83 {
84 ASTCreateQuotaQuery::Limits create_query_limits;
85 create_query_limits.duration = limits.duration;
86 create_query_limits.randomize_interval = limits.randomize_interval;
87 for (auto resource_type : ext::range(Quota::MAX_RESOURCE_TYPE))
88 if (limits.max[resource_type])
89 create_query_limits.max[resource_type] = limits.max[resource_type];
90 create_query->all_limits.push_back(create_query_limits);
91 }
92
93 if (!quota->roles.empty() || quota->all_roles)
94 {
95 auto create_query_roles = std::make_shared<ASTRoleList>();
96 create_query_roles->roles = quota->roles;
97 create_query_roles->all_roles = quota->all_roles;
98 create_query_roles->except_roles = quota->except_roles;
99 create_query->roles = std::move(create_query_roles);
100 }
101
102 return create_query;
103}
104
105
106ASTPtr InterpreterShowCreateAccessEntityQuery::getCreateRowPolicyQuery(const ASTShowCreateAccessEntityQuery & show_query) const
107{
108 auto & access_control = context.getAccessControlManager();
109 RowPolicyPtr policy = access_control.read<RowPolicy>(show_query.row_policy_name.getFullName(context));
110
111 auto create_query = std::make_shared<ASTCreateRowPolicyQuery>();
112 create_query->name_parts = RowPolicy::FullNameParts{policy->getDatabase(), policy->getTableName(), policy->getName()};
113 if (policy->isRestrictive())
114 create_query->is_restrictive = policy->isRestrictive();
115
116 for (auto index : ext::range_with_static_cast<RowPolicy::ConditionIndex>(RowPolicy::MAX_CONDITION_INDEX))
117 {
118 const auto & condition = policy->conditions[index];
119 if (!condition.empty())
120 {
121 ParserExpression parser;
122 ASTPtr expr = parseQuery(parser, condition, 0);
123 create_query->conditions.push_back(std::pair{index, expr});
124 }
125 }
126
127 if (!policy->roles.empty() || policy->all_roles)
128 {
129 auto create_query_roles = std::make_shared<ASTRoleList>();
130 create_query_roles->roles = policy->roles;
131 create_query_roles->all_roles = policy->all_roles;
132 create_query_roles->except_roles = policy->except_roles;
133 create_query->roles = std::move(create_query_roles);
134 }
135
136 return create_query;
137}
138}
139