OmniSciDB  eb3a3d0a03
 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);
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  virtual 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 
396  } else if (ddl_command_ == "CREATE_DB") {
397  auto create_db_stmt = Parser::CreateDBStmt(extractPayload(*ddl_data_));
398  create_db_stmt.execute(*session_ptr_);
399  return result;
400  } else if (ddl_command_ == "DROP_DB") {
401  auto drop_db_stmt = Parser::DropDBStmt(extractPayload(*ddl_data_));
402  drop_db_stmt.execute(*session_ptr_);
403  return result;
404  } else if (ddl_command_ == "RENAME_DB") {
405  auto rename_db_stmt = Parser::RenameDBStmt(extractPayload(*ddl_data_));
406  rename_db_stmt.execute(*session_ptr_);
407  return result;
408  } else if (ddl_command_ == "CREATE_USER") {
409  auto create_user_stmt = Parser::CreateUserStmt(extractPayload(*ddl_data_));
410  create_user_stmt.execute(*session_ptr_);
411  return result;
412  } else if (ddl_command_ == "DROP_USER") {
413  auto drop_user_stmt = Parser::DropUserStmt(extractPayload(*ddl_data_));
414  drop_user_stmt.execute(*session_ptr_);
415  return result;
416  } else if (ddl_command_ == "ALTER_USER") {
417  auto alter_user_stmt = Parser::AlterUserStmt(extractPayload(*ddl_data_));
418  alter_user_stmt.execute(*session_ptr_);
419  return result;
420  } else if (ddl_command_ == "RENAME_USER") {
421  auto rename_user_stmt = Parser::RenameUserStmt(extractPayload(*ddl_data_));
422  rename_user_stmt.execute(*session_ptr_);
423  return result;
424  } else if (ddl_command_ == "CREATE_ROLE") {
425  auto create_role_stmt = Parser::CreateRoleStmt(extractPayload(*ddl_data_));
426  create_role_stmt.execute(*session_ptr_);
427  return result;
428  } else if (ddl_command_ == "DROP_ROLE") {
429  auto drop_role_stmt = Parser::DropRoleStmt(extractPayload(*ddl_data_));
430  drop_role_stmt.execute(*session_ptr_);
431  return result;
432  } else if (ddl_command_ == "GRANT_ROLE") {
433  auto grant_role_stmt = Parser::GrantRoleStmt(extractPayload(*ddl_data_));
434  grant_role_stmt.execute(*session_ptr_);
435  return result;
436  } else if (ddl_command_ == "REVOKE_ROLE") {
437  auto revoke_role_stmt = Parser::RevokeRoleStmt(extractPayload(*ddl_data_));
438  revoke_role_stmt.execute(*session_ptr_);
439  return result;
440  } else if (ddl_command_ == "GRANT_PRIVILEGE") {
441  auto grant_privilege_stmt = Parser::GrantPrivilegesStmt(extractPayload(*ddl_data_));
442  grant_privilege_stmt.execute(*session_ptr_);
443  return result;
444  } else if (ddl_command_ == "REVOKE_PRIVILEGE") {
445  auto revoke_privileges_stmt =
447  revoke_privileges_stmt.execute(*session_ptr_);
448  return result;
449  } else if (ddl_command_ == "CREATE_DATAFRAME") {
450  auto create_dataframe_stmt = Parser::CreateDataframeStmt(extractPayload(*ddl_data_));
451  create_dataframe_stmt.execute(*session_ptr_);
452  return result;
453  } else if (ddl_command_ == "VALIDATE_SYSTEM") {
454  // VALIDATE should have been excuted in outer context before it reaches here
455  UNREACHABLE();
456  }
457 
458  // the following commands require a global unique lock until proper table locking has
459  // been implemented and/or verified
460  auto execute_write_lock = mapd_unique_lock<mapd_shared_mutex>(
463  // TODO(vancouver): add appropriate table locking
464 
465  if (ddl_command_ == "CREATE_SERVER") {
466  result = CreateForeignServerCommand{*ddl_data_, session_ptr_}.execute();
467  } else if (ddl_command_ == "DROP_SERVER") {
468  result = DropForeignServerCommand{*ddl_data_, session_ptr_}.execute();
469  } else if (ddl_command_ == "CREATE_FOREIGN_TABLE") {
470  result = CreateForeignTableCommand{*ddl_data_, session_ptr_}.execute();
471  } else if (ddl_command_ == "DROP_FOREIGN_TABLE") {
472  result = DropForeignTableCommand{*ddl_data_, session_ptr_}.execute();
473  } else if (ddl_command_ == "SHOW_TABLES") {
474  result = ShowTablesCommand{*ddl_data_, session_ptr_}.execute();
475  } else if (ddl_command_ == "SHOW_TABLE_DETAILS") {
476  result = ShowTableDetailsCommand{*ddl_data_, session_ptr_}.execute();
477  } else if (ddl_command_ == "SHOW_DATABASES") {
478  result = ShowDatabasesCommand{*ddl_data_, session_ptr_}.execute();
479  } else if (ddl_command_ == "SHOW_SERVERS") {
480  result = ShowForeignServersCommand{*ddl_data_, session_ptr_}.execute();
481  } else if (ddl_command_ == "ALTER_SERVER") {
482  result = AlterForeignServerCommand{*ddl_data_, session_ptr_}.execute();
483  } else if (ddl_command_ == "ALTER_FOREIGN_TABLE") {
484  result = AlterForeignTableCommand{*ddl_data_, session_ptr_}.execute();
485  } else if (ddl_command_ == "REFRESH_FOREIGN_TABLES") {
486  result = RefreshForeignTablesCommand{*ddl_data_, session_ptr_}.execute();
487  } else if (ddl_command_ == "SHOW_DISK_CACHE_USAGE") {
488  result = ShowDiskCacheUsageCommand{*ddl_data_, session_ptr_}.execute();
489  } else if (ddl_command_ == "SHOW_USER_DETAILS") {
490  result = ShowUserDetailsCommand{*ddl_data_, session_ptr_}.execute();
491  } else if (ddl_command_ == "REASSIGN_OWNED") {
492  result = ReassignOwnedCommand{*ddl_data_, session_ptr_}.execute();
493  } else {
494  throw std::runtime_error("Unsupported DDL command");
495  }
496 
497  return result;
498 }
499 
501  return (ddl_command_ == "SHOW_USER_SESSIONS");
502 }
503 
505  return (ddl_command_ == "SHOW_QUERIES");
506 }
507 
509  return (ddl_command_ == "KILL_QUERY");
510 }
511 
513  return (ddl_command_ == "SHOW_CREATE_TABLE");
514 }
515 
517  DistributedExecutionDetails execution_details;
518  if (ddl_command_ == "CREATE_DATAFRAME" || ddl_command_ == "RENAME_TABLE" ||
519  ddl_command_ == "ALTER_TABLE" || ddl_command_ == "CREATE_TABLE" ||
520  ddl_command_ == "DROP_TABLE" || ddl_command_ == "TRUNCATE_TABLE" ||
521  ddl_command_ == "DUMP_TABLE" || ddl_command_ == "RESTORE_TABLE" ||
522  ddl_command_ == "OPTIMIZE_TABLE" || ddl_command_ == "CREATE_VIEW" ||
523  ddl_command_ == "DROP_VIEW" || ddl_command_ == "CREATE_DB" ||
524  ddl_command_ == "DROP_DB" || ddl_command_ == "RENAME_DB" ||
525  ddl_command_ == "CREATE_USER" || ddl_command_ == "DROP_USER" ||
526  ddl_command_ == "ALTER_USER" || ddl_command_ == "RENAME_USER" ||
527  ddl_command_ == "CREATE_ROLE" || ddl_command_ == "DROP_ROLE" ||
528  ddl_command_ == "GRANT_ROLE" || ddl_command_ == "REVOKE_ROLE" ||
529  ddl_command_ == "REASSIGN_OWNED") {
530  // group user/role/db commands
532  execution_details.aggregation_type = AggregationType::NONE;
533  } else if (ddl_command_ == "GRANT_PRIVILEGE" || ddl_command_ == "REVOKE_PRIVILEGE") {
534  auto& ddl_payload = extractPayload(*ddl_data_);
535  CHECK(ddl_payload.HasMember("type"));
536  const std::string& targetType = ddl_payload["type"].GetString();
537  if (targetType == "DASHBOARD") {
538  // dashboard commands should run on Aggregator alone
540  execution_details.aggregation_type = AggregationType::NONE;
541  } else {
543  execution_details.aggregation_type = AggregationType::NONE;
544  }
545 
546  } else if (ddl_command_ == "SHOW_TABLE_DETAILS") {
548  execution_details.aggregation_type = AggregationType::UNION;
549  } else {
550  // Commands that fall here : COPY_TABLE, EXPORT_QUERY, etc.
552  execution_details.aggregation_type = AggregationType::NONE;
553  }
554  return execution_details;
555 }
556 
558  // caller should check whether DDL indicates KillQuery request
559  // i.e., use isKillQuery() before calling this function
560  auto& ddl_payload = extractPayload(*ddl_data_);
561  CHECK(isKillQuery());
562  CHECK(ddl_payload.HasMember("querySession"));
563  const std::string& query_session = ddl_payload["querySession"].GetString();
564  // regex matcher for public_session: start_time{3}-session_id{4} (Example:819-4RDo)
565  boost::regex session_id_regex{R"([0-9]{3}-[a-zA-Z0-9]{4})",
566  boost::regex::extended | boost::regex::icase};
567  if (!boost::regex_match(query_session, session_id_regex)) {
568  throw std::runtime_error(
569  "Please provide the correct session ID of the query that you want to interrupt.");
570  }
571  return query_session;
572 }
573 
574 const std::string DdlCommandExecutor::commandStr() {
575  return ddl_command_;
576 }
577 
579  const DdlCommandData& ddl_data,
580  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
581  : DdlCommand(ddl_data, session_ptr) {
582  auto& ddl_payload = extractPayload(ddl_data_);
583  CHECK(ddl_payload.HasMember("serverName"));
584  CHECK(ddl_payload["serverName"].IsString());
585  CHECK(ddl_payload.HasMember("dataWrapper"));
586  CHECK(ddl_payload["dataWrapper"].IsString());
587  if (ddl_payload.HasMember("options")) {
588  CHECK(ddl_payload["options"].IsObject());
589  }
590  CHECK(ddl_payload.HasMember("ifNotExists"));
591  CHECK(ddl_payload["ifNotExists"].IsBool());
592 }
593 
596 
597  auto& ddl_payload = extractPayload(ddl_data_);
598  std::string server_name = ddl_payload["serverName"].GetString();
599  if (isDefaultServer(server_name)) {
600  throw std::runtime_error{"Server names cannot start with \"omnisci\"."};
601  }
602  bool if_not_exists = ddl_payload["ifNotExists"].GetBool();
603  if (session_ptr_->getCatalog().getForeignServer(server_name)) {
604  if (if_not_exists) {
605  return result;
606  } else {
607  throw std::runtime_error{"A foreign server with name \"" + server_name +
608  "\" already exists."};
609  }
610  }
611  // check access privileges
612  if (!session_ptr_->checkDBAccessPrivileges(DBObjectType::ServerDBObjectType,
614  throw std::runtime_error("Server " + std::string(server_name) +
615  " will not be created. User has no create privileges.");
616  }
617 
618  auto& current_user = session_ptr_->get_currentUser();
619  auto foreign_server = std::make_unique<foreign_storage::ForeignServer>();
620  foreign_server->data_wrapper_type = to_upper(ddl_payload["dataWrapper"].GetString());
621  foreign_server->name = server_name;
622  foreign_server->user_id = current_user.userId;
623  if (ddl_payload.HasMember("options")) {
624  foreign_server->populateOptionsMap(ddl_payload["options"]);
625  }
626  foreign_server->validate();
627 
628  auto& catalog = session_ptr_->getCatalog();
629  catalog.createForeignServer(std::move(foreign_server),
630  ddl_payload["ifNotExists"].GetBool());
632  current_user, server_name, ServerDBObjectType, catalog);
633 
634  return result;
635 }
636 
638  const DdlCommandData& ddl_data,
639  std::shared_ptr<const Catalog_Namespace::SessionInfo> session_ptr)
640  : DdlCommand(ddl_data, session_ptr) {
641  auto& ddl_payload = extractPayload(ddl_data_);
642  CHECK(ddl_payload.HasMember("serverName"));
643  CHECK(ddl_payload["serverName"].IsString());
644  CHECK(ddl_payload.HasMember("alterType"));
645  CHECK(ddl_payload["alterType"].IsString());
646  if (ddl_payload["alterType"] == "SET_OPTIONS") {
647  CHECK(ddl_payload.HasMember("options"));
648  CHECK(ddl_payload["options"].IsObject());
649  } else if (ddl_payload["alterType"] == "SET_DATA_WRAPPER") {
650  CHECK(ddl_payload.HasMember("dataWrapper"));
651  CHECK(ddl_payload["dataWrapper"].IsString());
652  } else if (ddl_payload["alterType"] == "RENAME_SERVER") {
653  CHECK(ddl_payload.HasMember("newServerName"));
654  CHECK(ddl_payload["newServerName"].IsString());
655  } else if (ddl_payload["alterType"] == "CHANGE_OWNER") {
656  CHECK(ddl_payload.HasMember("newOwner"));
657  CHECK(ddl_payload["newOwner"].IsString());
658  } else {
659  UNREACHABLE(); // not-implemented alterType
660  }
661 }
662 
664  auto& ddl_payload = extractPayload(ddl_data_);
665  std::string server_name = ddl_payload["serverName"].GetString();
666  if (isDefaultServer(server_name)) {
667  throw std::runtime_error{"OmniSci default servers cannot be altered."};
668  }
669  if (!session_ptr_->getCatalog().getForeignServer(server_name)) {
670  throw std::runtime_error{"Foreign server with name \"" + server_name +
671  "\" does not exist and can not be altered."};
672  }
673  if (!hasAlterServerPrivileges()) {
674  throw std::runtime_error("Server " + server_name +
675  " can not be altered. User has no ALTER SERVER privileges.");
676  }
677  std::string alter_type = ddl_payload["alterType"].GetString();
678  if (alter_type == "CHANGE_OWNER") {
680  } else if (alter_type == "SET_DATA_WRAPPER") {
682  } else if (alter_type == "SET_OPTIONS") {
684  } else if (alter_type == "RENAME_SERVER") {
686  }
687 
688  return ExecutionResult();
689 }
690 
692  auto& ddl_payload = extractPayload(ddl_data_);
693  std::string server_name = ddl_payload["serverName"].GetString();
694  std::string new_owner = ddl_payload["newOwner"].GetString();
695  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
696  if (!session_ptr_->get_currentUser().isSuper) {
697  throw std::runtime_error(
698  "Only a super user can change a foreign server's owner. "
699  "Current user is not a super-user. "
700  "Foreign server with name \"" +
701  server_name + "\" will not have owner changed.");
702  }
703  Catalog_Namespace::UserMetadata user, original_owner;
704  if (!sys_cat.getMetadataForUser(new_owner, user)) {
705  throw std::runtime_error("User with username \"" + new_owner + "\" does not exist. " +
706  "Foreign server with name \"" + server_name +
707  "\" can not have owner changed.");
708  }
709  auto& cat = session_ptr_->getCatalog();
710  // get original owner metadata
711  bool original_owner_exists = sys_cat.getMetadataForUserById(
712  cat.getForeignServer(server_name)->user_id, original_owner);
713  // update catalog
714  cat.changeForeignServerOwner(server_name, user.userId);
715  try {
716  // update permissions
717  DBObject db_object(server_name, DBObjectType::ServerDBObjectType);
718  sys_cat.changeDBObjectOwnership(
719  user, original_owner, db_object, cat, original_owner_exists);
720  } catch (const std::runtime_error& e) {
721  // update permissions failed, revert catalog update
722  cat.changeForeignServerOwner(server_name, original_owner.userId);
723  throw;
724  }
725 }
726 
728  auto& ddl_payload = extractPayload(ddl_data_);
729  std::string server_name = ddl_payload["serverName"].GetString();
730  std::string new_server_name = ddl_payload["newServerName"].GetString();
731  if (isDefaultServer(new_server_name)) {
732  throw std::runtime_error{"OmniSci prefix can not be used for new name of server."};
733  }
734  auto& cat = session_ptr_->getCatalog();
735  // check for a conflicting server
736  if (cat.getForeignServer(new_server_name)) {
737  throw std::runtime_error("Foreign server with name \"" + server_name +
738  "\" can not be renamed to \"" + new_server_name + "\"." +
739  "Foreign server with name \"" + new_server_name +
740  "\" exists.");
741  }
742  // update catalog
743  cat.renameForeignServer(server_name, new_server_name);
744  try {
745  // migrate object privileges
746  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
747  sys_cat.renameDBObject(server_name,
748  new_server_name,
750  cat.getForeignServer(new_server_name)->id,
751  cat);
752  } catch (const std::runtime_error& e) {
753  // permission migration failed, revert catalog update
754  cat.renameForeignServer(new_server_name, server_name);
755  throw;
756  }
757 }
758 
760  auto& ddl_payload = extractPayload(ddl_data_);
761  std::string server_name = ddl_payload["serverName"].GetString();
762  auto& cat = session_ptr_->getCatalog();
763  // update catalog
764  const auto foreign_server = cat.getForeignServer(server_name);
766  opt.populateOptionsMap(foreign_server->getOptionsAsJsonString());
767  opt.populateOptionsMap(ddl_payload["options"]);
768  cat.setForeignServerOptions(server_name, opt.getOptionsAsJsonString());
769 }
770 
772  auto& ddl_payload = extractPayload(ddl_data_);
773  std::string server_name = ddl_payload["serverName"].GetString();
774  std::string data_wrapper = ddl_payload["dataWrapper"].GetString();
775  auto& cat = session_ptr_->getCatalog();
776  // update catalog
777  cat.setForeignServerDataWrapper(server_name, data_wrapper);
778 }
779 
781  // TODO: implement `GRANT/REVOKE ALTER_SERVER` DDL commands
782  auto& ddl_payload = extractPayload(ddl_data_);
783  std::string server_name = ddl_payload["serverName"].GetString();
784  return session_ptr_->checkDBAccessPrivileges(
786 }
787 
789  const DdlCommandData& ddl_data,
790  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
791  : DdlCommand(ddl_data, session_ptr) {
792  auto& ddl_payload = extractPayload(ddl_data_);
793  CHECK(ddl_payload.HasMember("serverName"));
794  CHECK(ddl_payload["serverName"].IsString());
795  CHECK(ddl_payload.HasMember("ifExists"));
796  CHECK(ddl_payload["ifExists"].IsBool());
797 }
798 
800  auto& ddl_payload = extractPayload(ddl_data_);
801  std::string server_name = ddl_payload["serverName"].GetString();
802  if (isDefaultServer(server_name)) {
803  throw std::runtime_error{"OmniSci default servers cannot be dropped."};
804  }
805  bool if_exists = ddl_payload["ifExists"].GetBool();
806  if (!session_ptr_->getCatalog().getForeignServer(server_name)) {
807  if (if_exists) {
808  return ExecutionResult();
809  } else {
810  throw std::runtime_error{"Foreign server with name \"" + server_name +
811  "\" can not be dropped. Server does not exist."};
812  }
813  }
814  // check access privileges
815  if (!session_ptr_->checkDBAccessPrivileges(
817  throw std::runtime_error("Server " + server_name +
818  " will not be dropped. User has no DROP SERVER privileges.");
819  }
821  DBObject(server_name, ServerDBObjectType), session_ptr_->get_catalog_ptr().get());
822  session_ptr_->getCatalog().dropForeignServer(ddl_payload["serverName"].GetString());
823 
824  return ExecutionResult();
825 }
826 
827 SQLTypes JsonColumnSqlType::getSqlType(const rapidjson::Value& data_type) {
828  CHECK(data_type.IsObject());
829  CHECK(data_type.HasMember("type"));
830  CHECK(data_type["type"].IsString());
831 
832  std::string type = data_type["type"].GetString();
833  if (boost::iequals(type, "ARRAY")) {
834  CHECK(data_type.HasMember("array"));
835  CHECK(data_type["array"].IsObject());
836 
837  const auto& array = data_type["array"].GetObject();
838  CHECK(array.HasMember("elementType"));
839  CHECK(array["elementType"].IsString());
840  type = array["elementType"].GetString();
841  }
842  return getSqlType(type);
843 }
844 
845 SQLTypes JsonColumnSqlType::getSqlType(const std::string& type) {
846  if (boost::iequals(type, "BIGINT")) {
847  return kBIGINT;
848  }
849  if (boost::iequals(type, "BOOLEAN")) {
850  return kBOOLEAN;
851  }
852  if (boost::iequals(type, "DATE")) {
853  return kDATE;
854  }
855  if (boost::iequals(type, "DECIMAL")) {
856  return kDECIMAL;
857  }
858  if (boost::iequals(type, "DOUBLE")) {
859  return kDOUBLE;
860  }
861  if (boost::iequals(type, "FLOAT")) {
862  return kFLOAT;
863  }
864  if (boost::iequals(type, "INTEGER")) {
865  return kINT;
866  }
867  if (boost::iequals(type, "LINESTRING")) {
868  return kLINESTRING;
869  }
870  if (boost::iequals(type, "MULTIPOLYGON")) {
871  return kMULTIPOLYGON;
872  }
873  if (boost::iequals(type, "POINT")) {
874  return kPOINT;
875  }
876  if (boost::iequals(type, "POLYGON")) {
877  return kPOLYGON;
878  }
879  if (boost::iequals(type, "SMALLINT")) {
880  return kSMALLINT;
881  }
882  if (boost::iequals(type, "TEXT")) {
883  return kTEXT;
884  }
885  if (boost::iequals(type, "TIME")) {
886  return kTIME;
887  }
888  if (boost::iequals(type, "TIMESTAMP")) {
889  return kTIMESTAMP;
890  }
891  if (boost::iequals(type, "TINYINT")) {
892  return kTINYINT;
893  }
894 
895  throw std::runtime_error{"Unsupported type \"" + type + "\" specified."};
896 }
897 
898 int JsonColumnSqlType::getParam1(const rapidjson::Value& data_type) {
899  int param1 = -1;
900  CHECK(data_type.IsObject());
901  if (data_type.HasMember("precision") && !data_type["precision"].IsNull()) {
902  CHECK(data_type["precision"].IsInt());
903  param1 = data_type["precision"].GetInt();
904  } else if (auto type = getSqlType(data_type); IS_GEO(type)) {
905  param1 = static_cast<int>(kGEOMETRY);
906  }
907  return param1;
908 }
909 
910 int JsonColumnSqlType::getParam2(const rapidjson::Value& data_type) {
911  int param2 = 0;
912  CHECK(data_type.IsObject());
913  if (data_type.HasMember("scale") && !data_type["scale"].IsNull()) {
914  CHECK(data_type["scale"].IsInt());
915  param2 = data_type["scale"].GetInt();
916  } else if (auto type = getSqlType(data_type); IS_GEO(type) &&
917  data_type.HasMember("coordinateSystem") &&
918  !data_type["coordinateSystem"].IsNull()) {
919  CHECK(data_type["coordinateSystem"].IsInt());
920  param2 = data_type["coordinateSystem"].GetInt();
921  }
922  return param2;
923 }
924 
925 bool JsonColumnSqlType::isArray(const rapidjson::Value& data_type) {
926  CHECK(data_type.IsObject());
927  CHECK(data_type.HasMember("type"));
928  CHECK(data_type["type"].IsString());
929  return boost::iequals(data_type["type"].GetString(), "ARRAY");
930 }
931 
932 int JsonColumnSqlType::getArraySize(const rapidjson::Value& data_type) {
933  int size = -1;
934  if (isArray(data_type)) {
935  CHECK(data_type.HasMember("array"));
936  CHECK(data_type["array"].IsObject());
937 
938  const auto& array = data_type["array"].GetObject();
939  if (array.HasMember("size") && !array["size"].IsNull()) {
940  CHECK(array["size"].IsInt());
941  size = array["size"].GetInt();
942  }
943  }
944  return size;
945 }
946 
947 std::string* JsonColumnEncoding::getEncodingName(const rapidjson::Value& data_type) {
948  CHECK(data_type.IsObject());
949  CHECK(data_type.HasMember("encoding"));
950  CHECK(data_type["encoding"].IsObject());
951 
952  const auto& encoding = data_type["encoding"].GetObject();
953  CHECK(encoding.HasMember("type"));
954  CHECK(encoding["type"].IsString());
955  return new std::string(encoding["type"].GetString());
956 }
957 
958 int JsonColumnEncoding::getEncodingParam(const rapidjson::Value& data_type) {
959  CHECK(data_type.IsObject());
960  CHECK(data_type.HasMember("encoding"));
961  CHECK(data_type["encoding"].IsObject());
962 
963  int encoding_size = 0;
964  const auto& encoding = data_type["encoding"].GetObject();
965  if (encoding.HasMember("size") && !encoding["size"].IsNull()) {
966  CHECK(encoding["size"].IsInt());
967  encoding_size = encoding["size"].GetInt();
968  }
969  return encoding_size;
970 }
971 
973  const DdlCommandData& ddl_data,
974  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
975  : DdlCommand(ddl_data, session_ptr) {
976  auto& ddl_payload = extractPayload(ddl_data);
977  CHECK(ddl_payload.HasMember("serverName"));
978  CHECK(ddl_payload["serverName"].IsString());
979  CHECK(ddl_payload.HasMember("tableName"));
980  CHECK(ddl_payload["tableName"].IsString());
981  CHECK(ddl_payload.HasMember("ifNotExists"));
982  CHECK(ddl_payload["ifNotExists"].IsBool());
983  CHECK(ddl_payload.HasMember("columns"));
984  CHECK(ddl_payload["columns"].IsArray());
985 }
986 
988  auto& catalog = session_ptr_->getCatalog();
989  auto& ddl_payload = extractPayload(ddl_data_);
990 
991  const std::string& table_name = ddl_payload["tableName"].GetString();
992  if (!session_ptr_->checkDBAccessPrivileges(DBObjectType::TableDBObjectType,
994  throw std::runtime_error(
995  "Foreign table \"" + table_name +
996  "\" will not be created. User has no CREATE TABLE privileges.");
997  }
998 
999  bool if_not_exists = ddl_payload["ifNotExists"].GetBool();
1000  if (!catalog.validateNonExistentTableOrView(table_name, if_not_exists)) {
1001  return ExecutionResult();
1002  }
1003 
1004  foreign_storage::ForeignTable foreign_table{};
1005  std::list<ColumnDescriptor> columns{};
1006  setColumnDetails(columns);
1007  setTableDetails(table_name, foreign_table, columns);
1008  catalog.createTable(foreign_table, columns, {}, true);
1009 
1010  // TODO (max): It's transactionally unsafe, should be fixed: we may create object w/o
1011  // privileges
1013  session_ptr_->get_currentUser(),
1014  foreign_table.tableName,
1016  catalog);
1017 
1018  return ExecutionResult();
1019 }
1020 
1022  const std::string& table_name,
1023  TableDescriptor& td,
1024  const std::list<ColumnDescriptor>& columns) {
1025  ddl_utils::set_default_table_attributes(table_name, td, columns.size());
1026  td.userId = session_ptr_->get_currentUser().userId;
1028  td.hasDeletedCol = false;
1029  td.keyMetainfo = "[]";
1030  td.fragments = "";
1031  td.partitions = "";
1032 
1033  auto& ddl_payload = extractPayload(ddl_data_);
1034  auto& foreign_table = dynamic_cast<foreign_storage::ForeignTable&>(td);
1035  const std::string server_name = ddl_payload["serverName"].GetString();
1036  foreign_table.foreign_server = session_ptr_->getCatalog().getForeignServer(server_name);
1037  if (!foreign_table.foreign_server) {
1038  throw std::runtime_error{
1039  "Foreign Table with name \"" + table_name +
1040  "\" can not be created. Associated foreign server with name \"" + server_name +
1041  "\" does not exist."};
1042  }
1043 
1044  // check server usage privileges
1045  if (!isDefaultServer(server_name) &&
1046  !session_ptr_->checkDBAccessPrivileges(DBObjectType::ServerDBObjectType,
1048  server_name)) {
1049  throw std::runtime_error(
1050  "Current user does not have USAGE privilege on foreign server: " + server_name);
1051  }
1052 
1053  if (ddl_payload.HasMember("options") && !ddl_payload["options"].IsNull()) {
1054  CHECK(ddl_payload["options"].IsObject());
1055  foreign_table.initializeOptions(ddl_payload["options"]);
1056  } else {
1057  // Initialize options even if none were provided to verify a legal state.
1058  // This is necessary because some options (like "file_path") are optional only if a
1059  // paired option ("base_path") exists in the server.
1060  foreign_table.initializeOptions();
1061  }
1062  foreign_table.validateSchema(columns);
1063 
1064  if (const auto it = foreign_table.options.find("FRAGMENT_SIZE");
1065  it != foreign_table.options.end()) {
1066  foreign_table.maxFragRows = std::stoi(it->second);
1067  }
1068 }
1069 
1070 void CreateForeignTableCommand::setColumnDetails(std::list<ColumnDescriptor>& columns) {
1071  auto& ddl_payload = extractPayload(ddl_data_);
1072  std::unordered_set<std::string> column_names{};
1073  for (auto& column_def : ddl_payload["columns"].GetArray()) {
1074  CHECK(column_def.IsObject());
1075  CHECK(column_def.HasMember("name"));
1076  CHECK(column_def["name"].IsString());
1077  const std::string& column_name = column_def["name"].GetString();
1078 
1079  CHECK(column_def.HasMember("dataType"));
1080  CHECK(column_def["dataType"].IsObject());
1081 
1082  JsonColumnSqlType sql_type{column_def["dataType"]};
1083  const auto& data_type = column_def["dataType"].GetObject();
1084  CHECK(data_type.HasMember("notNull"));
1085  CHECK(data_type["notNull"].IsBool());
1086 
1087  std::unique_ptr<JsonColumnEncoding> encoding;
1088  if (data_type.HasMember("encoding") && !data_type["encoding"].IsNull()) {
1089  CHECK(data_type["encoding"].IsObject());
1090  encoding = std::make_unique<JsonColumnEncoding>(column_def["dataType"]);
1091  }
1092 
1093  ColumnDescriptor cd;
1094  ddl_utils::validate_non_duplicate_column(column_name, column_names);
1097  cd,
1098  &sql_type,
1099  data_type["notNull"].GetBool(),
1100  encoding.get(),
1101  nullptr);
1102  columns.emplace_back(cd);
1103  }
1104 }
1105 
1107  const DdlCommandData& ddl_data,
1108  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1109  : DdlCommand(ddl_data, session_ptr) {
1110  auto& ddl_payload = extractPayload(ddl_data_);
1111  CHECK(ddl_payload.HasMember("tableName"));
1112  CHECK(ddl_payload["tableName"].IsString());
1113  CHECK(ddl_payload.HasMember("ifExists"));
1114  CHECK(ddl_payload["ifExists"].IsBool());
1115 }
1116 
1118  auto& catalog = session_ptr_->getCatalog();
1119  auto& ddl_payload = extractPayload(ddl_data_);
1120 
1121  const std::string& table_name = ddl_payload["tableName"].GetString();
1122  const TableDescriptor* td{nullptr};
1123  std::unique_ptr<lockmgr::TableSchemaLockContainer<lockmgr::WriteLock>> td_with_lock;
1124 
1125  try {
1126  td_with_lock =
1127  std::make_unique<lockmgr::TableSchemaLockContainer<lockmgr::WriteLock>>(
1129  catalog, table_name, false));
1130  CHECK(td_with_lock);
1131  td = (*td_with_lock)();
1132  } catch (const std::runtime_error& e) {
1133  // TODO(Misiu): This should not just swallow any exception, it should only catch
1134  // exceptions that stem from the table not existing.
1135  if (ddl_payload["ifExists"].GetBool()) {
1136  return ExecutionResult();
1137  } else {
1138  throw e;
1139  }
1140  }
1141 
1142  CHECK(td);
1143 
1144  if (!session_ptr_->checkDBAccessPrivileges(
1146  throw std::runtime_error(
1147  "Foreign table \"" + table_name +
1148  "\" will not be dropped. User has no DROP TABLE privileges.");
1149  }
1150 
1152  auto table_data_write_lock =
1154  catalog.dropTable(td);
1155 
1156  return ExecutionResult();
1157 }
1158 
1160  const DdlCommandData& ddl_data,
1161  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1162  : DdlCommand(ddl_data, session_ptr) {}
1163 
1165  // Get all table names in the same way as OmniSql \t command
1166 
1167  // label_infos -> column labels
1168  std::vector<std::string> labels{"table_name"};
1169  std::vector<TargetMetaInfo> label_infos;
1170  for (const auto& label : labels) {
1171  label_infos.emplace_back(label, SQLTypeInfo(kTEXT, true));
1172  }
1173 
1174  // Get all table names
1175  auto cat_ptr = session_ptr_->get_catalog_ptr();
1176  auto cur_user = session_ptr_->get_currentUser();
1177  auto table_names = cat_ptr->getTableNamesForUser(cur_user, GET_PHYSICAL_TABLES);
1178 
1179  // logical_values -> table data
1180  std::vector<RelLogicalValues::RowValues> logical_values;
1181  for (auto table_name : table_names) {
1182  logical_values.emplace_back(RelLogicalValues::RowValues{});
1183  logical_values.back().emplace_back(genLiteralStr(table_name));
1184  }
1185 
1186  // Create ResultSet
1187  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1188  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1189 
1190  return ExecutionResult(rSet, label_infos);
1191 }
1192 
1194  const DdlCommandData& ddl_data,
1195  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1196  : DdlCommand(ddl_data, session_ptr) {
1197  auto& ddl_payload = extractPayload(ddl_data_);
1198  if (ddl_payload.HasMember("tableNames")) {
1199  CHECK(ddl_payload["tableNames"].IsArray());
1200  for (const auto& table_name : ddl_payload["tableNames"].GetArray()) {
1201  CHECK(table_name.IsString());
1202  }
1203  }
1204 }
1205 
1207  const auto catalog = session_ptr_->get_catalog_ptr();
1208  std::vector<std::string> filtered_table_names = getFilteredTableNames();
1209 
1210  std::vector<TargetMetaInfo> label_infos;
1211  set_headers_with_type(label_infos,
1212  {// { label, type, notNull }
1213  {"table_id", kBIGINT, true},
1214  {"table_name", kTEXT, true},
1215  {"column_count", kBIGINT, true},
1216  {"is_sharded_table", kBOOLEAN, true},
1217  {"shard_count", kBIGINT, true},
1218  {"max_rows", kBIGINT, true},
1219  {"fragment_size", kBIGINT, true},
1220  {"max_rollback_epochs", kBIGINT, true},
1221  {"min_epoch", kBIGINT, true},
1222  {"max_epoch", kBIGINT, true},
1223  {"min_epoch_floor", kBIGINT, true},
1224  {"max_epoch_floor", kBIGINT, true},
1225  {"metadata_file_count", kBIGINT, true},
1226  {"total_metadata_file_size", kBIGINT, true},
1227  {"total_metadata_page_count", kBIGINT, true},
1228  {"total_free_metadata_page_count", kBIGINT, false},
1229  {"data_file_count", kBIGINT, true},
1230  {"total_data_file_size", kBIGINT, true},
1231  {"total_data_page_count", kBIGINT, true},
1232  {"total_free_data_page_count", kBIGINT, false}});
1233 
1234  std::vector<RelLogicalValues::RowValues> logical_values;
1235  for (const auto& table_name : filtered_table_names) {
1236  auto [td, td_with_lock] =
1237  get_table_descriptor_with_lock<lockmgr::ReadLock>(*catalog, table_name, false);
1238  auto agg_storage_stats = get_agg_storage_stats(td, catalog.get());
1239  add_table_details(logical_values, td, agg_storage_stats);
1240  }
1241 
1242  // Create ResultSet
1243  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1244  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1245 
1246  return ExecutionResult(rSet, label_infos);
1247 }
1248 
1250  const auto catalog = session_ptr_->get_catalog_ptr();
1251  auto& ddl_payload = extractPayload(ddl_data_);
1252  auto all_table_names =
1253  catalog->getTableNamesForUser(session_ptr_->get_currentUser(), GET_PHYSICAL_TABLES);
1254  std::transform(all_table_names.begin(),
1255  all_table_names.end(),
1256  all_table_names.begin(),
1257  [](const std::string& s) { return to_upper(s); });
1258  std::vector<std::string> filtered_table_names;
1259  if (ddl_payload.HasMember("tableNames")) {
1260  std::set<std::string> all_table_names_set(all_table_names.begin(),
1261  all_table_names.end());
1262  for (const auto& table_name_json : ddl_payload["tableNames"].GetArray()) {
1263  std::string table_name = table_name_json.GetString();
1264  if (all_table_names_set.find(to_upper(table_name)) == all_table_names_set.end()) {
1265  throw std::runtime_error{"Unable to show table details for table: " + table_name +
1266  ". Table does not exist."};
1267  }
1268  auto [td, td_with_lock] =
1269  get_table_descriptor_with_lock<lockmgr::ReadLock>(*catalog, table_name, false);
1270  if (td->isForeignTable()) {
1271  throw std::runtime_error{
1272  "SHOW TABLE DETAILS is not supported for foreign tables. Table name: " +
1273  table_name + "."};
1274  }
1275  if (td->isTemporaryTable()) {
1276  throw std::runtime_error{
1277  "SHOW TABLE DETAILS is not supported for temporary tables. Table name: " +
1278  table_name + "."};
1279  }
1280  filtered_table_names.emplace_back(table_name);
1281  }
1282  } else {
1283  for (const auto& table_name : all_table_names) {
1284  auto [td, td_with_lock] =
1285  get_table_descriptor_with_lock<lockmgr::ReadLock>(*catalog, table_name, false);
1286  if (td->isForeignTable() || td->isTemporaryTable()) {
1287  continue;
1288  }
1289  filtered_table_names.emplace_back(table_name);
1290  }
1291  }
1292  return filtered_table_names;
1293 }
1294 
1296  const DdlCommandData& ddl_data,
1297  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1298  : DdlCommand(ddl_data, session_ptr) {}
1299 
1301  // label_infos -> column labels
1302  std::vector<std::string> labels{"Database", "Owner"};
1303  std::vector<TargetMetaInfo> label_infos;
1304  for (const auto& label : labels) {
1305  label_infos.emplace_back(label, SQLTypeInfo(kTEXT, true));
1306  }
1307 
1308  // Get all table names
1309  auto cur_user = session_ptr_->get_currentUser();
1310  const Catalog_Namespace::DBSummaryList db_summaries =
1312 
1313  // logical_values -> table data
1314  std::vector<RelLogicalValues::RowValues> logical_values;
1315  for (const auto& db_summary : db_summaries) {
1316  logical_values.emplace_back(RelLogicalValues::RowValues{});
1317  logical_values.back().emplace_back(genLiteralStr(db_summary.dbName));
1318  logical_values.back().emplace_back(genLiteralStr(db_summary.dbOwnerName));
1319  }
1320 
1321  // Create ResultSet
1322  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1323  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1324 
1325  return ExecutionResult(rSet, label_infos);
1326 }
1327 
1329  const DdlCommandData& ddl_data,
1330  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1331  : DdlCommand(ddl_data, session_ptr) {
1332  if (!g_enable_fsi) {
1333  throw std::runtime_error("Unsupported command: SHOW FOREIGN SERVERS");
1334  }
1335  // Verify that members are valid
1336  auto& ddl_payload = extractPayload(ddl_data_);
1337  CHECK(ddl_payload.HasMember("command"));
1338  if (ddl_payload.HasMember("filters")) {
1339  CHECK(ddl_payload["filters"].IsArray());
1340  int num_filters = 0;
1341  for (auto const& filter_def : ddl_payload["filters"].GetArray()) {
1342  CHECK(filter_def.IsObject());
1343  CHECK(filter_def.HasMember("attribute"));
1344  CHECK(filter_def["attribute"].IsString());
1345  CHECK(filter_def.HasMember("value"));
1346  CHECK(filter_def["value"].IsString());
1347  CHECK(filter_def.HasMember("operation"));
1348  CHECK(filter_def["operation"].IsString());
1349  if (num_filters > 0) {
1350  CHECK(filter_def.HasMember("chain"));
1351  CHECK(filter_def["chain"].IsString());
1352  } else {
1353  CHECK(!filter_def.HasMember("chain"));
1354  }
1355  num_filters++;
1356  }
1357  }
1358 }
1359 
1361  std::vector<TargetMetaInfo> label_infos;
1362  auto& ddl_payload = extractPayload(ddl_data_);
1363 
1364  // label_infos -> column labels
1365  std::vector<std::string> labels{"server_name", "data_wrapper", "created_at", "options"};
1366  label_infos.emplace_back(labels[0], SQLTypeInfo(kTEXT, true));
1367  label_infos.emplace_back(labels[1], SQLTypeInfo(kTEXT, true));
1368  // created_at is a TIMESTAMP
1369  label_infos.emplace_back(labels[2], SQLTypeInfo(kTIMESTAMP, true));
1370  label_infos.emplace_back(labels[3], SQLTypeInfo(kTEXT, true));
1371 
1372  const auto& user = session_ptr_->get_currentUser();
1373 
1374  std::vector<const foreign_storage::ForeignServer*> results;
1375 
1376  session_ptr_->getCatalog().getForeignServersForUser(
1377  extractFilters(ddl_payload), user, results);
1378 
1379  // logical_values -> table data
1380  std::vector<RelLogicalValues::RowValues> logical_values;
1381  for (auto const& server_ptr : results) {
1382  logical_values.emplace_back(RelLogicalValues::RowValues{});
1383  logical_values.back().emplace_back(genLiteralStr(server_ptr->name));
1384  logical_values.back().emplace_back(genLiteralStr(server_ptr->data_wrapper_type));
1385  logical_values.back().emplace_back(genLiteralTimestamp(server_ptr->creation_time));
1386  logical_values.back().emplace_back(
1387  genLiteralStr(server_ptr->getOptionsAsJsonString()));
1388  }
1389 
1390  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1391  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1392 
1393  return ExecutionResult(rSet, label_infos);
1394 }
1395 
1397  const DdlCommandData& ddl_data,
1398  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1399  : DdlCommand(ddl_data, session_ptr) {
1400  auto& ddl_payload = extractPayload(ddl_data_);
1401  CHECK(ddl_payload.HasMember("tableNames"));
1402  CHECK(ddl_payload["tableNames"].IsArray());
1403  for (auto const& tablename_def : ddl_payload["tableNames"].GetArray()) {
1404  CHECK(tablename_def.IsString());
1405  }
1406 }
1407 
1409  bool evict_cached_entries{false};
1411  auto& ddl_payload = extractPayload(ddl_data_);
1412  if (ddl_payload.HasMember("options") && !ddl_payload["options"].IsNull()) {
1413  opt.populateOptionsMap(ddl_payload["options"]);
1414  for (const auto& entry : opt.options) {
1415  if (entry.first != "EVICT") {
1416  throw std::runtime_error{
1417  "Invalid option \"" + entry.first +
1418  "\" provided for refresh command. Only \"EVICT\" option is supported."};
1419  }
1420  }
1421  CHECK(opt.options.find("EVICT") != opt.options.end());
1422 
1423  if (boost::iequals(opt.options["EVICT"], "true") ||
1424  boost::iequals(opt.options["EVICT"], "false")) {
1425  if (boost::iequals(opt.options["EVICT"], "true")) {
1426  evict_cached_entries = true;
1427  }
1428  } else {
1429  throw std::runtime_error{
1430  "Invalid value \"" + opt.options["EVICT"] +
1431  "\" provided for EVICT option. Value must be either \"true\" or \"false\"."};
1432  }
1433  }
1434 
1435  auto& cat = session_ptr_->getCatalog();
1436  const auto& current_user = session_ptr_->get_currentUser();
1437  /* verify object ownership if not suser */
1438  if (!current_user.isSuper) {
1439  for (const auto& table_name_json : ddl_payload["tableNames"].GetArray()) {
1440  std::string table_name = table_name_json.GetString();
1441  if (!Catalog_Namespace::SysCatalog::instance().verifyDBObjectOwnership(
1442  current_user, DBObject(table_name, TableDBObjectType), cat)) {
1443  throw std::runtime_error(
1444  std::string("REFRESH FOREIGN TABLES failed on table \"") + table_name +
1445  "\". It can only be executed by super user or "
1446  "owner of the "
1447  "object.");
1448  }
1449  }
1450  }
1451 
1452  for (const auto& table_name_json : ddl_payload["tableNames"].GetArray()) {
1453  std::string table_name = table_name_json.GetString();
1454  foreign_storage::refresh_foreign_table(cat, table_name, evict_cached_entries);
1455  }
1456 
1458 
1459  return ExecutionResult();
1460 }
1461 
1463  const DdlCommandData& ddl_data,
1464  std::shared_ptr<const Catalog_Namespace::SessionInfo> session_ptr)
1465  : DdlCommand(ddl_data, session_ptr) {
1466  auto& ddl_payload = extractPayload(ddl_data_);
1467  CHECK(ddl_payload.HasMember("tableName"));
1468  CHECK(ddl_payload["tableName"].IsString());
1469  CHECK(ddl_payload.HasMember("alterType"));
1470  CHECK(ddl_payload["alterType"].IsString());
1471  if (ddl_payload["alterType"] == "RENAME_TABLE") {
1472  CHECK(ddl_payload.HasMember("newTableName"));
1473  CHECK(ddl_payload["newTableName"].IsString());
1474  } else if (ddl_payload["alterType"] == "RENAME_COLUMN") {
1475  CHECK(ddl_payload.HasMember("oldColumnName"));
1476  CHECK(ddl_payload["oldColumnName"].IsString());
1477  CHECK(ddl_payload.HasMember("newColumnName"));
1478  CHECK(ddl_payload["newColumnName"].IsString());
1479  } else if (ddl_payload["alterType"] == "ALTER_OPTIONS") {
1480  CHECK(ddl_payload.HasMember("options"));
1481  CHECK(ddl_payload["options"].IsObject());
1482  } else {
1483  UNREACHABLE() << "Not a valid alter foreign table command: "
1484  << ddl_payload["alterType"].GetString();
1485  }
1486 }
1487 
1489  auto& ddl_payload = extractPayload(ddl_data_);
1490  auto& catalog = session_ptr_->getCatalog();
1491  const std::string& table_name = ddl_payload["tableName"].GetString();
1492  auto [td, td_with_lock] =
1493  get_table_descriptor_with_lock<lockmgr::WriteLock>(catalog, table_name, false);
1494 
1496 
1497  if (!session_ptr_->checkDBAccessPrivileges(
1499  throw std::runtime_error(
1500  "Current user does not have the privilege to alter foreign table: " + table_name);
1501  }
1502 
1503  auto table_data_write_lock =
1505  auto foreign_table = dynamic_cast<const foreign_storage::ForeignTable*>(td);
1506  CHECK(foreign_table);
1507 
1508  std::string alter_type = ddl_payload["alterType"].GetString();
1509  if (alter_type == "RENAME_TABLE") {
1510  renameTable(foreign_table);
1511  } else if (alter_type == "RENAME_COLUMN") {
1512  renameColumn(foreign_table);
1513  } else if (alter_type == "ALTER_OPTIONS") {
1514  alterOptions(foreign_table);
1515  }
1516 
1517  return ExecutionResult();
1518 }
1519 
1521  const foreign_storage::ForeignTable* foreign_table) {
1522  auto& ddl_payload = extractPayload(ddl_data_);
1523  auto& cat = session_ptr_->getCatalog();
1524  const std::string& table_name = ddl_payload["tableName"].GetString();
1525  const std::string& new_table_name = ddl_payload["newTableName"].GetString();
1526  if (cat.getForeignTable(new_table_name)) {
1527  throw std::runtime_error("Foreign table with name \"" + table_name +
1528  "\" can not be renamed to \"" + new_table_name + "\". " +
1529  "A different table with name \"" + new_table_name +
1530  "\" already exists.");
1531  }
1532  cat.renameTable(foreign_table, new_table_name);
1533 }
1534 
1536  const foreign_storage::ForeignTable* foreign_table) {
1537  auto& ddl_payload = extractPayload(ddl_data_);
1538  auto& cat = session_ptr_->getCatalog();
1539  const std::string& old_column_name = ddl_payload["oldColumnName"].GetString();
1540  const std::string& new_column_name = ddl_payload["newColumnName"].GetString();
1541  auto column = cat.getMetadataForColumn(foreign_table->tableId, old_column_name);
1542  if (!column) {
1543  throw std::runtime_error("Column with name \"" + old_column_name +
1544  "\" can not be renamed to \"" + new_column_name + "\". " +
1545  "Column with name \"" + old_column_name +
1546  "\" does not exist.");
1547  }
1548  if (cat.getMetadataForColumn(foreign_table->tableId, new_column_name)) {
1549  throw std::runtime_error("Column with name \"" + old_column_name +
1550  "\" can not be renamed to \"" + new_column_name + "\". " +
1551  "A column with name \"" + new_column_name +
1552  "\" already exists.");
1553  }
1554  cat.renameColumn(foreign_table, column, new_column_name);
1555 }
1556 
1558  const foreign_storage::ForeignTable* foreign_table) {
1559  auto& ddl_payload = extractPayload(ddl_data_);
1560  const std::string& table_name = ddl_payload["tableName"].GetString();
1561  auto& cat = session_ptr_->getCatalog();
1562  auto new_options_map =
1563  foreign_storage::ForeignTable::createOptionsMap(ddl_payload["options"]);
1564  foreign_table->validateSupportedOptionKeys(new_options_map);
1566  cat.setForeignTableOptions(table_name, new_options_map, false);
1567 }
1568 
1570  const DdlCommandData& ddl_data,
1571  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1572  : DdlCommand(ddl_data, session_ptr) {
1573  auto& ddl_payload = extractPayload(ddl_data_);
1574  if (ddl_payload.HasMember("tableNames")) {
1575  CHECK(ddl_payload["tableNames"].IsArray());
1576  for (auto const& tablename_def : ddl_payload["tableNames"].GetArray()) {
1577  CHECK(tablename_def.IsString());
1578  }
1579  }
1580 }
1581 
1583  auto table_names = session_ptr_->get_catalog_ptr()->getTableNamesForUser(
1584  session_ptr_->get_currentUser(), GET_PHYSICAL_TABLES);
1585 
1586  auto& ddl_payload = extractPayload(ddl_data_);
1587  if (ddl_payload.HasMember("tableNames")) {
1588  std::vector<std::string> filtered_names;
1589  for (const auto& tablename_def : ddl_payload["tableNames"].GetArray()) {
1590  std::string filter_name = tablename_def.GetString();
1591  if (std::find(table_names.begin(), table_names.end(), filter_name) !=
1592  table_names.end()) {
1593  filtered_names.emplace_back(filter_name);
1594  } else {
1595  throw std::runtime_error("Can not show disk cache usage for table: " +
1596  filter_name + ". Table does not exist.");
1597  }
1598  }
1599  return filtered_names;
1600  } else {
1601  return table_names;
1602  }
1603 }
1604 
1606  auto cat_ptr = session_ptr_->get_catalog_ptr();
1607  auto table_names = getFilteredTableNames();
1608 
1609  const auto disk_cache = cat_ptr->getDataMgr().getPersistentStorageMgr()->getDiskCache();
1610  if (!disk_cache) {
1611  throw std::runtime_error{"Disk cache not enabled. Cannot show disk cache usage."};
1612  }
1613 
1614  // label_infos -> column labels
1615  std::vector<std::string> labels{"table name", "current cache size"};
1616  std::vector<TargetMetaInfo> label_infos;
1617  label_infos.emplace_back(labels[0], SQLTypeInfo(kTEXT, true));
1618  label_infos.emplace_back(labels[1], SQLTypeInfo(kBIGINT, true));
1619 
1620  std::vector<RelLogicalValues::RowValues> logical_values;
1621 
1622  for (auto& table_name : table_names) {
1623  auto [td, td_with_lock] =
1624  get_table_descriptor_with_lock<lockmgr::ReadLock>(*cat_ptr, table_name, false);
1625 
1626  auto table_cache_size =
1627  disk_cache->getSpaceReservedByTable(cat_ptr->getDatabaseId(), td->tableId);
1628 
1629  // logical_values -> table data
1630  logical_values.emplace_back(RelLogicalValues::RowValues{});
1631  logical_values.back().emplace_back(genLiteralStr(table_name));
1632  logical_values.back().emplace_back(genLiteralBigInt(table_cache_size));
1633  }
1634 
1635  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1636  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1637 
1638  return ExecutionResult(rSet, label_infos);
1639 }
1640 
1642  const DdlCommandData& ddl_data,
1643  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1644  : DdlCommand(ddl_data, session_ptr) {
1645  auto& ddl_payload = extractPayload(ddl_data);
1646  if (ddl_payload.HasMember("userNames")) {
1647  CHECK(ddl_payload["userNames"].IsArray());
1648  for (const auto& user_name : ddl_payload["userNames"].GetArray()) {
1649  CHECK(user_name.IsString());
1650  }
1651  }
1652 }
1653 
1655  auto& ddl_payload = extractPayload(ddl_data_);
1656  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
1657 
1658  // label_infos -> column labels
1659  std::vector<std::string> labels{"NAME", "ID", "IS_SUPER", "DEFAULT_DB", "CAN_LOGIN"};
1660  std::vector<TargetMetaInfo> label_infos;
1661  label_infos.emplace_back(labels[0], SQLTypeInfo(kTEXT, true));
1662  label_infos.emplace_back(labels[1], SQLTypeInfo(kBIGINT, true));
1663  label_infos.emplace_back(labels[2], SQLTypeInfo(kBOOLEAN, true));
1664  label_infos.emplace_back(labels[3], SQLTypeInfo(kTEXT, true));
1665  label_infos.emplace_back(labels[4], SQLTypeInfo(kBOOLEAN, true));
1666  std::vector<RelLogicalValues::RowValues> logical_values;
1667 
1668  Catalog_Namespace::UserMetadata self = session_ptr_->get_currentUser();
1669  Catalog_Namespace::DBSummaryList dbsums = sys_cat.getDatabaseListForUser(self);
1670  std::unordered_set<std::string> visible_databases;
1671  if (!self.isSuper) {
1672  for (const auto& dbsum : dbsums) {
1673  visible_databases.insert(dbsum.dbName);
1674  }
1675  }
1676 
1677  std::list<Catalog_Namespace::UserMetadata> user_list;
1678  if (ddl_payload.HasMember("userNames")) {
1679  for (const auto& user_name_json : ddl_payload["userNames"].GetArray()) {
1680  std::string user_name = user_name_json.GetString();
1682  if (!sys_cat.getMetadataForUser(user_name, user)) {
1683  throw std::runtime_error("User with username \"" + user_name +
1684  "\" does not exist. ");
1685  }
1686  user_list.emplace_back(std::move(user));
1687  }
1688  } else {
1689  user_list = sys_cat.getAllUserMetadata();
1690  }
1691 
1692  for (const auto& user : user_list) {
1693  // database
1694  std::string dbname;
1696  if (sys_cat.getMetadataForDBById(user.defaultDbId, db)) {
1697  if (self.isSuper.load() || visible_databases.count(db.dbName)) {
1698  dbname = db.dbName;
1699  }
1700  }
1701  if (self.isSuper.load()) {
1702  dbname += "(" + std::to_string(user.defaultDbId) + ")";
1703  }
1704 
1705  // logical_values -> table data
1706  logical_values.emplace_back(RelLogicalValues::RowValues{});
1707  logical_values.back().emplace_back(genLiteralStr(user.userName));
1708  logical_values.back().emplace_back(genLiteralBigInt(user.userId));
1709  logical_values.back().emplace_back(genLiteralBoolean(user.isSuper.load()));
1710  logical_values.back().emplace_back(genLiteralStr(dbname));
1711  logical_values.back().emplace_back(genLiteralBoolean(user.can_login));
1712  }
1713 
1714  // Create ResultSet
1715  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1716  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1717 
1718  return ExecutionResult(rSet, label_infos);
1719 }
1720 
1722  const DdlCommandData& ddl_data,
1723  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1724  : DdlCommand(ddl_data, session_ptr) {
1725  auto& ddl_payload = extractPayload(ddl_data_);
1726  CHECK(ddl_payload.HasMember("oldOwners"));
1727  CHECK(ddl_payload["oldOwners"].IsArray());
1728  for (const auto& old_owner : ddl_payload["oldOwners"].GetArray()) {
1729  CHECK(old_owner.IsString());
1730  old_owners_.emplace(old_owner.GetString());
1731  }
1732  CHECK(ddl_payload.HasMember("newOwner"));
1733  CHECK(ddl_payload["newOwner"].IsString());
1734  new_owner_ = ddl_payload["newOwner"].GetString();
1735 }
1736 
1738  if (!session_ptr_->get_currentUser().isSuper) {
1739  throw std::runtime_error{
1740  "Only super users can reassign ownership of database objects."};
1741  }
1742  const auto catalog = session_ptr_->get_catalog_ptr();
1743  catalog->reassignOwners(old_owners_, new_owner_);
1744  return ExecutionResult();
1745 }
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:217
std::string partitions
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.
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:102
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:223
#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:253
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:107
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:633
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:603
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_
const std::string commandStr()
static SysCatalog & instance()
Definition: SysCatalog.h:318
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:103
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:277
uint64_t total_metadata_page_count
Definition: FileMgr.h:102
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:642
specifies the content in-memory of a row in the column metadata table
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:4121
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:619
File_Namespace::GlobalFileMgr * getGlobalFileMgr() const
Definition: DataMgr.cpp:549
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:101
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:7105
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:650
const ForeignServer * foreign_server
Definition: ForeignTable.h:54
void renameTable(const foreign_storage::ForeignTable *foreign_table)
#define CHECK(condition)
Definition: Logger.h:209
bool isDefaultServer(const std::string &server_name)
std::list< DBSummary > DBSummaryList
Definition: SysCatalog.h:149
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:93
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:303
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