OmniSciDB  91042dcc5b
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DdlCommandExecutor.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 OmniSci, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "DdlCommandExecutor.h"
18 
19 #include <boost/algorithm/string/predicate.hpp>
20 
21 #include "rapidjson/document.h"
22 
23 // Note: avoid adding #include(s) that require thrift
24 
25 #include "Catalog/Catalog.h"
26 #include "Catalog/SysCatalog.h"
28 #include "LockMgr/LockMgr.h"
29 #include "Parser/ParserNode.h"
30 #include "Shared/StringTransform.h"
31 
32 #include "QueryEngine/Execute.h" // Executor::getArenaBlockSize()
35 
36 extern bool g_enable_fsi;
37 
38 bool DdlCommand::isDefaultServer(const std::string& server_name) {
39  return boost::iequals(server_name.substr(0, 7), "omnisci");
40 }
41 
42 namespace {
43 template <class LockType>
44 std::tuple<const TableDescriptor*,
45  std::unique_ptr<lockmgr::TableSchemaLockContainer<LockType>>>
47  const std::string& table_name,
48  const bool populate_fragmenter) {
49  const TableDescriptor* td{nullptr};
50  std::unique_ptr<lockmgr::TableSchemaLockContainer<LockType>> td_with_lock =
51  std::make_unique<lockmgr::TableSchemaLockContainer<LockType>>(
53  cat, table_name, populate_fragmenter));
54  CHECK(td_with_lock);
55  td = (*td_with_lock)();
56  CHECK(td);
57  return std::make_tuple(td, std::move(td_with_lock));
58 }
59 
61  int32_t min_epoch;
62  int32_t max_epoch;
63  int32_t min_epoch_floor;
64  int32_t max_epoch_floor;
65 
67  : File_Namespace::StorageStats(storage_stats)
68  , min_epoch(storage_stats.epoch)
69  , max_epoch(storage_stats.epoch)
70  , min_epoch_floor(storage_stats.epoch_floor)
71  , max_epoch_floor(storage_stats.epoch_floor) {}
72 
73  void aggregate(const File_Namespace::StorageStats& storage_stats) {
74  metadata_file_count += storage_stats.metadata_file_count;
75  total_metadata_file_size += storage_stats.total_metadata_file_size;
76  total_metadata_page_count += storage_stats.total_metadata_page_count;
77  if (storage_stats.total_free_metadata_page_count) {
78  if (total_free_metadata_page_count) {
79  total_free_metadata_page_count.value() +=
80  storage_stats.total_free_metadata_page_count.value();
81  } else {
82  total_free_metadata_page_count = storage_stats.total_free_metadata_page_count;
83  }
84  }
85  data_file_count += storage_stats.data_file_count;
86  total_data_file_size += storage_stats.total_data_file_size;
87  total_data_page_count += storage_stats.total_data_page_count;
88  if (storage_stats.total_free_data_page_count) {
89  if (total_free_data_page_count) {
90  total_free_data_page_count.value() +=
91  storage_stats.total_free_data_page_count.value();
92  } else {
93  total_free_data_page_count = storage_stats.total_free_data_page_count;
94  }
95  }
96  min_epoch = std::min(min_epoch, storage_stats.epoch);
97  max_epoch = std::max(max_epoch, storage_stats.epoch);
98  min_epoch_floor = std::min(min_epoch_floor, storage_stats.epoch_floor);
99  max_epoch_floor = std::max(max_epoch_floor, storage_stats.epoch_floor);
100  }
101 };
102 
104  const Catalog_Namespace::Catalog* catalog) {
105  const auto global_file_mgr = catalog->getDataMgr().getGlobalFileMgr();
106  std::optional<AggregratedStorageStats> agg_storage_stats;
107  if (td->nShards > 0) {
108  const auto physical_tables = catalog->getPhysicalTablesDescriptors(td, false);
109  CHECK_EQ(static_cast<size_t>(td->nShards), physical_tables.size());
110 
111  for (const auto physical_table : physical_tables) {
112  auto storage_stats = global_file_mgr->getStorageStats(catalog->getDatabaseId(),
113  physical_table->tableId);
114  if (agg_storage_stats) {
115  agg_storage_stats.value().aggregate(storage_stats);
116  } else {
117  agg_storage_stats = storage_stats;
118  }
119  }
120  } else {
121  agg_storage_stats =
122  global_file_mgr->getStorageStats(catalog->getDatabaseId(), td->tableId);
123  }
124  CHECK(agg_storage_stats.has_value());
125  return agg_storage_stats.value();
126 }
127 
128 std::unique_ptr<RexLiteral> genLiteralStr(std::string val) {
129  return std::unique_ptr<RexLiteral>(
130  new RexLiteral(val, SQLTypes::kTEXT, SQLTypes::kTEXT, 0, 0, 0, 0));
131 }
132 
133 std::unique_ptr<RexLiteral> genLiteralTimestamp(time_t val) {
134  return std::unique_ptr<RexLiteral>(new RexLiteral(
135  (int64_t)val, SQLTypes::kTIMESTAMP, SQLTypes::kTIMESTAMP, 0, 8, 0, 8));
136 }
137 
138 std::unique_ptr<RexLiteral> genLiteralBigInt(int64_t val) {
139  return std::unique_ptr<RexLiteral>(
140  new RexLiteral(val, SQLTypes::kBIGINT, SQLTypes::kBIGINT, 0, 8, 0, 8));
141 }
142 
143 std::unique_ptr<RexLiteral> genLiteralBoolean(bool val) {
144  return std::unique_ptr<RexLiteral>(
145  // new RexLiteral(val, SQLTypes::kBOOLEAN, SQLTypes::kBOOLEAN, 0, 0, 0, 0));
146  new RexLiteral(
147  (int64_t)(val ? 1 : 0), SQLTypes::kBIGINT, SQLTypes::kBIGINT, 0, 8, 0, 8));
148 }
149 
151  std::vector<TargetMetaInfo>& label_infos,
152  const std::vector<std::tuple<std::string, SQLTypes, bool>>& headers) {
153  for (const auto& header : headers) {
154  auto [_val, _type, _notnull] = header;
155  if (_type == kBIGINT || _type == kTEXT || _type == kTIMESTAMP || _type == kBOOLEAN) {
156  label_infos.emplace_back(_val, SQLTypeInfo(_type, _notnull));
157  } else {
158  UNREACHABLE() << "Unsupported type provided for header. SQL type: "
159  << to_string(_type);
160  }
161  }
162 }
163 
164 void add_table_details(std::vector<RelLogicalValues::RowValues>& logical_values,
165  const TableDescriptor* logical_table,
166  const AggregratedStorageStats& agg_storage_stats) {
167  bool is_sharded_table = (logical_table->nShards > 0);
168  logical_values.emplace_back(RelLogicalValues::RowValues{});
169  logical_values.back().emplace_back(genLiteralBigInt(logical_table->tableId));
170  logical_values.back().emplace_back(genLiteralStr(logical_table->tableName));
171  logical_values.back().emplace_back(genLiteralBigInt(logical_table->nColumns));
172  logical_values.back().emplace_back(genLiteralBoolean(is_sharded_table));
173  logical_values.back().emplace_back(genLiteralBigInt(logical_table->nShards));
174  logical_values.back().emplace_back(genLiteralBigInt(logical_table->maxRows));
175  logical_values.back().emplace_back(genLiteralBigInt(logical_table->maxFragRows));
176  logical_values.back().emplace_back(genLiteralBigInt(logical_table->maxRollbackEpochs));
177  logical_values.back().emplace_back(genLiteralBigInt(agg_storage_stats.min_epoch));
178  logical_values.back().emplace_back(genLiteralBigInt(agg_storage_stats.max_epoch));
179  logical_values.back().emplace_back(genLiteralBigInt(agg_storage_stats.min_epoch_floor));
180  logical_values.back().emplace_back(genLiteralBigInt(agg_storage_stats.max_epoch_floor));
181  logical_values.back().emplace_back(
182  genLiteralBigInt(agg_storage_stats.metadata_file_count));
183  logical_values.back().emplace_back(
184  genLiteralBigInt(agg_storage_stats.total_metadata_file_size));
185  logical_values.back().emplace_back(
186  genLiteralBigInt(agg_storage_stats.total_metadata_page_count));
187 
188  if (agg_storage_stats.total_free_metadata_page_count) {
189  logical_values.back().emplace_back(
190  genLiteralBigInt(agg_storage_stats.total_free_metadata_page_count.value()));
191  } else {
192  logical_values.back().emplace_back(genLiteralBigInt(NULL_BIGINT));
193  }
194 
195  logical_values.back().emplace_back(genLiteralBigInt(agg_storage_stats.data_file_count));
196  logical_values.back().emplace_back(
197  genLiteralBigInt(agg_storage_stats.total_data_file_size));
198  logical_values.back().emplace_back(
199  genLiteralBigInt(agg_storage_stats.total_data_page_count));
200 
201  if (agg_storage_stats.total_free_data_page_count) {
202  logical_values.back().emplace_back(
203  genLiteralBigInt(agg_storage_stats.total_free_data_page_count.value()));
204  } else {
205  logical_values.back().emplace_back(genLiteralBigInt(NULL_BIGINT));
206  }
207 }
208 
209 // -----------------------------------------------------------------------
210 // class: JsonColumnSqlType
211 // Defined & Implemented here to avoid exposing rapidjson in the header file
212 // -----------------------------------------------------------------------
213 
216  public:
217  JsonColumnSqlType(const rapidjson::Value& data_type)
218  : ddl_utils::SqlType(getSqlType(data_type),
219  getParam1(data_type),
220  getParam2(data_type),
221  isArray(data_type),
222  getArraySize(data_type)) {}
223 
224  private:
225  static SQLTypes getSqlType(const rapidjson::Value& data_type);
226  static SQLTypes getSqlType(const std::string& type);
227  static int getParam1(const rapidjson::Value& data_type);
228  static int getParam2(const rapidjson::Value& data_type);
229  static bool isArray(const rapidjson::Value& data_type);
230  static int getArraySize(const rapidjson::Value& data_type);
231 };
232 
234  public:
235  JsonColumnEncoding(const rapidjson::Value& data_type)
236  : ddl_utils::Encoding(getEncodingName(data_type), getEncodingParam(data_type)) {}
237 
238  private:
239  static std::string* getEncodingName(const rapidjson::Value& data_type);
240  static int getEncodingParam(const rapidjson::Value& data_type);
241 };
242 
243 // -----------------------------------------------------------------------
244 // class DdlCommandDataImpl:
245 //
246 // Concrete class to cache parse data
247 // Defined & Implemented here to avoid exposing rapidjson in the header file
248 // Helper/access fns available to get useful pieces of cache data
249 // -----------------------------------------------------------------------
251  public:
252  DdlCommandDataImpl(const std::string& ddl_statement);
253  ~DdlCommandDataImpl() override;
254 
255  // The full query available for futher analysis
256  const rapidjson::Value& query() const;
257 
258  // payload as extracted from the query
259  const rapidjson::Value& payload() const;
260 
261  // commandStr extracted from the payload
262  std::string commandStr() override;
263 
264  rapidjson::Document ddl_query;
265 };
266 
267 DdlCommandDataImpl::DdlCommandDataImpl(const std::string& ddl_statement)
268  : DdlCommandData(ddl_statement) {
269  ddl_query.Parse(ddl_statement);
270 }
271 
273 
274 const rapidjson::Value& DdlCommandDataImpl::query() const {
275  return ddl_query;
276 }
277 
278 const rapidjson::Value& DdlCommandDataImpl::payload() const {
279  CHECK(ddl_query.HasMember("payload"));
280  CHECK(ddl_query["payload"].IsObject());
281  return ddl_query["payload"];
282 }
283 
285  if (ddl_query.IsObject() && ddl_query.HasMember("payload") &&
286  ddl_query["payload"].IsObject()) {
287  auto& payload = ddl_query["payload"];
288  if (payload.HasMember("command") && payload["command"].IsString()) {
289  return payload["command"].GetString();
290  }
291  }
292  return "";
293 }
294 
295 // Helper Fn to get the payload from the abstract base class
296 const rapidjson::Value& extractPayload(const DdlCommandData& ddl_data) {
297  const DdlCommandDataImpl* data = static_cast<const DdlCommandDataImpl*>(&ddl_data);
298  return data->payload();
299 }
300 
301 const rapidjson::Value* extractFilters(const rapidjson::Value& payload) {
302  const rapidjson::Value* filters = nullptr;
303  if (payload.HasMember("filters") && payload["filters"].IsArray()) {
304  filters = &payload["filters"];
305  }
306  return filters;
307 }
308 
309 } // namespace
310 
312  const std::string& ddl_statement,
313  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
314  : session_ptr_(session_ptr) {
315  CHECK(!ddl_statement.empty());
316  ddl_statement_ = ddl_statement;
317 
318  // parse the incoming query,
319  // cache the parsed rapidjson object inside a DdlCommandDataImpl
320  // store the "abstract/base class" reference in ddl_data_
321  DdlCommandDataImpl* ddl_query_data = new DdlCommandDataImpl(ddl_statement);
322  ddl_data_ = std::unique_ptr<DdlCommandData>(ddl_query_data);
323 
324  VLOG(2) << "Parsing JSON DDL from Calcite: " << ddl_statement;
325  auto& ddl_query = ddl_query_data->query();
326  CHECK(ddl_query.IsObject()) << ddl_statement;
327  CHECK(ddl_query.HasMember("payload"));
328  CHECK(ddl_query["payload"].IsObject());
329  const auto& payload = ddl_query["payload"].GetObject();
330  CHECK(payload.HasMember("command"));
331  CHECK(payload["command"].IsString());
332  ddl_command_ = payload["command"].GetString();
333 }
334 
337 
338  // the following commands use parser node locking to ensure safe concurrent access
339  if (ddl_command_ == "CREATE_TABLE") {
340  auto create_table_stmt = Parser::CreateTableStmt(extractPayload(*ddl_data_));
341  create_table_stmt.execute(*session_ptr_);
342  return result;
343  } else if (ddl_command_ == "CREATE_VIEW") {
344  auto create_view_stmt = Parser::CreateViewStmt(extractPayload(*ddl_data_));
345  create_view_stmt.execute(*session_ptr_);
346  return result;
347  } else if (ddl_command_ == "DROP_TABLE") {
348  auto drop_table_stmt = Parser::DropTableStmt(extractPayload(*ddl_data_));
349  drop_table_stmt.execute(*session_ptr_);
350  return result;
351  } else if (ddl_command_ == "DROP_VIEW") {
352  auto drop_view_stmt = Parser::DropViewStmt(extractPayload(*ddl_data_));
353  drop_view_stmt.execute(*session_ptr_);
354  return result;
355  } else if (ddl_command_ == "RENAME_TABLE") {
356  auto rename_table_stmt = Parser::RenameTableStmt(extractPayload(*ddl_data_));
357  rename_table_stmt.execute(*session_ptr_);
358  return result;
359  } else if (ddl_command_ == "ALTER_TABLE") {
361  if (stmt != nullptr) {
362  stmt->execute(*session_ptr_);
363  }
364  return result;
365  } else if (ddl_command_ == "TRUNCATE_TABLE") {
366  auto truncate_table_stmt = Parser::TruncateTableStmt(extractPayload(*ddl_data_));
367  truncate_table_stmt.execute(*session_ptr_);
368  return result;
369  } else if (ddl_command_ == "DUMP_TABLE") {
370  auto dump_table_stmt = Parser::DumpTableStmt(extractPayload(*ddl_data_));
371  dump_table_stmt.execute(*session_ptr_);
372  return result;
373  } else if (ddl_command_ == "RESTORE_TABLE") {
374  auto restore_table_stmt = Parser::RestoreTableStmt(extractPayload(*ddl_data_));
375  restore_table_stmt.execute(*session_ptr_);
376  return result;
377  } else if (ddl_command_ == "OPTIMIZE_TABLE") {
378  auto optimize_table_stmt = Parser::OptimizeTableStmt(extractPayload(*ddl_data_));
379  optimize_table_stmt.execute(*session_ptr_);
380  return result;
381  } else if (ddl_command_ == "SHOW_CREATE_TABLE") {
382  auto show_create_table_stmt = Parser::ShowCreateTableStmt(extractPayload(*ddl_data_));
383  show_create_table_stmt.execute(*session_ptr_);
384  const auto create_string = show_create_table_stmt.getCreateStmt();
385  result.updateResultSet(create_string, ExecutionResult::SimpleResult);
386  return result;
387  } else if (ddl_command_ == "COPY_TABLE") {
388  auto copy_table_stmt = Parser::CopyTableStmt(extractPayload(*ddl_data_));
389  copy_table_stmt.execute(*session_ptr_);
390  return result;
391  } else if (ddl_command_ == "EXPORT_QUERY") {
392  auto export_query_stmt = Parser::ExportQueryStmt(extractPayload(*ddl_data_));
393  export_query_stmt.execute(*session_ptr_);
394  return result;
395  } else if (ddl_command_ == "CREATE_DB") {
396  auto create_db_stmt = Parser::CreateDBStmt(extractPayload(*ddl_data_));
397  create_db_stmt.execute(*session_ptr_);
398  return result;
399  } else if (ddl_command_ == "DROP_DB") {
400  auto drop_db_stmt = Parser::DropDBStmt(extractPayload(*ddl_data_));
401  drop_db_stmt.execute(*session_ptr_);
402  return result;
403  } else if (ddl_command_ == "RENAME_DB") {
404  auto rename_db_stmt = Parser::RenameDBStmt(extractPayload(*ddl_data_));
405  rename_db_stmt.execute(*session_ptr_);
406  return result;
407  } else if (ddl_command_ == "CREATE_USER") {
408  auto create_user_stmt = Parser::CreateUserStmt(extractPayload(*ddl_data_));
409  create_user_stmt.execute(*session_ptr_);
410  return result;
411  } else if (ddl_command_ == "DROP_USER") {
412  auto drop_user_stmt = Parser::DropUserStmt(extractPayload(*ddl_data_));
413  drop_user_stmt.execute(*session_ptr_);
414  return result;
415  } else if (ddl_command_ == "ALTER_USER") {
416  auto alter_user_stmt = Parser::AlterUserStmt(extractPayload(*ddl_data_));
417  alter_user_stmt.execute(*session_ptr_);
418  return result;
419  } else if (ddl_command_ == "RENAME_USER") {
420  auto rename_user_stmt = Parser::RenameUserStmt(extractPayload(*ddl_data_));
421  rename_user_stmt.execute(*session_ptr_);
422  return result;
423  } else if (ddl_command_ == "CREATE_ROLE") {
424  auto create_role_stmt = Parser::CreateRoleStmt(extractPayload(*ddl_data_));
425  create_role_stmt.execute(*session_ptr_);
426  return result;
427  } else if (ddl_command_ == "DROP_ROLE") {
428  auto drop_role_stmt = Parser::DropRoleStmt(extractPayload(*ddl_data_));
429  drop_role_stmt.execute(*session_ptr_);
430  return result;
431  } else if (ddl_command_ == "GRANT_ROLE") {
432  auto grant_role_stmt = Parser::GrantRoleStmt(extractPayload(*ddl_data_));
433  grant_role_stmt.execute(*session_ptr_);
434  return result;
435  } else if (ddl_command_ == "REVOKE_ROLE") {
436  auto revoke_role_stmt = Parser::RevokeRoleStmt(extractPayload(*ddl_data_));
437  revoke_role_stmt.execute(*session_ptr_);
438  return result;
439  } else if (ddl_command_ == "GRANT_PRIVILEGE") {
440  auto grant_privilege_stmt = Parser::GrantPrivilegesStmt(extractPayload(*ddl_data_));
441  grant_privilege_stmt.execute(*session_ptr_);
442  return result;
443  } else if (ddl_command_ == "REVOKE_PRIVILEGE") {
444  auto revoke_privileges_stmt =
446  revoke_privileges_stmt.execute(*session_ptr_);
447  return result;
448  } else if (ddl_command_ == "CREATE_DATAFRAME") {
449  auto create_dataframe_stmt = Parser::CreateDataframeStmt(extractPayload(*ddl_data_));
450  create_dataframe_stmt.execute(*session_ptr_);
451  return result;
452  } else if (ddl_command_ == "VALIDATE_SYSTEM") {
453  // VALIDATE should have been excuted in outer context before it reaches here
454  UNREACHABLE();
455  }
456 
457  // the following commands require a global unique lock until proper table locking has
458  // been implemented and/or verified
459  auto execute_write_lock = mapd_unique_lock<mapd_shared_mutex>(
462  // TODO(vancouver): add appropriate table locking
463 
464  if (ddl_command_ == "CREATE_SERVER") {
465  result = CreateForeignServerCommand{*ddl_data_, session_ptr_}.execute();
466  } else if (ddl_command_ == "DROP_SERVER") {
467  result = DropForeignServerCommand{*ddl_data_, session_ptr_}.execute();
468  } else if (ddl_command_ == "CREATE_FOREIGN_TABLE") {
469  result = CreateForeignTableCommand{*ddl_data_, session_ptr_}.execute();
470  } else if (ddl_command_ == "DROP_FOREIGN_TABLE") {
471  result = DropForeignTableCommand{*ddl_data_, session_ptr_}.execute();
472  } else if (ddl_command_ == "SHOW_TABLES") {
473  result = ShowTablesCommand{*ddl_data_, session_ptr_}.execute();
474  } else if (ddl_command_ == "SHOW_TABLE_DETAILS") {
475  result = ShowTableDetailsCommand{*ddl_data_, session_ptr_}.execute();
476  } else if (ddl_command_ == "SHOW_DATABASES") {
477  result = ShowDatabasesCommand{*ddl_data_, session_ptr_}.execute();
478  } else if (ddl_command_ == "SHOW_SERVERS") {
479  result = ShowForeignServersCommand{*ddl_data_, session_ptr_}.execute();
480  } else if (ddl_command_ == "ALTER_SERVER") {
481  result = AlterForeignServerCommand{*ddl_data_, session_ptr_}.execute();
482  } else if (ddl_command_ == "ALTER_FOREIGN_TABLE") {
483  result = AlterForeignTableCommand{*ddl_data_, session_ptr_}.execute();
484  } else if (ddl_command_ == "REFRESH_FOREIGN_TABLES") {
485  result = RefreshForeignTablesCommand{*ddl_data_, session_ptr_}.execute();
486  } else if (ddl_command_ == "SHOW_DISK_CACHE_USAGE") {
487  result = ShowDiskCacheUsageCommand{*ddl_data_, session_ptr_}.execute();
488  } else if (ddl_command_ == "SHOW_USER_DETAILS") {
489  result = ShowUserDetailsCommand{*ddl_data_, session_ptr_}.execute();
490  } else if (ddl_command_ == "SHOW_ROLES") {
491  result = ShowRolesCommand{*ddl_data_, session_ptr_}.execute();
492  } else if (ddl_command_ == "REASSIGN_OWNED") {
493  result = ReassignOwnedCommand{*ddl_data_, session_ptr_}.execute();
494  } else {
495  throw std::runtime_error("Unsupported DDL command");
496  }
497 
498  return result;
499 }
500 
502  return (ddl_command_ == "SHOW_USER_SESSIONS");
503 }
504 
506  return (ddl_command_ == "SHOW_QUERIES");
507 }
508 
510  return (ddl_command_ == "KILL_QUERY");
511 }
512 
514  return (ddl_command_ == "SHOW_CREATE_TABLE");
515 }
516 
518  return (ddl_command_ == "ALTER_SYSTEM_CLEAR");
519 }
520 
522  CHECK(ddl_command_ == "ALTER_SYSTEM_CLEAR");
523  auto& ddl_payload = extractPayload(*ddl_data_);
524  CHECK(ddl_payload.HasMember("cacheType"));
525  CHECK(ddl_payload["cacheType"].IsString());
526  return ddl_payload["cacheType"].GetString();
527 }
528 
530  DistributedExecutionDetails execution_details;
531  if (ddl_command_ == "CREATE_DATAFRAME" || ddl_command_ == "RENAME_TABLE" ||
532  ddl_command_ == "ALTER_TABLE" || ddl_command_ == "CREATE_TABLE" ||
533  ddl_command_ == "DROP_TABLE" || ddl_command_ == "TRUNCATE_TABLE" ||
534  ddl_command_ == "DUMP_TABLE" || ddl_command_ == "RESTORE_TABLE" ||
535  ddl_command_ == "OPTIMIZE_TABLE" || ddl_command_ == "CREATE_VIEW" ||
536  ddl_command_ == "DROP_VIEW" || ddl_command_ == "CREATE_DB" ||
537  ddl_command_ == "DROP_DB" || ddl_command_ == "RENAME_DB" ||
538  ddl_command_ == "CREATE_USER" || ddl_command_ == "DROP_USER" ||
539  ddl_command_ == "ALTER_USER" || ddl_command_ == "RENAME_USER" ||
540  ddl_command_ == "CREATE_ROLE" || ddl_command_ == "DROP_ROLE" ||
541  ddl_command_ == "GRANT_ROLE" || ddl_command_ == "REVOKE_ROLE" ||
542  ddl_command_ == "REASSIGN_OWNED" || ddl_command_ == "CREATE_POLICY" ||
543  ddl_command_ == "DROP_POLICY") {
544  // group user/role/db commands
546  execution_details.aggregation_type = AggregationType::NONE;
547  } else if (ddl_command_ == "GRANT_PRIVILEGE" || ddl_command_ == "REVOKE_PRIVILEGE") {
548  auto& ddl_payload = extractPayload(*ddl_data_);
549  CHECK(ddl_payload.HasMember("type"));
550  const std::string& targetType = ddl_payload["type"].GetString();
551  if (targetType == "DASHBOARD") {
552  // dashboard commands should run on Aggregator alone
554  execution_details.aggregation_type = AggregationType::NONE;
555  } else {
557  execution_details.aggregation_type = AggregationType::NONE;
558  }
559 
560  } else if (ddl_command_ == "SHOW_TABLE_DETAILS") {
562  execution_details.aggregation_type = AggregationType::UNION;
563  } else {
564  // Commands that fall here : COPY_TABLE, EXPORT_QUERY, etc.
566  execution_details.aggregation_type = AggregationType::NONE;
567  }
568  return execution_details;
569 }
570 
572  // caller should check whether DDL indicates KillQuery request
573  // i.e., use isKillQuery() before calling this function
574  auto& ddl_payload = extractPayload(*ddl_data_);
575  CHECK(isKillQuery());
576  CHECK(ddl_payload.HasMember("querySession"));
577  const std::string& query_session = ddl_payload["querySession"].GetString();
578  // regex matcher for public_session: start_time{3}-session_id{4} (Example:819-4RDo)
579  boost::regex session_id_regex{R"([0-9]{3}-[a-zA-Z0-9]{4})",
580  boost::regex::extended | boost::regex::icase};
581  if (!boost::regex_match(query_session, session_id_regex)) {
582  throw std::runtime_error(
583  "Please provide the correct session ID of the query that you want to interrupt.");
584  }
585  return query_session;
586 }
587 
588 const std::string DdlCommandExecutor::commandStr() {
589  return ddl_command_;
590 }
591 
593  const DdlCommandData& ddl_data,
594  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
595  : DdlCommand(ddl_data, session_ptr) {
596  auto& ddl_payload = extractPayload(ddl_data_);
597  CHECK(ddl_payload.HasMember("serverName"));
598  CHECK(ddl_payload["serverName"].IsString());
599  CHECK(ddl_payload.HasMember("dataWrapper"));
600  CHECK(ddl_payload["dataWrapper"].IsString());
601  if (ddl_payload.HasMember("options")) {
602  CHECK(ddl_payload["options"].IsObject());
603  }
604  CHECK(ddl_payload.HasMember("ifNotExists"));
605  CHECK(ddl_payload["ifNotExists"].IsBool());
606 }
607 
610 
611  auto& ddl_payload = extractPayload(ddl_data_);
612  std::string server_name = ddl_payload["serverName"].GetString();
613  if (isDefaultServer(server_name)) {
614  throw std::runtime_error{"Server names cannot start with \"omnisci\"."};
615  }
616  bool if_not_exists = ddl_payload["ifNotExists"].GetBool();
617  if (session_ptr_->getCatalog().getForeignServer(server_name)) {
618  if (if_not_exists) {
619  return result;
620  } else {
621  throw std::runtime_error{"A foreign server with name \"" + server_name +
622  "\" already exists."};
623  }
624  }
625  // check access privileges
626  if (!session_ptr_->checkDBAccessPrivileges(DBObjectType::ServerDBObjectType,
628  throw std::runtime_error("Server " + std::string(server_name) +
629  " will not be created. User has no create privileges.");
630  }
631 
632  auto& current_user = session_ptr_->get_currentUser();
633  auto foreign_server = std::make_unique<foreign_storage::ForeignServer>();
634  foreign_server->data_wrapper_type = to_upper(ddl_payload["dataWrapper"].GetString());
635  foreign_server->name = server_name;
636  foreign_server->user_id = current_user.userId;
637  if (ddl_payload.HasMember("options")) {
638  foreign_server->populateOptionsMap(ddl_payload["options"]);
639  }
640  foreign_server->validate();
641 
642  auto& catalog = session_ptr_->getCatalog();
643  catalog.createForeignServer(std::move(foreign_server),
644  ddl_payload["ifNotExists"].GetBool());
646  current_user, server_name, ServerDBObjectType, catalog);
647 
648  return result;
649 }
650 
652  const DdlCommandData& ddl_data,
653  std::shared_ptr<const Catalog_Namespace::SessionInfo> session_ptr)
654  : DdlCommand(ddl_data, session_ptr) {
655  auto& ddl_payload = extractPayload(ddl_data_);
656  CHECK(ddl_payload.HasMember("serverName"));
657  CHECK(ddl_payload["serverName"].IsString());
658  CHECK(ddl_payload.HasMember("alterType"));
659  CHECK(ddl_payload["alterType"].IsString());
660  if (ddl_payload["alterType"] == "SET_OPTIONS") {
661  CHECK(ddl_payload.HasMember("options"));
662  CHECK(ddl_payload["options"].IsObject());
663  } else if (ddl_payload["alterType"] == "SET_DATA_WRAPPER") {
664  CHECK(ddl_payload.HasMember("dataWrapper"));
665  CHECK(ddl_payload["dataWrapper"].IsString());
666  } else if (ddl_payload["alterType"] == "RENAME_SERVER") {
667  CHECK(ddl_payload.HasMember("newServerName"));
668  CHECK(ddl_payload["newServerName"].IsString());
669  } else if (ddl_payload["alterType"] == "CHANGE_OWNER") {
670  CHECK(ddl_payload.HasMember("newOwner"));
671  CHECK(ddl_payload["newOwner"].IsString());
672  } else {
673  UNREACHABLE(); // not-implemented alterType
674  }
675 }
676 
678  auto& ddl_payload = extractPayload(ddl_data_);
679  std::string server_name = ddl_payload["serverName"].GetString();
680  if (isDefaultServer(server_name)) {
681  throw std::runtime_error{"OmniSci default servers cannot be altered."};
682  }
683  if (!session_ptr_->getCatalog().getForeignServer(server_name)) {
684  throw std::runtime_error{"Foreign server with name \"" + server_name +
685  "\" does not exist and can not be altered."};
686  }
687  if (!hasAlterServerPrivileges()) {
688  throw std::runtime_error("Server " + server_name +
689  " can not be altered. User has no ALTER SERVER privileges.");
690  }
691  std::string alter_type = ddl_payload["alterType"].GetString();
692  if (alter_type == "CHANGE_OWNER") {
694  } else if (alter_type == "SET_DATA_WRAPPER") {
696  } else if (alter_type == "SET_OPTIONS") {
698  } else if (alter_type == "RENAME_SERVER") {
700  }
701 
702  return ExecutionResult();
703 }
704 
706  auto& ddl_payload = extractPayload(ddl_data_);
707  std::string server_name = ddl_payload["serverName"].GetString();
708  std::string new_owner = ddl_payload["newOwner"].GetString();
709  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
710  if (!session_ptr_->get_currentUser().isSuper) {
711  throw std::runtime_error(
712  "Only a super user can change a foreign server's owner. "
713  "Current user is not a super-user. "
714  "Foreign server with name \"" +
715  server_name + "\" will not have owner changed.");
716  }
717  Catalog_Namespace::UserMetadata user, original_owner;
718  if (!sys_cat.getMetadataForUser(new_owner, user)) {
719  throw std::runtime_error("User with username \"" + new_owner + "\" does not exist. " +
720  "Foreign server with name \"" + server_name +
721  "\" can not have owner changed.");
722  }
723  auto& cat = session_ptr_->getCatalog();
724  // get original owner metadata
725  bool original_owner_exists = sys_cat.getMetadataForUserById(
726  cat.getForeignServer(server_name)->user_id, original_owner);
727  // update catalog
728  cat.changeForeignServerOwner(server_name, user.userId);
729  try {
730  // update permissions
731  DBObject db_object(server_name, DBObjectType::ServerDBObjectType);
732  sys_cat.changeDBObjectOwnership(
733  user, original_owner, db_object, cat, original_owner_exists);
734  } catch (const std::runtime_error& e) {
735  // update permissions failed, revert catalog update
736  cat.changeForeignServerOwner(server_name, original_owner.userId);
737  throw;
738  }
739 }
740 
742  auto& ddl_payload = extractPayload(ddl_data_);
743  std::string server_name = ddl_payload["serverName"].GetString();
744  std::string new_server_name = ddl_payload["newServerName"].GetString();
745  if (isDefaultServer(new_server_name)) {
746  throw std::runtime_error{"OmniSci prefix can not be used for new name of server."};
747  }
748  auto& cat = session_ptr_->getCatalog();
749  // check for a conflicting server
750  if (cat.getForeignServer(new_server_name)) {
751  throw std::runtime_error("Foreign server with name \"" + server_name +
752  "\" can not be renamed to \"" + new_server_name + "\"." +
753  "Foreign server with name \"" + new_server_name +
754  "\" exists.");
755  }
756  // update catalog
757  cat.renameForeignServer(server_name, new_server_name);
758  try {
759  // migrate object privileges
760  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
761  sys_cat.renameDBObject(server_name,
762  new_server_name,
764  cat.getForeignServer(new_server_name)->id,
765  cat);
766  } catch (const std::runtime_error& e) {
767  // permission migration failed, revert catalog update
768  cat.renameForeignServer(new_server_name, server_name);
769  throw;
770  }
771 }
772 
774  auto& ddl_payload = extractPayload(ddl_data_);
775  std::string server_name = ddl_payload["serverName"].GetString();
776  auto& cat = session_ptr_->getCatalog();
777  // update catalog
778  const auto foreign_server = cat.getForeignServer(server_name);
780  opt.populateOptionsMap(foreign_server->getOptionsAsJsonString());
781  opt.populateOptionsMap(ddl_payload["options"]);
782  cat.setForeignServerOptions(server_name, opt.getOptionsAsJsonString());
783 }
784 
786  auto& ddl_payload = extractPayload(ddl_data_);
787  std::string server_name = ddl_payload["serverName"].GetString();
788  std::string data_wrapper = ddl_payload["dataWrapper"].GetString();
789  auto& cat = session_ptr_->getCatalog();
790  // update catalog
791  cat.setForeignServerDataWrapper(server_name, data_wrapper);
792 }
793 
795  // TODO: implement `GRANT/REVOKE ALTER_SERVER` DDL commands
796  auto& ddl_payload = extractPayload(ddl_data_);
797  std::string server_name = ddl_payload["serverName"].GetString();
798  return session_ptr_->checkDBAccessPrivileges(
800 }
801 
803  const DdlCommandData& ddl_data,
804  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
805  : DdlCommand(ddl_data, session_ptr) {
806  auto& ddl_payload = extractPayload(ddl_data_);
807  CHECK(ddl_payload.HasMember("serverName"));
808  CHECK(ddl_payload["serverName"].IsString());
809  CHECK(ddl_payload.HasMember("ifExists"));
810  CHECK(ddl_payload["ifExists"].IsBool());
811 }
812 
814  auto& ddl_payload = extractPayload(ddl_data_);
815  std::string server_name = ddl_payload["serverName"].GetString();
816  if (isDefaultServer(server_name)) {
817  throw std::runtime_error{"OmniSci default servers cannot be dropped."};
818  }
819  bool if_exists = ddl_payload["ifExists"].GetBool();
820  if (!session_ptr_->getCatalog().getForeignServer(server_name)) {
821  if (if_exists) {
822  return ExecutionResult();
823  } else {
824  throw std::runtime_error{"Foreign server with name \"" + server_name +
825  "\" can not be dropped. Server does not exist."};
826  }
827  }
828  // check access privileges
829  if (!session_ptr_->checkDBAccessPrivileges(
831  throw std::runtime_error("Server " + server_name +
832  " will not be dropped. User has no DROP SERVER privileges.");
833  }
835  DBObject(server_name, ServerDBObjectType), session_ptr_->get_catalog_ptr().get());
836  session_ptr_->getCatalog().dropForeignServer(ddl_payload["serverName"].GetString());
837 
838  return ExecutionResult();
839 }
840 
841 SQLTypes JsonColumnSqlType::getSqlType(const rapidjson::Value& data_type) {
842  CHECK(data_type.IsObject());
843  CHECK(data_type.HasMember("type"));
844  CHECK(data_type["type"].IsString());
845 
846  std::string type = data_type["type"].GetString();
847  if (boost::iequals(type, "ARRAY")) {
848  CHECK(data_type.HasMember("array"));
849  CHECK(data_type["array"].IsObject());
850 
851  const auto& array = data_type["array"].GetObject();
852  CHECK(array.HasMember("elementType"));
853  CHECK(array["elementType"].IsString());
854  type = array["elementType"].GetString();
855  }
856  return getSqlType(type);
857 }
858 
859 SQLTypes JsonColumnSqlType::getSqlType(const std::string& type) {
860  if (boost::iequals(type, "BIGINT")) {
861  return kBIGINT;
862  }
863  if (boost::iequals(type, "BOOLEAN")) {
864  return kBOOLEAN;
865  }
866  if (boost::iequals(type, "DATE")) {
867  return kDATE;
868  }
869  if (boost::iequals(type, "DECIMAL")) {
870  return kDECIMAL;
871  }
872  if (boost::iequals(type, "DOUBLE")) {
873  return kDOUBLE;
874  }
875  if (boost::iequals(type, "FLOAT")) {
876  return kFLOAT;
877  }
878  if (boost::iequals(type, "INTEGER")) {
879  return kINT;
880  }
881  if (boost::iequals(type, "LINESTRING")) {
882  return kLINESTRING;
883  }
884  if (boost::iequals(type, "MULTIPOLYGON")) {
885  return kMULTIPOLYGON;
886  }
887  if (boost::iequals(type, "POINT")) {
888  return kPOINT;
889  }
890  if (boost::iequals(type, "POLYGON")) {
891  return kPOLYGON;
892  }
893  if (boost::iequals(type, "SMALLINT")) {
894  return kSMALLINT;
895  }
896  if (boost::iequals(type, "TEXT")) {
897  return kTEXT;
898  }
899  if (boost::iequals(type, "TIME")) {
900  return kTIME;
901  }
902  if (boost::iequals(type, "TIMESTAMP")) {
903  return kTIMESTAMP;
904  }
905  if (boost::iequals(type, "TINYINT")) {
906  return kTINYINT;
907  }
908 
909  throw std::runtime_error{"Unsupported type \"" + type + "\" specified."};
910 }
911 
912 int JsonColumnSqlType::getParam1(const rapidjson::Value& data_type) {
913  int param1 = -1;
914  CHECK(data_type.IsObject());
915  if (data_type.HasMember("precision") && !data_type["precision"].IsNull()) {
916  CHECK(data_type["precision"].IsInt());
917  param1 = data_type["precision"].GetInt();
918  } else if (auto type = getSqlType(data_type); IS_GEO(type)) {
919  param1 = static_cast<int>(kGEOMETRY);
920  }
921  return param1;
922 }
923 
924 int JsonColumnSqlType::getParam2(const rapidjson::Value& data_type) {
925  int param2 = 0;
926  CHECK(data_type.IsObject());
927  if (data_type.HasMember("scale") && !data_type["scale"].IsNull()) {
928  CHECK(data_type["scale"].IsInt());
929  param2 = data_type["scale"].GetInt();
930  } else if (auto type = getSqlType(data_type); IS_GEO(type) &&
931  data_type.HasMember("coordinateSystem") &&
932  !data_type["coordinateSystem"].IsNull()) {
933  CHECK(data_type["coordinateSystem"].IsInt());
934  param2 = data_type["coordinateSystem"].GetInt();
935  }
936  return param2;
937 }
938 
939 bool JsonColumnSqlType::isArray(const rapidjson::Value& data_type) {
940  CHECK(data_type.IsObject());
941  CHECK(data_type.HasMember("type"));
942  CHECK(data_type["type"].IsString());
943  return boost::iequals(data_type["type"].GetString(), "ARRAY");
944 }
945 
946 int JsonColumnSqlType::getArraySize(const rapidjson::Value& data_type) {
947  int size = -1;
948  if (isArray(data_type)) {
949  CHECK(data_type.HasMember("array"));
950  CHECK(data_type["array"].IsObject());
951 
952  const auto& array = data_type["array"].GetObject();
953  if (array.HasMember("size") && !array["size"].IsNull()) {
954  CHECK(array["size"].IsInt());
955  size = array["size"].GetInt();
956  }
957  }
958  return size;
959 }
960 
961 std::string* JsonColumnEncoding::getEncodingName(const rapidjson::Value& data_type) {
962  CHECK(data_type.IsObject());
963  CHECK(data_type.HasMember("encoding"));
964  CHECK(data_type["encoding"].IsObject());
965 
966  const auto& encoding = data_type["encoding"].GetObject();
967  CHECK(encoding.HasMember("type"));
968  CHECK(encoding["type"].IsString());
969  return new std::string(encoding["type"].GetString());
970 }
971 
972 int JsonColumnEncoding::getEncodingParam(const rapidjson::Value& data_type) {
973  CHECK(data_type.IsObject());
974  CHECK(data_type.HasMember("encoding"));
975  CHECK(data_type["encoding"].IsObject());
976 
977  int encoding_size = 0;
978  const auto& encoding = data_type["encoding"].GetObject();
979  if (encoding.HasMember("size") && !encoding["size"].IsNull()) {
980  CHECK(encoding["size"].IsInt());
981  encoding_size = encoding["size"].GetInt();
982  }
983  return encoding_size;
984 }
985 
987  const DdlCommandData& ddl_data,
988  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
989  : DdlCommand(ddl_data, session_ptr) {
990  auto& ddl_payload = extractPayload(ddl_data);
991  CHECK(ddl_payload.HasMember("serverName"));
992  CHECK(ddl_payload["serverName"].IsString());
993  CHECK(ddl_payload.HasMember("tableName"));
994  CHECK(ddl_payload["tableName"].IsString());
995  CHECK(ddl_payload.HasMember("ifNotExists"));
996  CHECK(ddl_payload["ifNotExists"].IsBool());
997  CHECK(ddl_payload.HasMember("columns"));
998  CHECK(ddl_payload["columns"].IsArray());
999 }
1000 
1002  auto& catalog = session_ptr_->getCatalog();
1003  auto& ddl_payload = extractPayload(ddl_data_);
1004 
1005  const std::string& table_name = ddl_payload["tableName"].GetString();
1006  if (!session_ptr_->checkDBAccessPrivileges(DBObjectType::TableDBObjectType,
1008  throw std::runtime_error(
1009  "Foreign table \"" + table_name +
1010  "\" will not be created. User has no CREATE TABLE privileges.");
1011  }
1012 
1013  bool if_not_exists = ddl_payload["ifNotExists"].GetBool();
1014  if (!catalog.validateNonExistentTableOrView(table_name, if_not_exists)) {
1015  return ExecutionResult();
1016  }
1017 
1018  foreign_storage::ForeignTable foreign_table{};
1019  std::list<ColumnDescriptor> columns{};
1020  setColumnDetails(columns);
1021  setTableDetails(table_name, foreign_table, columns);
1022  catalog.createTable(foreign_table, columns, {}, true);
1023 
1024  // TODO (max): It's transactionally unsafe, should be fixed: we may create object w/o
1025  // privileges
1027  session_ptr_->get_currentUser(),
1028  foreign_table.tableName,
1030  catalog);
1031 
1032  return ExecutionResult();
1033 }
1034 
1036  const std::string& table_name,
1037  TableDescriptor& td,
1038  const std::list<ColumnDescriptor>& columns) {
1039  ddl_utils::set_default_table_attributes(table_name, td, columns.size());
1040  td.userId = session_ptr_->get_currentUser().userId;
1042  td.hasDeletedCol = false;
1043  td.keyMetainfo = "[]";
1044  td.fragments = "";
1045  td.partitions = "";
1046 
1047  auto& ddl_payload = extractPayload(ddl_data_);
1048  auto& foreign_table = dynamic_cast<foreign_storage::ForeignTable&>(td);
1049  const std::string server_name = ddl_payload["serverName"].GetString();
1050  foreign_table.foreign_server = session_ptr_->getCatalog().getForeignServer(server_name);
1051  if (!foreign_table.foreign_server) {
1052  throw std::runtime_error{
1053  "Foreign Table with name \"" + table_name +
1054  "\" can not be created. Associated foreign server with name \"" + server_name +
1055  "\" does not exist."};
1056  }
1057 
1058  // check server usage privileges
1059  if (!isDefaultServer(server_name) &&
1060  !session_ptr_->checkDBAccessPrivileges(DBObjectType::ServerDBObjectType,
1062  server_name)) {
1063  throw std::runtime_error(
1064  "Current user does not have USAGE privilege on foreign server: " + server_name);
1065  }
1066 
1067  if (ddl_payload.HasMember("options") && !ddl_payload["options"].IsNull()) {
1068  CHECK(ddl_payload["options"].IsObject());
1069  foreign_table.initializeOptions(ddl_payload["options"]);
1070  } else {
1071  // Initialize options even if none were provided to verify a legal state.
1072  // This is necessary because some options (like "file_path") are optional only if a
1073  // paired option ("base_path") exists in the server.
1074  foreign_table.initializeOptions();
1075  }
1076  foreign_table.validateSchema(columns);
1077 
1078  if (const auto it = foreign_table.options.find("FRAGMENT_SIZE");
1079  it != foreign_table.options.end()) {
1080  foreign_table.maxFragRows = std::stoi(it->second);
1081  }
1082 
1083  if (const auto it = foreign_table.options.find("MAX_CHUNK_SIZE");
1084  it != foreign_table.options.end()) {
1085  foreign_table.maxChunkSize = std::stol(it->second);
1086  }
1087 }
1088 
1089 void CreateForeignTableCommand::setColumnDetails(std::list<ColumnDescriptor>& columns) {
1090  auto& ddl_payload = extractPayload(ddl_data_);
1091  std::unordered_set<std::string> column_names{};
1092  for (auto& column_def : ddl_payload["columns"].GetArray()) {
1093  CHECK(column_def.IsObject());
1094  CHECK(column_def.HasMember("name"));
1095  CHECK(column_def["name"].IsString());
1096  const std::string& column_name = column_def["name"].GetString();
1097 
1098  CHECK(column_def.HasMember("dataType"));
1099  CHECK(column_def["dataType"].IsObject());
1100 
1101  JsonColumnSqlType sql_type{column_def["dataType"]};
1102  const auto& data_type = column_def["dataType"].GetObject();
1103  CHECK(data_type.HasMember("notNull"));
1104  CHECK(data_type["notNull"].IsBool());
1105 
1106  std::unique_ptr<JsonColumnEncoding> encoding;
1107  if (data_type.HasMember("encoding") && !data_type["encoding"].IsNull()) {
1108  CHECK(data_type["encoding"].IsObject());
1109  encoding = std::make_unique<JsonColumnEncoding>(column_def["dataType"]);
1110  }
1111 
1112  ColumnDescriptor cd;
1113  ddl_utils::validate_non_duplicate_column(column_name, column_names);
1116  cd,
1117  &sql_type,
1118  data_type["notNull"].GetBool(),
1119  encoding.get(),
1120  nullptr);
1121  columns.emplace_back(cd);
1122  }
1123 }
1124 
1126  const DdlCommandData& ddl_data,
1127  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1128  : DdlCommand(ddl_data, session_ptr) {
1129  auto& ddl_payload = extractPayload(ddl_data_);
1130  CHECK(ddl_payload.HasMember("tableName"));
1131  CHECK(ddl_payload["tableName"].IsString());
1132  CHECK(ddl_payload.HasMember("ifExists"));
1133  CHECK(ddl_payload["ifExists"].IsBool());
1134 }
1135 
1137  auto& catalog = session_ptr_->getCatalog();
1138  auto& ddl_payload = extractPayload(ddl_data_);
1139 
1140  const std::string& table_name = ddl_payload["tableName"].GetString();
1141  const TableDescriptor* td{nullptr};
1142  std::unique_ptr<lockmgr::TableSchemaLockContainer<lockmgr::WriteLock>> td_with_lock;
1143 
1144  try {
1145  td_with_lock =
1146  std::make_unique<lockmgr::TableSchemaLockContainer<lockmgr::WriteLock>>(
1148  catalog, table_name, false));
1149  CHECK(td_with_lock);
1150  td = (*td_with_lock)();
1151  } catch (const std::runtime_error& e) {
1152  // TODO(Misiu): This should not just swallow any exception, it should only catch
1153  // exceptions that stem from the table not existing.
1154  if (ddl_payload["ifExists"].GetBool()) {
1155  return ExecutionResult();
1156  } else {
1157  throw e;
1158  }
1159  }
1160 
1161  CHECK(td);
1162 
1163  if (!session_ptr_->checkDBAccessPrivileges(
1165  throw std::runtime_error(
1166  "Foreign table \"" + table_name +
1167  "\" will not be dropped. User has no DROP TABLE privileges.");
1168  }
1169 
1171  auto table_data_write_lock =
1173  catalog.dropTable(td);
1174 
1175  return ExecutionResult();
1176 }
1177 
1179  const DdlCommandData& ddl_data,
1180  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1181  : DdlCommand(ddl_data, session_ptr) {}
1182 
1184  // Get all table names in the same way as OmniSql \t command
1185 
1186  // label_infos -> column labels
1187  std::vector<std::string> labels{"table_name"};
1188  std::vector<TargetMetaInfo> label_infos;
1189  for (const auto& label : labels) {
1190  label_infos.emplace_back(label, SQLTypeInfo(kTEXT, true));
1191  }
1192 
1193  // Get all table names
1194  auto cat_ptr = session_ptr_->get_catalog_ptr();
1195  auto cur_user = session_ptr_->get_currentUser();
1196  auto table_names = cat_ptr->getTableNamesForUser(cur_user, GET_PHYSICAL_TABLES);
1197 
1198  // logical_values -> table data
1199  std::vector<RelLogicalValues::RowValues> logical_values;
1200  for (auto table_name : table_names) {
1201  logical_values.emplace_back(RelLogicalValues::RowValues{});
1202  logical_values.back().emplace_back(genLiteralStr(table_name));
1203  }
1204 
1205  // Create ResultSet
1206  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1207  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1208 
1209  return ExecutionResult(rSet, label_infos);
1210 }
1211 
1213  const DdlCommandData& ddl_data,
1214  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1215  : DdlCommand(ddl_data, session_ptr) {
1216  auto& ddl_payload = extractPayload(ddl_data_);
1217  if (ddl_payload.HasMember("tableNames")) {
1218  CHECK(ddl_payload["tableNames"].IsArray());
1219  for (const auto& table_name : ddl_payload["tableNames"].GetArray()) {
1220  CHECK(table_name.IsString());
1221  }
1222  }
1223 }
1224 
1226  const auto catalog = session_ptr_->get_catalog_ptr();
1227  std::vector<std::string> filtered_table_names = getFilteredTableNames();
1228 
1229  std::vector<TargetMetaInfo> label_infos;
1230  set_headers_with_type(label_infos,
1231  {// { label, type, notNull }
1232  {"table_id", kBIGINT, true},
1233  {"table_name", kTEXT, true},
1234  {"column_count", kBIGINT, true},
1235  {"is_sharded_table", kBOOLEAN, true},
1236  {"shard_count", kBIGINT, true},
1237  {"max_rows", kBIGINT, true},
1238  {"fragment_size", kBIGINT, true},
1239  {"max_rollback_epochs", kBIGINT, true},
1240  {"min_epoch", kBIGINT, true},
1241  {"max_epoch", kBIGINT, true},
1242  {"min_epoch_floor", kBIGINT, true},
1243  {"max_epoch_floor", kBIGINT, true},
1244  {"metadata_file_count", kBIGINT, true},
1245  {"total_metadata_file_size", kBIGINT, true},
1246  {"total_metadata_page_count", kBIGINT, true},
1247  {"total_free_metadata_page_count", kBIGINT, false},
1248  {"data_file_count", kBIGINT, true},
1249  {"total_data_file_size", kBIGINT, true},
1250  {"total_data_page_count", kBIGINT, true},
1251  {"total_free_data_page_count", kBIGINT, false}});
1252 
1253  std::vector<RelLogicalValues::RowValues> logical_values;
1254  for (const auto& table_name : filtered_table_names) {
1255  auto [td, td_with_lock] =
1256  get_table_descriptor_with_lock<lockmgr::ReadLock>(*catalog, table_name, false);
1257  auto agg_storage_stats = get_agg_storage_stats(td, catalog.get());
1258  add_table_details(logical_values, td, agg_storage_stats);
1259  }
1260 
1261  // Create ResultSet
1262  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1263  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1264 
1265  return ExecutionResult(rSet, label_infos);
1266 }
1267 
1269  const auto catalog = session_ptr_->get_catalog_ptr();
1270  auto& ddl_payload = extractPayload(ddl_data_);
1271  auto all_table_names =
1272  catalog->getTableNamesForUser(session_ptr_->get_currentUser(), GET_PHYSICAL_TABLES);
1273  std::transform(all_table_names.begin(),
1274  all_table_names.end(),
1275  all_table_names.begin(),
1276  [](const std::string& s) { return to_upper(s); });
1277  std::vector<std::string> filtered_table_names;
1278  if (ddl_payload.HasMember("tableNames")) {
1279  std::set<std::string> all_table_names_set(all_table_names.begin(),
1280  all_table_names.end());
1281  for (const auto& table_name_json : ddl_payload["tableNames"].GetArray()) {
1282  std::string table_name = table_name_json.GetString();
1283  if (all_table_names_set.find(to_upper(table_name)) == all_table_names_set.end()) {
1284  throw std::runtime_error{"Unable to show table details for table: " + table_name +
1285  ". Table does not exist."};
1286  }
1287  auto [td, td_with_lock] =
1288  get_table_descriptor_with_lock<lockmgr::ReadLock>(*catalog, table_name, false);
1289  if (td->isForeignTable()) {
1290  throw std::runtime_error{
1291  "SHOW TABLE DETAILS is not supported for foreign tables. Table name: " +
1292  table_name + "."};
1293  }
1294  if (td->isTemporaryTable()) {
1295  throw std::runtime_error{
1296  "SHOW TABLE DETAILS is not supported for temporary tables. Table name: " +
1297  table_name + "."};
1298  }
1299  filtered_table_names.emplace_back(table_name);
1300  }
1301  } else {
1302  for (const auto& table_name : all_table_names) {
1303  auto [td, td_with_lock] =
1304  get_table_descriptor_with_lock<lockmgr::ReadLock>(*catalog, table_name, false);
1305  if (td->isForeignTable() || td->isTemporaryTable()) {
1306  continue;
1307  }
1308  filtered_table_names.emplace_back(table_name);
1309  }
1310  }
1311  return filtered_table_names;
1312 }
1313 
1315  const DdlCommandData& ddl_data,
1316  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1317  : DdlCommand(ddl_data, session_ptr) {}
1318 
1320  // label_infos -> column labels
1321  std::vector<std::string> labels{"Database", "Owner"};
1322  std::vector<TargetMetaInfo> label_infos;
1323  for (const auto& label : labels) {
1324  label_infos.emplace_back(label, SQLTypeInfo(kTEXT, true));
1325  }
1326 
1327  // Get all table names
1328  auto cur_user = session_ptr_->get_currentUser();
1329  const Catalog_Namespace::DBSummaryList db_summaries =
1331 
1332  // logical_values -> table data
1333  std::vector<RelLogicalValues::RowValues> logical_values;
1334  for (const auto& db_summary : db_summaries) {
1335  logical_values.emplace_back(RelLogicalValues::RowValues{});
1336  logical_values.back().emplace_back(genLiteralStr(db_summary.dbName));
1337  logical_values.back().emplace_back(genLiteralStr(db_summary.dbOwnerName));
1338  }
1339 
1340  // Create ResultSet
1341  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1342  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1343 
1344  return ExecutionResult(rSet, label_infos);
1345 }
1346 
1348  const DdlCommandData& ddl_data,
1349  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1350  : DdlCommand(ddl_data, session_ptr) {
1351  if (!g_enable_fsi) {
1352  throw std::runtime_error("Unsupported command: SHOW FOREIGN SERVERS");
1353  }
1354  // Verify that members are valid
1355  auto& ddl_payload = extractPayload(ddl_data_);
1356  CHECK(ddl_payload.HasMember("command"));
1357  if (ddl_payload.HasMember("filters")) {
1358  CHECK(ddl_payload["filters"].IsArray());
1359  int num_filters = 0;
1360  for (auto const& filter_def : ddl_payload["filters"].GetArray()) {
1361  CHECK(filter_def.IsObject());
1362  CHECK(filter_def.HasMember("attribute"));
1363  CHECK(filter_def["attribute"].IsString());
1364  CHECK(filter_def.HasMember("value"));
1365  CHECK(filter_def["value"].IsString());
1366  CHECK(filter_def.HasMember("operation"));
1367  CHECK(filter_def["operation"].IsString());
1368  if (num_filters > 0) {
1369  CHECK(filter_def.HasMember("chain"));
1370  CHECK(filter_def["chain"].IsString());
1371  } else {
1372  CHECK(!filter_def.HasMember("chain"));
1373  }
1374  num_filters++;
1375  }
1376  }
1377 }
1378 
1380  std::vector<TargetMetaInfo> label_infos;
1381  auto& ddl_payload = extractPayload(ddl_data_);
1382 
1383  // label_infos -> column labels
1384  std::vector<std::string> labels{"server_name", "data_wrapper", "created_at", "options"};
1385  label_infos.emplace_back(labels[0], SQLTypeInfo(kTEXT, true));
1386  label_infos.emplace_back(labels[1], SQLTypeInfo(kTEXT, true));
1387  // created_at is a TIMESTAMP
1388  label_infos.emplace_back(labels[2], SQLTypeInfo(kTIMESTAMP, true));
1389  label_infos.emplace_back(labels[3], SQLTypeInfo(kTEXT, true));
1390 
1391  const auto& user = session_ptr_->get_currentUser();
1392 
1393  std::vector<const foreign_storage::ForeignServer*> results;
1394 
1395  session_ptr_->getCatalog().getForeignServersForUser(
1396  extractFilters(ddl_payload), user, results);
1397 
1398  // logical_values -> table data
1399  std::vector<RelLogicalValues::RowValues> logical_values;
1400  for (auto const& server_ptr : results) {
1401  logical_values.emplace_back(RelLogicalValues::RowValues{});
1402  logical_values.back().emplace_back(genLiteralStr(server_ptr->name));
1403  logical_values.back().emplace_back(genLiteralStr(server_ptr->data_wrapper_type));
1404  logical_values.back().emplace_back(genLiteralTimestamp(server_ptr->creation_time));
1405  logical_values.back().emplace_back(
1406  genLiteralStr(server_ptr->getOptionsAsJsonString()));
1407  }
1408 
1409  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1410  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1411 
1412  return ExecutionResult(rSet, label_infos);
1413 }
1414 
1416  const DdlCommandData& ddl_data,
1417  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1418  : DdlCommand(ddl_data, session_ptr) {
1419  auto& ddl_payload = extractPayload(ddl_data_);
1420  CHECK(ddl_payload.HasMember("tableNames"));
1421  CHECK(ddl_payload["tableNames"].IsArray());
1422  for (auto const& tablename_def : ddl_payload["tableNames"].GetArray()) {
1423  CHECK(tablename_def.IsString());
1424  }
1425 }
1426 
1428  bool evict_cached_entries{false};
1430  auto& ddl_payload = extractPayload(ddl_data_);
1431  if (ddl_payload.HasMember("options") && !ddl_payload["options"].IsNull()) {
1432  opt.populateOptionsMap(ddl_payload["options"]);
1433  for (const auto& entry : opt.options) {
1434  if (entry.first != "EVICT") {
1435  throw std::runtime_error{
1436  "Invalid option \"" + entry.first +
1437  "\" provided for refresh command. Only \"EVICT\" option is supported."};
1438  }
1439  }
1440  CHECK(opt.options.find("EVICT") != opt.options.end());
1441 
1442  if (boost::iequals(opt.options["EVICT"], "true") ||
1443  boost::iequals(opt.options["EVICT"], "false")) {
1444  if (boost::iequals(opt.options["EVICT"], "true")) {
1445  evict_cached_entries = true;
1446  }
1447  } else {
1448  throw std::runtime_error{
1449  "Invalid value \"" + opt.options["EVICT"] +
1450  "\" provided for EVICT option. Value must be either \"true\" or \"false\"."};
1451  }
1452  }
1453 
1454  auto& cat = session_ptr_->getCatalog();
1455  const auto& current_user = session_ptr_->get_currentUser();
1456  /* verify object ownership if not suser */
1457  if (!current_user.isSuper) {
1458  for (const auto& table_name_json : ddl_payload["tableNames"].GetArray()) {
1459  std::string table_name = table_name_json.GetString();
1460  if (!Catalog_Namespace::SysCatalog::instance().verifyDBObjectOwnership(
1461  current_user, DBObject(table_name, TableDBObjectType), cat)) {
1462  throw std::runtime_error(
1463  std::string("REFRESH FOREIGN TABLES failed on table \"") + table_name +
1464  "\". It can only be executed by super user or "
1465  "owner of the "
1466  "object.");
1467  }
1468  }
1469  }
1470 
1471  for (const auto& table_name_json : ddl_payload["tableNames"].GetArray()) {
1472  std::string table_name = table_name_json.GetString();
1473  foreign_storage::refresh_foreign_table(cat, table_name, evict_cached_entries);
1474  }
1475 
1476  // todo(yoonmin) : allow per-table cache invalidation for the foreign table
1478 
1479  return ExecutionResult();
1480 }
1481 
1483  const DdlCommandData& ddl_data,
1484  std::shared_ptr<const Catalog_Namespace::SessionInfo> session_ptr)
1485  : DdlCommand(ddl_data, session_ptr) {
1486  auto& ddl_payload = extractPayload(ddl_data_);
1487  CHECK(ddl_payload.HasMember("tableName"));
1488  CHECK(ddl_payload["tableName"].IsString());
1489  CHECK(ddl_payload.HasMember("alterType"));
1490  CHECK(ddl_payload["alterType"].IsString());
1491  if (ddl_payload["alterType"] == "RENAME_TABLE") {
1492  CHECK(ddl_payload.HasMember("newTableName"));
1493  CHECK(ddl_payload["newTableName"].IsString());
1494  } else if (ddl_payload["alterType"] == "RENAME_COLUMN") {
1495  CHECK(ddl_payload.HasMember("oldColumnName"));
1496  CHECK(ddl_payload["oldColumnName"].IsString());
1497  CHECK(ddl_payload.HasMember("newColumnName"));
1498  CHECK(ddl_payload["newColumnName"].IsString());
1499  } else if (ddl_payload["alterType"] == "ALTER_OPTIONS") {
1500  CHECK(ddl_payload.HasMember("options"));
1501  CHECK(ddl_payload["options"].IsObject());
1502  } else {
1503  UNREACHABLE() << "Not a valid alter foreign table command: "
1504  << ddl_payload["alterType"].GetString();
1505  }
1506 }
1507 
1509  auto& ddl_payload = extractPayload(ddl_data_);
1510  auto& catalog = session_ptr_->getCatalog();
1511  const std::string& table_name = ddl_payload["tableName"].GetString();
1512  auto [td, td_with_lock] =
1513  get_table_descriptor_with_lock<lockmgr::WriteLock>(catalog, table_name, false);
1514 
1516 
1517  if (!session_ptr_->checkDBAccessPrivileges(
1519  throw std::runtime_error(
1520  "Current user does not have the privilege to alter foreign table: " + table_name);
1521  }
1522 
1523  auto table_data_write_lock =
1525  auto foreign_table = dynamic_cast<const foreign_storage::ForeignTable*>(td);
1526  CHECK(foreign_table);
1527 
1528  std::string alter_type = ddl_payload["alterType"].GetString();
1529  if (alter_type == "RENAME_TABLE") {
1530  renameTable(foreign_table);
1531  } else if (alter_type == "RENAME_COLUMN") {
1532  renameColumn(foreign_table);
1533  } else if (alter_type == "ALTER_OPTIONS") {
1534  alterOptions(foreign_table);
1535  }
1536 
1537  return ExecutionResult();
1538 }
1539 
1541  const foreign_storage::ForeignTable* foreign_table) {
1542  auto& ddl_payload = extractPayload(ddl_data_);
1543  auto& cat = session_ptr_->getCatalog();
1544  const std::string& table_name = ddl_payload["tableName"].GetString();
1545  const std::string& new_table_name = ddl_payload["newTableName"].GetString();
1546  if (cat.getForeignTable(new_table_name)) {
1547  throw std::runtime_error("Foreign table with name \"" + table_name +
1548  "\" can not be renamed to \"" + new_table_name + "\". " +
1549  "A different table with name \"" + new_table_name +
1550  "\" already exists.");
1551  }
1552  cat.renameTable(foreign_table, new_table_name);
1553 }
1554 
1556  const foreign_storage::ForeignTable* foreign_table) {
1557  auto& ddl_payload = extractPayload(ddl_data_);
1558  auto& cat = session_ptr_->getCatalog();
1559  const std::string& old_column_name = ddl_payload["oldColumnName"].GetString();
1560  const std::string& new_column_name = ddl_payload["newColumnName"].GetString();
1561  auto column = cat.getMetadataForColumn(foreign_table->tableId, old_column_name);
1562  if (!column) {
1563  throw std::runtime_error("Column with name \"" + old_column_name +
1564  "\" can not be renamed to \"" + new_column_name + "\". " +
1565  "Column with name \"" + old_column_name +
1566  "\" does not exist.");
1567  }
1568  if (cat.getMetadataForColumn(foreign_table->tableId, new_column_name)) {
1569  throw std::runtime_error("Column with name \"" + old_column_name +
1570  "\" can not be renamed to \"" + new_column_name + "\". " +
1571  "A column with name \"" + new_column_name +
1572  "\" already exists.");
1573  }
1574  cat.renameColumn(foreign_table, column, new_column_name);
1575 }
1576 
1578  const foreign_storage::ForeignTable* foreign_table) {
1579  auto& ddl_payload = extractPayload(ddl_data_);
1580  const std::string& table_name = ddl_payload["tableName"].GetString();
1581  auto& cat = session_ptr_->getCatalog();
1582  auto new_options_map =
1583  foreign_storage::ForeignTable::createOptionsMap(ddl_payload["options"]);
1584  foreign_table->validateSupportedOptionKeys(new_options_map);
1586  cat.setForeignTableOptions(table_name, new_options_map, false);
1587 }
1588 
1590  const DdlCommandData& ddl_data,
1591  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1592  : DdlCommand(ddl_data, session_ptr) {
1593  auto& ddl_payload = extractPayload(ddl_data_);
1594  if (ddl_payload.HasMember("tableNames")) {
1595  CHECK(ddl_payload["tableNames"].IsArray());
1596  for (auto const& tablename_def : ddl_payload["tableNames"].GetArray()) {
1597  CHECK(tablename_def.IsString());
1598  }
1599  }
1600 }
1601 
1603  auto table_names = session_ptr_->get_catalog_ptr()->getTableNamesForUser(
1604  session_ptr_->get_currentUser(), GET_PHYSICAL_TABLES);
1605 
1606  auto& ddl_payload = extractPayload(ddl_data_);
1607  if (ddl_payload.HasMember("tableNames")) {
1608  std::vector<std::string> filtered_names;
1609  for (const auto& tablename_def : ddl_payload["tableNames"].GetArray()) {
1610  std::string filter_name = tablename_def.GetString();
1611  if (std::find(table_names.begin(), table_names.end(), filter_name) !=
1612  table_names.end()) {
1613  filtered_names.emplace_back(filter_name);
1614  } else {
1615  throw std::runtime_error("Can not show disk cache usage for table: " +
1616  filter_name + ". Table does not exist.");
1617  }
1618  }
1619  return filtered_names;
1620  } else {
1621  return table_names;
1622  }
1623 }
1624 
1626  auto cat_ptr = session_ptr_->get_catalog_ptr();
1627  auto table_names = getFilteredTableNames();
1628 
1629  const auto disk_cache = cat_ptr->getDataMgr().getPersistentStorageMgr()->getDiskCache();
1630  if (!disk_cache) {
1631  throw std::runtime_error{"Disk cache not enabled. Cannot show disk cache usage."};
1632  }
1633 
1634  // label_infos -> column labels
1635  std::vector<std::string> labels{"table name", "current cache size"};
1636  std::vector<TargetMetaInfo> label_infos;
1637  label_infos.emplace_back(labels[0], SQLTypeInfo(kTEXT, true));
1638  label_infos.emplace_back(labels[1], SQLTypeInfo(kBIGINT, true));
1639 
1640  std::vector<RelLogicalValues::RowValues> logical_values;
1641 
1642  for (auto& table_name : table_names) {
1643  auto [td, td_with_lock] =
1644  get_table_descriptor_with_lock<lockmgr::ReadLock>(*cat_ptr, table_name, false);
1645 
1646  auto table_cache_size =
1647  disk_cache->getSpaceReservedByTable(cat_ptr->getDatabaseId(), td->tableId);
1648 
1649  // logical_values -> table data
1650  logical_values.emplace_back(RelLogicalValues::RowValues{});
1651  logical_values.back().emplace_back(genLiteralStr(table_name));
1652  logical_values.back().emplace_back(genLiteralBigInt(table_cache_size));
1653  }
1654 
1655  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1656  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1657 
1658  return ExecutionResult(rSet, label_infos);
1659 }
1660 
1662  const DdlCommandData& ddl_data,
1663  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1664  : DdlCommand(ddl_data, session_ptr) {
1665  auto& ddl_payload = extractPayload(ddl_data);
1666  if (ddl_payload.HasMember("userNames")) {
1667  CHECK(ddl_payload["userNames"].IsArray());
1668  for (const auto& user_name : ddl_payload["userNames"].GetArray()) {
1669  CHECK(user_name.IsString());
1670  }
1671  }
1672 }
1673 
1675  auto& ddl_payload = extractPayload(ddl_data_);
1676  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
1677 
1678  // label_infos -> column labels
1679  std::vector<std::string> labels{"NAME", "ID", "IS_SUPER", "DEFAULT_DB", "CAN_LOGIN"};
1680  std::vector<TargetMetaInfo> label_infos;
1681  label_infos.emplace_back(labels[0], SQLTypeInfo(kTEXT, true));
1682  label_infos.emplace_back(labels[1], SQLTypeInfo(kBIGINT, true));
1683  label_infos.emplace_back(labels[2], SQLTypeInfo(kBOOLEAN, true));
1684  label_infos.emplace_back(labels[3], SQLTypeInfo(kTEXT, true));
1685  label_infos.emplace_back(labels[4], SQLTypeInfo(kBOOLEAN, true));
1686  std::vector<RelLogicalValues::RowValues> logical_values;
1687 
1688  Catalog_Namespace::UserMetadata self = session_ptr_->get_currentUser();
1689  Catalog_Namespace::DBSummaryList dbsums = sys_cat.getDatabaseListForUser(self);
1690  std::unordered_set<std::string> visible_databases;
1691  if (!self.isSuper) {
1692  for (const auto& dbsum : dbsums) {
1693  visible_databases.insert(dbsum.dbName);
1694  }
1695  }
1696 
1697  std::list<Catalog_Namespace::UserMetadata> user_list;
1698  if (ddl_payload.HasMember("userNames")) {
1699  for (const auto& user_name_json : ddl_payload["userNames"].GetArray()) {
1700  std::string user_name = user_name_json.GetString();
1702  if (!sys_cat.getMetadataForUser(user_name, user)) {
1703  throw std::runtime_error("User with username \"" + user_name +
1704  "\" does not exist. ");
1705  }
1706  user_list.emplace_back(std::move(user));
1707  }
1708  } else {
1709  user_list = sys_cat.getAllUserMetadata();
1710  }
1711 
1712  for (const auto& user : user_list) {
1713  // database
1714  std::string dbname;
1716  if (sys_cat.getMetadataForDBById(user.defaultDbId, db)) {
1717  if (self.isSuper.load() || visible_databases.count(db.dbName)) {
1718  dbname = db.dbName;
1719  }
1720  }
1721  if (self.isSuper.load()) {
1722  dbname += "(" + std::to_string(user.defaultDbId) + ")";
1723  }
1724 
1725  // logical_values -> table data
1726  logical_values.emplace_back(RelLogicalValues::RowValues{});
1727  logical_values.back().emplace_back(genLiteralStr(user.userName));
1728  logical_values.back().emplace_back(genLiteralBigInt(user.userId));
1729  logical_values.back().emplace_back(genLiteralBoolean(user.isSuper.load()));
1730  logical_values.back().emplace_back(genLiteralStr(dbname));
1731  logical_values.back().emplace_back(genLiteralBoolean(user.can_login));
1732  }
1733 
1734  // Create ResultSet
1735  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1736  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1737 
1738  return ExecutionResult(rSet, label_infos);
1739 }
1740 
1742  const DdlCommandData& ddl_data,
1743  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1744  : DdlCommand(ddl_data, session_ptr) {
1745  auto& ddl_payload = extractPayload(ddl_data);
1746  CHECK(ddl_payload["userName"].IsString());
1747  CHECK(ddl_payload["effective"].IsBool());
1748 }
1749 
1751  auto& ddl_payload = extractPayload(ddl_data_);
1752  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
1753 
1754  // label_infos -> column labels
1755  std::vector<TargetMetaInfo> label_infos;
1756  std::vector<std::string> labels{"ROLES"};
1757  label_infos.emplace_back(labels[0], SQLTypeInfo(kTEXT, true));
1758 
1759  // logical_values -> table data
1760  std::vector<RelLogicalValues::RowValues> logical_values;
1761  std::vector<std::string> roles_list;
1762  Catalog_Namespace::UserMetadata self = session_ptr_->get_currentUser();
1763  std::string user_name = ddl_payload["userName"].GetString();
1764  bool effective = ddl_payload["effective"].GetBool();
1765  if (user_name.empty()) {
1766  user_name = self.userName;
1767  }
1769  bool is_user = sys_cat.getMetadataForUser(user_name, user);
1770  if (!self.isSuper) {
1771  if (is_user) {
1772  if (self.userId != user.userId) {
1773  throw std::runtime_error(
1774  "Only a superuser is authorized to request list of roles granted to another "
1775  "user.");
1776  }
1777  } else {
1778  if (!sys_cat.isRoleGrantedToGrantee(
1779  self.userName, user_name, /*only_direct=*/false)) {
1780  throw std::runtime_error(
1781  "Only a superuser is authorized to request list of roles granted to a role "
1782  "they don't have.");
1783  }
1784  }
1785  }
1786  if (user.isSuper) {
1787  auto s = sys_cat.getCreatedRoles();
1788  roles_list.insert(roles_list.end(), s.begin(), s.end());
1789  } else {
1790  roles_list = sys_cat.getRoles(user_name, effective);
1791  }
1792  for (const std::string& role_name : roles_list) {
1793  logical_values.emplace_back(RelLogicalValues::RowValues{});
1794  logical_values.back().emplace_back(genLiteralStr(role_name));
1795  }
1796 
1797  // Create ResultSet
1798  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1799  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1800 
1801  return ExecutionResult(rSet, label_infos);
1802 }
1803 
1805  const DdlCommandData& ddl_data,
1806  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1807  : DdlCommand(ddl_data, session_ptr) {
1808  auto& ddl_payload = extractPayload(ddl_data_);
1809  CHECK(ddl_payload.HasMember("oldOwners"));
1810  CHECK(ddl_payload["oldOwners"].IsArray());
1811  for (const auto& old_owner : ddl_payload["oldOwners"].GetArray()) {
1812  CHECK(old_owner.IsString());
1813  old_owners_.emplace(old_owner.GetString());
1814  }
1815  CHECK(ddl_payload.HasMember("newOwner"));
1816  CHECK(ddl_payload["newOwner"].IsString());
1817  new_owner_ = ddl_payload["newOwner"].GetString();
1818 }
1819 
1821  if (!session_ptr_->get_currentUser().isSuper) {
1822  throw std::runtime_error{
1823  "Only super users can reassign ownership of database objects."};
1824  }
1825  const auto catalog = session_ptr_->get_catalog_ptr();
1826  catalog->reassignOwners(old_owners_, new_owner_);
1827  return ExecutionResult();
1828 }
int32_t maxRollbackEpochs
ShowForeignServersCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
#define CHECK_EQ(x, y)
Definition: Logger.h:219
std::string partitions
ShowRolesCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
ExecutionResult execute() override
AlterForeignServerCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
static void validateAlterOptions(const OptionsMap &options_map)
Verifies that the given options map only contains options that can be legally altered.
std::string returnCacheType()
declare this class scoped local to avoid exposing rapidjson in the header file
static const AccessPrivileges DROP_SERVER
Definition: DBObject.h:191
std::string cat(Ts &&...args)
std::unique_ptr< DdlCommandData > ddl_data_
std::string getOptionsAsJsonString() const
class for a per-database catalog. also includes metadata for the current database and the current use...
Definition: Catalog.h:114
Definition: sqltypes.h:49
SQLTypes
Definition: sqltypes.h:38
std::string tableName
static const AccessPrivileges ALTER_TABLE
Definition: DBObject.h:167
CreateForeignServerCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
Data_Namespace::DataMgr & getDataMgr() const
Definition: Catalog.h:229
#define NULL_BIGINT
static WriteLock getWriteLockForTable(const Catalog_Namespace::Catalog &cat, const std::string &table_name)
Definition: LockMgrImpl.h:155
ShowDatabasesCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
std::string storageType
void revokeDBObjectPrivilegesFromAll(DBObject object, Catalog *catalog)
static const AccessPrivileges SERVER_USAGE
Definition: DBObject.h:193
DropForeignTableCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
#define UNREACHABLE()
Definition: Logger.h:255
std::string fragments
ExecutionResult execute() override
CreateForeignTableCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
void validateSupportedOptionKeys(const OptionsMap &options_map) const
Verifies that the options_map contains the keys required by a foreign table; including those specifie...
void add_table_details(std::vector< RelLogicalValues::RowValues > &logical_values, const TableDescriptor *logical_table, const AggregratedStorageStats &agg_storage_stats)
void aggregate(const File_Namespace::StorageStats &storage_stats)
std::optional< uint64_t > total_free_data_page_count
Definition: FileMgr.h:113
void refresh_foreign_table(Catalog_Namespace::Catalog &catalog, const std::string &table_name, const bool evict_cached_entries)
static void invalidateCaches()
ShowTablesCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
ShowDiskCacheUsageCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
void createDBObject(const UserMetadata &user, const std::string &objectName, DBObjectType type, const Catalog_Namespace::Catalog &catalog, int32_t objectId=-1)
std::string to_string(char const *&&v)
void set_headers_with_type(std::vector< TargetMetaInfo > &label_infos, const std::vector< std::tuple< std::string, SQLTypes, bool >> &headers)
std::tuple< const TableDescriptor *, std::unique_ptr< lockmgr::TableSchemaLockContainer< LockType > > > get_table_descriptor_with_lock(const Catalog_Namespace::Catalog &cat, const std::string &table_name, const bool populate_fragmenter)
void validate_non_duplicate_column(const std::string &column_name, std::unordered_set< std::string > &upper_column_names)
Definition: DdlUtils.cpp:675
std::set< std::string > old_owners_
void set_column_descriptor(const std::string &column_name, ColumnDescriptor &cd, SqlType *column_type, const bool not_null, const Encoding *encoding, const std::string *default_value)
Definition: DdlUtils.cpp:645
static OptionsMap createOptionsMap(const rapidjson::Value &json_options)
Creates an options map from given options. Converts options that must be upper case appropriately...
static const AccessPrivileges ALTER_SERVER
Definition: DBObject.h:192
std::unique_ptr< RexLiteral > genLiteralBigInt(int64_t val)
This file contains the class specification and related data structures for Catalog.
void setTableDetails(const std::string &table_name, TableDescriptor &td, const std::list< ColumnDescriptor > &columns)
const std::string getTargetQuerySessionToKill()
const DdlCommandData & ddl_data_
ExecutionResult execute() override
const std::string commandStr()
static SysCatalog & instance()
Definition: SysCatalog.h:312
This file contains the class specification and related data structures for SysCatalog.
Classes representing a parse tree.
ShowTableDetailsCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
void setColumnDetails(std::list< ColumnDescriptor > &columns)
DropForeignServerCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
static const AccessPrivileges DROP_TABLE
Definition: DBObject.h:161
ExecutionResult execute() override
std::optional< uint64_t > total_free_metadata_page_count
Definition: FileMgr.h:109
void populateOptionsMap(OptionsMap &&options_map, bool clear=false)
const rapidjson::Value & extractPayload(const DdlCommandData &ddl_data)
std::unique_ptr< RexLiteral > genLiteralTimestamp(time_t val)
ExecutionResult execute() override
ExecutionResult execute() override
DBSummaryList getDatabaseListForUser(const UserMetadata &user)
int getDatabaseId() const
Definition: Catalog.h:284
uint64_t total_metadata_page_count
Definition: FileMgr.h:108
static const AccessPrivileges CREATE_SERVER
Definition: DBObject.h:190
void updateResultSet(const std::string &query_ra, RType type, bool success=true)
ExecutionResult execute() override
std::unique_ptr< RexLiteral > genLiteralBoolean(bool val)
void validate_non_reserved_keyword(const std::string &column_name)
Definition: DdlUtils.cpp:684
specifies the content in-memory of a row in the column metadata table
OUTPUT transform(INPUT const &input, FUNC const &func)
Definition: misc.h:290
static const AccessPrivileges CREATE_TABLE
Definition: DBObject.h:160
std::vector< const TableDescriptor * > getPhysicalTablesDescriptors(const TableDescriptor *logical_table_desc, bool populate_fragmenter=true) const
Definition: Catalog.cpp:4150
ExecutionResult execute() override
std::string keyMetainfo
void set_default_table_attributes(const std::string &table_name, TableDescriptor &td, const int32_t column_count)
Definition: DdlUtils.cpp:661
File_Namespace::GlobalFileMgr * getGlobalFileMgr() const
Definition: DataMgr.cpp:616
std::string to_upper(const std::string &str)
static ResultSet * create(std::vector< TargetMetaInfo > &label_infos, std::vector< RelLogicalValues::RowValues > &logical_values)
ExecutionResult execute() override
void alterOptions(const foreign_storage::ForeignTable *foreign_table)
DistributedExecutionDetails getDistributedExecutionDetails()
ExecutionResult execute()
Definition: sqltypes.h:52
Definition: sqltypes.h:53
std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr_
std::vector< std::string > getFilteredTableNames()
DdlCommandExecutor(const std::string &ddl_statement, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
AggregratedStorageStats get_agg_storage_stats(const TableDescriptor *td, const Catalog_Namespace::Catalog *catalog)
uint64_t total_metadata_file_size
Definition: FileMgr.h:107
Basic constructors and methods of the row set interface.
ReassignOwnedCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
std::vector< std::string > getFilteredTableNames()
ExecutionResult execute() override
static std::unique_ptr< RexLiteral > genLiteralStr(std::string val)
Definition: DBHandler.cpp:7432
ExecutionResult execute() override
static std::shared_ptr< MutexType > getMutex(const LockType lockType, const KeyType &key)
Definition: LegacyLockMgr.h:51
void validate_table_type(const TableDescriptor *td, const TableType expected_table_type, const std::string &command)
Definition: DdlUtils.cpp:692
const ForeignServer * foreign_server
Definition: ForeignTable.h:55
void renameTable(const foreign_storage::ForeignTable *foreign_table)
#define CHECK(condition)
Definition: Logger.h:211
bool isDefaultServer(const std::string &server_name)
std::list< DBSummary > DBSummaryList
Definition: SysCatalog.h:137
Definition: sqltypes.h:45
AggregratedStorageStats(const File_Namespace::StorageStats &storage_stats)
std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr_
std::vector< std::unique_ptr< const RexScalar >> RowValues
ExecutionLocation execution_location
const rapidjson::Value * extractFilters(const rapidjson::Value &payload)
AlterForeignTableCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
void renameColumn(const foreign_storage::ForeignTable *foreign_table)
static constexpr char const * FOREIGN_TABLE
bool g_enable_fsi
Definition: Catalog.cpp:94
ExecutionResult execute() override
ExecutionResult execute() override
ExecutionResult execute() override
ShowUserDetailsCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
#define IS_GEO(T)
Definition: sqltypes.h:251
#define VLOG(n)
Definition: Logger.h:305
std::atomic< bool > isSuper
Definition: SysCatalog.h:109
static std::unique_ptr< Parser::DDLStmt > delegate(const rapidjson::Value &payload)
RefreshForeignTablesCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
ExecutionResult execute() override