/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 | 18.1k | transaction_pool_provider_(std::move(transaction_pool_provider)) { |
70 | 18.1k | } |
71 | | |
72 | 1 | QLEnv::~QLEnv() {} |
73 | | |
74 | | //------------------------------------------------------------------------------------------------ |
75 | 1.66k | unique_ptr<YBTableCreator> QLEnv::NewTableCreator() { |
76 | 1.66k | return client_->NewTableCreator(); |
77 | 1.66k | } |
78 | | |
79 | 57 | unique_ptr<YBTableAlterer> QLEnv::NewTableAlterer(const YBTableName& table_name) { |
80 | 57 | return client_->NewTableAlterer(table_name); |
81 | 57 | } |
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.16k | CHECKED_STATUS QLEnv::DeleteTable(const YBTableName& name) { |
88 | 1.16k | return client_->DeleteTable(name); |
89 | 1.16k | } |
90 | | |
91 | 106 | CHECKED_STATUS QLEnv::DeleteIndexTable(const YBTableName& name, YBTableName* indexed_table_name) { |
92 | 106 | return client_->DeleteIndexTable(name, indexed_table_name); |
93 | 106 | } |
94 | | |
95 | | //------------------------------------------------------------------------------------------------ |
96 | | Result<YBTransactionPtr> QLEnv::NewTransaction(const YBTransactionPtr& transaction, |
97 | | const IsolationLevel isolation_level, |
98 | 120k | CoarseTimePoint deadline) { |
99 | 120k | if (transaction) { |
100 | 0 | DCHECK(transaction->IsRestartRequired()); |
101 | 0 | return transaction->CreateRestartedTransaction(); |
102 | 0 | } |
103 | 120k | if (transaction_pool_ == nullptr) { |
104 | 1.03k | if (transaction_pool_provider_1.03k ) { |
105 | 1.03k | transaction_pool_ = transaction_pool_provider_(); |
106 | 18.4E | } else { |
107 | 18.4E | return STATUS(InternalError, "No transaction pool provider"); |
108 | 18.4E | } |
109 | 1.03k | } |
110 | 120k | auto result = transaction_pool_->Take(client::ForceGlobalTransaction::kTrue, deadline); |
111 | 120k | RETURN_NOT_OK(result->Init(isolation_level)); |
112 | 120k | return result; |
113 | 120k | } |
114 | | |
115 | 97.1k | YBSessionPtr QLEnv::NewSession() { |
116 | 97.1k | return std::make_shared<YBSession>(client_, clock_); |
117 | 97.1k | } |
118 | | |
119 | | //------------------------------------------------------------------------------------------------ |
120 | 326k | shared_ptr<YBTable> QLEnv::GetTableDesc(const YBTableName& table_name, bool* cache_used) { |
121 | | // Hide tables in system_redis keyspace. |
122 | 326k | if (table_name.is_redis_namespace()) { |
123 | 0 | return nullptr; |
124 | 0 | } |
125 | 326k | shared_ptr<YBTable> yb_table; |
126 | 326k | Status s = metadata_cache_->GetTable(table_name, &yb_table, cache_used); |
127 | | |
128 | 326k | if (!s.ok()) { |
129 | 2.26k | VLOG(3) << "GetTableDesc: Server returns an error: " << s.ToString()0 ; |
130 | 2.26k | return nullptr; |
131 | 2.26k | } |
132 | | |
133 | 324k | return yb_table; |
134 | 326k | } |
135 | | |
136 | 1.44k | shared_ptr<YBTable> QLEnv::GetTableDesc(const TableId& table_id, bool* cache_used) { |
137 | 1.44k | shared_ptr<YBTable> yb_table; |
138 | 1.44k | Status s = metadata_cache_->GetTable(table_id, &yb_table, cache_used); |
139 | | |
140 | 1.44k | if (!s.ok()) { |
141 | 0 | VLOG(3) << "GetTableDesc: Server returns an error: " << s.ToString(); |
142 | 0 | return nullptr; |
143 | 0 | } |
144 | | |
145 | 1.44k | return yb_table; |
146 | 1.44k | } |
147 | | |
148 | | CHECKED_STATUS QLEnv::GetUpToDateTableSchemaVersion(const YBTableName& table_name, |
149 | 110 | uint32_t* ver) { |
150 | 110 | shared_ptr<YBTable> yb_table; |
151 | 110 | RETURN_NOT_OK(client_->OpenTable(table_name, &yb_table)); |
152 | | |
153 | 102 | if (yb_table) { |
154 | 102 | *ver = yb_table->schema().version(); |
155 | 102 | return Status::OK(); |
156 | 102 | } else { |
157 | 0 | return STATUS_SUBSTITUTE(NotFound, "Cannot get table $0", table_name.ToString()); |
158 | 0 | } |
159 | 102 | } |
160 | | |
161 | | shared_ptr<QLType> QLEnv::GetUDType(const std::string& keyspace_name, |
162 | | const std::string& type_name, |
163 | 82 | bool* cache_used) { |
164 | 82 | shared_ptr<QLType> ql_type = std::make_shared<QLType>(keyspace_name, type_name); |
165 | 82 | Status s = metadata_cache_->GetUDType(keyspace_name, type_name, &ql_type, cache_used); |
166 | | |
167 | 82 | if (!s.ok()) { |
168 | 7 | VLOG(3) << "GetTypeDesc: Server returned an error: " << s.ToString()0 ; |
169 | 7 | return nullptr; |
170 | 7 | } |
171 | | |
172 | 75 | return ql_type; |
173 | 82 | } |
174 | | |
175 | 9.51k | void QLEnv::RemoveCachedTableDesc(const YBTableName& table_name) { |
176 | 9.51k | metadata_cache_->RemoveCachedTable(table_name); |
177 | 9.51k | } |
178 | | |
179 | 0 | void QLEnv::RemoveCachedTableDesc(const TableId& table_id) { |
180 | 0 | metadata_cache_->RemoveCachedTable(table_id); |
181 | 0 | } |
182 | | |
183 | 60 | void QLEnv::RemoveCachedUDType(const std::string& keyspace_name, const std::string& type_name) { |
184 | 60 | metadata_cache_->RemoveCachedUDType(keyspace_name, type_name); |
185 | 60 | } |
186 | | |
187 | | //------------------------------------------------------------------------------------------------ |
188 | | Status QLEnv::GrantRevokePermission(client::GrantRevokeStatementType statement_type, |
189 | | const PermissionType& permission, |
190 | | const ResourceType& resource_type, |
191 | | const std::string& canonical_resource, |
192 | | const char* resource_name, |
193 | | const char* namespace_name, |
194 | 721 | const std::string& role_name) { |
195 | 721 | return client_->GrantRevokePermission(statement_type, permission, resource_type, |
196 | 721 | canonical_resource, resource_name, namespace_name, |
197 | 721 | role_name); |
198 | 721 | } |
199 | | |
200 | | //------------------------------------------------------------------------------------------------ |
201 | 1.67k | Status QLEnv::CreateKeyspace(const std::string& keyspace_name) { |
202 | 1.67k | return client_->CreateNamespace(keyspace_name, YQLDatabase::YQL_DATABASE_CQL, CurrentRoleName()); |
203 | 1.67k | } |
204 | | |
205 | 1.53k | Status QLEnv::DeleteKeyspace(const string& keyspace_name) { |
206 | 1.53k | RETURN_NOT_OK(client_->DeleteNamespace(keyspace_name)); |
207 | | |
208 | | // Reset the current keyspace name if it's dropped. |
209 | 1.53k | if (ql_session()->current_keyspace() == keyspace_name) { |
210 | 1.01k | ql_session()->set_current_keyspace(kUndefinedKeyspace); |
211 | 1.01k | } |
212 | 1.53k | return Status::OK(); |
213 | 1.53k | } |
214 | | |
215 | 4.43k | Status QLEnv::UseKeyspace(const string& keyspace_name) { |
216 | | // Check if a keyspace with the specified name exists. |
217 | 4.43k | Result<bool> exists = client_->NamespaceExists(keyspace_name); |
218 | 4.43k | RETURN_NOT_OK(exists); |
219 | 4.43k | if (!exists.get()) { |
220 | 1 | return STATUS(NotFound, "Cannot use unknown keyspace"); |
221 | 1 | } |
222 | | |
223 | 4.43k | ql_session()->set_current_keyspace(keyspace_name); |
224 | 4.43k | return Status::OK(); |
225 | 4.43k | } |
226 | | |
227 | 21 | Status QLEnv::AlterKeyspace(const string& keyspace_name) { |
228 | | // Check if a keyspace with the specified name exists. |
229 | 21 | Result<bool> exists = client_->NamespaceExists(keyspace_name); |
230 | 21 | RETURN_NOT_OK(exists); |
231 | 21 | if (!exists.get()) { |
232 | 1 | return STATUS(NotFound, "Cannot alter unknown keyspace"); |
233 | 1 | } |
234 | | |
235 | | // Current implementation does not update any keyspace properties. |
236 | 20 | return Status::OK(); |
237 | 21 | } |
238 | | |
239 | | //------------------------------------------------------------------------------------------------ |
240 | | Status QLEnv::CreateRole(const std::string& role_name, |
241 | | const std::string& salted_hash, |
242 | 757 | const bool login, const bool superuser) { |
243 | 757 | return client_->CreateRole(role_name, salted_hash, login, superuser, CurrentRoleName()); |
244 | 757 | } |
245 | | |
246 | | Status QLEnv::AlterRole(const std::string& role_name, |
247 | | const boost::optional<std::string>& salted_hash, |
248 | | const boost::optional<bool> login, |
249 | 58 | const boost::optional<bool> superuser) { |
250 | 58 | return client_->AlterRole(role_name, salted_hash, login, superuser, CurrentRoleName()); |
251 | 58 | } |
252 | | |
253 | 730 | Status QLEnv::DeleteRole(const std::string& role_name) { |
254 | 730 | return client_->DeleteRole(role_name, CurrentRoleName()); |
255 | 730 | } |
256 | | |
257 | | Status QLEnv::GrantRevokeRole(client::GrantRevokeStatementType statement_type, |
258 | | const std::string& granted_role_name, |
259 | 52 | const std::string& recipient_role_name) { |
260 | 52 | return client_->GrantRevokeRole(statement_type, granted_role_name, recipient_role_name); |
261 | 52 | } |
262 | | |
263 | | Status QLEnv::HasResourcePermission(const string& canonical_name, |
264 | | const ql::ObjectType& object_type, |
265 | | const PermissionType permission, |
266 | | const NamespaceName& keyspace, |
267 | 8.77k | const TableName& table) { |
268 | 8.77k | DFATAL_OR_RETURN_ERROR_IF(!FLAGS_use_cassandra_authentication, STATUS(IllegalState, |
269 | 8.77k | "Permissions check is not allowed when use_cassandra_authentication flag is disabled")); |
270 | 8.77k | return metadata_cache_->HasResourcePermission(canonical_name, object_type, CurrentRoleName(), |
271 | 8.77k | permission, keyspace, table, |
272 | 8.77k | client::CacheCheckMode::RETRY); |
273 | 8.77k | } |
274 | | |
275 | 519 | Result<std::string> QLEnv::RoleSaltedHash(const RoleName& role_name) { |
276 | 519 | return metadata_cache_->RoleSaltedHash(role_name); |
277 | 519 | } |
278 | | |
279 | 398 | Result<bool> QLEnv::RoleCanLogin(const RoleName& role_name) { |
280 | 398 | return metadata_cache_->RoleCanLogin(role_name); |
281 | 398 | } |
282 | | |
283 | | Status QLEnv::HasTablePermission(const NamespaceName& keyspace_name, |
284 | | const TableName& table_name, |
285 | 4.29k | const PermissionType permission) { |
286 | 4.29k | return metadata_cache_->HasTablePermission(keyspace_name, table_name, CurrentRoleName(), |
287 | 4.29k | permission); |
288 | 4.29k | } |
289 | | |
290 | | Status QLEnv::HasTablePermission(const client::YBTableName table_name, |
291 | 1.88k | const PermissionType permission) { |
292 | 1.88k | return HasTablePermission(table_name.namespace_name(), table_name.table_name(), permission); |
293 | 1.88k | } |
294 | | |
295 | 1.96k | Status QLEnv::HasRolePermission(const RoleName& role_name, const PermissionType permission) { |
296 | 1.96k | return HasResourcePermission(get_canonical_role(role_name), ObjectType::ROLE, permission); |
297 | 1.96k | } |
298 | | |
299 | | //------------------------------------------------------------------------------------------------ |
300 | | Status QLEnv::CreateUDType(const std::string& keyspace_name, |
301 | | const std::string& type_name, |
302 | | const std::vector<std::string>& field_names, |
303 | 47 | const std::vector<std::shared_ptr<QLType>>& field_types) { |
304 | 47 | return client_->CreateUDType(keyspace_name, type_name, field_names, field_types); |
305 | 47 | } |
306 | | |
307 | 54 | Status QLEnv::DeleteUDType(const std::string& keyspace_name, const std::string& type_name) { |
308 | 54 | return client_->DeleteUDType(keyspace_name, type_name); |
309 | 54 | } |
310 | | |
311 | | } // namespace ql |
312 | | } // namespace yb |