/Users/deen/code/yugabyte-db/src/yb/yql/cql/ql/util/ql_env.cc
Line | Count | Source (jump to first uncovered line) |
1 | | //-------------------------------------------------------------------------------------------------- |
2 | | // Copyright (c) YugaByte, Inc. |
3 | | // |
4 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
5 | | // in compliance with the License. You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
10 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
11 | | // or implied. See the License for the specific language governing permissions and limitations |
12 | | // under the License. |
13 | | // |
14 | | // |
15 | | // QLEnv represents the environment where SQL statements are being processed. |
16 | | //-------------------------------------------------------------------------------------------------- |
17 | | |
18 | | #include "yb/yql/cql/ql/util/ql_env.h" |
19 | | |
20 | | #include "yb/client/client.h" |
21 | | #include "yb/client/meta_data_cache.h" |
22 | | #include "yb/client/permissions.h" |
23 | | #include "yb/client/schema.h" |
24 | | #include "yb/client/session.h" |
25 | | #include "yb/client/table.h" |
26 | | #include "yb/client/table_alterer.h" |
27 | | #include "yb/client/table_creator.h" |
28 | | #include "yb/client/transaction.h" |
29 | | #include "yb/client/transaction_pool.h" |
30 | | |
31 | | #include "yb/common/ql_type.h" |
32 | | |
33 | | #include "yb/util/result.h" |
34 | | #include "yb/util/status_format.h" |
35 | | #include "yb/util/status_log.h" |
36 | | |
37 | | DEFINE_bool(use_cassandra_authentication, false, "If to require authentication on startup."); |
38 | | DEFINE_bool(ycql_cache_login_info, false, "Use authentication information cached locally."); |
39 | | DEFINE_bool(ycql_require_drop_privs_for_truncate, false, |
40 | | "Require DROP TABLE permission in order to truncate table"); |
41 | | |
42 | | namespace yb { |
43 | | namespace ql { |
44 | | |
45 | | using std::string; |
46 | | using std::shared_ptr; |
47 | | using std::unique_ptr; |
48 | | using std::weak_ptr; |
49 | | |
50 | | using client::TransactionManager; |
51 | | using client::YBClient; |
52 | | using client::YBSession; |
53 | | using client::YBSessionPtr; |
54 | | using client::YBTable; |
55 | | using client::YBTransaction; |
56 | | using client::YBTransactionPtr; |
57 | | using client::YBMetaDataCache; |
58 | | using client::YBTableCreator; |
59 | | using client::YBTableAlterer; |
60 | | using client::YBTableName; |
61 | | |
62 | | QLEnv::QLEnv(client::YBClient* client, |
63 | | shared_ptr<YBMetaDataCache> cache, |
64 | | const server::ClockPtr& clock, |
65 | | TransactionPoolProvider transaction_pool_provider) |
66 | | : client_(client), |
67 | | metadata_cache_(std::move(cache)), |
68 | | clock_(std::move(clock)), |
69 | 17.1k | transaction_pool_provider_(std::move(transaction_pool_provider)) { |
70 | 17.1k | } |
71 | | |
72 | 1 | QLEnv::~QLEnv() {} |
73 | | |
74 | | //------------------------------------------------------------------------------------------------ |
75 | 1.59k | unique_ptr<YBTableCreator> QLEnv::NewTableCreator() { |
76 | 1.59k | return client_->NewTableCreator(); |
77 | 1.59k | } |
78 | | |
79 | 55 | unique_ptr<YBTableAlterer> QLEnv::NewTableAlterer(const YBTableName& table_name) { |
80 | 55 | return client_->NewTableAlterer(table_name); |
81 | 55 | } |
82 | | |
83 | 3.02k | CHECKED_STATUS QLEnv::TruncateTable(const string& table_id) { |
84 | 3.02k | return client_->TruncateTable(table_id); |
85 | 3.02k | } |
86 | | |
87 | 1.10k | CHECKED_STATUS QLEnv::DeleteTable(const YBTableName& name) { |
88 | 1.10k | return client_->DeleteTable(name); |
89 | 1.10k | } |
90 | | |
91 | 105 | CHECKED_STATUS QLEnv::DeleteIndexTable(const YBTableName& name, YBTableName* indexed_table_name) { |
92 | 105 | return client_->DeleteIndexTable(name, indexed_table_name); |
93 | 105 | } |
94 | | |
95 | | //------------------------------------------------------------------------------------------------ |
96 | | Result<YBTransactionPtr> QLEnv::NewTransaction(const YBTransactionPtr& transaction, |
97 | 136k | const IsolationLevel isolation_level) { |
98 | 136k | if (transaction) { |
99 | 0 | DCHECK(transaction->IsRestartRequired()); |
100 | 0 | return transaction->CreateRestartedTransaction(); |
101 | 0 | } |
102 | 136k | if (transaction_pool_ == nullptr) { |
103 | 1.03k | if (transaction_pool_provider_) { |
104 | 1.03k | transaction_pool_ = transaction_pool_provider_(); |
105 | 0 | } else { |
106 | 0 | return STATUS(InternalError, "No transaction pool provider"); |
107 | 0 | } |
108 | 136k | } |
109 | 136k | auto result = transaction_pool_->Take(client::ForceGlobalTransaction::kTrue); |
110 | 136k | RETURN_NOT_OK(result->Init(isolation_level)); |
111 | 136k | return result; |
112 | 136k | } |
113 | | |
114 | 97.3k | YBSessionPtr QLEnv::NewSession() { |
115 | 97.3k | return std::make_shared<YBSession>(client_, clock_); |
116 | 97.3k | } |
117 | | |
118 | | //------------------------------------------------------------------------------------------------ |
119 | 318k | shared_ptr<YBTable> QLEnv::GetTableDesc(const YBTableName& table_name, bool* cache_used) { |
120 | | // Hide tables in system_redis keyspace. |
121 | 318k | if (table_name.is_redis_namespace()) { |
122 | 0 | return nullptr; |
123 | 0 | } |
124 | 318k | shared_ptr<YBTable> yb_table; |
125 | 318k | Status s = metadata_cache_->GetTable(table_name, &yb_table, cache_used); |
126 | | |
127 | 318k | if (!s.ok()) { |
128 | 0 | VLOG(3) << "GetTableDesc: Server returns an error: " << s.ToString(); |
129 | 2.26k | return nullptr; |
130 | 2.26k | } |
131 | | |
132 | 316k | return yb_table; |
133 | 316k | } |
134 | | |
135 | 1.41k | shared_ptr<YBTable> QLEnv::GetTableDesc(const TableId& table_id, bool* cache_used) { |
136 | 1.41k | shared_ptr<YBTable> yb_table; |
137 | 1.41k | Status s = metadata_cache_->GetTable(table_id, &yb_table, cache_used); |
138 | | |
139 | 1.41k | if (!s.ok()) { |
140 | 0 | VLOG(3) << "GetTableDesc: Server returns an error: " << s.ToString(); |
141 | 0 | return nullptr; |
142 | 0 | } |
143 | | |
144 | 1.41k | return yb_table; |
145 | 1.41k | } |
146 | | |
147 | | CHECKED_STATUS QLEnv::GetUpToDateTableSchemaVersion(const YBTableName& table_name, |
148 | 110 | uint32_t* ver) { |
149 | 110 | shared_ptr<YBTable> yb_table; |
150 | 110 | RETURN_NOT_OK(client_->OpenTable(table_name, &yb_table)); |
151 | | |
152 | 102 | if (yb_table) { |
153 | 102 | *ver = yb_table->schema().version(); |
154 | 102 | return Status::OK(); |
155 | 0 | } else { |
156 | 0 | return STATUS_SUBSTITUTE(NotFound, "Cannot get table $0", table_name.ToString()); |
157 | 0 | } |
158 | 102 | } |
159 | | |
160 | | shared_ptr<QLType> QLEnv::GetUDType(const std::string& keyspace_name, |
161 | | const std::string& type_name, |
162 | 81 | bool* cache_used) { |
163 | 81 | shared_ptr<QLType> ql_type = std::make_shared<QLType>(keyspace_name, type_name); |
164 | 81 | Status s = metadata_cache_->GetUDType(keyspace_name, type_name, &ql_type, cache_used); |
165 | | |
166 | 81 | if (!s.ok()) { |
167 | 0 | VLOG(3) << "GetTypeDesc: Server returned an error: " << s.ToString(); |
168 | 7 | return nullptr; |
169 | 7 | } |
170 | | |
171 | 74 | return ql_type; |
172 | 74 | } |
173 | | |
174 | 9.24k | void QLEnv::RemoveCachedTableDesc(const YBTableName& table_name) { |
175 | 9.24k | metadata_cache_->RemoveCachedTable(table_name); |
176 | 9.24k | } |
177 | | |
178 | 0 | void QLEnv::RemoveCachedTableDesc(const TableId& table_id) { |
179 | 0 | metadata_cache_->RemoveCachedTable(table_id); |
180 | 0 | } |
181 | | |
182 | 59 | void QLEnv::RemoveCachedUDType(const std::string& keyspace_name, const std::string& type_name) { |
183 | 59 | metadata_cache_->RemoveCachedUDType(keyspace_name, type_name); |
184 | 59 | } |
185 | | |
186 | | //------------------------------------------------------------------------------------------------ |
187 | | Status QLEnv::GrantRevokePermission(client::GrantRevokeStatementType statement_type, |
188 | | const PermissionType& permission, |
189 | | const ResourceType& resource_type, |
190 | | const std::string& canonical_resource, |
191 | | const char* resource_name, |
192 | | const char* namespace_name, |
193 | 721 | const std::string& role_name) { |
194 | 721 | return client_->GrantRevokePermission(statement_type, permission, resource_type, |
195 | 721 | canonical_resource, resource_name, namespace_name, |
196 | 721 | role_name); |
197 | 721 | } |
198 | | |
199 | | //------------------------------------------------------------------------------------------------ |
200 | 1.61k | Status QLEnv::CreateKeyspace(const std::string& keyspace_name) { |
201 | 1.61k | return client_->CreateNamespace(keyspace_name, YQLDatabase::YQL_DATABASE_CQL, CurrentRoleName()); |
202 | 1.61k | } |
203 | | |
204 | 1.49k | Status QLEnv::DeleteKeyspace(const string& keyspace_name) { |
205 | 1.49k | RETURN_NOT_OK(client_->DeleteNamespace(keyspace_name)); |
206 | | |
207 | | // Reset the current keyspace name if it's dropped. |
208 | 1.49k | if (ql_session()->current_keyspace() == keyspace_name) { |
209 | 990 | ql_session()->set_current_keyspace(kUndefinedKeyspace); |
210 | 990 | } |
211 | 1.49k | return Status::OK(); |
212 | 1.49k | } |
213 | | |
214 | 4.18k | Status QLEnv::UseKeyspace(const string& keyspace_name) { |
215 | | // Check if a keyspace with the specified name exists. |
216 | 4.18k | Result<bool> exists = client_->NamespaceExists(keyspace_name); |
217 | 4.18k | RETURN_NOT_OK(exists); |
218 | 4.18k | if (!exists.get()) { |
219 | 1 | return STATUS(NotFound, "Cannot use unknown keyspace"); |
220 | 1 | } |
221 | | |
222 | 4.18k | ql_session()->set_current_keyspace(keyspace_name); |
223 | 4.18k | return Status::OK(); |
224 | 4.18k | } |
225 | | |
226 | 21 | Status QLEnv::AlterKeyspace(const string& keyspace_name) { |
227 | | // Check if a keyspace with the specified name exists. |
228 | 21 | Result<bool> exists = client_->NamespaceExists(keyspace_name); |
229 | 21 | RETURN_NOT_OK(exists); |
230 | 21 | if (!exists.get()) { |
231 | 1 | return STATUS(NotFound, "Cannot alter unknown keyspace"); |
232 | 1 | } |
233 | | |
234 | | // Current implementation does not update any keyspace properties. |
235 | 20 | return Status::OK(); |
236 | 20 | } |
237 | | |
238 | | //------------------------------------------------------------------------------------------------ |
239 | | Status QLEnv::CreateRole(const std::string& role_name, |
240 | | const std::string& salted_hash, |
241 | 757 | const bool login, const bool superuser) { |
242 | 757 | return client_->CreateRole(role_name, salted_hash, login, superuser, CurrentRoleName()); |
243 | 757 | } |
244 | | |
245 | | Status QLEnv::AlterRole(const std::string& role_name, |
246 | | const boost::optional<std::string>& salted_hash, |
247 | | const boost::optional<bool> login, |
248 | 58 | const boost::optional<bool> superuser) { |
249 | 58 | return client_->AlterRole(role_name, salted_hash, login, superuser, CurrentRoleName()); |
250 | 58 | } |
251 | | |
252 | 730 | Status QLEnv::DeleteRole(const std::string& role_name) { |
253 | 730 | return client_->DeleteRole(role_name, CurrentRoleName()); |
254 | 730 | } |
255 | | |
256 | | Status QLEnv::GrantRevokeRole(client::GrantRevokeStatementType statement_type, |
257 | | const std::string& granted_role_name, |
258 | 52 | const std::string& recipient_role_name) { |
259 | 52 | return client_->GrantRevokeRole(statement_type, granted_role_name, recipient_role_name); |
260 | 52 | } |
261 | | |
262 | | Status QLEnv::HasResourcePermission(const string& canonical_name, |
263 | | const ql::ObjectType& object_type, |
264 | | const PermissionType permission, |
265 | | const NamespaceName& keyspace, |
266 | 8.77k | const TableName& table) { |
267 | 8.77k | DFATAL_OR_RETURN_ERROR_IF(!FLAGS_use_cassandra_authentication, STATUS(IllegalState, |
268 | 8.77k | "Permissions check is not allowed when use_cassandra_authentication flag is disabled")); |
269 | 8.77k | return metadata_cache_->HasResourcePermission(canonical_name, object_type, CurrentRoleName(), |
270 | 8.77k | permission, keyspace, table, |
271 | 8.77k | client::CacheCheckMode::RETRY); |
272 | 8.77k | } |
273 | | |
274 | 519 | Result<std::string> QLEnv::RoleSaltedHash(const RoleName& role_name) { |
275 | 519 | return metadata_cache_->RoleSaltedHash(role_name); |
276 | 519 | } |
277 | | |
278 | 398 | Result<bool> QLEnv::RoleCanLogin(const RoleName& role_name) { |
279 | 398 | return metadata_cache_->RoleCanLogin(role_name); |
280 | 398 | } |
281 | | |
282 | | Status QLEnv::HasTablePermission(const NamespaceName& keyspace_name, |
283 | | const TableName& table_name, |
284 | 4.29k | const PermissionType permission) { |
285 | 4.29k | return metadata_cache_->HasTablePermission(keyspace_name, table_name, CurrentRoleName(), |
286 | 4.29k | permission); |
287 | 4.29k | } |
288 | | |
289 | | Status QLEnv::HasTablePermission(const client::YBTableName table_name, |
290 | 1.88k | const PermissionType permission) { |
291 | 1.88k | return HasTablePermission(table_name.namespace_name(), table_name.table_name(), permission); |
292 | 1.88k | } |
293 | | |
294 | 1.96k | Status QLEnv::HasRolePermission(const RoleName& role_name, const PermissionType permission) { |
295 | 1.96k | return HasResourcePermission(get_canonical_role(role_name), ObjectType::ROLE, permission); |
296 | 1.96k | } |
297 | | |
298 | | //------------------------------------------------------------------------------------------------ |
299 | | Status QLEnv::CreateUDType(const std::string& keyspace_name, |
300 | | const std::string& type_name, |
301 | | const std::vector<std::string>& field_names, |
302 | 46 | const std::vector<std::shared_ptr<QLType>>& field_types) { |
303 | 46 | return client_->CreateUDType(keyspace_name, type_name, field_names, field_types); |
304 | 46 | } |
305 | | |
306 | 53 | Status QLEnv::DeleteUDType(const std::string& keyspace_name, const std::string& type_name) { |
307 | 53 | return client_->DeleteUDType(keyspace_name, type_name); |
308 | 53 | } |
309 | | |
310 | | } // namespace ql |
311 | | } // namespace yb |