OmniSciDB  a667adc9c8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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 extern bool g_enable_s3_fsi;
38 
39 bool DdlCommand::isDefaultServer(const std::string& server_name) {
40  return boost::iequals(server_name.substr(0, 7), "omnisci");
41 }
42 
43 namespace {
44 template <class LockType>
45 std::tuple<const TableDescriptor*,
46  std::unique_ptr<lockmgr::TableSchemaLockContainer<LockType>>>
48  const std::string& table_name,
49  const bool populate_fragmenter) {
50  const TableDescriptor* td{nullptr};
51  std::unique_ptr<lockmgr::TableSchemaLockContainer<LockType>> td_with_lock =
52  std::make_unique<lockmgr::TableSchemaLockContainer<LockType>>(
54  cat, table_name, populate_fragmenter));
55  CHECK(td_with_lock);
56  td = (*td_with_lock)();
57  CHECK(td);
58  return std::make_tuple(td, std::move(td_with_lock));
59 }
60 
62  int32_t min_epoch;
63  int32_t max_epoch;
64  int32_t min_epoch_floor;
65  int32_t max_epoch_floor;
66 
68  : File_Namespace::StorageStats(storage_stats)
69  , min_epoch(storage_stats.epoch)
70  , max_epoch(storage_stats.epoch)
71  , min_epoch_floor(storage_stats.epoch_floor)
72  , max_epoch_floor(storage_stats.epoch_floor) {}
73 
74  void aggregate(const File_Namespace::StorageStats& storage_stats) {
75  metadata_file_count += storage_stats.metadata_file_count;
76  total_metadata_file_size += storage_stats.total_metadata_file_size;
77  total_metadata_page_count += storage_stats.total_metadata_page_count;
78  if (storage_stats.total_free_metadata_page_count) {
79  if (total_free_metadata_page_count) {
80  total_free_metadata_page_count.value() +=
81  storage_stats.total_free_metadata_page_count.value();
82  } else {
83  total_free_metadata_page_count = storage_stats.total_free_metadata_page_count;
84  }
85  }
86  data_file_count += storage_stats.data_file_count;
87  total_data_file_size += storage_stats.total_data_file_size;
88  total_data_page_count += storage_stats.total_data_page_count;
89  if (storage_stats.total_free_data_page_count) {
90  if (total_free_data_page_count) {
91  total_free_data_page_count.value() +=
92  storage_stats.total_free_data_page_count.value();
93  } else {
94  total_free_data_page_count = storage_stats.total_free_data_page_count;
95  }
96  }
97  min_epoch = std::min(min_epoch, storage_stats.epoch);
98  max_epoch = std::max(max_epoch, storage_stats.epoch);
99  min_epoch_floor = std::min(min_epoch_floor, storage_stats.epoch_floor);
100  max_epoch_floor = std::max(max_epoch_floor, storage_stats.epoch_floor);
101  }
102 };
103 
105  const Catalog_Namespace::Catalog* catalog) {
106  const auto global_file_mgr = catalog->getDataMgr().getGlobalFileMgr();
107  std::optional<AggregratedStorageStats> agg_storage_stats;
108  if (td->nShards > 0) {
109  const auto physical_tables = catalog->getPhysicalTablesDescriptors(td, false);
110  CHECK_EQ(static_cast<size_t>(td->nShards), physical_tables.size());
111 
112  for (const auto physical_table : physical_tables) {
113  auto storage_stats = global_file_mgr->getStorageStats(catalog->getDatabaseId(),
114  physical_table->tableId);
115  if (agg_storage_stats) {
116  agg_storage_stats.value().aggregate(storage_stats);
117  } else {
118  agg_storage_stats = storage_stats;
119  }
120  }
121  } else {
122  agg_storage_stats =
123  global_file_mgr->getStorageStats(catalog->getDatabaseId(), td->tableId);
124  }
125  CHECK(agg_storage_stats.has_value());
126  return agg_storage_stats.value();
127 }
128 
129 std::unique_ptr<RexLiteral> genLiteralStr(std::string val) {
130  return std::unique_ptr<RexLiteral>(
131  new RexLiteral(val, SQLTypes::kTEXT, SQLTypes::kTEXT, 0, 0, 0, 0));
132 }
133 
134 std::unique_ptr<RexLiteral> genLiteralTimestamp(time_t val) {
135  return std::unique_ptr<RexLiteral>(new RexLiteral(
136  (int64_t)val, SQLTypes::kTIMESTAMP, SQLTypes::kTIMESTAMP, 0, 8, 0, 8));
137 }
138 
139 std::unique_ptr<RexLiteral> genLiteralBigInt(int64_t val) {
140  return std::unique_ptr<RexLiteral>(
141  new RexLiteral(val, SQLTypes::kBIGINT, SQLTypes::kBIGINT, 0, 8, 0, 8));
142 }
143 
144 std::unique_ptr<RexLiteral> genLiteralBoolean(bool val) {
145  return std::unique_ptr<RexLiteral>(
146  // new RexLiteral(val, SQLTypes::kBOOLEAN, SQLTypes::kBOOLEAN, 0, 0, 0, 0));
147  new RexLiteral(
148  (int64_t)(val ? 1 : 0), SQLTypes::kBIGINT, SQLTypes::kBIGINT, 0, 8, 0, 8));
149 }
150 
152  std::vector<TargetMetaInfo>& label_infos,
153  const std::vector<std::tuple<std::string, SQLTypes, bool>>& headers) {
154  for (const auto& header : headers) {
155  auto [_val, _type, _notnull] = header;
156  if (_type == kBIGINT || _type == kTEXT || _type == kTIMESTAMP || _type == kBOOLEAN) {
157  label_infos.emplace_back(_val, SQLTypeInfo(_type, _notnull));
158  } else {
159  UNREACHABLE() << "Unsupported type provided for header. SQL type: "
160  << to_string(_type);
161  }
162  }
163 }
164 
165 void add_table_details(std::vector<RelLogicalValues::RowValues>& logical_values,
166  const TableDescriptor* logical_table,
167  const AggregratedStorageStats& agg_storage_stats) {
168  bool is_sharded_table = (logical_table->nShards > 0);
169  logical_values.emplace_back(RelLogicalValues::RowValues{});
170  logical_values.back().emplace_back(genLiteralBigInt(logical_table->tableId));
171  logical_values.back().emplace_back(genLiteralStr(logical_table->tableName));
172  logical_values.back().emplace_back(genLiteralBigInt(logical_table->nColumns));
173  logical_values.back().emplace_back(genLiteralBoolean(is_sharded_table));
174  logical_values.back().emplace_back(genLiteralBigInt(logical_table->nShards));
175  logical_values.back().emplace_back(genLiteralBigInt(logical_table->maxRows));
176  logical_values.back().emplace_back(genLiteralBigInt(logical_table->maxFragRows));
177  logical_values.back().emplace_back(genLiteralBigInt(logical_table->maxRollbackEpochs));
178  logical_values.back().emplace_back(genLiteralBigInt(agg_storage_stats.min_epoch));
179  logical_values.back().emplace_back(genLiteralBigInt(agg_storage_stats.max_epoch));
180  logical_values.back().emplace_back(genLiteralBigInt(agg_storage_stats.min_epoch_floor));
181  logical_values.back().emplace_back(genLiteralBigInt(agg_storage_stats.max_epoch_floor));
182  logical_values.back().emplace_back(
183  genLiteralBigInt(agg_storage_stats.metadata_file_count));
184  logical_values.back().emplace_back(
185  genLiteralBigInt(agg_storage_stats.total_metadata_file_size));
186  logical_values.back().emplace_back(
187  genLiteralBigInt(agg_storage_stats.total_metadata_page_count));
188 
189  if (agg_storage_stats.total_free_metadata_page_count) {
190  logical_values.back().emplace_back(
191  genLiteralBigInt(agg_storage_stats.total_free_metadata_page_count.value()));
192  } else {
193  logical_values.back().emplace_back(genLiteralBigInt(NULL_BIGINT));
194  }
195 
196  logical_values.back().emplace_back(genLiteralBigInt(agg_storage_stats.data_file_count));
197  logical_values.back().emplace_back(
198  genLiteralBigInt(agg_storage_stats.total_data_file_size));
199  logical_values.back().emplace_back(
200  genLiteralBigInt(agg_storage_stats.total_data_page_count));
201 
202  if (agg_storage_stats.total_free_data_page_count) {
203  logical_values.back().emplace_back(
204  genLiteralBigInt(agg_storage_stats.total_free_data_page_count.value()));
205  } else {
206  logical_values.back().emplace_back(genLiteralBigInt(NULL_BIGINT));
207  }
208 }
209 
210 // -----------------------------------------------------------------------
211 // class: JsonColumnSqlType
212 // Defined & Implemented here to avoid exposing rapidjson in the header file
213 // -----------------------------------------------------------------------
214 
217  public:
218  JsonColumnSqlType(const rapidjson::Value& data_type)
219  : ddl_utils::SqlType(getSqlType(data_type),
220  getParam1(data_type),
221  getParam2(data_type),
222  isArray(data_type),
223  getArraySize(data_type)) {}
224 
225  private:
226  static SQLTypes getSqlType(const rapidjson::Value& data_type);
227  static SQLTypes getSqlType(const std::string& type);
228  static int getParam1(const rapidjson::Value& data_type);
229  static int getParam2(const rapidjson::Value& data_type);
230  static bool isArray(const rapidjson::Value& data_type);
231  static int getArraySize(const rapidjson::Value& data_type);
232 };
233 
235  public:
236  JsonColumnEncoding(const rapidjson::Value& data_type)
237  : ddl_utils::Encoding(getEncodingName(data_type), getEncodingParam(data_type)) {}
238 
239  private:
240  static std::string* getEncodingName(const rapidjson::Value& data_type);
241  static int getEncodingParam(const rapidjson::Value& data_type);
242 };
243 
244 // -----------------------------------------------------------------------
245 // class DdlCommandDataImpl:
246 //
247 // Concrete class to cache parse data
248 // Defined & Implemented here to avoid exposing rapidjson in the header file
249 // Helper/access fns available to get useful pieces of cache data
250 // -----------------------------------------------------------------------
252  public:
253  DdlCommandDataImpl(const std::string& ddl_statement);
255 
256  // The full query available for futher analysis
257  const rapidjson::Value& query() const;
258 
259  // payload as extracted from the query
260  const rapidjson::Value& payload() const;
261 
262  // commandStr extracted from the payload
263  virtual std::string commandStr() override;
264 
265  rapidjson::Document ddl_query;
266 };
267 
268 DdlCommandDataImpl::DdlCommandDataImpl(const std::string& ddl_statement)
269  : DdlCommandData(ddl_statement) {
270  ddl_query.Parse(ddl_statement);
271 }
272 
274 
275 const rapidjson::Value& DdlCommandDataImpl::query() const {
276  return ddl_query;
277 }
278 
279 const rapidjson::Value& DdlCommandDataImpl::payload() const {
280  CHECK(ddl_query.HasMember("payload"));
281  CHECK(ddl_query["payload"].IsObject());
282  return ddl_query["payload"];
283 }
284 
286  if (ddl_query.IsObject() && ddl_query.HasMember("payload") &&
287  ddl_query["payload"].IsObject()) {
288  auto& payload = ddl_query["payload"];
289  if (payload.HasMember("command") && payload["command"].IsString()) {
290  return payload["command"].GetString();
291  }
292  }
293  return "";
294 }
295 
296 // Helper Fn to get the payload from the abstract base class
297 const rapidjson::Value& extractPayload(const DdlCommandData& ddl_data) {
298  const DdlCommandDataImpl* data = static_cast<const DdlCommandDataImpl*>(&ddl_data);
299  return data->payload();
300 }
301 
302 const rapidjson::Value* extractFilters(const rapidjson::Value& payload) {
303  const rapidjson::Value* filters = nullptr;
304  if (payload.HasMember("filters") && payload["filters"].IsArray()) {
305  filters = &payload["filters"];
306  }
307  return filters;
308 }
309 
310 } // namespace
311 
313  const std::string& ddl_statement,
314  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
315  : session_ptr_(session_ptr) {
316  CHECK(!ddl_statement.empty());
317  ddl_statement_ = ddl_statement;
318 
319  // parse the incoming query,
320  // cache the parsed rapidjson object inside a DdlCommandDataImpl
321  // store the "abstract/base class" reference in ddl_data_
322  DdlCommandDataImpl* ddl_query_data = new DdlCommandDataImpl(ddl_statement);
323  ddl_data_ = std::unique_ptr<DdlCommandData>(ddl_query_data);
324 
325  VLOG(2) << "Parsing JSON DDL from Calcite: " << ddl_statement;
326  auto& ddl_query = ddl_query_data->query();
327  CHECK(ddl_query.IsObject()) << ddl_statement;
328  CHECK(ddl_query.HasMember("payload"));
329  CHECK(ddl_query["payload"].IsObject());
330  const auto& payload = ddl_query["payload"].GetObject();
331  CHECK(payload.HasMember("command"));
332  CHECK(payload["command"].IsString());
333  ddl_command_ = payload["command"].GetString();
334 }
335 
338 
339  // the following commands use parser node locking to ensure safe concurrent access
340  if (ddl_command_ == "CREATE_TABLE") {
341  auto create_table_stmt = Parser::CreateTableStmt(extractPayload(*ddl_data_));
342  create_table_stmt.execute(*session_ptr_);
343  return result;
344  } else if (ddl_command_ == "CREATE_VIEW") {
345  auto create_view_stmt = Parser::CreateViewStmt(extractPayload(*ddl_data_));
346  create_view_stmt.execute(*session_ptr_);
347  return result;
348  } else if (ddl_command_ == "DROP_TABLE") {
349  auto drop_table_stmt = Parser::DropTableStmt(extractPayload(*ddl_data_));
350  drop_table_stmt.execute(*session_ptr_);
351  return result;
352  } else if (ddl_command_ == "DROP_VIEW") {
353  auto drop_view_stmt = Parser::DropViewStmt(extractPayload(*ddl_data_));
354  drop_view_stmt.execute(*session_ptr_);
355  return result;
356  } else if (ddl_command_ == "RENAME_TABLE") {
357  auto rename_table_stmt = Parser::RenameTableStmt(extractPayload(*ddl_data_));
358  rename_table_stmt.execute(*session_ptr_);
359  return result;
360  }
361 
362  // the following commands require a global unique lock until proper table locking has
363  // been implemented and/or verified
364  auto execute_write_lock = mapd_unique_lock<mapd_shared_mutex>(
367  // TODO(vancouver): add appropriate table locking
368 
369  if (ddl_command_ == "CREATE_SERVER") {
370  result = CreateForeignServerCommand{*ddl_data_, session_ptr_}.execute();
371  } else if (ddl_command_ == "DROP_SERVER") {
372  result = DropForeignServerCommand{*ddl_data_, session_ptr_}.execute();
373  } else if (ddl_command_ == "CREATE_FOREIGN_TABLE") {
374  result = CreateForeignTableCommand{*ddl_data_, session_ptr_}.execute();
375  } else if (ddl_command_ == "DROP_FOREIGN_TABLE") {
376  result = DropForeignTableCommand{*ddl_data_, session_ptr_}.execute();
377  } else if (ddl_command_ == "SHOW_TABLES") {
378  result = ShowTablesCommand{*ddl_data_, session_ptr_}.execute();
379  } else if (ddl_command_ == "SHOW_TABLE_DETAILS") {
380  result = ShowTableDetailsCommand{*ddl_data_, session_ptr_}.execute();
381  } else if (ddl_command_ == "SHOW_DATABASES") {
382  result = ShowDatabasesCommand{*ddl_data_, session_ptr_}.execute();
383  } else if (ddl_command_ == "SHOW_SERVERS") {
384  result = ShowForeignServersCommand{*ddl_data_, session_ptr_}.execute();
385  } else if (ddl_command_ == "ALTER_SERVER") {
386  result = AlterForeignServerCommand{*ddl_data_, session_ptr_}.execute();
387  } else if (ddl_command_ == "ALTER_FOREIGN_TABLE") {
388  result = AlterForeignTableCommand{*ddl_data_, session_ptr_}.execute();
389  } else if (ddl_command_ == "REFRESH_FOREIGN_TABLES") {
390  result = RefreshForeignTablesCommand{*ddl_data_, session_ptr_}.execute();
391  } else if (ddl_command_ == "SHOW_QUERIES") {
392  LOG(ERROR) << "SHOW QUERIES DDL is not ready yet!\n";
393  } else if (ddl_command_ == "SHOW_DISK_CACHE_USAGE") {
394  result = ShowDiskCacheUsageCommand{*ddl_data_, session_ptr_}.execute();
395  } else if (ddl_command_ == "KILL_QUERY") {
396  auto& ddl_payload = extractPayload(*ddl_data_);
397  CHECK(ddl_payload.HasMember("querySession"));
398  const std::string& querySessionPayload = ddl_payload["querySession"].GetString();
399  auto querySession = querySessionPayload.substr(1, 8);
400  CHECK_EQ(querySession.length(),
401  (unsigned long)8); // public_session_id's length + two quotes
402  LOG(ERROR) << "TRY TO KILL QUERY " << querySession
403  << " BUT KILL QUERY DDL is not ready yet!\n";
404  } else {
405  throw std::runtime_error("Unsupported DDL command");
406  }
407 
408  return result;
409 }
410 
412  return (ddl_command_ == "SHOW_USER_SESSIONS");
413 }
414 
416  return (ddl_command_ == "SHOW_QUERIES");
417 }
418 
420  return (ddl_command_ == "KILL_QUERY");
421 }
422 
424  DistributedExecutionDetails execution_details;
425  if (ddl_command_ == "CREATE_TABLE" || ddl_command_ == "DROP_TABLE" ||
426  ddl_command_ == "CREATE_VIEW" || ddl_command_ == "DROP_VIEW" ||
427  ddl_command_ == "RENAME_TABLE") {
429  execution_details.aggregation_type = AggregationType::NONE;
430  } else if (ddl_command_ == "SHOW_TABLE_DETAILS") {
432  execution_details.aggregation_type = AggregationType::UNION;
433  } else {
435  execution_details.aggregation_type = AggregationType::NONE;
436  }
437  return execution_details;
438 }
439 
441  // caller should check whether DDL indicates KillQuery request
442  // i.e., use isKillQuery() before calling this function
443  auto& ddl_payload = extractPayload(*ddl_data_);
444  CHECK(isKillQuery());
445  CHECK(ddl_payload.HasMember("querySession"));
446  const std::string& query_session = ddl_payload["querySession"].GetString();
447  // regex matcher for public_session: start_time{3}-session_id{4} (Example:819-4RDo)
448  boost::regex session_id_regex{R"([0-9]{3}-[a-zA-Z0-9]{4})",
449  boost::regex::extended | boost::regex::icase};
450  if (!boost::regex_match(query_session, session_id_regex)) {
451  throw std::runtime_error(
452  "Please provide the correct session ID of the query that you want to interrupt.");
453  }
454  return query_session;
455 }
456 
457 const std::string DdlCommandExecutor::commandStr() {
458  return ddl_command_;
459 }
460 
462  const DdlCommandData& ddl_data,
463  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
464  : DdlCommand(ddl_data, session_ptr) {
465  auto& ddl_payload = extractPayload(ddl_data_);
466  CHECK(ddl_payload.HasMember("serverName"));
467  CHECK(ddl_payload["serverName"].IsString());
468  CHECK(ddl_payload.HasMember("dataWrapper"));
469  CHECK(ddl_payload["dataWrapper"].IsString());
470  if (ddl_payload.HasMember("options")) {
471  CHECK(ddl_payload["options"].IsObject());
472  }
473  CHECK(ddl_payload.HasMember("ifNotExists"));
474  CHECK(ddl_payload["ifNotExists"].IsBool());
475 }
476 
479 
480  auto& ddl_payload = extractPayload(ddl_data_);
481  std::string server_name = ddl_payload["serverName"].GetString();
482  if (isDefaultServer(server_name)) {
483  throw std::runtime_error{"Server names cannot start with \"omnisci\"."};
484  }
485  bool if_not_exists = ddl_payload["ifNotExists"].GetBool();
486  if (session_ptr_->getCatalog().getForeignServer(server_name)) {
487  if (if_not_exists) {
488  return result;
489  } else {
490  throw std::runtime_error{"A foreign server with name \"" + server_name +
491  "\" already exists."};
492  }
493  }
494  // check access privileges
495  if (!session_ptr_->checkDBAccessPrivileges(DBObjectType::ServerDBObjectType,
497  throw std::runtime_error("Server " + std::string(server_name) +
498  " will not be created. User has no create privileges.");
499  }
500 
501  auto& current_user = session_ptr_->get_currentUser();
502  auto foreign_server = std::make_unique<foreign_storage::ForeignServer>();
503  foreign_server->data_wrapper_type = to_upper(ddl_payload["dataWrapper"].GetString());
504  foreign_server->name = server_name;
505  foreign_server->user_id = current_user.userId;
506  if (ddl_payload.HasMember("options")) {
507  foreign_server->populateOptionsMap(ddl_payload["options"]);
508  }
509  foreign_server->validate();
510 
511  auto& catalog = session_ptr_->getCatalog();
512  catalog.createForeignServer(std::move(foreign_server),
513  ddl_payload["ifNotExists"].GetBool());
515  current_user, server_name, ServerDBObjectType, catalog);
516 
517  return result;
518 }
519 
521  const DdlCommandData& ddl_data,
522  std::shared_ptr<const Catalog_Namespace::SessionInfo> session_ptr)
523  : DdlCommand(ddl_data, session_ptr) {
524  auto& ddl_payload = extractPayload(ddl_data_);
525  CHECK(ddl_payload.HasMember("serverName"));
526  CHECK(ddl_payload["serverName"].IsString());
527  CHECK(ddl_payload.HasMember("alterType"));
528  CHECK(ddl_payload["alterType"].IsString());
529  if (ddl_payload["alterType"] == "SET_OPTIONS") {
530  CHECK(ddl_payload.HasMember("options"));
531  CHECK(ddl_payload["options"].IsObject());
532  } else if (ddl_payload["alterType"] == "SET_DATA_WRAPPER") {
533  CHECK(ddl_payload.HasMember("dataWrapper"));
534  CHECK(ddl_payload["dataWrapper"].IsString());
535  } else if (ddl_payload["alterType"] == "RENAME_SERVER") {
536  CHECK(ddl_payload.HasMember("newServerName"));
537  CHECK(ddl_payload["newServerName"].IsString());
538  } else if (ddl_payload["alterType"] == "CHANGE_OWNER") {
539  CHECK(ddl_payload.HasMember("newOwner"));
540  CHECK(ddl_payload["newOwner"].IsString());
541  } else {
542  UNREACHABLE(); // not-implemented alterType
543  }
544 }
545 
547  auto& ddl_payload = extractPayload(ddl_data_);
548  std::string server_name = ddl_payload["serverName"].GetString();
549  if (isDefaultServer(server_name)) {
550  throw std::runtime_error{"OmniSci default servers cannot be altered."};
551  }
552  if (!session_ptr_->getCatalog().getForeignServer(server_name)) {
553  throw std::runtime_error{"Foreign server with name \"" + server_name +
554  "\" does not exist and can not be altered."};
555  }
556  if (!hasAlterServerPrivileges()) {
557  throw std::runtime_error("Server " + server_name +
558  " can not be altered. User has no ALTER SERVER privileges.");
559  }
560  std::string alter_type = ddl_payload["alterType"].GetString();
561  if (alter_type == "CHANGE_OWNER") {
563  } else if (alter_type == "SET_DATA_WRAPPER") {
565  } else if (alter_type == "SET_OPTIONS") {
567  } else if (alter_type == "RENAME_SERVER") {
569  }
570 
571  return ExecutionResult();
572 }
573 
575  auto& ddl_payload = extractPayload(ddl_data_);
576  std::string server_name = ddl_payload["serverName"].GetString();
577  std::string new_owner = ddl_payload["newOwner"].GetString();
578  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
579  if (!session_ptr_->get_currentUser().isSuper) {
580  throw std::runtime_error(
581  "Only a super user can change a foreign server's owner. "
582  "Current user is not a super-user. "
583  "Foreign server with name \"" +
584  server_name + "\" will not have owner changed.");
585  }
586  Catalog_Namespace::UserMetadata user, original_owner;
587  if (!sys_cat.getMetadataForUser(new_owner, user)) {
588  throw std::runtime_error("User with username \"" + new_owner + "\" does not exist. " +
589  "Foreign server with name \"" + server_name +
590  "\" can not have owner changed.");
591  }
592  auto& cat = session_ptr_->getCatalog();
593  // get original owner metadata
594  bool original_owner_exists = sys_cat.getMetadataForUserById(
595  cat.getForeignServer(server_name)->user_id, original_owner);
596  // update catalog
597  cat.changeForeignServerOwner(server_name, user.userId);
598  try {
599  // update permissions
600  DBObject db_object(server_name, DBObjectType::ServerDBObjectType);
601  sys_cat.changeDBObjectOwnership(
602  user, original_owner, db_object, cat, original_owner_exists);
603  } catch (const std::runtime_error& e) {
604  // update permissions failed, revert catalog update
605  cat.changeForeignServerOwner(server_name, original_owner.userId);
606  throw;
607  }
608 }
609 
611  auto& ddl_payload = extractPayload(ddl_data_);
612  std::string server_name = ddl_payload["serverName"].GetString();
613  std::string new_server_name = ddl_payload["newServerName"].GetString();
614  if (isDefaultServer(new_server_name)) {
615  throw std::runtime_error{"OmniSci prefix can not be used for new name of server."};
616  }
617  auto& cat = session_ptr_->getCatalog();
618  // check for a conflicting server
619  if (cat.getForeignServer(new_server_name)) {
620  throw std::runtime_error("Foreign server with name \"" + server_name +
621  "\" can not be renamed to \"" + new_server_name + "\"." +
622  "Foreign server with name \"" + new_server_name +
623  "\" exists.");
624  }
625  // update catalog
626  cat.renameForeignServer(server_name, new_server_name);
627  try {
628  // migrate object privileges
629  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
630  sys_cat.renameDBObject(server_name,
631  new_server_name,
633  cat.getForeignServer(new_server_name)->id,
634  cat);
635  } catch (const std::runtime_error& e) {
636  // permission migration failed, revert catalog update
637  cat.renameForeignServer(new_server_name, server_name);
638  throw;
639  }
640 }
641 
643  auto& ddl_payload = extractPayload(ddl_data_);
644  std::string server_name = ddl_payload["serverName"].GetString();
645  auto& cat = session_ptr_->getCatalog();
646  // update catalog
647  const auto foreign_server = cat.getForeignServer(server_name);
649  opt.populateOptionsMap(foreign_server->getOptionsAsJsonString());
650  opt.populateOptionsMap(ddl_payload["options"]);
651  cat.setForeignServerOptions(server_name, opt.getOptionsAsJsonString());
652 }
653 
655  auto& ddl_payload = extractPayload(ddl_data_);
656  std::string server_name = ddl_payload["serverName"].GetString();
657  std::string data_wrapper = ddl_payload["dataWrapper"].GetString();
658  auto& cat = session_ptr_->getCatalog();
659  // update catalog
660  cat.setForeignServerDataWrapper(server_name, data_wrapper);
661 }
662 
664  // TODO: implement `GRANT/REVOKE ALTER_SERVER` DDL commands
665  auto& ddl_payload = extractPayload(ddl_data_);
666  std::string server_name = ddl_payload["serverName"].GetString();
667  return session_ptr_->checkDBAccessPrivileges(
669 }
670 
672  const DdlCommandData& ddl_data,
673  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
674  : DdlCommand(ddl_data, session_ptr) {
675  auto& ddl_payload = extractPayload(ddl_data_);
676  CHECK(ddl_payload.HasMember("serverName"));
677  CHECK(ddl_payload["serverName"].IsString());
678  CHECK(ddl_payload.HasMember("ifExists"));
679  CHECK(ddl_payload["ifExists"].IsBool());
680 }
681 
683  auto& ddl_payload = extractPayload(ddl_data_);
684  std::string server_name = ddl_payload["serverName"].GetString();
685  if (isDefaultServer(server_name)) {
686  throw std::runtime_error{"OmniSci default servers cannot be dropped."};
687  }
688  bool if_exists = ddl_payload["ifExists"].GetBool();
689  if (!session_ptr_->getCatalog().getForeignServer(server_name)) {
690  if (if_exists) {
691  return ExecutionResult();
692  } else {
693  throw std::runtime_error{"Foreign server with name \"" + server_name +
694  "\" can not be dropped. Server does not exist."};
695  }
696  }
697  // check access privileges
698  if (!session_ptr_->checkDBAccessPrivileges(
700  throw std::runtime_error("Server " + server_name +
701  " will not be dropped. User has no DROP SERVER privileges.");
702  }
704  DBObject(server_name, ServerDBObjectType), session_ptr_->get_catalog_ptr().get());
705  session_ptr_->getCatalog().dropForeignServer(ddl_payload["serverName"].GetString());
706 
707  return ExecutionResult();
708 }
709 
710 SQLTypes JsonColumnSqlType::getSqlType(const rapidjson::Value& data_type) {
711  CHECK(data_type.IsObject());
712  CHECK(data_type.HasMember("type"));
713  CHECK(data_type["type"].IsString());
714 
715  std::string type = data_type["type"].GetString();
716  if (boost::iequals(type, "ARRAY")) {
717  CHECK(data_type.HasMember("array"));
718  CHECK(data_type["array"].IsObject());
719 
720  const auto& array = data_type["array"].GetObject();
721  CHECK(array.HasMember("elementType"));
722  CHECK(array["elementType"].IsString());
723  type = array["elementType"].GetString();
724  }
725  return getSqlType(type);
726 }
727 
728 SQLTypes JsonColumnSqlType::getSqlType(const std::string& type) {
729  if (boost::iequals(type, "BIGINT")) {
730  return kBIGINT;
731  }
732  if (boost::iequals(type, "BOOLEAN")) {
733  return kBOOLEAN;
734  }
735  if (boost::iequals(type, "DATE")) {
736  return kDATE;
737  }
738  if (boost::iequals(type, "DECIMAL")) {
739  return kDECIMAL;
740  }
741  if (boost::iequals(type, "DOUBLE")) {
742  return kDOUBLE;
743  }
744  if (boost::iequals(type, "FLOAT")) {
745  return kFLOAT;
746  }
747  if (boost::iequals(type, "INTEGER")) {
748  return kINT;
749  }
750  if (boost::iequals(type, "LINESTRING")) {
751  return kLINESTRING;
752  }
753  if (boost::iequals(type, "MULTIPOLYGON")) {
754  return kMULTIPOLYGON;
755  }
756  if (boost::iequals(type, "POINT")) {
757  return kPOINT;
758  }
759  if (boost::iequals(type, "POLYGON")) {
760  return kPOLYGON;
761  }
762  if (boost::iequals(type, "SMALLINT")) {
763  return kSMALLINT;
764  }
765  if (boost::iequals(type, "TEXT")) {
766  return kTEXT;
767  }
768  if (boost::iequals(type, "TIME")) {
769  return kTIME;
770  }
771  if (boost::iequals(type, "TIMESTAMP")) {
772  return kTIMESTAMP;
773  }
774  if (boost::iequals(type, "TINYINT")) {
775  return kTINYINT;
776  }
777 
778  throw std::runtime_error{"Unsupported type \"" + type + "\" specified."};
779 }
780 
781 int JsonColumnSqlType::getParam1(const rapidjson::Value& data_type) {
782  int param1 = -1;
783  CHECK(data_type.IsObject());
784  if (data_type.HasMember("precision") && !data_type["precision"].IsNull()) {
785  CHECK(data_type["precision"].IsInt());
786  param1 = data_type["precision"].GetInt();
787  } else if (auto type = getSqlType(data_type); IS_GEO(type)) {
788  param1 = static_cast<int>(kGEOMETRY);
789  }
790  return param1;
791 }
792 
793 int JsonColumnSqlType::getParam2(const rapidjson::Value& data_type) {
794  int param2 = 0;
795  CHECK(data_type.IsObject());
796  if (data_type.HasMember("scale") && !data_type["scale"].IsNull()) {
797  CHECK(data_type["scale"].IsInt());
798  param2 = data_type["scale"].GetInt();
799  } else if (auto type = getSqlType(data_type); IS_GEO(type) &&
800  data_type.HasMember("coordinateSystem") &&
801  !data_type["coordinateSystem"].IsNull()) {
802  CHECK(data_type["coordinateSystem"].IsInt());
803  param2 = data_type["coordinateSystem"].GetInt();
804  }
805  return param2;
806 }
807 
808 bool JsonColumnSqlType::isArray(const rapidjson::Value& data_type) {
809  CHECK(data_type.IsObject());
810  CHECK(data_type.HasMember("type"));
811  CHECK(data_type["type"].IsString());
812  return boost::iequals(data_type["type"].GetString(), "ARRAY");
813 }
814 
815 int JsonColumnSqlType::getArraySize(const rapidjson::Value& data_type) {
816  int size = -1;
817  if (isArray(data_type)) {
818  CHECK(data_type.HasMember("array"));
819  CHECK(data_type["array"].IsObject());
820 
821  const auto& array = data_type["array"].GetObject();
822  if (array.HasMember("size") && !array["size"].IsNull()) {
823  CHECK(array["size"].IsInt());
824  size = array["size"].GetInt();
825  }
826  }
827  return size;
828 }
829 
830 std::string* JsonColumnEncoding::getEncodingName(const rapidjson::Value& data_type) {
831  CHECK(data_type.IsObject());
832  CHECK(data_type.HasMember("encoding"));
833  CHECK(data_type["encoding"].IsObject());
834 
835  const auto& encoding = data_type["encoding"].GetObject();
836  CHECK(encoding.HasMember("type"));
837  CHECK(encoding["type"].IsString());
838  return new std::string(encoding["type"].GetString());
839 }
840 
841 int JsonColumnEncoding::getEncodingParam(const rapidjson::Value& data_type) {
842  CHECK(data_type.IsObject());
843  CHECK(data_type.HasMember("encoding"));
844  CHECK(data_type["encoding"].IsObject());
845 
846  int encoding_size = 0;
847  const auto& encoding = data_type["encoding"].GetObject();
848  if (encoding.HasMember("size") && !encoding["size"].IsNull()) {
849  CHECK(encoding["size"].IsInt());
850  encoding_size = encoding["size"].GetInt();
851  }
852  return encoding_size;
853 }
854 
856  const DdlCommandData& ddl_data,
857  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
858  : DdlCommand(ddl_data, session_ptr) {
859  auto& ddl_payload = extractPayload(ddl_data);
860  CHECK(ddl_payload.HasMember("serverName"));
861  CHECK(ddl_payload["serverName"].IsString());
862  CHECK(ddl_payload.HasMember("tableName"));
863  CHECK(ddl_payload["tableName"].IsString());
864  CHECK(ddl_payload.HasMember("ifNotExists"));
865  CHECK(ddl_payload["ifNotExists"].IsBool());
866  CHECK(ddl_payload.HasMember("columns"));
867  CHECK(ddl_payload["columns"].IsArray());
868 }
869 
871  auto& catalog = session_ptr_->getCatalog();
872  auto& ddl_payload = extractPayload(ddl_data_);
873 
874  const std::string& table_name = ddl_payload["tableName"].GetString();
875  if (!session_ptr_->checkDBAccessPrivileges(DBObjectType::TableDBObjectType,
877  throw std::runtime_error(
878  "Foreign table \"" + table_name +
879  "\" will not be created. User has no CREATE TABLE privileges.");
880  }
881 
882  bool if_not_exists = ddl_payload["ifNotExists"].GetBool();
883  if (!catalog.validateNonExistentTableOrView(table_name, if_not_exists)) {
884  return ExecutionResult();
885  }
886 
887  foreign_storage::ForeignTable foreign_table{};
888  std::list<ColumnDescriptor> columns{};
889  setColumnDetails(columns);
890  setTableDetails(table_name, foreign_table, columns);
891  catalog.createTable(foreign_table, columns, {}, true);
892 
893  // TODO (max): It's transactionally unsafe, should be fixed: we may create object w/o
894  // privileges
896  session_ptr_->get_currentUser(),
897  foreign_table.tableName,
899  catalog);
900 
901  return ExecutionResult();
902 }
903 
905  const std::string& table_name,
906  TableDescriptor& td,
907  const std::list<ColumnDescriptor>& columns) {
908  ddl_utils::set_default_table_attributes(table_name, td, columns.size());
909  td.userId = session_ptr_->get_currentUser().userId;
911  td.hasDeletedCol = false;
912  td.keyMetainfo = "[]";
913  td.fragments = "";
914  td.partitions = "";
915 
916  auto& ddl_payload = extractPayload(ddl_data_);
917  auto& foreign_table = dynamic_cast<foreign_storage::ForeignTable&>(td);
918  const std::string server_name = ddl_payload["serverName"].GetString();
919  foreign_table.foreign_server = session_ptr_->getCatalog().getForeignServer(server_name);
920  if (!foreign_table.foreign_server) {
921  throw std::runtime_error{
922  "Foreign Table with name \"" + table_name +
923  "\" can not be created. Associated foreign server with name \"" + server_name +
924  "\" does not exist."};
925  }
926 
927  // check server usage privileges
928  if (!isDefaultServer(server_name) &&
929  !session_ptr_->checkDBAccessPrivileges(DBObjectType::ServerDBObjectType,
931  server_name)) {
932  throw std::runtime_error(
933  "Current user does not have USAGE privilege on foreign server: " + server_name);
934  }
935 
936  if (ddl_payload.HasMember("options") && !ddl_payload["options"].IsNull()) {
937  CHECK(ddl_payload["options"].IsObject());
938  foreign_table.initializeOptions(ddl_payload["options"]);
939  } else {
940  // Initialize options even if none were provided to verify a legal state.
941  // This is necessary because some options (like "file_path") are optional only if a
942  // paired option ("base_path") exists in the server.
943  foreign_table.initializeOptions();
944  }
945  foreign_table.validateSchema(columns);
946 
947  if (const auto it = foreign_table.options.find("FRAGMENT_SIZE");
948  it != foreign_table.options.end()) {
949  foreign_table.maxFragRows = std::stoi(it->second);
950  }
951 }
952 
953 void CreateForeignTableCommand::setColumnDetails(std::list<ColumnDescriptor>& columns) {
954  auto& ddl_payload = extractPayload(ddl_data_);
955  std::unordered_set<std::string> column_names{};
956  for (auto& column_def : ddl_payload["columns"].GetArray()) {
957  CHECK(column_def.IsObject());
958  CHECK(column_def.HasMember("name"));
959  CHECK(column_def["name"].IsString());
960  const std::string& column_name = column_def["name"].GetString();
961 
962  CHECK(column_def.HasMember("dataType"));
963  CHECK(column_def["dataType"].IsObject());
964 
965  JsonColumnSqlType sql_type{column_def["dataType"]};
966  const auto& data_type = column_def["dataType"].GetObject();
967  CHECK(data_type.HasMember("notNull"));
968  CHECK(data_type["notNull"].IsBool());
969 
970  std::unique_ptr<JsonColumnEncoding> encoding;
971  if (data_type.HasMember("encoding") && !data_type["encoding"].IsNull()) {
972  CHECK(data_type["encoding"].IsObject());
973  encoding = std::make_unique<JsonColumnEncoding>(column_def["dataType"]);
974  }
975 
976  ColumnDescriptor cd;
977  ddl_utils::validate_non_duplicate_column(column_name, column_names);
980  column_name, cd, &sql_type, data_type["notNull"].GetBool(), encoding.get());
981  columns.emplace_back(cd);
982  }
983 }
984 
986  const DdlCommandData& ddl_data,
987  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
988  : DdlCommand(ddl_data, session_ptr) {
989  auto& ddl_payload = extractPayload(ddl_data_);
990  CHECK(ddl_payload.HasMember("tableName"));
991  CHECK(ddl_payload["tableName"].IsString());
992  CHECK(ddl_payload.HasMember("ifExists"));
993  CHECK(ddl_payload["ifExists"].IsBool());
994 }
995 
997  auto& catalog = session_ptr_->getCatalog();
998  auto& ddl_payload = extractPayload(ddl_data_);
999 
1000  const std::string& table_name = ddl_payload["tableName"].GetString();
1001  const TableDescriptor* td{nullptr};
1002  std::unique_ptr<lockmgr::TableSchemaLockContainer<lockmgr::WriteLock>> td_with_lock;
1003 
1004  try {
1005  td_with_lock =
1006  std::make_unique<lockmgr::TableSchemaLockContainer<lockmgr::WriteLock>>(
1008  catalog, table_name, false));
1009  CHECK(td_with_lock);
1010  td = (*td_with_lock)();
1011  } catch (const std::runtime_error& e) {
1012  // TODO(Misiu): This should not just swallow any exception, it should only catch
1013  // exceptions that stem from the table not existing.
1014  if (ddl_payload["ifExists"].GetBool()) {
1015  return ExecutionResult();
1016  } else {
1017  throw e;
1018  }
1019  }
1020 
1021  CHECK(td);
1022 
1023  if (!session_ptr_->checkDBAccessPrivileges(
1025  throw std::runtime_error(
1026  "Foreign table \"" + table_name +
1027  "\" will not be dropped. User has no DROP TABLE privileges.");
1028  }
1029 
1031  auto table_data_write_lock =
1033  catalog.dropTable(td);
1034 
1035  return ExecutionResult();
1036 }
1037 
1039  const DdlCommandData& ddl_data,
1040  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1041  : DdlCommand(ddl_data, session_ptr) {}
1042 
1044  // Get all table names in the same way as OmniSql \t command
1045 
1046  // label_infos -> column labels
1047  std::vector<std::string> labels{"table_name"};
1048  std::vector<TargetMetaInfo> label_infos;
1049  for (const auto& label : labels) {
1050  label_infos.emplace_back(label, SQLTypeInfo(kTEXT, true));
1051  }
1052 
1053  // Get all table names
1054  auto cat_ptr = session_ptr_->get_catalog_ptr();
1055  auto cur_user = session_ptr_->get_currentUser();
1056  auto table_names = cat_ptr->getTableNamesForUser(cur_user, GET_PHYSICAL_TABLES);
1057 
1058  // logical_values -> table data
1059  std::vector<RelLogicalValues::RowValues> logical_values;
1060  for (auto table_name : table_names) {
1061  logical_values.emplace_back(RelLogicalValues::RowValues{});
1062  logical_values.back().emplace_back(genLiteralStr(table_name));
1063  }
1064 
1065  // Create ResultSet
1066  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1067  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1068 
1069  return ExecutionResult(rSet, label_infos);
1070 }
1071 
1073  const DdlCommandData& ddl_data,
1074  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1075  : DdlCommand(ddl_data, session_ptr) {
1076  auto& ddl_payload = extractPayload(ddl_data_);
1077  if (ddl_payload.HasMember("tableNames")) {
1078  CHECK(ddl_payload["tableNames"].IsArray());
1079  for (const auto& table_name : ddl_payload["tableNames"].GetArray()) {
1080  CHECK(table_name.IsString());
1081  }
1082  }
1083 }
1084 
1086  const auto catalog = session_ptr_->get_catalog_ptr();
1087  std::vector<std::string> filtered_table_names = getFilteredTableNames();
1088 
1089  std::vector<TargetMetaInfo> label_infos;
1090  set_headers_with_type(label_infos,
1091  {// { label, type, notNull }
1092  {"table_id", kBIGINT, true},
1093  {"table_name", kTEXT, true},
1094  {"column_count", kBIGINT, true},
1095  {"is_sharded_table", kBOOLEAN, true},
1096  {"shard_count", kBIGINT, true},
1097  {"max_rows", kBIGINT, true},
1098  {"fragment_size", kBIGINT, true},
1099  {"max_rollback_epochs", kBIGINT, true},
1100  {"min_epoch", kBIGINT, true},
1101  {"max_epoch", kBIGINT, true},
1102  {"min_epoch_floor", kBIGINT, true},
1103  {"max_epoch_floor", kBIGINT, true},
1104  {"metadata_file_count", kBIGINT, true},
1105  {"total_metadata_file_size", kBIGINT, true},
1106  {"total_metadata_page_count", kBIGINT, true},
1107  {"total_free_metadata_page_count", kBIGINT, false},
1108  {"data_file_count", kBIGINT, true},
1109  {"total_data_file_size", kBIGINT, true},
1110  {"total_data_page_count", kBIGINT, true},
1111  {"total_free_data_page_count", kBIGINT, false}});
1112 
1113  std::vector<RelLogicalValues::RowValues> logical_values;
1114  for (const auto& table_name : filtered_table_names) {
1115  auto [td, td_with_lock] =
1116  get_table_descriptor_with_lock<lockmgr::ReadLock>(*catalog, table_name, false);
1117  auto agg_storage_stats = get_agg_storage_stats(td, catalog.get());
1118  add_table_details(logical_values, td, agg_storage_stats);
1119  }
1120 
1121  // Create ResultSet
1122  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1123  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1124 
1125  return ExecutionResult(rSet, label_infos);
1126 }
1127 
1129  const auto catalog = session_ptr_->get_catalog_ptr();
1130  auto& ddl_payload = extractPayload(ddl_data_);
1131  auto all_table_names =
1132  catalog->getTableNamesForUser(session_ptr_->get_currentUser(), GET_PHYSICAL_TABLES);
1133  std::transform(all_table_names.begin(),
1134  all_table_names.end(),
1135  all_table_names.begin(),
1136  [](const std::string& s) { return to_upper(s); });
1137  std::vector<std::string> filtered_table_names;
1138  if (ddl_payload.HasMember("tableNames")) {
1139  std::set<std::string> all_table_names_set(all_table_names.begin(),
1140  all_table_names.end());
1141  for (const auto& table_name_json : ddl_payload["tableNames"].GetArray()) {
1142  std::string table_name = table_name_json.GetString();
1143  if (all_table_names_set.find(to_upper(table_name)) == all_table_names_set.end()) {
1144  throw std::runtime_error{"Unable to show table details for table: " + table_name +
1145  ". Table does not exist."};
1146  }
1147  auto [td, td_with_lock] =
1148  get_table_descriptor_with_lock<lockmgr::ReadLock>(*catalog, table_name, false);
1149  if (td->isForeignTable()) {
1150  throw std::runtime_error{
1151  "SHOW TABLE DETAILS is not supported for foreign tables. Table name: " +
1152  table_name + "."};
1153  }
1154  if (td->isTemporaryTable()) {
1155  throw std::runtime_error{
1156  "SHOW TABLE DETAILS is not supported for temporary tables. Table name: " +
1157  table_name + "."};
1158  }
1159  filtered_table_names.emplace_back(table_name);
1160  }
1161  } else {
1162  for (const auto& table_name : all_table_names) {
1163  auto [td, td_with_lock] =
1164  get_table_descriptor_with_lock<lockmgr::ReadLock>(*catalog, table_name, false);
1165  if (td->isForeignTable() || td->isTemporaryTable()) {
1166  continue;
1167  }
1168  filtered_table_names.emplace_back(table_name);
1169  }
1170  }
1171  return filtered_table_names;
1172 }
1173 
1175  const DdlCommandData& ddl_data,
1176  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1177  : DdlCommand(ddl_data, session_ptr) {}
1178 
1180  // label_infos -> column labels
1181  std::vector<std::string> labels{"Database", "Owner"};
1182  std::vector<TargetMetaInfo> label_infos;
1183  for (const auto& label : labels) {
1184  label_infos.emplace_back(label, SQLTypeInfo(kTEXT, true));
1185  }
1186 
1187  // Get all table names
1188  auto cur_user = session_ptr_->get_currentUser();
1189  const Catalog_Namespace::DBSummaryList db_summaries =
1191 
1192  // logical_values -> table data
1193  std::vector<RelLogicalValues::RowValues> logical_values;
1194  for (const auto& db_summary : db_summaries) {
1195  logical_values.emplace_back(RelLogicalValues::RowValues{});
1196  logical_values.back().emplace_back(genLiteralStr(db_summary.dbName));
1197  logical_values.back().emplace_back(genLiteralStr(db_summary.dbOwnerName));
1198  }
1199 
1200  // Create ResultSet
1201  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1202  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1203 
1204  return ExecutionResult(rSet, label_infos);
1205 }
1206 
1208  const DdlCommandData& ddl_data,
1209  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1210  : DdlCommand(ddl_data, session_ptr) {
1211  if (!g_enable_fsi) {
1212  throw std::runtime_error("Unsupported command: SHOW FOREIGN SERVERS");
1213  }
1214  // Verify that members are valid
1215  auto& ddl_payload = extractPayload(ddl_data_);
1216  CHECK(ddl_payload.HasMember("command"));
1217  if (ddl_payload.HasMember("filters")) {
1218  CHECK(ddl_payload["filters"].IsArray());
1219  int num_filters = 0;
1220  for (auto const& filter_def : ddl_payload["filters"].GetArray()) {
1221  CHECK(filter_def.IsObject());
1222  CHECK(filter_def.HasMember("attribute"));
1223  CHECK(filter_def["attribute"].IsString());
1224  CHECK(filter_def.HasMember("value"));
1225  CHECK(filter_def["value"].IsString());
1226  CHECK(filter_def.HasMember("operation"));
1227  CHECK(filter_def["operation"].IsString());
1228  if (num_filters > 0) {
1229  CHECK(filter_def.HasMember("chain"));
1230  CHECK(filter_def["chain"].IsString());
1231  } else {
1232  CHECK(!filter_def.HasMember("chain"));
1233  }
1234  num_filters++;
1235  }
1236  }
1237 }
1238 
1240  std::vector<TargetMetaInfo> label_infos;
1241  auto& ddl_payload = extractPayload(ddl_data_);
1242 
1243  // label_infos -> column labels
1244  std::vector<std::string> labels{"server_name", "data_wrapper", "created_at", "options"};
1245  label_infos.emplace_back(labels[0], SQLTypeInfo(kTEXT, true));
1246  label_infos.emplace_back(labels[1], SQLTypeInfo(kTEXT, true));
1247  // created_at is a TIMESTAMP
1248  label_infos.emplace_back(labels[2], SQLTypeInfo(kTIMESTAMP, true));
1249  label_infos.emplace_back(labels[3], SQLTypeInfo(kTEXT, true));
1250 
1251  const auto& user = session_ptr_->get_currentUser();
1252 
1253  std::vector<const foreign_storage::ForeignServer*> results;
1254 
1255  session_ptr_->getCatalog().getForeignServersForUser(
1256  extractFilters(ddl_payload), user, results);
1257 
1258  // logical_values -> table data
1259  std::vector<RelLogicalValues::RowValues> logical_values;
1260  for (auto const& server_ptr : results) {
1261  logical_values.emplace_back(RelLogicalValues::RowValues{});
1262  logical_values.back().emplace_back(genLiteralStr(server_ptr->name));
1263  logical_values.back().emplace_back(genLiteralStr(server_ptr->data_wrapper_type));
1264  logical_values.back().emplace_back(genLiteralTimestamp(server_ptr->creation_time));
1265  logical_values.back().emplace_back(
1266  genLiteralStr(server_ptr->getOptionsAsJsonString()));
1267  }
1268 
1269  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1270  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1271 
1272  return ExecutionResult(rSet, label_infos);
1273 }
1274 
1276  const DdlCommandData& ddl_data,
1277  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1278  : DdlCommand(ddl_data, session_ptr) {
1279  auto& ddl_payload = extractPayload(ddl_data_);
1280  CHECK(ddl_payload.HasMember("tableNames"));
1281  CHECK(ddl_payload["tableNames"].IsArray());
1282  for (auto const& tablename_def : ddl_payload["tableNames"].GetArray()) {
1283  CHECK(tablename_def.IsString());
1284  }
1285 }
1286 
1288  bool evict_cached_entries{false};
1290  auto& ddl_payload = extractPayload(ddl_data_);
1291  if (ddl_payload.HasMember("options") && !ddl_payload["options"].IsNull()) {
1292  opt.populateOptionsMap(ddl_payload["options"]);
1293  for (const auto& entry : opt.options) {
1294  if (entry.first != "EVICT") {
1295  throw std::runtime_error{
1296  "Invalid option \"" + entry.first +
1297  "\" provided for refresh command. Only \"EVICT\" option is supported."};
1298  }
1299  }
1300  CHECK(opt.options.find("EVICT") != opt.options.end());
1301 
1302  if (boost::iequals(opt.options["EVICT"], "true") ||
1303  boost::iequals(opt.options["EVICT"], "false")) {
1304  if (boost::iequals(opt.options["EVICT"], "true")) {
1305  evict_cached_entries = true;
1306  }
1307  } else {
1308  throw std::runtime_error{
1309  "Invalid value \"" + opt.options["EVICT"] +
1310  "\" provided for EVICT option. Value must be either \"true\" or \"false\"."};
1311  }
1312  }
1313 
1314  auto& cat = session_ptr_->getCatalog();
1315  const auto& current_user = session_ptr_->get_currentUser();
1316  /* verify object ownership if not suser */
1317  if (!current_user.isSuper) {
1318  for (const auto& table_name_json : ddl_payload["tableNames"].GetArray()) {
1319  std::string table_name = table_name_json.GetString();
1320  if (!Catalog_Namespace::SysCatalog::instance().verifyDBObjectOwnership(
1321  current_user, DBObject(table_name, TableDBObjectType), cat)) {
1322  throw std::runtime_error(
1323  std::string("REFRESH FOREIGN TABLES failed on table \"") + table_name +
1324  "\". It can only be executed by super user or "
1325  "owner of the "
1326  "object.");
1327  }
1328  }
1329  }
1330 
1331  for (const auto& table_name_json : ddl_payload["tableNames"].GetArray()) {
1332  std::string table_name = table_name_json.GetString();
1333  foreign_storage::refresh_foreign_table(cat, table_name, evict_cached_entries);
1334  }
1335 
1337 
1338  return ExecutionResult();
1339 }
1340 
1342  const DdlCommandData& ddl_data,
1343  std::shared_ptr<const Catalog_Namespace::SessionInfo> session_ptr)
1344  : DdlCommand(ddl_data, session_ptr) {
1345  auto& ddl_payload = extractPayload(ddl_data_);
1346  CHECK(ddl_payload.HasMember("tableName"));
1347  CHECK(ddl_payload["tableName"].IsString());
1348  CHECK(ddl_payload.HasMember("alterType"));
1349  CHECK(ddl_payload["alterType"].IsString());
1350  if (ddl_payload["alterType"] == "RENAME_TABLE") {
1351  CHECK(ddl_payload.HasMember("newTableName"));
1352  CHECK(ddl_payload["newTableName"].IsString());
1353  } else if (ddl_payload["alterType"] == "RENAME_COLUMN") {
1354  CHECK(ddl_payload.HasMember("oldColumnName"));
1355  CHECK(ddl_payload["oldColumnName"].IsString());
1356  CHECK(ddl_payload.HasMember("newColumnName"));
1357  CHECK(ddl_payload["newColumnName"].IsString());
1358  } else if (ddl_payload["alterType"] == "ALTER_OPTIONS") {
1359  CHECK(ddl_payload.HasMember("options"));
1360  CHECK(ddl_payload["options"].IsObject());
1361  } else {
1362  UNREACHABLE() << "Not a valid alter foreign table command: "
1363  << ddl_payload["alterType"].GetString();
1364  }
1365 }
1366 
1368  auto& ddl_payload = extractPayload(ddl_data_);
1369  auto& catalog = session_ptr_->getCatalog();
1370  const std::string& table_name = ddl_payload["tableName"].GetString();
1371  auto [td, td_with_lock] =
1372  get_table_descriptor_with_lock<lockmgr::WriteLock>(catalog, table_name, false);
1373 
1375 
1376  if (!session_ptr_->checkDBAccessPrivileges(
1378  throw std::runtime_error(
1379  "Current user does not have the privilege to alter foreign table: " + table_name);
1380  }
1381 
1382  auto table_data_write_lock =
1384  auto foreign_table = dynamic_cast<const foreign_storage::ForeignTable*>(td);
1385  CHECK(foreign_table);
1386 
1387  std::string alter_type = ddl_payload["alterType"].GetString();
1388  if (alter_type == "RENAME_TABLE") {
1389  renameTable(foreign_table);
1390  } else if (alter_type == "RENAME_COLUMN") {
1391  renameColumn(foreign_table);
1392  } else if (alter_type == "ALTER_OPTIONS") {
1393  alterOptions(foreign_table);
1394  }
1395 
1396  return ExecutionResult();
1397 }
1398 
1400  const foreign_storage::ForeignTable* foreign_table) {
1401  auto& ddl_payload = extractPayload(ddl_data_);
1402  auto& cat = session_ptr_->getCatalog();
1403  const std::string& table_name = ddl_payload["tableName"].GetString();
1404  const std::string& new_table_name = ddl_payload["newTableName"].GetString();
1405  if (cat.getForeignTable(new_table_name)) {
1406  throw std::runtime_error("Foreign table with name \"" + table_name +
1407  "\" can not be renamed to \"" + new_table_name + "\". " +
1408  "A different table with name \"" + new_table_name +
1409  "\" already exists.");
1410  }
1411  cat.renameTable(foreign_table, new_table_name);
1412 }
1413 
1415  const foreign_storage::ForeignTable* foreign_table) {
1416  auto& ddl_payload = extractPayload(ddl_data_);
1417  auto& cat = session_ptr_->getCatalog();
1418  const std::string& old_column_name = ddl_payload["oldColumnName"].GetString();
1419  const std::string& new_column_name = ddl_payload["newColumnName"].GetString();
1420  auto column = cat.getMetadataForColumn(foreign_table->tableId, old_column_name);
1421  if (!column) {
1422  throw std::runtime_error("Column with name \"" + old_column_name +
1423  "\" can not be renamed to \"" + new_column_name + "\". " +
1424  "Column with name \"" + old_column_name +
1425  "\" does not exist.");
1426  }
1427  if (cat.getMetadataForColumn(foreign_table->tableId, new_column_name)) {
1428  throw std::runtime_error("Column with name \"" + old_column_name +
1429  "\" can not be renamed to \"" + new_column_name + "\". " +
1430  "A column with name \"" + new_column_name +
1431  "\" already exists.");
1432  }
1433  cat.renameColumn(foreign_table, column, new_column_name);
1434 }
1435 
1437  const foreign_storage::ForeignTable* foreign_table) {
1438  auto& ddl_payload = extractPayload(ddl_data_);
1439  const std::string& table_name = ddl_payload["tableName"].GetString();
1440  auto& cat = session_ptr_->getCatalog();
1441  auto new_options_map =
1442  foreign_storage::ForeignTable::createOptionsMap(ddl_payload["options"]);
1443  foreign_table->validateSupportedOptionKeys(new_options_map);
1445  cat.setForeignTableOptions(table_name, new_options_map, false);
1446 }
1447 
1449  const DdlCommandData& ddl_data,
1450  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1451  : DdlCommand(ddl_data, session_ptr) {
1452  auto& ddl_payload = extractPayload(ddl_data_);
1453  if (ddl_payload.HasMember("tableNames")) {
1454  CHECK(ddl_payload["tableNames"].IsArray());
1455  for (auto const& tablename_def : ddl_payload["tableNames"].GetArray()) {
1456  CHECK(tablename_def.IsString());
1457  }
1458  }
1459 }
1460 
1462  auto table_names = session_ptr_->get_catalog_ptr()->getTableNamesForUser(
1463  session_ptr_->get_currentUser(), GET_PHYSICAL_TABLES);
1464 
1465  auto& ddl_payload = extractPayload(ddl_data_);
1466  if (ddl_payload.HasMember("tableNames")) {
1467  std::vector<std::string> filtered_names;
1468  for (const auto& tablename_def : ddl_payload["tableNames"].GetArray()) {
1469  std::string filter_name = tablename_def.GetString();
1470  if (std::find(table_names.begin(), table_names.end(), filter_name) !=
1471  table_names.end()) {
1472  filtered_names.emplace_back(filter_name);
1473  } else {
1474  throw std::runtime_error("Can not show disk cache usage for table: " +
1475  filter_name + ". Table does not exist.");
1476  }
1477  }
1478  return filtered_names;
1479  } else {
1480  return table_names;
1481  }
1482 }
1483 
1485  auto cat_ptr = session_ptr_->get_catalog_ptr();
1486  auto table_names = getFilteredTableNames();
1487 
1488  const auto disk_cache = cat_ptr->getDataMgr().getPersistentStorageMgr()->getDiskCache();
1489  if (!disk_cache) {
1490  throw std::runtime_error{"Disk cache not enabled. Cannot show disk cache usage."};
1491  }
1492 
1493  // label_infos -> column labels
1494  std::vector<std::string> labels{"table name", "current cache size"};
1495  std::vector<TargetMetaInfo> label_infos;
1496  label_infos.emplace_back(labels[0], SQLTypeInfo(kTEXT, true));
1497  label_infos.emplace_back(labels[1], SQLTypeInfo(kBIGINT, true));
1498 
1499  std::vector<RelLogicalValues::RowValues> logical_values;
1500 
1501  for (auto& table_name : table_names) {
1502  auto [td, td_with_lock] =
1503  get_table_descriptor_with_lock<lockmgr::ReadLock>(*cat_ptr, table_name, false);
1504 
1505  auto table_cache_size =
1506  disk_cache->getSpaceReservedByTable(cat_ptr->getDatabaseId(), td->tableId);
1507 
1508  // logical_values -> table data
1509  logical_values.emplace_back(RelLogicalValues::RowValues{});
1510  logical_values.back().emplace_back(genLiteralStr(table_name));
1511  logical_values.back().emplace_back(genLiteralBigInt(table_cache_size));
1512  }
1513 
1514  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1515  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1516 
1517  return ExecutionResult(rSet, label_infos);
1518 }
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:205
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:101
Definition: sqltypes.h:48
SQLTypes
Definition: sqltypes.h:37
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:222
#define NULL_BIGINT
#define LOG(tag)
Definition: Logger.h:188
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:241
std::string fragments
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:102
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:521
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:292
This file contains the class specification and related data structures for SysCatalog.
bool g_enable_s3_fsi
Definition: Catalog.cpp:93
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:98
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:276
uint64_t total_metadata_page_count
Definition: FileMgr.h:97
static const AccessPrivileges CREATE_SERVER
Definition: DBObject.h:190
ExecutionResult execute() override
std::unique_ptr< RexLiteral > genLiteralBoolean(bool val)
void validate_non_reserved_keyword(const std::string &column_name)
Definition: DdlUtils.cpp:530
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:4013
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:507
File_Namespace::GlobalFileMgr * getGlobalFileMgr() const
Definition: DataMgr.cpp:543
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()
void set_column_descriptor(const std::string &column_name, ColumnDescriptor &cd, SqlType *column_type, const bool not_null, const Encoding *encoding)
Definition: DdlUtils.cpp:493
ExecutionResult execute()
Definition: sqltypes.h:51
Definition: sqltypes.h:52
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:96
Basic constructors and methods of the row set interface.
std::vector< std::string > getFilteredTableNames()
ExecutionResult execute() override
static std::unique_ptr< RexLiteral > genLiteralStr(std::string val)
Definition: DBHandler.cpp:6678
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:538
const ForeignServer * foreign_server
Definition: ForeignTable.h:53
void renameTable(const foreign_storage::ForeignTable *foreign_table)
#define CHECK(condition)
Definition: Logger.h:197
bool isDefaultServer(const std::string &server_name)
std::list< DBSummary > DBSummaryList
Definition: SysCatalog.h:129
Definition: sqltypes.h:44
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:92
ExecutionResult execute() override
ExecutionResult execute() override
ExecutionResult execute() override
#define IS_GEO(T)
Definition: sqltypes.h:245
#define VLOG(n)
Definition: Logger.h:291
RefreshForeignTablesCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)