OmniSciDB  72c90bc290
 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 2022 HEAVY.AI, 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 <algorithm>
20 
21 #include <boost/algorithm/string/predicate.hpp>
22 #include <boost/uuid/uuid_generators.hpp>
23 #include <boost/uuid/uuid_io.hpp>
24 
25 #include "rapidjson/document.h"
26 
27 // Note: avoid adding #include(s) that require thrift
28 
29 #include "Catalog/Catalog.h"
30 #include "Catalog/SysCatalog.h"
32 #include "LockMgr/LockMgr.h"
33 #include "Parser/ParserNode.h"
34 #include "Shared/StringTransform.h"
35 #include "Shared/SysDefinitions.h"
36 
38 #include "QueryEngine/Execute.h" // Executor::getArenaBlockSize()
44 
45 extern bool g_enable_fsi;
46 extern bool g_enable_ml_functions;
48 
49 namespace {
50 
52  const TableDescriptor* td) {
53  if (!td->hasDeletedCol) {
54  return;
55  }
56 
57  DEBUG_TIMER(__func__);
58 
60  const TableOptimizer optimizer(td, executor, catalog);
61  auto total_time_ms = measure<>::execution([&]() { optimizer.vacuumDeletedRows(); });
62  LOG(INFO) << "Vacuum time (alter column data type): " << total_time_ms << "ms";
63 
64  // Reload fragmenter
65  catalog.getMetadataForTable(td->tableName, true);
66 }
67 
68 void validate_alter_type_allowed(const std::string& colname,
69  const SQLTypeInfo& src,
70  const SQLTypeInfo& dst) {
71  if (!src.is_string()) {
72  throw std::runtime_error("Altering column " + colname +
73  " type not allowed. Column type must be TEXT.");
74  }
75 }
76 
78  const TableDescriptor* td,
79  const ColumnDescriptor& cd) {
80  ChunkMetadataVector column_metadata;
82  column_metadata, {catalog.getDatabaseId(), td->tableId, cd.columnId});
83 
84  const bool is_not_null = cd.columnType.get_notnull();
85  // check for non nulls
86  for (const auto& [key, metadata] : column_metadata) {
87  if (is_not_null && metadata->chunkStats.has_nulls) {
88  throw std::runtime_error("Alter column type: Column " + cd.columnName +
89  ": NULL value not allowed in NOT NULL column");
90  }
91  }
92 
93  if (td->nShards > 0) {
94  throw std::runtime_error("Alter column type: Column " + cd.columnName +
95  ": altering a sharded table is unsupported");
96  }
97  // further checks on metadata can be done to prevent late exceptions
98 }
99 
100 std::list<std::pair<const ColumnDescriptor*, std::list<const ColumnDescriptor*>>>
102  const AlterTableAlterColumnCommand::TypePairs& src_dst_cds,
103  const std::list<std::list<ColumnDescriptor>>& phys_cds) {
104  std::list<std::pair<const ColumnDescriptor*, std::list<const ColumnDescriptor*>>>
105  geo_src_dst_column_pairs;
106 
107  auto phys_cds_it = phys_cds.begin();
108  for (auto& [src_cd, dst_cd] : src_dst_cds) {
109  if (dst_cd->columnType.is_geometry()) {
110  geo_src_dst_column_pairs.emplace_back();
111  auto& pair = geo_src_dst_column_pairs.back();
112  pair.first = src_cd;
113 
114  std::list<const ColumnDescriptor*> geo_dst_cds;
115  CHECK(phys_cds_it != phys_cds.end());
116  auto& phy_geo_columns = *phys_cds_it;
117  geo_dst_cds.push_back(dst_cd);
118  for (const auto& cd : phy_geo_columns) {
119  geo_dst_cds.push_back(&cd);
120  }
121  pair.second = geo_dst_cds;
122 
123  phys_cds_it++;
124  }
125  }
126 
127  return geo_src_dst_column_pairs;
128 }
129 
131  std::list<ColumnDescriptor>& src_cds,
132  std::list<ColumnDescriptor>& dst_cds) {
133  CHECK_EQ(src_cds.size(), dst_cds.size());
134  AlterTableAlterColumnCommand::TypePairs src_dst_column_pairs;
135  auto src_cd_it = src_cds.begin();
136  auto dst_cd_it = dst_cds.begin();
137  for (; src_cd_it != src_cds.end(); ++src_cd_it, ++dst_cd_it) {
138  src_dst_column_pairs.emplace_back(&(*src_cd_it), &(*dst_cd_it));
139  }
140  return src_dst_column_pairs;
141 }
142 
143 std::pair<std::list<ColumnDescriptor>, std::list<ColumnDescriptor>>
144 get_alter_column_src_dst_cds(const std::list<Parser::ColumnDef>& columns,
146  const TableDescriptor* td) {
147  std::list<ColumnDescriptor> src_cds;
148  std::list<ColumnDescriptor> dst_cds;
149  for (const auto& coldef : columns) {
150  dst_cds.emplace_back();
151  ColumnDescriptor& dst_cd = dst_cds.back();
152  set_column_descriptor(dst_cd, &coldef);
153 
154  // update kENCODING_DICT column descriptors to reflect correct sizing based on comp
155  // param
156  if (dst_cd.columnType.is_dict_encoded_string()) {
157  switch (dst_cd.columnType.get_comp_param()) {
158  case 8:
159  dst_cd.columnType.set_size(1);
160  break;
161  case 16:
162  dst_cd.columnType.set_size(2);
163  break;
164  case 32:
165  dst_cd.columnType.set_size(4);
166  break;
167  default:
168  UNREACHABLE();
169  }
170  }
171 
172  auto catalog_cd = catalog.getMetadataForColumn(td->tableId, dst_cd.columnName);
173  CHECK(catalog_cd);
174 
176  dst_cd.columnName, catalog_cd->columnType, dst_cd.columnType);
177 
178  // Set remaining values in column descriptor that must be obtained from catalog
179  dst_cd.columnId = catalog_cd->columnId;
180  dst_cd.tableId = catalog_cd->tableId;
181  dst_cd.sourceName = catalog_cd->sourceName;
182  dst_cd.chunks = catalog_cd->chunks;
183  dst_cd.db_id = catalog_cd->db_id;
184 
185  // This branch handles the special case where a string dictionary column
186  // type is not changed, but altering is required (for example default
187  // changes)
188  if (catalog_cd->columnType.is_dict_encoded_type() &&
189  dst_cd.columnType.is_dict_encoded_type() &&
191  .sql_types_match) {
192  dst_cd.columnType.set_comp_param(catalog_cd->columnType.get_comp_param());
193  dst_cd.columnType.setStringDictKey(catalog_cd->columnType.getStringDictKey());
194  }
195 
197  .exact_match) {
198  throw std::runtime_error("Altering column " + dst_cd.columnName +
199  " results in no change to column, please review command.");
200  }
201 
202  validate_alter_type_metadata(catalog, td, dst_cd);
203 
204  // A copy of the catalog column descriptor is stored for the source because
205  // the catalog may delete its version of the source descriptor in progress
206  // of the alter column command
207  src_cds.emplace_back();
208  src_cds.back() = *catalog_cd;
209  }
210  return {src_cds, dst_cds};
211 }
212 
213 template <class LockType>
214 std::tuple<const TableDescriptor*,
215  std::unique_ptr<lockmgr::TableSchemaLockContainer<LockType>>>
217  const std::string& table_name,
218  const bool populate_fragmenter) {
219  const TableDescriptor* td{nullptr};
220  std::unique_ptr<lockmgr::TableSchemaLockContainer<LockType>> td_with_lock =
221  std::make_unique<lockmgr::TableSchemaLockContainer<LockType>>(
223  cat, table_name, populate_fragmenter));
224  CHECK(td_with_lock);
225  td = (*td_with_lock)();
226  CHECK(td);
227  return std::make_tuple(td, std::move(td_with_lock));
228 }
229 
230 // There are cases where we may query a catalog for a list of table names and then perform
231 // some action on those tables without acquiring a lock, which means the tables could have
232 // been dropped in between the query and the action. In such cases, sometimes we want to
233 // skip that action if the table no longer exists without throwing an error.
234 template <class Func>
235 void exec_for_tables_which_exist(const std::vector<std::string>& table_names,
237  Func func) {
238  for (const auto& table_name : table_names) {
239  try {
240  auto [td, td_with_lock] =
241  get_table_descriptor_with_lock<lockmgr::ReadLock>(*cat_ptr, table_name, false);
242  func(td, table_name);
243  } catch (const Catalog_Namespace::TableNotFoundException& e) {
244  continue;
245  }
246  }
247 }
248 
250  int32_t min_epoch;
251  int32_t max_epoch;
254 
256  : File_Namespace::StorageStats(storage_stats)
257  , min_epoch(storage_stats.epoch)
258  , max_epoch(storage_stats.epoch)
259  , min_epoch_floor(storage_stats.epoch_floor)
260  , max_epoch_floor(storage_stats.epoch_floor) {}
261 
262  void aggregate(const File_Namespace::StorageStats& storage_stats) {
263  metadata_file_count += storage_stats.metadata_file_count;
264  total_metadata_file_size += storage_stats.total_metadata_file_size;
265  total_metadata_page_count += storage_stats.total_metadata_page_count;
266  if (storage_stats.total_free_metadata_page_count) {
267  if (total_free_metadata_page_count) {
268  total_free_metadata_page_count.value() +=
269  storage_stats.total_free_metadata_page_count.value();
270  } else {
271  total_free_metadata_page_count = storage_stats.total_free_metadata_page_count;
272  }
273  }
274  data_file_count += storage_stats.data_file_count;
275  total_data_file_size += storage_stats.total_data_file_size;
276  total_data_page_count += storage_stats.total_data_page_count;
277  if (storage_stats.total_free_data_page_count) {
278  if (total_free_data_page_count) {
279  total_free_data_page_count.value() +=
280  storage_stats.total_free_data_page_count.value();
281  } else {
282  total_free_data_page_count = storage_stats.total_free_data_page_count;
283  }
284  }
285  min_epoch = std::min(min_epoch, storage_stats.epoch);
286  max_epoch = std::max(max_epoch, storage_stats.epoch);
287  min_epoch_floor = std::min(min_epoch_floor, storage_stats.epoch_floor);
288  max_epoch_floor = std::max(max_epoch_floor, storage_stats.epoch_floor);
289  }
290 };
291 
293  const Catalog_Namespace::Catalog* catalog) {
294  const auto global_file_mgr = catalog->getDataMgr().getGlobalFileMgr();
295  std::optional<AggregratedStorageStats> agg_storage_stats;
296  if (td->nShards > 0) {
297  const auto physical_tables = catalog->getPhysicalTablesDescriptors(td, false);
298  CHECK_EQ(static_cast<size_t>(td->nShards), physical_tables.size());
299 
300  for (const auto physical_table : physical_tables) {
301  auto storage_stats = global_file_mgr->getStorageStats(catalog->getDatabaseId(),
302  physical_table->tableId);
303  if (agg_storage_stats) {
304  agg_storage_stats.value().aggregate(storage_stats);
305  } else {
306  agg_storage_stats = storage_stats;
307  }
308  }
309  } else {
310  agg_storage_stats =
311  global_file_mgr->getStorageStats(catalog->getDatabaseId(), td->tableId);
312  }
313  CHECK(agg_storage_stats.has_value());
314  return agg_storage_stats.value();
315 }
316 
317 std::unique_ptr<RexLiteral> genLiteralStr(std::string val) {
318  return std::unique_ptr<RexLiteral>(
319  new RexLiteral(val, SQLTypes::kTEXT, SQLTypes::kTEXT, 0, 0, 0, 0));
320 }
321 
322 std::unique_ptr<RexLiteral> genLiteralTimestamp(time_t val) {
323  return std::unique_ptr<RexLiteral>(new RexLiteral(
324  (int64_t)val, SQLTypes::kTIMESTAMP, SQLTypes::kTIMESTAMP, 0, 8, 0, 8));
325 }
326 
327 std::unique_ptr<RexLiteral> genLiteralBigInt(int64_t val) {
328  return std::unique_ptr<RexLiteral>(
329  new RexLiteral(val, SQLTypes::kBIGINT, SQLTypes::kBIGINT, 0, 8, 0, 8));
330 }
331 
332 std::unique_ptr<RexLiteral> genLiteralDouble(double val) {
333  return std::unique_ptr<RexLiteral>(
334  new RexLiteral(val, SQLTypes::kDOUBLE, SQLTypes::kDOUBLE, 0, 8, 0, 8));
335 }
336 
337 std::unique_ptr<RexLiteral> genLiteralBoolean(bool val) {
338  return std::unique_ptr<RexLiteral>(new RexLiteral(
339  (int64_t)(val ? 1 : 0), SQLTypes::kBIGINT, SQLTypes::kBIGINT, 0, 8, 0, 8));
340 }
341 
343  std::vector<TargetMetaInfo>& label_infos,
344  const std::vector<std::tuple<std::string, SQLTypes, bool>>& headers) {
345  for (const auto& header : headers) {
346  auto [_val, _type, _notnull] = header;
347  if (_type == kBIGINT || _type == kTEXT || _type == kTIMESTAMP || _type == kBOOLEAN) {
348  label_infos.emplace_back(_val, SQLTypeInfo(_type, _notnull));
349  } else {
350  UNREACHABLE() << "Unsupported type provided for header. SQL type: "
351  << to_string(_type);
352  }
353  }
354 }
355 
356 void add_table_details(std::vector<RelLogicalValues::RowValues>& logical_values,
357  const TableDescriptor* logical_table,
358  const AggregratedStorageStats& agg_storage_stats) {
359  bool is_sharded_table = (logical_table->nShards > 0);
360  logical_values.emplace_back(RelLogicalValues::RowValues{});
361  logical_values.back().emplace_back(genLiteralBigInt(logical_table->tableId));
362  logical_values.back().emplace_back(genLiteralStr(logical_table->tableName));
363  logical_values.back().emplace_back(genLiteralBigInt(logical_table->nColumns));
364  logical_values.back().emplace_back(genLiteralBoolean(is_sharded_table));
365  logical_values.back().emplace_back(genLiteralBigInt(logical_table->nShards));
366  logical_values.back().emplace_back(genLiteralBigInt(logical_table->maxRows));
367  logical_values.back().emplace_back(genLiteralBigInt(logical_table->maxFragRows));
368  logical_values.back().emplace_back(genLiteralBigInt(logical_table->maxRollbackEpochs));
369  logical_values.back().emplace_back(genLiteralBigInt(agg_storage_stats.min_epoch));
370  logical_values.back().emplace_back(genLiteralBigInt(agg_storage_stats.max_epoch));
371  logical_values.back().emplace_back(genLiteralBigInt(agg_storage_stats.min_epoch_floor));
372  logical_values.back().emplace_back(genLiteralBigInt(agg_storage_stats.max_epoch_floor));
373  logical_values.back().emplace_back(
374  genLiteralBigInt(agg_storage_stats.metadata_file_count));
375  logical_values.back().emplace_back(
376  genLiteralBigInt(agg_storage_stats.total_metadata_file_size));
377  logical_values.back().emplace_back(
378  genLiteralBigInt(agg_storage_stats.total_metadata_page_count));
379 
380  if (agg_storage_stats.total_free_metadata_page_count) {
381  logical_values.back().emplace_back(
382  genLiteralBigInt(agg_storage_stats.total_free_metadata_page_count.value()));
383  } else {
384  logical_values.back().emplace_back(genLiteralBigInt(NULL_BIGINT));
385  }
386 
387  logical_values.back().emplace_back(genLiteralBigInt(agg_storage_stats.data_file_count));
388  logical_values.back().emplace_back(
389  genLiteralBigInt(agg_storage_stats.total_data_file_size));
390  logical_values.back().emplace_back(
391  genLiteralBigInt(agg_storage_stats.total_data_page_count));
392 
393  if (agg_storage_stats.total_free_data_page_count) {
394  logical_values.back().emplace_back(
395  genLiteralBigInt(agg_storage_stats.total_free_data_page_count.value()));
396  } else {
397  logical_values.back().emplace_back(genLiteralBigInt(NULL_BIGINT));
398  }
399 }
400 
401 // -----------------------------------------------------------------------
402 // class: JsonColumnSqlType
403 // Defined & Implemented here to avoid exposing rapidjson in the header file
404 // -----------------------------------------------------------------------
405 
408  public:
409  JsonColumnSqlType(const rapidjson::Value& data_type)
410  : ddl_utils::SqlType(getSqlType(data_type),
411  getParam1(data_type),
412  getParam2(data_type),
413  isArray(data_type),
414  getArraySize(data_type)) {}
415 
416  private:
417  static SQLTypes getSqlType(const rapidjson::Value& data_type);
418  static SQLTypes getSqlType(const std::string& type);
419  static int getParam1(const rapidjson::Value& data_type);
420  static int getParam2(const rapidjson::Value& data_type);
421  static bool isArray(const rapidjson::Value& data_type);
422  static int getArraySize(const rapidjson::Value& data_type);
423 };
424 
426  public:
427  JsonColumnEncoding(const rapidjson::Value& data_type)
428  : ddl_utils::Encoding(getEncodingName(data_type), getEncodingParam(data_type)) {}
429 
430  private:
431  static std::string* getEncodingName(const rapidjson::Value& data_type);
432  static int getEncodingParam(const rapidjson::Value& data_type);
433 };
434 
435 // -----------------------------------------------------------------------
436 // class DdlCommandDataImpl:
437 //
438 // Concrete class to cache parse data
439 // Defined & Implemented here to avoid exposing rapidjson in the header file
440 // Helper/access fns available to get useful pieces of cache data
441 // -----------------------------------------------------------------------
443  public:
444  DdlCommandDataImpl(const std::string& ddl_statement);
445  ~DdlCommandDataImpl() override;
446 
447  // The full query available for futher analysis
448  const rapidjson::Value& query() const;
449 
450  // payload as extracted from the query
451  const rapidjson::Value& payload() const;
452 
453  // commandStr extracted from the payload
454  std::string commandStr() override;
455 
456  rapidjson::Document ddl_query;
457 };
458 
459 DdlCommandDataImpl::DdlCommandDataImpl(const std::string& ddl_statement)
460  : DdlCommandData(ddl_statement) {
461  ddl_query.Parse(ddl_statement);
462 }
463 
465 
466 const rapidjson::Value& DdlCommandDataImpl::query() const {
467  return ddl_query;
468 }
469 
470 const rapidjson::Value& DdlCommandDataImpl::payload() const {
471  CHECK(ddl_query.HasMember("payload"));
472  CHECK(ddl_query["payload"].IsObject());
473  return ddl_query["payload"];
474 }
475 
477  if (ddl_query.IsObject() && ddl_query.HasMember("payload") &&
478  ddl_query["payload"].IsObject()) {
479  auto& payload = ddl_query["payload"];
480  if (payload.HasMember("command") && payload["command"].IsString()) {
481  return payload["command"].GetString();
482  }
483  }
484  return "";
485 }
486 
487 // Helper Fn to get the payload from the abstract base class
488 const rapidjson::Value& extractPayload(const DdlCommandData& ddl_data) {
489  const DdlCommandDataImpl* data = static_cast<const DdlCommandDataImpl*>(&ddl_data);
490  return data->payload();
491 }
492 
493 const rapidjson::Value* extractFilters(const rapidjson::Value& payload) {
494  const rapidjson::Value* filters = nullptr;
495  if (payload.HasMember("filters") && payload["filters"].IsArray()) {
496  filters = &payload["filters"];
497  }
498  return filters;
499 }
500 } // namespace
501 
503  const std::string& ddl_statement,
504  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
505  : session_ptr_(session_ptr) {
506  CHECK(!ddl_statement.empty());
507  ddl_statement_ = ddl_statement;
508 
509  // parse the incoming query,
510  // cache the parsed rapidjson object inside a DdlCommandDataImpl
511  // store the "abstract/base class" reference in ddl_data_
512  DdlCommandDataImpl* ddl_query_data = new DdlCommandDataImpl(ddl_statement);
513  ddl_data_ = std::unique_ptr<DdlCommandData>(ddl_query_data);
514 
515  VLOG(2) << "Parsing JSON DDL from Calcite: " << ddl_statement;
516  auto& ddl_query = ddl_query_data->query();
517  CHECK(ddl_query.IsObject()) << ddl_statement;
518  CHECK(ddl_query.HasMember("payload"));
519  CHECK(ddl_query["payload"].IsObject());
520  const auto& payload = ddl_query["payload"].GetObject();
521  CHECK(payload.HasMember("command"));
522  CHECK(payload["command"].IsString());
523  ddl_command_ = payload["command"].GetString();
524 }
525 
528 
529  // the following commands use parser node locking to ensure safe concurrent access
530  if (ddl_command_ == "CREATE_TABLE") {
531  auto create_table_stmt = Parser::CreateTableStmt(extractPayload(*ddl_data_));
532  create_table_stmt.execute(*session_ptr_, read_only_mode);
533  return result;
534  } else if (ddl_command_ == "CREATE_VIEW") {
535  auto create_view_stmt = Parser::CreateViewStmt(extractPayload(*ddl_data_));
536  create_view_stmt.execute(*session_ptr_, read_only_mode);
537  return result;
538  } else if (ddl_command_ == "DROP_TABLE") {
539  auto drop_table_stmt = Parser::DropTableStmt(extractPayload(*ddl_data_));
540  drop_table_stmt.execute(*session_ptr_, read_only_mode);
541  return result;
542  } else if (ddl_command_ == "DROP_VIEW") {
543  auto drop_view_stmt = Parser::DropViewStmt(extractPayload(*ddl_data_));
544  drop_view_stmt.execute(*session_ptr_, read_only_mode);
545  return result;
546  } else if (ddl_command_ == "RENAME_TABLE") {
547  auto rename_table_stmt = Parser::RenameTableStmt(extractPayload(*ddl_data_));
548  rename_table_stmt.execute(*session_ptr_, read_only_mode);
549  return result;
550  } else if (ddl_command_ == "ALTER_TABLE") {
551  // ALTER TABLE uses the parser node locking partially as well as the global locking
552  // scheme for some cases
553  return AlterTableCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
554  } else if (ddl_command_ == "TRUNCATE_TABLE") {
555  auto truncate_table_stmt = Parser::TruncateTableStmt(extractPayload(*ddl_data_));
556  truncate_table_stmt.execute(*session_ptr_, read_only_mode);
557  return result;
558  } else if (ddl_command_ == "DUMP_TABLE") {
559  auto dump_table_stmt = Parser::DumpTableStmt(extractPayload(*ddl_data_));
560  dump_table_stmt.execute(*session_ptr_, read_only_mode);
561  return result;
562  } else if (ddl_command_ == "RESTORE_TABLE") {
563  auto restore_table_stmt = Parser::RestoreTableStmt(extractPayload(*ddl_data_));
564  restore_table_stmt.execute(*session_ptr_, read_only_mode);
565  return result;
566  } else if (ddl_command_ == "OPTIMIZE_TABLE") {
567  auto optimize_table_stmt = Parser::OptimizeTableStmt(extractPayload(*ddl_data_));
568  optimize_table_stmt.execute(*session_ptr_, read_only_mode);
569  return result;
570  } else if (ddl_command_ == "COPY_TABLE") {
571  auto copy_table_stmt = Parser::CopyTableStmt(extractPayload(*ddl_data_));
572  copy_table_stmt.execute(*session_ptr_, read_only_mode);
573  return result;
574  } else if (ddl_command_ == "EXPORT_QUERY") {
575  auto export_query_stmt = Parser::ExportQueryStmt(extractPayload(*ddl_data_));
576  export_query_stmt.execute(*session_ptr_, read_only_mode);
577  return result;
578  } else if (ddl_command_ == "CREATE_DB") {
579  auto create_db_stmt = Parser::CreateDBStmt(extractPayload(*ddl_data_));
580  create_db_stmt.execute(*session_ptr_, read_only_mode);
581  return result;
582  } else if (ddl_command_ == "DROP_DB") {
583  auto drop_db_stmt = Parser::DropDBStmt(extractPayload(*ddl_data_));
584  drop_db_stmt.execute(*session_ptr_, read_only_mode);
585  return result;
586  } else if (ddl_command_ == "CREATE_USER") {
587  auto create_user_stmt = Parser::CreateUserStmt(extractPayload(*ddl_data_));
588  create_user_stmt.execute(*session_ptr_, read_only_mode);
589  return result;
590  } else if (ddl_command_ == "DROP_USER") {
591  auto drop_user_stmt = Parser::DropUserStmt(extractPayload(*ddl_data_));
592  drop_user_stmt.execute(*session_ptr_, read_only_mode);
593  return result;
594  } else if (ddl_command_ == "ALTER_USER") {
595  auto alter_user_stmt = Parser::AlterUserStmt(extractPayload(*ddl_data_));
596  alter_user_stmt.execute(*session_ptr_, read_only_mode);
597  return result;
598  } else if (ddl_command_ == "RENAME_USER") {
599  auto rename_user_stmt = Parser::RenameUserStmt(extractPayload(*ddl_data_));
600  rename_user_stmt.execute(*session_ptr_, read_only_mode);
601  return result;
602  } else if (ddl_command_ == "CREATE_ROLE") {
603  auto create_role_stmt = Parser::CreateRoleStmt(extractPayload(*ddl_data_));
604  create_role_stmt.execute(*session_ptr_, read_only_mode);
605  return result;
606  } else if (ddl_command_ == "DROP_ROLE") {
607  auto drop_role_stmt = Parser::DropRoleStmt(extractPayload(*ddl_data_));
608  drop_role_stmt.execute(*session_ptr_, read_only_mode);
609  return result;
610  } else if (ddl_command_ == "GRANT_ROLE") {
611  auto grant_role_stmt = Parser::GrantRoleStmt(extractPayload(*ddl_data_));
612  grant_role_stmt.execute(*session_ptr_, read_only_mode);
613  return result;
614  } else if (ddl_command_ == "REVOKE_ROLE") {
615  auto revoke_role_stmt = Parser::RevokeRoleStmt(extractPayload(*ddl_data_));
616  revoke_role_stmt.execute(*session_ptr_, read_only_mode);
617  return result;
618  } else if (ddl_command_ == "GRANT_PRIVILEGE") {
619  auto grant_privilege_stmt = Parser::GrantPrivilegesStmt(extractPayload(*ddl_data_));
620  grant_privilege_stmt.execute(*session_ptr_, read_only_mode);
621  return result;
622  } else if (ddl_command_ == "REVOKE_PRIVILEGE") {
623  auto revoke_privileges_stmt =
625  revoke_privileges_stmt.execute(*session_ptr_, read_only_mode);
626  return result;
627  } else if (ddl_command_ == "CREATE_DATAFRAME") {
628  auto create_dataframe_stmt = Parser::CreateDataframeStmt(extractPayload(*ddl_data_));
629  create_dataframe_stmt.execute(*session_ptr_, read_only_mode);
630  return result;
631  } else if (ddl_command_ == "CREATE_MODEL") {
632  auto create_model_stmt = Parser::CreateModelStmt(extractPayload(*ddl_data_));
633  create_model_stmt.execute(*session_ptr_, read_only_mode);
634  return result;
635  } else if (ddl_command_ == "DROP_MODEL") {
636  auto drop_model_stmt = Parser::DropModelStmt(extractPayload(*ddl_data_));
637  drop_model_stmt.execute(*session_ptr_, read_only_mode);
638  return result;
639  } else if (ddl_command_ == "EVALUATE_MODEL") {
640  result = EvaluateModelCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
641  } else if (ddl_command_ == "VALIDATE_SYSTEM") {
642  // VALIDATE should have been excuted in outer context before it reaches here
643  UNREACHABLE();
644  } else if (ddl_command_ == "REFRESH_FOREIGN_TABLES") {
645  result =
646  RefreshForeignTablesCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
647  return result;
648  } else if (ddl_command_ == "CREATE_SERVER") {
649  result = CreateForeignServerCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
650  } else if (ddl_command_ == "DROP_SERVER") {
651  result = DropForeignServerCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
652  } else if (ddl_command_ == "CREATE_FOREIGN_TABLE") {
653  result = CreateForeignTableCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
654  } else if (ddl_command_ == "DROP_FOREIGN_TABLE") {
655  result = DropForeignTableCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
656  } else if (ddl_command_ == "SHOW_TABLES") {
657  result = ShowTablesCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
658  } else if (ddl_command_ == "SHOW_TABLE_DETAILS") {
659  result = ShowTableDetailsCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
660  } else if (ddl_command_ == "SHOW_CREATE_TABLE") {
661  result = ShowCreateTableCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
662  } else if (ddl_command_ == "SHOW_DATABASES") {
663  result = ShowDatabasesCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
664  } else if (ddl_command_ == "SHOW_SERVERS") {
665  result = ShowForeignServersCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
666  } else if (ddl_command_ == "SHOW_CREATE_SERVER") {
667  result = ShowCreateServerCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
668  } else if (ddl_command_ == "SHOW_FUNCTIONS") {
669  result = ShowFunctionsCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
670  } else if (ddl_command_ == "SHOW_RUNTIME_FUNCTIONS") {
671  result =
672  ShowRuntimeFunctionsCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
673  } else if (ddl_command_ == "SHOW_TABLE_FUNCTIONS") {
674  result = ShowTableFunctionsCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
675  } else if (ddl_command_ == "SHOW_RUNTIME_TABLE_FUNCTIONS") {
677  read_only_mode);
678  } else if (ddl_command_ == "SHOW_MODELS") {
679  result = ShowModelsCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
680  } else if (ddl_command_ == "SHOW_MODEL_DETAILS") {
681  result = ShowModelDetailsCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
682  } else if (ddl_command_ == "SHOW_MODEL_FEATURE_DETAILS") {
683  result =
684  ShowModelFeatureDetailsCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
685  } else if (ddl_command_ == "ALTER_SERVER") {
686  result = AlterForeignServerCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
687  } else if (ddl_command_ == "ALTER_DATABASE") {
688  result = AlterDatabaseCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
689  } else if (ddl_command_ == "ALTER_FOREIGN_TABLE") {
690  result = AlterForeignTableCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
691  } else if (ddl_command_ == "SHOW_DISK_CACHE_USAGE") {
692  result = ShowDiskCacheUsageCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
693  } else if (ddl_command_ == "SHOW_USER_DETAILS") {
694  result = ShowUserDetailsCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
695  } else if (ddl_command_ == "SHOW_ROLES") {
696  result = ShowRolesCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
697  } else if (ddl_command_ == "REASSIGN_OWNED") {
698  result = ReassignOwnedCommand{*ddl_data_, session_ptr_}.execute(read_only_mode);
699  } else {
700  throw std::runtime_error("Unsupported DDL command");
701  }
702 
703  return result;
704 }
705 
707  return (ddl_command_ == "SHOW_USER_SESSIONS");
708 }
709 
711  return (ddl_command_ == "SHOW_QUERIES");
712 }
713 
715  return (ddl_command_ == "KILL_QUERY");
716 }
717 
719  return (ddl_command_ == "ALTER_SYSTEM_CLEAR");
720 }
721 
723  return (ddl_command_ == "ALTER_SESSION_SET");
724 }
725 
726 std::pair<std::string, std::string> DdlCommandExecutor::getSessionParameter() const {
727  enum SetParameterType { String_t, Numeric_t };
728  static const std::unordered_map<std::string, SetParameterType>
729  session_set_parameters_map = {{"EXECUTOR_DEVICE", SetParameterType::String_t},
730  {"CURRENT_DATABASE", SetParameterType::String_t}};
731 
732  auto& ddl_payload = extractPayload(*ddl_data_);
733  CHECK(ddl_payload.HasMember("sessionParameter"));
734  CHECK(ddl_payload["sessionParameter"].IsString());
735  CHECK(ddl_payload.HasMember("parameterValue"));
736  CHECK(ddl_payload["parameterValue"].IsString());
737  std::string parameter_name = to_upper(ddl_payload["sessionParameter"].GetString());
738  std::string parameter_value = ddl_payload["parameterValue"].GetString();
739 
740  const auto param_it = session_set_parameters_map.find(parameter_name);
741  if (param_it == session_set_parameters_map.end()) {
742  throw std::runtime_error(parameter_name + " is not a settable session parameter.");
743  }
744  if (param_it->second == SetParameterType::Numeric_t) {
745  if (!std::regex_match(parameter_value, std::regex("[(-|+)|][0-9]+"))) {
746  throw std::runtime_error("The value of session parameter " + param_it->first +
747  " should be a numeric.");
748  }
749  }
750  return {parameter_name, parameter_value};
751 }
752 
754  CHECK(ddl_command_ == "ALTER_SYSTEM_CLEAR");
755  auto& ddl_payload = extractPayload(*ddl_data_);
756  CHECK(ddl_payload.HasMember("cacheType"));
757  CHECK(ddl_payload["cacheType"].IsString());
758  return ddl_payload["cacheType"].GetString();
759 }
760 
762  return (ddl_command_ == "ALTER_SYSTEM_CONTROL_EXECUTOR_QUEUE");
763 }
764 
766  CHECK(ddl_command_ == "ALTER_SYSTEM_CONTROL_EXECUTOR_QUEUE");
767  auto& ddl_payload = extractPayload(*ddl_data_);
768  CHECK(ddl_payload.HasMember("queueAction"));
769  CHECK(ddl_payload["queueAction"].IsString());
770  return ddl_payload["queueAction"].GetString();
771 }
772 
774  DistributedExecutionDetails execution_details;
775  if (ddl_command_ == "CREATE_DATAFRAME" || ddl_command_ == "RENAME_TABLE" ||
776  ddl_command_ == "ALTER_TABLE" || ddl_command_ == "CREATE_TABLE" ||
777  ddl_command_ == "DROP_TABLE" || ddl_command_ == "TRUNCATE_TABLE" ||
778  ddl_command_ == "DUMP_TABLE" || ddl_command_ == "RESTORE_TABLE" ||
779  ddl_command_ == "OPTIMIZE_TABLE" || ddl_command_ == "CREATE_VIEW" ||
780  ddl_command_ == "DROP_VIEW" || ddl_command_ == "CREATE_DB" ||
781  ddl_command_ == "DROP_DB" || ddl_command_ == "ALTER_DATABASE" ||
782  ddl_command_ == "CREATE_USER" || ddl_command_ == "DROP_USER" ||
783  ddl_command_ == "ALTER_USER" || ddl_command_ == "RENAME_USER" ||
784  ddl_command_ == "CREATE_ROLE" || ddl_command_ == "DROP_ROLE" ||
785  ddl_command_ == "GRANT_ROLE" || ddl_command_ == "REVOKE_ROLE" ||
786  ddl_command_ == "REASSIGN_OWNED" || ddl_command_ == "CREATE_POLICY" ||
787  ddl_command_ == "DROP_POLICY" || ddl_command_ == "CREATE_SERVER" ||
788  ddl_command_ == "DROP_SERVER" || ddl_command_ == "CREATE_FOREIGN_TABLE" ||
789  ddl_command_ == "DROP_FOREIGN_TABLE" || ddl_command_ == "CREATE_USER_MAPPING" ||
790  ddl_command_ == "DROP_USER_MAPPING" || ddl_command_ == "ALTER_FOREIGN_TABLE" ||
791  ddl_command_ == "ALTER_SERVER" || ddl_command_ == "REFRESH_FOREIGN_TABLES" ||
792  ddl_command_ == "ALTER_SYSTEM_CLEAR") {
793  // group user/role/db commands
795  execution_details.aggregation_type = AggregationType::NONE;
796  } else if (ddl_command_ == "GRANT_PRIVILEGE" || ddl_command_ == "REVOKE_PRIVILEGE") {
797  auto& ddl_payload = extractPayload(*ddl_data_);
798  CHECK(ddl_payload.HasMember("type"));
799  const std::string& targetType = ddl_payload["type"].GetString();
800  if (targetType == "DASHBOARD") {
801  // dashboard commands should run on Aggregator alone
803  execution_details.aggregation_type = AggregationType::NONE;
804  } else {
806  execution_details.aggregation_type = AggregationType::NONE;
807  }
808 
809  } else if (ddl_command_ == "SHOW_TABLE_DETAILS" ||
810  ddl_command_ == "SHOW_DISK_CACHE_USAGE") {
812  execution_details.aggregation_type = AggregationType::UNION;
813  } else {
814  // Commands that fall here : COPY_TABLE, EXPORT_QUERY, etc.
816  execution_details.aggregation_type = AggregationType::NONE;
817  }
818  return execution_details;
819 }
820 
822  // caller should check whether DDL indicates KillQuery request
823  // i.e., use isKillQuery() before calling this function
824  auto& ddl_payload = extractPayload(*ddl_data_);
825  CHECK(isKillQuery());
826  CHECK(ddl_payload.HasMember("querySession"));
827  const std::string& query_session = ddl_payload["querySession"].GetString();
828  // regex matcher for public_session: start_time{3}-session_id{4} (Example:819-4RDo)
829  boost::regex session_id_regex{R"([0-9]{3}-[a-zA-Z0-9]{4})",
830  boost::regex::extended | boost::regex::icase};
831  if (!boost::regex_match(query_session, session_id_regex)) {
832  throw std::runtime_error(
833  "Please provide the correct session ID of the query that you want to interrupt.");
834  }
835  return query_session;
836 }
837 
838 const std::string DdlCommandExecutor::commandStr() const {
839  return ddl_command_;
840 }
841 
842 namespace {
843 const std::array<std::string, 3> kReservedServerPrefixes{"default", "system", "internal"};
844 
845 bool is_default_server(const std::string& server_name) {
846  return std::any_of(kReservedServerPrefixes.begin(),
848  [&server_name](const std::string& reserved_prefix) {
849  return boost::istarts_with(server_name, reserved_prefix);
850  });
851 }
852 
854  std::string error_message{"Foreign server names cannot start with "};
855  for (size_t i = 0; i < kReservedServerPrefixes.size(); i++) {
856  if (i > 0) {
857  error_message += ", ";
858  }
859  if (i == kReservedServerPrefixes.size() - 1) {
860  error_message += "or ";
861  }
862  error_message += "\"" + kReservedServerPrefixes[i] + "\"";
863  }
864  error_message += ".";
865  throw std::runtime_error{error_message};
866 }
867 } // namespace
868 
870  const DdlCommandData& ddl_data,
871  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
872  : DdlCommand(ddl_data, session_ptr) {
873  if (!g_enable_fsi) {
874  throw std::runtime_error("Unsupported command: CREATE FOREIGN SERVER");
875  }
876  auto& ddl_payload = extractPayload(ddl_data_);
877  CHECK(ddl_payload.HasMember("serverName"));
878  CHECK(ddl_payload["serverName"].IsString());
879  CHECK(ddl_payload.HasMember("dataWrapper"));
880  CHECK(ddl_payload["dataWrapper"].IsString());
881  if (ddl_payload.HasMember("options")) {
882  CHECK(ddl_payload["options"].IsObject());
883  }
884  CHECK(ddl_payload.HasMember("ifNotExists"));
885  CHECK(ddl_payload["ifNotExists"].IsBool());
886 }
887 
889  auto execute_write_lock = legacylockmgr::getExecuteWriteLock();
890 
892 
893  if (read_only_mode) {
894  throw std::runtime_error("CREATE FOREIGN SERVER invalid in read only mode.");
895  }
896 
897  auto& ddl_payload = extractPayload(ddl_data_);
898  std::string server_name = ddl_payload["serverName"].GetString();
899  if (is_default_server(server_name)) {
901  }
902  bool if_not_exists = ddl_payload["ifNotExists"].GetBool();
903  if (session_ptr_->getCatalog().getForeignServer(server_name)) {
904  if (if_not_exists) {
905  return result;
906  } else {
907  throw std::runtime_error{"A foreign server with name \"" + server_name +
908  "\" already exists."};
909  }
910  }
911  // check access privileges
912  if (!session_ptr_->checkDBAccessPrivileges(DBObjectType::ServerDBObjectType,
914  throw std::runtime_error("Server " + std::string(server_name) +
915  " will not be created. User has no create privileges.");
916  }
917 
918  auto& current_user = session_ptr_->get_currentUser();
919  auto foreign_server = std::make_unique<foreign_storage::ForeignServer>();
920  foreign_server->data_wrapper_type = to_upper(ddl_payload["dataWrapper"].GetString());
921  foreign_server->name = server_name;
922  foreign_server->user_id = current_user.userId;
923  if (ddl_payload.HasMember("options")) {
924  foreign_server->populateOptionsMap(ddl_payload["options"]);
925  }
926  foreign_server->validate();
927 
928  auto& catalog = session_ptr_->getCatalog();
929  catalog.createForeignServer(std::move(foreign_server),
930  ddl_payload["ifNotExists"].GetBool());
932  current_user, server_name, ServerDBObjectType, catalog);
933 
934  return result;
935 }
936 
938  const DdlCommandData& ddl_data,
939  std::shared_ptr<const Catalog_Namespace::SessionInfo> session_ptr)
940  : DdlCommand(ddl_data, session_ptr) {
941  auto& ddl_payload = extractPayload(ddl_data_);
942  CHECK(ddl_payload.HasMember("databaseName"));
943  CHECK(ddl_payload["databaseName"].IsString());
944  CHECK(ddl_payload.HasMember("alterType"));
945  CHECK(ddl_payload["alterType"].IsString());
946  if (ddl_payload["alterType"] == "RENAME_DATABASE") {
947  CHECK(ddl_payload.HasMember("newDatabaseName"));
948  CHECK(ddl_payload["newDatabaseName"].IsString());
949  } else if (ddl_payload["alterType"] == "CHANGE_OWNER") {
950  CHECK(ddl_payload.HasMember("newOwner"));
951  CHECK(ddl_payload["newOwner"].IsString());
952  } else {
953  UNREACHABLE(); // not-implemented alterType
954  }
955 }
956 
958  auto execute_write_lock = legacylockmgr::getExecuteWriteLock();
959 
960  if (read_only_mode) {
961  throw std::runtime_error("ALTER DATABASE invalid in read only mode.");
962  }
963  auto& ddl_payload = extractPayload(ddl_data_);
964  std::string databaseName = ddl_payload["databaseName"].GetString();
965 
966  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
968  if (!sys_cat.getMetadataForDB(databaseName, db)) {
969  throw std::runtime_error("Database " + databaseName + " does not exists.");
970  }
971 
972  std::string alter_type = ddl_payload["alterType"].GetString();
973  if (alter_type == "CHANGE_OWNER") {
974  changeOwner();
975  } else if (alter_type == "RENAME_DATABASE") {
976  rename();
977  }
978 
979  return ExecutionResult();
980 }
981 
983  auto& ddl_payload = extractPayload(ddl_data_);
984  std::string database_name = ddl_payload["databaseName"].GetString();
985  std::string new_database_name = ddl_payload["newDatabaseName"].GetString();
986 
988  CHECK(Catalog_Namespace::SysCatalog::instance().getMetadataForDB(database_name, db));
989 
990  if (!session_ptr_->get_currentUser().isSuper &&
991  session_ptr_->get_currentUser().userId != db.dbOwner) {
992  throw std::runtime_error("Only a super user or the owner can rename the database.");
993  }
994 
996  new_database_name);
997 }
998 
1000  auto& ddl_payload = extractPayload(ddl_data_);
1001  std::string database_name = ddl_payload["databaseName"].GetString();
1002  std::string new_owner = ddl_payload["newOwner"].GetString();
1003  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
1004  if (!session_ptr_->get_currentUser().isSuper) {
1005  throw std::runtime_error(
1006  "Only a super user can change a database's owner. "
1007  "Current user is not a super-user. "
1008  "Database with name \"" +
1009  database_name + "\" will not have owner changed.");
1010  }
1011 
1012  sys_cat.changeDatabaseOwner(database_name, new_owner);
1013 }
1014 
1016  const DdlCommandData& ddl_data,
1017  std::shared_ptr<const Catalog_Namespace::SessionInfo> session_ptr)
1018  : DdlCommand(ddl_data, session_ptr) {
1019  if (!g_enable_fsi) {
1020  throw std::runtime_error("Unsupported command: ALTER FOREIGN SERVER");
1021  }
1022  auto& ddl_payload = extractPayload(ddl_data_);
1023  CHECK(ddl_payload.HasMember("serverName"));
1024  CHECK(ddl_payload["serverName"].IsString());
1025  CHECK(ddl_payload.HasMember("alterType"));
1026  CHECK(ddl_payload["alterType"].IsString());
1027  if (ddl_payload["alterType"] == "SET_OPTIONS") {
1028  CHECK(ddl_payload.HasMember("options"));
1029  CHECK(ddl_payload["options"].IsObject());
1030  } else if (ddl_payload["alterType"] == "SET_DATA_WRAPPER") {
1031  CHECK(ddl_payload.HasMember("dataWrapper"));
1032  CHECK(ddl_payload["dataWrapper"].IsString());
1033  } else if (ddl_payload["alterType"] == "RENAME_SERVER") {
1034  CHECK(ddl_payload.HasMember("newServerName"));
1035  CHECK(ddl_payload["newServerName"].IsString());
1036  } else if (ddl_payload["alterType"] == "CHANGE_OWNER") {
1037  CHECK(ddl_payload.HasMember("newOwner"));
1038  CHECK(ddl_payload["newOwner"].IsString());
1039  } else {
1040  UNREACHABLE(); // not-implemented alterType
1041  }
1042 }
1043 
1045  auto execute_write_lock = legacylockmgr::getExecuteWriteLock();
1046 
1047  if (read_only_mode) {
1048  throw std::runtime_error("ALTER FOREIGN SERVER invalid in read only mode.");
1049  }
1050  auto& ddl_payload = extractPayload(ddl_data_);
1051  std::string server_name = ddl_payload["serverName"].GetString();
1052  if (is_default_server(server_name)) {
1053  throw std::runtime_error{"Default servers cannot be altered."};
1054  }
1055  if (!session_ptr_->getCatalog().getForeignServer(server_name)) {
1056  throw std::runtime_error{"Foreign server with name \"" + server_name +
1057  "\" does not exist and can not be altered."};
1058  }
1059  if (!hasAlterServerPrivileges()) {
1060  throw std::runtime_error("Server " + server_name +
1061  " can not be altered. User has no ALTER SERVER privileges.");
1062  }
1063  std::string alter_type = ddl_payload["alterType"].GetString();
1064  if (alter_type == "CHANGE_OWNER") {
1066  } else if (alter_type == "SET_DATA_WRAPPER") {
1068  } else if (alter_type == "SET_OPTIONS") {
1070  } else if (alter_type == "RENAME_SERVER") {
1072  }
1073 
1074  return ExecutionResult();
1075 }
1076 
1078  auto& ddl_payload = extractPayload(ddl_data_);
1079  std::string server_name = ddl_payload["serverName"].GetString();
1080  std::string new_owner = ddl_payload["newOwner"].GetString();
1081  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
1082  if (!session_ptr_->get_currentUser().isSuper) {
1083  throw std::runtime_error(
1084  "Only a super user can change a foreign server's owner. "
1085  "Current user is not a super-user. "
1086  "Foreign server with name \"" +
1087  server_name + "\" will not have owner changed.");
1088  }
1089  Catalog_Namespace::UserMetadata user, original_owner;
1090  if (!sys_cat.getMetadataForUser(new_owner, user)) {
1091  throw std::runtime_error("User with username \"" + new_owner + "\" does not exist. " +
1092  "Foreign server with name \"" + server_name +
1093  "\" can not have owner changed.");
1094  }
1095  auto& cat = session_ptr_->getCatalog();
1096  // get original owner metadata
1097  bool original_owner_exists = sys_cat.getMetadataForUserById(
1098  cat.getForeignServer(server_name)->user_id, original_owner);
1099  // update catalog
1100  cat.changeForeignServerOwner(server_name, user.userId);
1101  try {
1102  // update permissions
1103  DBObject db_object(server_name, DBObjectType::ServerDBObjectType);
1104  sys_cat.changeDBObjectOwnership(
1105  user, original_owner, db_object, cat, original_owner_exists);
1106  } catch (const std::runtime_error& e) {
1107  // update permissions failed, revert catalog update
1108  cat.changeForeignServerOwner(server_name, original_owner.userId);
1109  throw;
1110  }
1111 }
1112 
1114  auto& ddl_payload = extractPayload(ddl_data_);
1115  std::string server_name = ddl_payload["serverName"].GetString();
1116  std::string new_server_name = ddl_payload["newServerName"].GetString();
1117  if (is_default_server(new_server_name)) {
1119  }
1120  auto& cat = session_ptr_->getCatalog();
1121  // check for a conflicting server
1122  if (cat.getForeignServer(new_server_name)) {
1123  throw std::runtime_error("Foreign server with name \"" + server_name +
1124  "\" can not be renamed to \"" + new_server_name + "\"." +
1125  "Foreign server with name \"" + new_server_name +
1126  "\" exists.");
1127  }
1128  // update catalog
1129  cat.renameForeignServer(server_name, new_server_name);
1130  try {
1131  // migrate object privileges
1132  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
1133  sys_cat.renameDBObject(server_name,
1134  new_server_name,
1136  cat.getForeignServer(new_server_name)->id,
1137  cat);
1138  } catch (const std::runtime_error& e) {
1139  // permission migration failed, revert catalog update
1140  cat.renameForeignServer(new_server_name, server_name);
1141  throw;
1142  }
1143 }
1144 
1146  auto& ddl_payload = extractPayload(ddl_data_);
1147  std::string server_name = ddl_payload["serverName"].GetString();
1148  auto& cat = session_ptr_->getCatalog();
1149  // update catalog
1150  const auto foreign_server = cat.getForeignServer(server_name);
1152  opt.populateOptionsMap(foreign_server->getOptionsAsJsonString());
1153  opt.populateOptionsMap(ddl_payload["options"]);
1154  cat.setForeignServerOptions(server_name, opt.getOptionsAsJsonString());
1155 }
1156 
1158  auto& ddl_payload = extractPayload(ddl_data_);
1159  std::string server_name = ddl_payload["serverName"].GetString();
1160  std::string data_wrapper = ddl_payload["dataWrapper"].GetString();
1161  auto& cat = session_ptr_->getCatalog();
1162  // update catalog
1163  cat.setForeignServerDataWrapper(server_name, data_wrapper);
1164 }
1165 
1167  // TODO: implement `GRANT/REVOKE ALTER_SERVER` DDL commands
1168  auto& ddl_payload = extractPayload(ddl_data_);
1169  std::string server_name = ddl_payload["serverName"].GetString();
1170  return session_ptr_->checkDBAccessPrivileges(
1172 }
1173 
1175  const DdlCommandData& ddl_data,
1176  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1177  : DdlCommand(ddl_data, session_ptr) {
1178  if (!g_enable_fsi) {
1179  throw std::runtime_error("Unsupported command: DROP FOREIGN SERVER");
1180  }
1181  auto& ddl_payload = extractPayload(ddl_data_);
1182  CHECK(ddl_payload.HasMember("serverName"));
1183  CHECK(ddl_payload["serverName"].IsString());
1184  CHECK(ddl_payload.HasMember("ifExists"));
1185  CHECK(ddl_payload["ifExists"].IsBool());
1186 }
1187 
1189  auto execute_write_lock = legacylockmgr::getExecuteWriteLock();
1190 
1191  if (read_only_mode) {
1192  throw std::runtime_error("DROP FOREIGN SERVER invalid in read only mode.");
1193  }
1194 
1195  auto& ddl_payload = extractPayload(ddl_data_);
1196  std::string server_name = ddl_payload["serverName"].GetString();
1197  if (is_default_server(server_name)) {
1198  throw std::runtime_error{"Default servers cannot be dropped."};
1199  }
1200  bool if_exists = ddl_payload["ifExists"].GetBool();
1201  if (!session_ptr_->getCatalog().getForeignServer(server_name)) {
1202  if (if_exists) {
1203  return ExecutionResult();
1204  } else {
1205  throw std::runtime_error{"Foreign server with name \"" + server_name +
1206  "\" can not be dropped. Server does not exist."};
1207  }
1208  }
1209  // check access privileges
1210  if (!session_ptr_->checkDBAccessPrivileges(
1212  throw std::runtime_error("Server " + server_name +
1213  " will not be dropped. User has no DROP SERVER privileges.");
1214  }
1216  DBObject(server_name, ServerDBObjectType), session_ptr_->get_catalog_ptr().get());
1217  session_ptr_->getCatalog().dropForeignServer(ddl_payload["serverName"].GetString());
1218 
1219  return ExecutionResult();
1220 }
1221 
1222 SQLTypes JsonColumnSqlType::getSqlType(const rapidjson::Value& data_type) {
1223  CHECK(data_type.IsObject());
1224  CHECK(data_type.HasMember("type"));
1225  CHECK(data_type["type"].IsString());
1226 
1227  std::string type = data_type["type"].GetString();
1228  if (boost::iequals(type, "ARRAY")) {
1229  CHECK(data_type.HasMember("array"));
1230  CHECK(data_type["array"].IsObject());
1231 
1232  const auto& array = data_type["array"].GetObject();
1233  CHECK(array.HasMember("elementType"));
1234  CHECK(array["elementType"].IsString());
1235  type = array["elementType"].GetString();
1236  }
1237  return getSqlType(type);
1238 }
1239 
1240 SQLTypes JsonColumnSqlType::getSqlType(const std::string& type) {
1241  if (boost::iequals(type, "BIGINT")) {
1242  return kBIGINT;
1243  }
1244  if (boost::iequals(type, "BOOLEAN")) {
1245  return kBOOLEAN;
1246  }
1247  if (boost::iequals(type, "DATE")) {
1248  return kDATE;
1249  }
1250  if (boost::iequals(type, "DECIMAL")) {
1251  return kDECIMAL;
1252  }
1253  if (boost::iequals(type, "DOUBLE")) {
1254  return kDOUBLE;
1255  }
1256  if (boost::iequals(type, "FLOAT")) {
1257  return kFLOAT;
1258  }
1259  if (boost::iequals(type, "INTEGER")) {
1260  return kINT;
1261  }
1262  if (boost::iequals(type, "LINESTRING")) {
1263  return kLINESTRING;
1264  }
1265  if (boost::iequals(type, "MULTILINESTRING")) {
1266  return kMULTILINESTRING;
1267  }
1268  if (boost::iequals(type, "MULTIPOLYGON")) {
1269  return kMULTIPOLYGON;
1270  }
1271  if (boost::iequals(type, "POINT")) {
1272  return kPOINT;
1273  }
1274  if (boost::iequals(type, "MULTIPOINT")) {
1275  return kMULTIPOINT;
1276  }
1277  if (boost::iequals(type, "POLYGON")) {
1278  return kPOLYGON;
1279  }
1280  if (boost::iequals(type, "SMALLINT")) {
1281  return kSMALLINT;
1282  }
1283  if (boost::iequals(type, "TEXT")) {
1284  return kTEXT;
1285  }
1286  if (boost::iequals(type, "TIME")) {
1287  return kTIME;
1288  }
1289  if (boost::iequals(type, "TIMESTAMP")) {
1290  return kTIMESTAMP;
1291  }
1292  if (boost::iequals(type, "TINYINT")) {
1293  return kTINYINT;
1294  }
1295 
1296  throw std::runtime_error{"Unsupported type \"" + type + "\" specified."};
1297 }
1298 
1299 int JsonColumnSqlType::getParam1(const rapidjson::Value& data_type) {
1300  int param1 = -1;
1301  CHECK(data_type.IsObject());
1302  if (data_type.HasMember("precision") && !data_type["precision"].IsNull()) {
1303  CHECK(data_type["precision"].IsInt());
1304  param1 = data_type["precision"].GetInt();
1305  } else if (auto type = getSqlType(data_type); IS_GEO(type)) {
1306  param1 = static_cast<int>(kGEOMETRY);
1307  }
1308  return param1;
1309 }
1310 
1311 int JsonColumnSqlType::getParam2(const rapidjson::Value& data_type) {
1312  int param2 = 0;
1313  CHECK(data_type.IsObject());
1314  if (data_type.HasMember("scale") && !data_type["scale"].IsNull()) {
1315  CHECK(data_type["scale"].IsInt());
1316  param2 = data_type["scale"].GetInt();
1317  } else if (auto type = getSqlType(data_type); IS_GEO(type) &&
1318  data_type.HasMember("coordinateSystem") &&
1319  !data_type["coordinateSystem"].IsNull()) {
1320  CHECK(data_type["coordinateSystem"].IsInt());
1321  param2 = data_type["coordinateSystem"].GetInt();
1322  }
1323  return param2;
1324 }
1325 
1326 bool JsonColumnSqlType::isArray(const rapidjson::Value& data_type) {
1327  CHECK(data_type.IsObject());
1328  CHECK(data_type.HasMember("type"));
1329  CHECK(data_type["type"].IsString());
1330  return boost::iequals(data_type["type"].GetString(), "ARRAY");
1331 }
1332 
1333 int JsonColumnSqlType::getArraySize(const rapidjson::Value& data_type) {
1334  int size = -1;
1335  if (isArray(data_type)) {
1336  CHECK(data_type.HasMember("array"));
1337  CHECK(data_type["array"].IsObject());
1338 
1339  const auto& array = data_type["array"].GetObject();
1340  if (array.HasMember("size") && !array["size"].IsNull()) {
1341  CHECK(array["size"].IsInt());
1342  size = array["size"].GetInt();
1343  }
1344  }
1345  return size;
1346 }
1347 
1348 std::string* JsonColumnEncoding::getEncodingName(const rapidjson::Value& data_type) {
1349  CHECK(data_type.IsObject());
1350  CHECK(data_type.HasMember("encoding"));
1351  CHECK(data_type["encoding"].IsObject());
1352 
1353  const auto& encoding = data_type["encoding"].GetObject();
1354  CHECK(encoding.HasMember("type"));
1355  CHECK(encoding["type"].IsString());
1356  return new std::string(encoding["type"].GetString());
1357 }
1358 
1359 int JsonColumnEncoding::getEncodingParam(const rapidjson::Value& data_type) {
1360  CHECK(data_type.IsObject());
1361  CHECK(data_type.HasMember("encoding"));
1362  CHECK(data_type["encoding"].IsObject());
1363 
1364  int encoding_size = 0;
1365  const auto& encoding = data_type["encoding"].GetObject();
1366  if (encoding.HasMember("size") && !encoding["size"].IsNull()) {
1367  CHECK(encoding["size"].IsInt());
1368  encoding_size = encoding["size"].GetInt();
1369  }
1370  return encoding_size;
1371 }
1372 
1374  const DdlCommandData& ddl_data,
1375  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1376  : DdlCommand(ddl_data, session_ptr) {
1377  if (!g_enable_fsi) {
1378  throw std::runtime_error("Unsupported command: CREATE FOREIGN TABLE");
1379  }
1380  auto& ddl_payload = extractPayload(ddl_data);
1381  CHECK(ddl_payload.HasMember("serverName"));
1382  CHECK(ddl_payload["serverName"].IsString());
1383  CHECK(ddl_payload.HasMember("tableName"));
1384  CHECK(ddl_payload["tableName"].IsString());
1385  CHECK(ddl_payload.HasMember("ifNotExists"));
1386  CHECK(ddl_payload["ifNotExists"].IsBool());
1387  CHECK(ddl_payload.HasMember("columns"));
1388  CHECK(ddl_payload["columns"].IsArray());
1389 }
1390 
1392  auto execute_write_lock = legacylockmgr::getExecuteWriteLock();
1393 
1394  auto& catalog = session_ptr_->getCatalog();
1395  auto& ddl_payload = extractPayload(ddl_data_);
1396 
1397  if (read_only_mode) {
1398  throw std::runtime_error("CREATE FOREIGN TABLE invalid in read only mode.");
1399  }
1400 
1401  const std::string& table_name = ddl_payload["tableName"].GetString();
1402  if (!session_ptr_->checkDBAccessPrivileges(DBObjectType::TableDBObjectType,
1404  throw std::runtime_error(
1405  "Foreign table \"" + table_name +
1406  "\" will not be created. User has no CREATE TABLE privileges.");
1407  }
1408 
1409  bool if_not_exists = ddl_payload["ifNotExists"].GetBool();
1410  if (!catalog.validateNonExistentTableOrView(table_name, if_not_exists)) {
1411  return ExecutionResult();
1412  }
1413 
1414  foreign_storage::ForeignTable foreign_table{};
1415  std::list<ColumnDescriptor> columns{};
1416  setColumnDetails(columns);
1417  setTableDetails(table_name, foreign_table, columns);
1418  catalog.createTable(foreign_table, columns, {}, true);
1419 
1420  // TODO (max): It's transactionally unsafe, should be fixed: we may create object w/o
1421  // privileges
1423  session_ptr_->get_currentUser(),
1424  foreign_table.tableName,
1426  catalog);
1427 
1428  return ExecutionResult();
1429 }
1430 
1432  const std::string& table_name,
1433  TableDescriptor& td,
1434  const std::list<ColumnDescriptor>& columns) {
1435  ddl_utils::set_default_table_attributes(table_name, td, columns.size());
1436  td.userId = session_ptr_->get_currentUser().userId;
1438  td.hasDeletedCol = false;
1439  td.keyMetainfo = "[]";
1440  td.fragments = "";
1441  td.partitions = "";
1442 
1443  auto& ddl_payload = extractPayload(ddl_data_);
1444  auto& foreign_table = dynamic_cast<foreign_storage::ForeignTable&>(td);
1445  const std::string server_name = ddl_payload["serverName"].GetString();
1446  foreign_table.foreign_server = session_ptr_->getCatalog().getForeignServer(server_name);
1447  if (!foreign_table.foreign_server) {
1448  throw std::runtime_error{
1449  "Foreign Table with name \"" + table_name +
1450  "\" can not be created. Associated foreign server with name \"" + server_name +
1451  "\" does not exist."};
1452  }
1453 
1454  // check server usage privileges
1455  if (!is_default_server(server_name) &&
1456  !session_ptr_->checkDBAccessPrivileges(DBObjectType::ServerDBObjectType,
1458  server_name)) {
1459  throw std::runtime_error(
1460  "Current user does not have USAGE privilege on foreign server: " + server_name);
1461  }
1462 
1463  if (ddl_payload.HasMember("options") && !ddl_payload["options"].IsNull()) {
1464  CHECK(ddl_payload["options"].IsObject());
1465  foreign_table.initializeOptions(ddl_payload["options"]);
1466  } else {
1467  // Initialize options even if none were provided to verify a legal state.
1468  // This is necessary because some options (like "file_path") are optional only if a
1469  // paired option ("base_path") exists in the server.
1470  foreign_table.initializeOptions();
1471  }
1472  foreign_table.validateSchema(columns);
1473 
1474  if (const auto it = foreign_table.options.find("FRAGMENT_SIZE");
1475  it != foreign_table.options.end()) {
1476  foreign_table.maxFragRows = Parser::validate_and_get_fragment_size(it->second);
1477  }
1478 
1479  if (const auto it = foreign_table.options.find("MAX_CHUNK_SIZE");
1480  it != foreign_table.options.end()) {
1481  foreign_table.maxChunkSize = std::stol(it->second);
1482  }
1483 
1484  if (const auto it = foreign_table.options.find("PARTITIONS");
1485  it != foreign_table.options.end()) {
1486  foreign_table.partitions = it->second;
1487  }
1488 }
1489 
1490 void CreateForeignTableCommand::setColumnDetails(std::list<ColumnDescriptor>& columns) {
1491  auto& ddl_payload = extractPayload(ddl_data_);
1492  std::unordered_set<std::string> column_names{};
1493  for (auto& column_def : ddl_payload["columns"].GetArray()) {
1494  CHECK(column_def.IsObject());
1495  CHECK(column_def.HasMember("name"));
1496  CHECK(column_def["name"].IsString());
1497  const std::string& column_name = column_def["name"].GetString();
1498 
1499  CHECK(column_def.HasMember("dataType"));
1500  CHECK(column_def["dataType"].IsObject());
1501 
1502  JsonColumnSqlType sql_type{column_def["dataType"]};
1503  const auto& data_type = column_def["dataType"].GetObject();
1504  CHECK(data_type.HasMember("notNull"));
1505  CHECK(data_type["notNull"].IsBool());
1506 
1507  std::unique_ptr<JsonColumnEncoding> encoding;
1508  if (data_type.HasMember("encoding") && !data_type["encoding"].IsNull()) {
1509  CHECK(data_type["encoding"].IsObject());
1510  encoding = std::make_unique<JsonColumnEncoding>(column_def["dataType"]);
1511  }
1512 
1513  ColumnDescriptor cd;
1514  ddl_utils::validate_non_duplicate_column(column_name, column_names);
1517  cd,
1518  &sql_type,
1519  data_type["notNull"].GetBool(),
1520  encoding.get(),
1521  nullptr);
1522  columns.emplace_back(cd);
1523  }
1524 }
1525 
1527  const DdlCommandData& ddl_data,
1528  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1529  : DdlCommand(ddl_data, session_ptr) {
1530  if (!g_enable_fsi) {
1531  throw std::runtime_error("Unsupported command: DROP FOREIGN TABLE");
1532  }
1533  auto& ddl_payload = extractPayload(ddl_data_);
1534  CHECK(ddl_payload.HasMember("tableName"));
1535  CHECK(ddl_payload["tableName"].IsString());
1536  CHECK(ddl_payload.HasMember("ifExists"));
1537  CHECK(ddl_payload["ifExists"].IsBool());
1538 }
1539 
1541  auto execute_write_lock = legacylockmgr::getExecuteWriteLock();
1542 
1543  auto& catalog = session_ptr_->getCatalog();
1544  auto& ddl_payload = extractPayload(ddl_data_);
1545 
1546  if (read_only_mode) {
1547  throw std::runtime_error("DROP FOREIGN TABLE invalid in read only mode.");
1548  }
1549  const std::string& table_name = ddl_payload["tableName"].GetString();
1550  const TableDescriptor* td{nullptr};
1551  std::unique_ptr<lockmgr::TableSchemaLockContainer<lockmgr::WriteLock>> td_with_lock;
1552 
1553  try {
1554  td_with_lock =
1555  std::make_unique<lockmgr::TableSchemaLockContainer<lockmgr::WriteLock>>(
1557  catalog, table_name, false));
1558  CHECK(td_with_lock);
1559  td = (*td_with_lock)();
1560  } catch (const std::runtime_error& e) {
1561  // TODO(Misiu): This should not just swallow any exception, it should only catch
1562  // exceptions that stem from the table not existing.
1563  if (ddl_payload["ifExists"].GetBool()) {
1564  return ExecutionResult();
1565  } else {
1566  throw e;
1567  }
1568  }
1569 
1570  CHECK(td);
1571 
1572  if (!session_ptr_->checkDBAccessPrivileges(
1574  throw std::runtime_error(
1575  "Foreign table \"" + table_name +
1576  "\" will not be dropped. User has no DROP TABLE privileges.");
1577  }
1578 
1580  auto table_data_write_lock =
1582  Executor::clearExternalCaches(false, td, catalog.getDatabaseId());
1583  catalog.dropTable(td);
1584 
1585  return ExecutionResult();
1586 }
1587 
1589  const DdlCommandData& ddl_data,
1590  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1591  : DdlCommand(ddl_data, session_ptr) {}
1592 
1594  auto execute_read_lock = legacylockmgr::getExecuteReadLock();
1595 
1596  // Get all table names in the same way as OmniSql \t command
1597 
1598  // valid in read_only_mode
1599 
1600  // label_infos -> column labels
1601  std::vector<std::string> labels{"table_name"};
1602  std::vector<TargetMetaInfo> label_infos;
1603  for (const auto& label : labels) {
1604  label_infos.emplace_back(label, SQLTypeInfo(kTEXT, true));
1605  }
1606 
1607  // Get all table names
1608  auto cat_ptr = session_ptr_->get_catalog_ptr();
1609  auto cur_user = session_ptr_->get_currentUser();
1610  auto table_names = cat_ptr->getTableNamesForUser(cur_user, GET_PHYSICAL_TABLES);
1611 
1612  // logical_values -> table data
1613  std::vector<RelLogicalValues::RowValues> logical_values;
1614  for (auto table_name : table_names) {
1615  logical_values.emplace_back(RelLogicalValues::RowValues{});
1616  logical_values.back().emplace_back(genLiteralStr(table_name));
1617  }
1618 
1619  // Create ResultSet
1620  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1621  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1622 
1623  return ExecutionResult(rSet, label_infos);
1624 }
1625 
1627  const DdlCommandData& ddl_data,
1628  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1629  : DdlCommand(ddl_data, session_ptr) {
1630  auto& ddl_payload = extractPayload(ddl_data_);
1631  if (ddl_payload.HasMember("tableNames")) {
1632  CHECK(ddl_payload["tableNames"].IsArray());
1633  for (const auto& table_name : ddl_payload["tableNames"].GetArray()) {
1634  CHECK(table_name.IsString());
1635  }
1636  }
1637 }
1638 
1640  auto execute_read_lock = legacylockmgr::getExecuteReadLock();
1641 
1642  const auto catalog = session_ptr_->get_catalog_ptr();
1643  std::vector<std::string> filtered_table_names = getFilteredTableNames();
1644 
1645  // valid in read_only_mode
1646 
1647  std::vector<TargetMetaInfo> label_infos;
1648  set_headers_with_type(label_infos,
1649  {// { label, type, notNull }
1650  {"table_id", kBIGINT, true},
1651  {"table_name", kTEXT, true},
1652  {"column_count", kBIGINT, true},
1653  {"is_sharded_table", kBOOLEAN, true},
1654  {"shard_count", kBIGINT, true},
1655  {"max_rows", kBIGINT, true},
1656  {"fragment_size", kBIGINT, true},
1657  {"max_rollback_epochs", kBIGINT, true},
1658  {"min_epoch", kBIGINT, true},
1659  {"max_epoch", kBIGINT, true},
1660  {"min_epoch_floor", kBIGINT, true},
1661  {"max_epoch_floor", kBIGINT, true},
1662  {"metadata_file_count", kBIGINT, true},
1663  {"total_metadata_file_size", kBIGINT, true},
1664  {"total_metadata_page_count", kBIGINT, true},
1665  {"total_free_metadata_page_count", kBIGINT, false},
1666  {"data_file_count", kBIGINT, true},
1667  {"total_data_file_size", kBIGINT, true},
1668  {"total_data_page_count", kBIGINT, true},
1669  {"total_free_data_page_count", kBIGINT, false}});
1670 
1671  std::vector<RelLogicalValues::RowValues> logical_values;
1672  exec_for_tables_which_exist(filtered_table_names,
1673  catalog.get(),
1674  [&logical_values, &catalog](const TableDescriptor* td,
1675  const std::string& table_name) {
1676  auto agg_storage_stats =
1677  get_agg_storage_stats(td, catalog.get());
1678  add_table_details(logical_values, td, agg_storage_stats);
1679  });
1680 
1681  // Create ResultSet
1682  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1683  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1684 
1685  return ExecutionResult(rSet, label_infos);
1686 }
1687 
1689  const auto catalog = session_ptr_->get_catalog_ptr();
1690  auto& ddl_payload = extractPayload(ddl_data_);
1691  auto all_table_names =
1692  catalog->getTableNamesForUser(session_ptr_->get_currentUser(), GET_PHYSICAL_TABLES);
1693  std::transform(all_table_names.begin(),
1694  all_table_names.end(),
1695  all_table_names.begin(),
1696  [](const std::string& s) { return to_upper(s); });
1697  std::vector<std::string> filtered_table_names;
1698  if (ddl_payload.HasMember("tableNames")) {
1699  std::set<std::string> all_table_names_set(all_table_names.begin(),
1700  all_table_names.end());
1701  for (const auto& table_name_json : ddl_payload["tableNames"].GetArray()) {
1702  std::string table_name = table_name_json.GetString();
1703  if (all_table_names_set.find(to_upper(table_name)) == all_table_names_set.end()) {
1704  throw std::runtime_error{"Unable to show table details for table: " + table_name +
1705  ". Table does not exist."};
1706  }
1707  auto [td, td_with_lock] =
1708  get_table_descriptor_with_lock<lockmgr::ReadLock>(*catalog, table_name, false);
1709  if (td->isForeignTable()) {
1710  throw std::runtime_error{
1711  "SHOW TABLE DETAILS is not supported for foreign tables. Table name: " +
1712  table_name + "."};
1713  }
1714  if (td->isTemporaryTable()) {
1715  throw std::runtime_error{
1716  "SHOW TABLE DETAILS is not supported for temporary tables. Table name: " +
1717  table_name + "."};
1718  }
1719  filtered_table_names.emplace_back(table_name);
1720  }
1721  } else {
1722  exec_for_tables_which_exist(all_table_names,
1723  catalog.get(),
1724  [&filtered_table_names](const TableDescriptor* td,
1725  const std::string& table_name) {
1726  if (td->isForeignTable() || td->isTemporaryTable()) {
1727  return;
1728  }
1729  filtered_table_names.emplace_back(table_name);
1730  });
1731  }
1732  return filtered_table_names;
1733 }
1734 
1736  const DdlCommandData& ddl_data,
1737  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1738  : DdlCommand(ddl_data, session_ptr) {}
1739 
1741  auto execute_read_lock = legacylockmgr::getExecuteReadLock();
1742 
1743  // valid in read_only_mode
1744 
1745  auto& ddl_payload = extractPayload(ddl_data_);
1746  CHECK(ddl_payload.HasMember("tableName"));
1747  CHECK(ddl_payload["tableName"].IsString());
1748  const std::string& table_name = ddl_payload["tableName"].GetString();
1749 
1750  auto& catalog = session_ptr_->getCatalog();
1751  auto table_read_lock =
1753 
1754  const TableDescriptor* td = catalog.getMetadataForTable(table_name, false);
1755  if (!td) {
1756  throw std::runtime_error("Table/View " + table_name + " does not exist.");
1757  }
1758 
1760  dbObject.loadKey(catalog);
1761  std::vector<DBObject> privObjects = {dbObject};
1762 
1763  if (!Catalog_Namespace::SysCatalog::instance().hasAnyPrivileges(
1764  session_ptr_->get_currentUser(), privObjects)) {
1765  throw std::runtime_error("Table/View " + table_name + " does not exist.");
1766  }
1767  if (td->isView && !session_ptr_->get_currentUser().isSuper) {
1768  auto query_state = query_state::QueryState::create(session_ptr_, td->viewSQL);
1769  auto query_state_proxy = query_state->createQueryStateProxy();
1770  auto calcite_mgr = catalog.getCalciteMgr();
1771  const auto calciteQueryParsingOption =
1772  calcite_mgr->getCalciteQueryParsingOption(true, false, false, false);
1773  const auto calciteOptimizationOption = calcite_mgr->getCalciteOptimizationOption(
1774  false,
1776  {},
1778  auto result = calcite_mgr->process(query_state_proxy,
1779  td->viewSQL,
1780  calciteQueryParsingOption,
1781  calciteOptimizationOption);
1782  try {
1783  calcite_mgr->checkAccessedObjectsPrivileges(query_state_proxy, result);
1784  } catch (const std::runtime_error&) {
1785  throw std::runtime_error("Not enough privileges to show the view SQL");
1786  }
1787  }
1788  // Construct
1789  auto create_table_sql = catalog.dumpCreateTable(td);
1792  return result;
1793 }
1794 
1796  const DdlCommandData& ddl_data,
1797  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1798  : DdlCommand(ddl_data, session_ptr) {}
1799 
1801  auto execute_read_lock = legacylockmgr::getExecuteReadLock();
1802 
1803  // valid in read_only_mode
1804 
1805  // label_infos -> column labels
1806  std::vector<std::string> labels{"Database", "Owner"};
1807  std::vector<TargetMetaInfo> label_infos;
1808  for (const auto& label : labels) {
1809  label_infos.emplace_back(label, SQLTypeInfo(kTEXT, true));
1810  }
1811 
1812  // Get all table names
1813  auto cur_user = session_ptr_->get_currentUser();
1814  const Catalog_Namespace::DBSummaryList db_summaries =
1816 
1817  // logical_values -> table data
1818  std::vector<RelLogicalValues::RowValues> logical_values;
1819  for (const auto& db_summary : db_summaries) {
1820  logical_values.emplace_back(RelLogicalValues::RowValues{});
1821  logical_values.back().emplace_back(genLiteralStr(db_summary.dbName));
1822  logical_values.back().emplace_back(genLiteralStr(db_summary.dbOwnerName));
1823  }
1824 
1825  // Create ResultSet
1826  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1827  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1828 
1829  return ExecutionResult(rSet, label_infos);
1830 }
1831 
1833  const DdlCommandData& ddl_data,
1834  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1835  : DdlCommand(ddl_data, session_ptr) {}
1836 
1838  auto execute_read_lock = legacylockmgr::getExecuteReadLock();
1839 
1840  // Get all row-wise functions
1841  auto& ddl_payload = extractPayload(ddl_data_);
1842  std::vector<TargetMetaInfo> label_infos;
1843  std::vector<RelLogicalValues::RowValues> logical_values;
1844 
1845  if (ddl_payload.HasMember("ScalarFnNames")) {
1846  // label_infos -> column labels
1847  label_infos.emplace_back("name", SQLTypeInfo(kTEXT, true));
1848  label_infos.emplace_back("signature", SQLTypeInfo(kTEXT, true));
1849  label_infos.emplace_back("CPU", SQLTypeInfo(kBOOLEAN, true));
1850  label_infos.emplace_back("GPU", SQLTypeInfo(kBOOLEAN, true));
1851  label_infos.emplace_back("Runtime", SQLTypeInfo(kBOOLEAN, true));
1852  for (const auto& udf_name_json : ddl_payload["ScalarFnNames"].GetArray()) {
1853  std::string udf_name = udf_name_json.GetString();
1854  std::vector<ExtensionFunction> ext_funcs =
1856 
1857  for (ExtensionFunction& fn : ext_funcs) {
1858  logical_values.emplace_back(RelLogicalValues::RowValues{});
1859  // Name
1860  logical_values.back().emplace_back(genLiteralStr(udf_name));
1861  // Signature
1862  logical_values.back().emplace_back(genLiteralStr(fn.toSignature()));
1863  // CPU?
1864  logical_values.back().emplace_back(genLiteralBoolean(fn.isCPU()));
1865  // GPU?
1866  logical_values.back().emplace_back(genLiteralBoolean(fn.isGPU()));
1867  // Runtime?
1868  logical_values.back().emplace_back(genLiteralBoolean(fn.isRuntime()));
1869  }
1870  }
1871 
1872  } else {
1873  // label_infos -> column labels
1874  for (const auto& label : {"Scalar UDF"}) {
1875  label_infos.emplace_back(label, SQLTypeInfo(kTEXT, true));
1876  }
1877 
1878  // logical_values -> table data
1879  for (auto name : ExtensionFunctionsWhitelist::get_udfs_name(/* is_runtime */ false)) {
1880  logical_values.emplace_back(RelLogicalValues::RowValues{});
1881  logical_values.back().emplace_back(genLiteralStr(name));
1882  }
1883  }
1884 
1885  // Create ResultSet
1886  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1887  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1888 
1889  return ExecutionResult(rSet, label_infos);
1890 }
1891 
1893  const DdlCommandData& ddl_data,
1894  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1895  : DdlCommand(ddl_data, session_ptr) {}
1896 
1898  auto execute_read_lock = legacylockmgr::getExecuteReadLock();
1899 
1900  // Get all runtime row-wise functions
1901  std::vector<TargetMetaInfo> label_infos;
1902  std::vector<RelLogicalValues::RowValues> logical_values;
1903 
1904  // label_infos -> column labels
1905  for (const auto& label : {"Runtime Scalar UDF"}) {
1906  label_infos.emplace_back(label, SQLTypeInfo(kTEXT, true));
1907  }
1908 
1909  // logical_values -> table data
1910  for (auto name : ExtensionFunctionsWhitelist::get_udfs_name(/* is_runtime */ true)) {
1911  logical_values.emplace_back(RelLogicalValues::RowValues{});
1912  logical_values.back().emplace_back(genLiteralStr(name));
1913  }
1914 
1915  // Create ResultSet
1916  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1917  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
1918 
1919  return ExecutionResult(rSet, label_infos);
1920 }
1921 
1923  const DdlCommandData& ddl_data,
1924  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1925  : DdlCommand(ddl_data, session_ptr) {}
1926 
1928  auto execute_read_lock = legacylockmgr::getExecuteReadLock();
1929 
1930  // valid in read_only_mode
1931 
1932  // Get all table functions
1933  auto& ddl_payload = extractPayload(ddl_data_);
1934  std::vector<TargetMetaInfo> label_infos;
1935  std::vector<RelLogicalValues::RowValues> logical_values;
1936 
1937  if (ddl_payload.HasMember("tfNames")) {
1938  // label_infos -> column labels
1939  label_infos.emplace_back("name", SQLTypeInfo(kTEXT, true));
1940  label_infos.emplace_back("signature", SQLTypeInfo(kTEXT, true));
1941  label_infos.emplace_back("input_names", SQLTypeInfo(kTEXT, true));
1942  label_infos.emplace_back("input_types", SQLTypeInfo(kTEXT, true));
1943  label_infos.emplace_back("input_arg_defaults", SQLTypeInfo(kTEXT, true));
1944  label_infos.emplace_back("output_names", SQLTypeInfo(kTEXT, true));
1945  label_infos.emplace_back("output_types", SQLTypeInfo(kTEXT, true));
1946  label_infos.emplace_back("CPU", SQLTypeInfo(kBOOLEAN, true));
1947  label_infos.emplace_back("GPU", SQLTypeInfo(kBOOLEAN, true));
1948  label_infos.emplace_back("Runtime", SQLTypeInfo(kBOOLEAN, true));
1949  label_infos.emplace_back("filter_table_transpose", SQLTypeInfo(kBOOLEAN, true));
1950  // logical_values -> table data
1951  for (const auto& tf_name_json : ddl_payload["tfNames"].GetArray()) {
1952  std::string tf_name = tf_name_json.GetString();
1954  for (table_functions::TableFunction& tf : tfs) {
1955  logical_values.emplace_back(RelLogicalValues::RowValues{});
1956  // Name
1957  logical_values.back().emplace_back(genLiteralStr(tf.getName(true, false)));
1958  // Signature
1959  logical_values.back().emplace_back(genLiteralStr(
1960  tf.getSignature(/*include_name*/ false, /*include_output*/ true)));
1961  // Input argument names
1962  logical_values.back().emplace_back(
1963  genLiteralStr(tf.getArgNames(/* use_input_args */ true)));
1964  // Input argument types
1965  logical_values.back().emplace_back(
1966  genLiteralStr(tf.getArgTypes(/* use_input_args */ true)));
1967  // Input argument default values
1968  logical_values.back().emplace_back(genLiteralStr(tf.getInputArgsDefaultValues()));
1969  // Output argument names
1970  logical_values.back().emplace_back(
1971  genLiteralStr(tf.getArgNames(/* use_input_args */ false)));
1972  // Output argument types
1973  logical_values.back().emplace_back(
1974  genLiteralStr(tf.getArgTypes(/* use_input_args */ false)));
1975  // CPU?
1976  logical_values.back().emplace_back(genLiteralBoolean(tf.isCPU()));
1977  // GPU?
1978  logical_values.back().emplace_back(genLiteralBoolean(tf.isGPU()));
1979  // Runtime?
1980  logical_values.back().emplace_back(genLiteralBoolean(tf.isRuntime()));
1981  // Implements filter_table_transpose?
1982  logical_values.back().emplace_back(genLiteralBoolean(
1983  !tf.getFunctionAnnotation("filter_table_function_transpose", "").empty()));
1984  }
1985  }
1986  } else {
1987  // label_infos -> column labels
1988  for (const auto& label : {"Table UDF"}) {
1989  label_infos.emplace_back(label, SQLTypeInfo(kTEXT, true));
1990  }
1991 
1992  // logical_values -> table data
1993  std::unordered_set<std::string> unique_names;
1995  /* is_runtime */ false)) {
1996  std::string name = tf.getName(true, true);
1997  if (unique_names.find(name) == unique_names.end()) {
1998  unique_names.emplace(name);
1999  logical_values.emplace_back(RelLogicalValues::RowValues{});
2000  logical_values.back().emplace_back(genLiteralStr(name));
2001  }
2002  }
2003  }
2004 
2005  // Create ResultSet
2006  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
2007  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
2008 
2009  return ExecutionResult(rSet, label_infos);
2010 }
2011 
2013  const DdlCommandData& ddl_data,
2014  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
2015  : DdlCommand(ddl_data, session_ptr) {}
2016 
2018  auto execute_read_lock = legacylockmgr::getExecuteReadLock();
2019 
2020  // valid in read_only_mode
2021 
2022  // Get all runtime table functions
2023  std::vector<TargetMetaInfo> label_infos;
2024  std::vector<RelLogicalValues::RowValues> logical_values;
2025 
2026  // label_infos -> column labels
2027  for (const auto& label : {"Runtime Table UDF"}) {
2028  label_infos.emplace_back(label, SQLTypeInfo(kTEXT, true));
2029  }
2030 
2031  // logical_values -> table data
2032  std::unordered_set<std::string> unique_names;
2033  for (auto tf :
2035  std::string name = tf.getName(true, true);
2036  if (unique_names.find(name) == unique_names.end()) {
2037  unique_names.emplace(name);
2038  logical_values.emplace_back(RelLogicalValues::RowValues{});
2039  logical_values.back().emplace_back(genLiteralStr(name));
2040  }
2041  }
2042 
2043  // Create ResultSet
2044  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
2045  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
2046 
2047  return ExecutionResult(rSet, label_infos);
2048 }
2049 
2051  const DdlCommandData& ddl_data,
2052  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
2053  : DdlCommand(ddl_data, session_ptr) {
2054  if (!g_enable_ml_functions) {
2055  throw std::runtime_error("Cannot show models. ML functions are disabled.");
2056  }
2058  // Check if user is super user
2059  const auto& current_user = session_ptr->get_currentUser();
2060  if (!current_user.isSuper) {
2061  throw std::runtime_error(
2062  "Cannot show models. Showing model information to non-superusers is disabled.");
2063  }
2064  }
2065 }
2066 
2068  auto execute_read_lock = legacylockmgr::getExecuteReadLock();
2069 
2070  // label_infos -> column labels
2071  std::vector<std::string> labels{"model_name"};
2072  std::vector<TargetMetaInfo> label_infos;
2073  for (const auto& label : labels) {
2074  label_infos.emplace_back(label, SQLTypeInfo(kTEXT, true));
2075  }
2076 
2077  // Get all model names
2078  const auto model_names = g_ml_models.getModelNames();
2079 
2080  // logical_values -> table data
2081  std::vector<RelLogicalValues::RowValues> logical_values;
2082  for (auto model_name : model_names) {
2083  logical_values.emplace_back(RelLogicalValues::RowValues{});
2084  logical_values.back().emplace_back(genLiteralStr(model_name));
2085  }
2086 
2087  // Create ResultSet
2088  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
2089  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
2090 
2091  return ExecutionResult(rSet, label_infos);
2092 }
2093 
2095  const DdlCommandData& ddl_data,
2096  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
2097  : DdlCommand(ddl_data, session_ptr) {
2098  if (!g_enable_ml_functions) {
2099  throw std::runtime_error("Cannot show model details. ML functions are disabled.");
2100  }
2102  // Check if user is super user
2103  const auto& current_user = session_ptr->get_currentUser();
2104  if (!current_user.isSuper) {
2105  throw std::runtime_error(
2106  "Cannot show model details. Showing model information to non-superusers is "
2107  "disabled.");
2108  }
2109  }
2110 }
2111 
2113  auto execute_read_lock = legacylockmgr::getExecuteReadLock();
2114 
2115  std::vector<TargetMetaInfo> label_infos;
2116  label_infos.emplace_back("model_name", SQLTypeInfo(kTEXT, true));
2117  label_infos.emplace_back("model_type", SQLTypeInfo(kTEXT, true));
2118  label_infos.emplace_back("predicted", SQLTypeInfo(kTEXT, true));
2119  label_infos.emplace_back("features", SQLTypeInfo(kTEXT, true));
2120  label_infos.emplace_back("training_query", SQLTypeInfo(kTEXT, true));
2121  label_infos.emplace_back("num_logical_features", SQLTypeInfo(kBIGINT, true));
2122  label_infos.emplace_back("num_physical_features", SQLTypeInfo(kBIGINT, true));
2123  label_infos.emplace_back("num_categorical_features", SQLTypeInfo(kBIGINT, true));
2124  label_infos.emplace_back("num_numeric_features", SQLTypeInfo(kBIGINT, true));
2125  label_infos.emplace_back("train_fraction", SQLTypeInfo(kDOUBLE, true));
2126  label_infos.emplace_back("eval_fraction", SQLTypeInfo(kDOUBLE, true));
2127 
2128  // Get all model names
2129  const auto model_names = getFilteredModelNames();
2130 
2131  // logical_values -> table data
2132  std::vector<RelLogicalValues::RowValues> logical_values;
2133  for (auto& model_name : model_names) {
2134  logical_values.emplace_back(RelLogicalValues::RowValues{});
2135  logical_values.back().emplace_back(genLiteralStr(model_name));
2136  const auto model_metadata = g_ml_models.getModelMetadata(model_name);
2137  logical_values.back().emplace_back(genLiteralStr(model_metadata.getModelTypeStr()));
2138  logical_values.back().emplace_back(genLiteralStr(model_metadata.getPredicted()));
2139  const auto& features = model_metadata.getFeatures();
2140  std::ostringstream features_oss;
2141  bool is_first_feature = true;
2142  for (auto& feature : features) {
2143  if (!is_first_feature) {
2144  features_oss << ", ";
2145  } else {
2146  is_first_feature = false;
2147  }
2148  features_oss << feature;
2149  }
2150  auto features_str = features_oss.str();
2151  logical_values.back().emplace_back(genLiteralStr(features_str));
2152  logical_values.back().emplace_back(genLiteralStr(model_metadata.getTrainingQuery()));
2153  logical_values.back().emplace_back(
2154  genLiteralBigInt(model_metadata.getNumLogicalFeatures()));
2155  logical_values.back().emplace_back(genLiteralBigInt(model_metadata.getNumFeatures()));
2156  logical_values.back().emplace_back(
2157  genLiteralBigInt(model_metadata.getNumCategoricalFeatures()));
2158  logical_values.back().emplace_back(
2159  genLiteralBigInt(model_metadata.getNumLogicalFeatures() -
2160  model_metadata.getNumCategoricalFeatures()));
2161  logical_values.back().emplace_back(
2162  genLiteralDouble(model_metadata.getDataSplitTrainFraction()));
2163  logical_values.back().emplace_back(
2164  genLiteralDouble(model_metadata.getDataSplitEvalFraction()));
2165  }
2166 
2167  // Create ResultSet
2168  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
2169  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
2170 
2171  return ExecutionResult(rSet, label_infos);
2172 }
2173 
2175  auto& ddl_payload = extractPayload(ddl_data_);
2176  auto all_model_names = g_ml_models.getModelNames();
2177  if (ddl_payload.HasMember("modelNames")) {
2178  std::vector<std::string> filtered_model_names;
2179  std::set<std::string> all_model_names_set(all_model_names.begin(),
2180  all_model_names.end());
2181  for (const auto& model_name_json : ddl_payload["modelNames"].GetArray()) {
2182  std::string model_name = model_name_json.GetString();
2183  const auto model_name_upper = to_upper(model_name);
2184  if (all_model_names_set.find(to_upper(model_name_upper)) ==
2185  all_model_names_set.end()) {
2186  throw std::runtime_error{"Unable to show model details for model: " +
2187  model_name_upper + ". Model does not exist."};
2188  }
2189  filtered_model_names.emplace_back(model_name_upper);
2190  }
2191  return filtered_model_names;
2192  } else {
2193  return all_model_names;
2194  }
2195 }
2196 
2198  const DdlCommandData& ddl_data,
2199  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
2200  : DdlCommand(ddl_data, session_ptr) {
2201  if (!g_enable_ml_functions) {
2202  throw std::runtime_error(
2203  "Cannot show model feature details. ML functions are disabled.");
2204  }
2206  // Check if user is super user
2207  const auto& current_user = session_ptr->get_currentUser();
2208  if (!current_user.isSuper) {
2209  throw std::runtime_error(
2210  "Cannot show model feature details. Showing model information to "
2211  "non-superusers is "
2212  "disabled.");
2213  }
2214  }
2215 }
2216 
2217 std::vector<TargetMetaInfo> ShowModelFeatureDetailsCommand::prepareLabelInfos() const {
2218  std::vector<TargetMetaInfo> label_infos;
2219  label_infos.emplace_back("feature_id", SQLTypeInfo(kBIGINT, true));
2220  label_infos.emplace_back("feature", SQLTypeInfo(kTEXT, true));
2221  label_infos.emplace_back("sub_feature_id", SQLTypeInfo(kBIGINT, true));
2222  label_infos.emplace_back("sub_feature", SQLTypeInfo(kTEXT, true));
2223  return label_infos;
2224 }
2225 
2226 std::pair<std::vector<double>, std::vector<std::vector<double>>>
2228  std::shared_ptr<AbstractMLModel> model,
2229  std::vector<TargetMetaInfo>& label_infos) const {
2230  std::vector<double> extra_metadata;
2231  std::vector<std::vector<double>> eigenvectors;
2232 
2233  switch (model->getModelType()) {
2234  case MLModelType::LINEAR_REG: {
2235  label_infos.emplace_back("coefficient", SQLTypeInfo(kDOUBLE, true));
2236  const auto linear_reg_model =
2237  std::dynamic_pointer_cast<LinearRegressionModel>(model);
2238  extra_metadata = linear_reg_model->getCoefs();
2239  break;
2240  }
2241 #ifdef HAVE_ONEDAL
2243  const auto random_forest_reg_model =
2244  std::dynamic_pointer_cast<RandomForestRegressionModel>(model);
2245  extra_metadata = random_forest_reg_model->getVariableImportanceScores();
2246  if (!extra_metadata.empty()) {
2247  label_infos.emplace_back("feature_importance", SQLTypeInfo(kDOUBLE, true));
2248  }
2249  break;
2250  }
2251  case MLModelType::PCA: {
2252  label_infos.emplace_back("eigenvalue", SQLTypeInfo(kDOUBLE, true));
2253  label_infos.emplace_back("eigenvector", SQLTypeInfo(kTEXT, true));
2254  const auto pca_model = std::dynamic_pointer_cast<PcaModel>(model);
2255  extra_metadata = pca_model->getEigenvalues();
2256  eigenvectors = pca_model->getEigenvectors();
2257  CHECK_EQ(eigenvectors.size(), extra_metadata.size());
2258  break;
2259  }
2260 #endif // HAVE_ONEDAL
2261  default: {
2262  break;
2263  }
2264  }
2265 
2266  return std::make_pair(std::move(extra_metadata), std::move(eigenvectors));
2267 }
2268 
2269 std::vector<RelLogicalValues::RowValues>
2271  const MLModelMetadata& model_metadata,
2272  const std::vector<std::vector<std::string>>& cat_sub_features,
2273  std::vector<double>& extra_metadata,
2274  const std::vector<std::vector<double>>& eigenvectors,
2275  const std::vector<int64_t>& inverse_permutations) const {
2276  std::vector<RelLogicalValues::RowValues> logical_values;
2277  const auto model_type = model_metadata.getModelType();
2278  if (model_type == MLModelType::LINEAR_REG) {
2279  logical_values.emplace_back(RelLogicalValues::RowValues{});
2280  logical_values.back().emplace_back(genLiteralBigInt(0));
2281  logical_values.back().emplace_back(genLiteralStr("intercept"));
2282  logical_values.back().emplace_back(genLiteralBigInt(1));
2283  logical_values.back().emplace_back(genLiteralStr(""));
2284  logical_values.back().emplace_back(genLiteralDouble(extra_metadata[0]));
2285  extra_metadata.erase(extra_metadata.begin());
2286  }
2287  const auto& features = model_metadata.getFeatures();
2288  const int64_t num_features = static_cast<int64_t>(features.size());
2289  std::vector<int64_t> physical_feature_idx_prefix_sums = {0};
2290  for (int64_t feature_idx = 1; feature_idx < num_features; ++feature_idx) {
2291  if (feature_idx - 1 < static_cast<int64_t>(cat_sub_features.size())) {
2292  physical_feature_idx_prefix_sums.emplace_back(
2293  physical_feature_idx_prefix_sums.back() +
2294  static_cast<int64_t>(cat_sub_features[feature_idx - 1].size()));
2295  } else {
2296  physical_feature_idx_prefix_sums.emplace_back(
2297  physical_feature_idx_prefix_sums.back() + 1);
2298  }
2299  }
2300  for (int64_t original_feature_idx = 0; original_feature_idx < num_features;
2301  ++original_feature_idx) {
2302  const auto feature_idx = inverse_permutations.empty()
2303  ? original_feature_idx
2304  : inverse_permutations[original_feature_idx];
2305  int64_t num_sub_features =
2306  feature_idx >= static_cast<int64_t>(cat_sub_features.size())
2307  ? 0
2308  : static_cast<int64_t>(cat_sub_features[feature_idx].size());
2309  const bool has_sub_features = num_sub_features > 0;
2310  num_sub_features = num_sub_features == 0 ? 1 : num_sub_features;
2311  int64_t physical_feature_idx = physical_feature_idx_prefix_sums[feature_idx];
2312  for (int64_t sub_feature_idx = 0; sub_feature_idx < num_sub_features;
2313  ++sub_feature_idx) {
2314  logical_values.emplace_back(RelLogicalValues::RowValues{});
2315  // Make feature id one-based
2316  logical_values.back().emplace_back(genLiteralBigInt(original_feature_idx + 1));
2317  logical_values.back().emplace_back(genLiteralStr(features[original_feature_idx]));
2318  logical_values.back().emplace_back(genLiteralBigInt(sub_feature_idx + 1));
2319  if (has_sub_features) {
2320  logical_values.back().emplace_back(
2321  genLiteralStr(cat_sub_features[feature_idx][sub_feature_idx]));
2322  } else {
2323  logical_values.back().emplace_back(genLiteralStr(""));
2324  }
2325  if (!extra_metadata.empty()) {
2326  logical_values.back().emplace_back(
2327  genLiteralDouble(extra_metadata[physical_feature_idx]));
2328  }
2329  if (!eigenvectors.empty()) {
2330  std::ostringstream eigenvector_oss;
2331  eigenvector_oss << "[";
2332  for (size_t i = 0; i < eigenvectors[physical_feature_idx].size(); ++i) {
2333  if (i > 0) {
2334  eigenvector_oss << ", ";
2335  }
2336  eigenvector_oss << eigenvectors[physical_feature_idx][i];
2337  }
2338  eigenvector_oss << "]";
2339  logical_values.back().emplace_back(genLiteralStr(eigenvector_oss.str()));
2340  }
2341  physical_feature_idx++;
2342  }
2343  }
2344  return logical_values;
2345 }
2346 
2348  auto execute_read_lock = legacylockmgr::getExecuteReadLock();
2349  auto& ddl_payload = extractPayload(ddl_data_);
2350  CHECK(ddl_payload.HasMember("modelName")) << "Model name missing.";
2351  const auto model_name = ddl_payload["modelName"].GetString();
2352  const auto model = g_ml_models.getModel(model_name);
2353  const auto model_metadata = model->getModelMetadata();
2354  // const auto& features = model_metadata.getFeatures();
2355  // const auto model_type = model_metadata.getModelType();
2356  const auto& feature_permutations = model_metadata.getFeaturePermutations();
2357 
2358  std::vector<int64_t> inverse_permutations(feature_permutations.size());
2359  for (int64_t perm_idx = 0; perm_idx < static_cast<int64_t>(feature_permutations.size());
2360  ++perm_idx) {
2361  inverse_permutations[feature_permutations[perm_idx]] = perm_idx;
2362  }
2363 
2364  auto label_infos = prepareLabelInfos();
2365  auto [extra_metadata, eigenvectors] = extractExtraMetadata(model, label_infos);
2366 
2367  // Todo(todd): Make cat_sub_features accessible from MLModelMetadata so we don't have to
2368  // access and pass it separately
2369  const auto& cat_sub_features = model->getCatFeatureKeys();
2370  auto logical_values = prepareLogicalValues(model_metadata,
2371  cat_sub_features,
2372  extra_metadata,
2373  eigenvectors,
2374  inverse_permutations);
2375 
2376  // Create ResultSet
2377  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
2378  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
2379 
2380  return ExecutionResult(rSet, label_infos);
2381 }
2382 
2384  const DdlCommandData& ddl_data,
2385  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
2386  : DdlCommand(ddl_data, session_ptr) {
2387  if (!g_enable_ml_functions) {
2388  throw std::runtime_error("Cannot evaluate model. ML functions are disabled.");
2389  }
2390 }
2391 
2393  auto execute_read_lock = legacylockmgr::getExecuteReadLock();
2394  auto& ddl_payload = extractPayload(ddl_data_);
2395  std::string model_name;
2396  std::string select_query;
2397  if (ddl_payload.HasMember("modelName")) {
2398  model_name = ddl_payload["modelName"].GetString();
2399  }
2400  if (ddl_payload.HasMember("query")) {
2401  select_query = ddl_payload["query"].GetString();
2402  }
2403  std::regex newline_re("\\n");
2404  std::regex backtick_re("`");
2405  select_query = std::regex_replace(select_query, newline_re, " ");
2406  select_query = std::regex_replace(select_query, backtick_re, "");
2407  const auto model_metadata = g_ml_models.getModelMetadata(model_name);
2408  const auto model_type = model_metadata.getModelType();
2409  if (!is_regression_model(model_type)) {
2410  const auto& model_type_str = model_metadata.getModelTypeStr();
2411  std::ostringstream error_oss;
2412  error_oss << "EVALUATE MODEL not supported for " << model_type_str << " models.";
2413  throw std::runtime_error(error_oss.str());
2414  }
2415 
2416  if (select_query.empty()) {
2417  const double data_split_eval_fraction = model_metadata.getDataSplitEvalFraction();
2418  CHECK_LE(data_split_eval_fraction, 1.0);
2419  if (data_split_eval_fraction <= 0.0) {
2420  throw std::runtime_error(
2421  "Unable to evaluate model: " + model_name +
2422  ". Model was not trained with a data split evaluation fraction.");
2423  }
2424  const auto& training_query = model_metadata.getTrainingQuery();
2425  const auto& feature_permutations = model_metadata.getFeaturePermutations();
2426  std::ostringstream select_query_oss;
2427  // To get a non-overlapping eval dataset (that does not overlap with the training
2428  // dataset), we need to use NOT SAMPLE_RATIO(training_fraction) and not
2429  // SAMPLE_RATIO(eval_fraction), as the latter will be a subset of the training
2430  // dataset
2431  const double data_split_train_fraction = 1.0 - data_split_eval_fraction;
2432  select_query_oss << "SELECT ";
2433  if (!feature_permutations.empty()) {
2434  select_query_oss << model_metadata.getPredicted() << ", ";
2435  const auto& features = model_metadata.getFeatures();
2436  for (const auto feature_permutation : feature_permutations) {
2437  select_query_oss << features[feature_permutation];
2438  if (feature_permutation != feature_permutations.back()) {
2439  select_query_oss << ", ";
2440  }
2441  }
2442  } else {
2443  select_query_oss << " * ";
2444  }
2445 
2446  select_query_oss << " FROM (" << training_query << ") WHERE NOT SAMPLE_RATIO("
2447  << data_split_train_fraction << ")";
2448  select_query = select_query_oss.str();
2449  } else {
2450  const auto& feature_permutations = model_metadata.getFeaturePermutations();
2451  if (!feature_permutations.empty()) {
2452  Parser::LocalQueryConnector local_connector;
2453  auto validate_query_state =
2455  auto validate_result = local_connector.query(
2456  validate_query_state->createQueryStateProxy(), select_query, {}, true, false);
2457  auto column_descriptors_list =
2458  local_connector.getColumnDescriptors(validate_result, true);
2459  std::vector<ColumnDescriptor> column_descriptors;
2460  for (auto& cd : column_descriptors_list) {
2461  column_descriptors.emplace_back(cd);
2462  }
2463  std::ostringstream select_query_oss;
2464  select_query_oss << "SELECT " << model_metadata.getPredicted() << ", ";
2465  for (const auto feature_permutation : feature_permutations) {
2466  select_query_oss << column_descriptors[feature_permutation + 1].columnName;
2467  if (feature_permutation != feature_permutations.back()) {
2468  select_query_oss << ", ";
2469  }
2470  }
2471  select_query_oss << " FROM (" << select_query << ")";
2472  select_query = select_query_oss.str();
2473  }
2474  }
2475  std::ostringstream r2_query_oss;
2476  r2_query_oss << "SELECT * FROM TABLE(r2_score(model_name => '" << model_name << "', "
2477  << "data => CURSOR(" << select_query << ")))";
2478  std::string r2_query = r2_query_oss.str();
2479 
2480  try {
2481  Parser::LocalQueryConnector local_connector;
2482  auto query_state = query_state::QueryState::create(session_ptr_, r2_query);
2483  auto result =
2484  local_connector.query(query_state->createQueryStateProxy(), r2_query, {}, false);
2485  std::vector<std::string> labels{"r2"};
2486  std::vector<TargetMetaInfo> label_infos;
2487  for (const auto& label : labels) {
2488  label_infos.emplace_back(label, SQLTypeInfo(kDOUBLE, true));
2489  }
2490  std::vector<RelLogicalValues::RowValues> logical_values;
2491  logical_values.emplace_back(RelLogicalValues::RowValues{});
2492 
2493  CHECK_EQ(result.size(), size_t(1));
2494  CHECK_EQ(result[0].rs->rowCount(), size_t(1));
2495  CHECK_EQ(result[0].rs->colCount(), size_t(1));
2496 
2497  auto result_row = result[0].rs->getNextRow(true, true);
2498 
2499  auto scalar_r = boost::get<ScalarTargetValue>(&result_row[0]);
2500  auto p = boost::get<double>(scalar_r);
2501 
2502  logical_values.back().emplace_back(genLiteralDouble(*p));
2503 
2504  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
2505  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
2506 
2507  return ExecutionResult(rSet, label_infos);
2508  } catch (const std::exception& e) {
2509  std::ostringstream error_oss;
2510  // Error messages from table functions come back like this:
2511  // Error executing table function: MLTableFunctions.hpp:1416 r2_score_impl: No
2512  // rows exist in evaluation data. Evaluation data must at least contain 1 row.
2513 
2514  // We want to take everything after the function name, so we will search for the
2515  // third colon. Todo(todd): Look at making this less hacky by setting a mode for the
2516  // table function that will return only the core error string and not the
2517  // preprending metadata
2518 
2519  auto get_error_substring = [](const std::string& message) -> std::string {
2520  size_t colon_position = std::string::npos;
2521  for (int i = 0; i < 3; ++i) {
2522  colon_position = message.find(':', colon_position + 1);
2523  if (colon_position == std::string::npos) {
2524  return message;
2525  }
2526  }
2527 
2528  if (colon_position + 2 >= message.length()) {
2529  return message;
2530  }
2531  return message.substr(colon_position + 2);
2532  };
2533 
2534  const auto error_substr = get_error_substring(e.what());
2535  error_oss << "Could not evaluate model " << model_name << ". " << error_substr;
2536  throw std::runtime_error(error_oss.str());
2537  }
2538 }
2539 
2541  const DdlCommandData& ddl_data,
2542  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
2543  : DdlCommand(ddl_data, session_ptr) {
2544  if (!g_enable_fsi) {
2545  throw std::runtime_error("Unsupported command: SHOW FOREIGN SERVERS");
2546  }
2547  // Verify that members are valid
2548  auto& ddl_payload = extractPayload(ddl_data_);
2549  CHECK(ddl_payload.HasMember("command"));
2550  if (ddl_payload.HasMember("filters")) {
2551  CHECK(ddl_payload["filters"].IsArray());
2552  int num_filters = 0;
2553  for (auto const& filter_def : ddl_payload["filters"].GetArray()) {
2554  CHECK(filter_def.IsObject());
2555  CHECK(filter_def.HasMember("attribute"));
2556  CHECK(filter_def["attribute"].IsString());
2557  CHECK(filter_def.HasMember("value"));
2558  CHECK(filter_def["value"].IsString());
2559  CHECK(filter_def.HasMember("operation"));
2560  CHECK(filter_def["operation"].IsString());
2561  if (num_filters > 0) {
2562  CHECK(filter_def.HasMember("chain"));
2563  CHECK(filter_def["chain"].IsString());
2564  } else {
2565  CHECK(!filter_def.HasMember("chain"));
2566  }
2567  num_filters++;
2568  }
2569  }
2570 }
2571 
2573  auto execute_read_lock = legacylockmgr::getExecuteReadLock();
2574 
2575  // valid in read_only_mode
2576 
2577  std::vector<TargetMetaInfo> label_infos;
2578  auto& ddl_payload = extractPayload(ddl_data_);
2579 
2580  // label_infos -> column labels
2581  std::vector<std::string> labels{"server_name", "data_wrapper", "created_at", "options"};
2582  label_infos.emplace_back(labels[0], SQLTypeInfo(kTEXT, true));
2583  label_infos.emplace_back(labels[1], SQLTypeInfo(kTEXT, true));
2584  // created_at is a TIMESTAMP
2585  label_infos.emplace_back(labels[2], SQLTypeInfo(kTIMESTAMP, true));
2586  label_infos.emplace_back(labels[3], SQLTypeInfo(kTEXT, true));
2587 
2588  const auto& user = session_ptr_->get_currentUser();
2589 
2590  std::vector<const foreign_storage::ForeignServer*> results;
2591 
2592  session_ptr_->getCatalog().getForeignServersForUser(
2593  extractFilters(ddl_payload), user, results);
2594 
2595  // logical_values -> table data
2596  std::vector<RelLogicalValues::RowValues> logical_values;
2597  for (auto const& server_ptr : results) {
2598  logical_values.emplace_back(RelLogicalValues::RowValues{});
2599  logical_values.back().emplace_back(genLiteralStr(server_ptr->name));
2600  logical_values.back().emplace_back(genLiteralStr(server_ptr->data_wrapper_type));
2601  logical_values.back().emplace_back(genLiteralTimestamp(server_ptr->creation_time));
2602  logical_values.back().emplace_back(
2603  genLiteralStr(server_ptr->getOptionsAsJsonString()));
2604  }
2605 
2606  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
2607  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
2608 
2609  return ExecutionResult(rSet, label_infos);
2610 }
2611 
2613  const DdlCommandData& ddl_data,
2614  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
2615  : DdlCommand(ddl_data, session_ptr) {
2616  if (!g_enable_fsi) {
2617  throw std::runtime_error("Unsupported command: SHOW CREATE SERVER");
2618  }
2619  // Verify that members are valid
2620  auto& payload = extractPayload(ddl_data_);
2621  CHECK(payload.HasMember("serverName"));
2622  CHECK(payload["serverName"].IsString());
2623  server_ = (payload["serverName"].GetString());
2624 }
2625 
2627  auto execute_read_lock = legacylockmgr::getExecuteReadLock();
2628  // valid in read_only_mode
2629 
2630  using namespace Catalog_Namespace;
2631  auto& catalog = session_ptr_->getCatalog();
2632  const auto server = catalog.getForeignServer(server_);
2633  if (!server) {
2634  throw std::runtime_error("Foreign server " + server_ + " does not exist.");
2635  }
2636  DBObject dbObject(server_, ServerDBObjectType);
2637  dbObject.loadKey(catalog);
2638  std::vector<DBObject> privObjects = {dbObject};
2639  if (!SysCatalog::instance().hasAnyPrivileges(session_ptr_->get_currentUser(),
2640  privObjects)) {
2641  throw std::runtime_error("Foreign server " + server_ + " does not exist.");
2642  }
2643  auto create_stmt = catalog.dumpCreateServer(server_);
2644 
2645  std::vector<std::string> labels{"create_server_sql"};
2646  std::vector<TargetMetaInfo> label_infos;
2647  label_infos.emplace_back(labels[0], SQLTypeInfo(kTEXT, true));
2648 
2649  std::vector<RelLogicalValues::RowValues> logical_values;
2650  logical_values.emplace_back(RelLogicalValues::RowValues{});
2651  logical_values.back().emplace_back(genLiteralStr(create_stmt));
2652 
2653  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
2654  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
2655 
2656  return ExecutionResult(rSet, label_infos);
2657 }
2658 
2660  const DdlCommandData& ddl_data,
2661  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
2662  : DdlCommand(ddl_data, session_ptr) {
2663  if (!g_enable_fsi) {
2664  throw std::runtime_error("Unsupported command: REFRESH FOREIGN TABLE");
2665  }
2666  auto& ddl_payload = extractPayload(ddl_data_);
2667  CHECK(ddl_payload.HasMember("tableNames"));
2668  CHECK(ddl_payload["tableNames"].IsArray());
2669  for (auto const& tablename_def : ddl_payload["tableNames"].GetArray()) {
2670  CHECK(tablename_def.IsString());
2671  }
2672 }
2673 
2675  if (read_only_mode) {
2676  throw std::runtime_error("REFRESH FOREIGN TABLE invalid in read only mode.");
2677  }
2678 
2679  const auto execute_read_lock = legacylockmgr::getExecuteReadLock();
2680 
2681  bool evict_cached_entries{false};
2683  auto& ddl_payload = extractPayload(ddl_data_);
2684  if (ddl_payload.HasMember("options") && !ddl_payload["options"].IsNull()) {
2685  opt.populateOptionsMap(ddl_payload["options"]);
2686  for (const auto& entry : opt.options) {
2687  if (entry.first != "EVICT") {
2688  throw std::runtime_error{
2689  "Invalid option \"" + entry.first +
2690  "\" provided for refresh command. Only \"EVICT\" option is supported."};
2691  }
2692  }
2693  CHECK(opt.options.find("EVICT") != opt.options.end());
2694 
2695  if (boost::iequals(opt.options["EVICT"], "true") ||
2696  boost::iequals(opt.options["EVICT"], "false")) {
2697  if (boost::iequals(opt.options["EVICT"], "true")) {
2698  evict_cached_entries = true;
2699  }
2700  } else {
2701  throw std::runtime_error{
2702  "Invalid value \"" + opt.options["EVICT"] +
2703  "\" provided for EVICT option. Value must be either \"true\" or \"false\"."};
2704  }
2705  }
2706 
2707  auto& cat = session_ptr_->getCatalog();
2708  const auto& current_user = session_ptr_->get_currentUser();
2709  /* verify object ownership if not suser */
2710  if (!current_user.isSuper) {
2711  for (const auto& table_name_json : ddl_payload["tableNames"].GetArray()) {
2712  std::string table_name = table_name_json.GetString();
2713  if (!Catalog_Namespace::SysCatalog::instance().verifyDBObjectOwnership(
2714  current_user, DBObject(table_name, TableDBObjectType), cat)) {
2715  throw std::runtime_error(
2716  std::string("REFRESH FOREIGN TABLES failed on table \"") + table_name +
2717  "\". It can only be executed by super user or "
2718  "owner of the "
2719  "object.");
2720  }
2721  }
2722  }
2723 
2724  for (const auto& table_name_json : ddl_payload["tableNames"].GetArray()) {
2725  std::string table_name = table_name_json.GetString();
2726  static const std::array<std::string, 4> log_system_tables{
2731  if (cat.isInfoSchemaDb() && !shared::contains(log_system_tables, table_name)) {
2732  throw std::runtime_error(
2733  "REFRESH FOREIGN TABLE can only be executed for the following tables: " +
2734  join(log_system_tables, ","));
2735  }
2736  foreign_storage::refresh_foreign_table(cat, table_name, evict_cached_entries);
2737  }
2738  return ExecutionResult();
2739 }
2740 
2742  const DdlCommandData& ddl_data,
2743  std::shared_ptr<const Catalog_Namespace::SessionInfo> session_ptr)
2744  : DdlCommand(ddl_data, session_ptr) {
2745  auto& ddl_payload = extractPayload(ddl_data_);
2746 
2747  CHECK(ddl_payload.HasMember("tableName"));
2748  CHECK(ddl_payload["tableName"].IsString());
2749 
2750  CHECK(ddl_payload.HasMember("alterType"));
2751  CHECK(ddl_payload["alterType"].IsString());
2752 }
2753 
2755  const DdlCommandData& ddl_data,
2756  std::shared_ptr<const Catalog_Namespace::SessionInfo> session_ptr)
2757  : DdlCommand(ddl_data, session_ptr)
2758  , recovery_mgr_(session_ptr->getCatalog())
2759 
2760 {
2761  auto& ddl_payload = extractPayload(ddl_data_);
2762 
2763  CHECK_EQ(std::string(ddl_payload["alterType"].GetString()), "ALTER_COLUMN");
2764 
2765  CHECK(ddl_payload.HasMember("alterData"));
2766  CHECK(ddl_payload["alterData"].IsArray());
2767 
2768  const auto elements = ddl_payload["alterData"].GetArray();
2769  for (const auto& element : elements) {
2770  CHECK(element.HasMember("type"));
2771  CHECK(element["type"].IsString());
2772  CHECK_EQ(std::string(element["type"].GetString()), "SQL_COLUMN_DECLARATION");
2773 
2774  CHECK(element.HasMember("name"));
2775  CHECK(element["name"].IsString());
2776 
2777  CHECK(element.HasMember("default"));
2778 
2779  CHECK(element.HasMember("nullable"));
2780  CHECK(element["nullable"].IsBool());
2781 
2782  CHECK(element.HasMember("encodingType"));
2783  CHECK(element.HasMember("encodingSize"));
2784 
2785  CHECK(element.HasMember("sqltype"));
2786  CHECK(element["sqltype"].IsString());
2787  }
2788 }
2789 
2791  const TypePairs& src_dst_cds) {
2792  auto& catalog = session_ptr_->getCatalog();
2793 
2794  for (auto& [src_cd, dst_cd] : src_dst_cds) {
2795  if (dst_cd->columnType.is_geometry()) {
2796  continue;
2797  }
2798  auto compare_result =
2800  CHECK(!compare_result.sql_types_match || !compare_result.defaults_match);
2801 
2802  catalog.alterColumnTypeTransactional(*dst_cd);
2803  }
2804 }
2805 
2806 std::list<const ColumnDescriptor*> AlterTableAlterColumnCommand::prepareColumns(
2807  const TableDescriptor* td,
2808  const TypePairs& src_dst_cds) {
2809  auto& catalog = session_ptr_->getCatalog();
2810 
2811  std::list<const ColumnDescriptor*> non_geo_cds;
2812  for (auto& [src_cd, dst_cd] : src_dst_cds) {
2813  if (dst_cd->columnType.is_geometry()) {
2814  continue;
2815  }
2816  non_geo_cds.emplace_back(dst_cd);
2817 
2818  auto compare_result =
2820  if (compare_result.sql_types_match) {
2821  continue;
2822  }
2823 
2824  if (dst_cd->columnType.is_dict_encoded_type()) {
2825  catalog.addDictionaryTransactional(*dst_cd);
2826  }
2827  }
2828 
2829  return non_geo_cds;
2830 }
2831 
2832 std::list<std::list<ColumnDescriptor>> AlterTableAlterColumnCommand::prepareGeoColumns(
2833  const TableDescriptor* td,
2834  const TypePairs& src_dst_cds) {
2835  auto& catalog = session_ptr_->getCatalog();
2836  std::list<std::list<ColumnDescriptor>> physical_geo_columns;
2837 
2838  for (auto& [src_cd, dst_cd] : src_dst_cds) {
2839  if (dst_cd->columnType.is_geometry()) {
2840  std::string col_name = src_cd->columnName;
2841  auto uuid = boost::uuids::random_generator()();
2842  catalog.renameColumn(td, src_cd, col_name + "_" + boost::uuids::to_string(uuid));
2843 
2844  physical_geo_columns.emplace_back();
2845  std::list<ColumnDescriptor>& phy_geo_columns = physical_geo_columns.back();
2846  catalog.expandGeoColumn(*dst_cd, phy_geo_columns);
2847 
2848  catalog.addColumnTransactional(*td, *dst_cd);
2849 
2850  for (auto& cd : phy_geo_columns) {
2851  catalog.addColumnTransactional(*td, cd);
2852  }
2853  }
2854  }
2855 
2856  return physical_geo_columns;
2857 }
2858 
2860  const TableDescriptor* td,
2861  const std::list<const ColumnDescriptor*>& cds) {
2862  if (cds.empty()) {
2863  return;
2864  }
2865  auto fragmenter = td->fragmenter;
2866  CHECK(fragmenter);
2867  auto io_fragmenter =
2868  dynamic_cast<Fragmenter_Namespace::InsertOrderFragmenter*>(fragmenter.get());
2869  CHECK(io_fragmenter);
2870  io_fragmenter->alterNonGeoColumnType(cds);
2871 }
2872 
2874  const TableDescriptor* td,
2875  const std::list<std::pair<const ColumnDescriptor*,
2876  std::list<const ColumnDescriptor*>>>& geo_src_dst_cds) {
2877  if (geo_src_dst_cds.empty()) {
2878  return;
2879  }
2880  auto fragmenter = td->fragmenter;
2881  CHECK(fragmenter);
2882  auto io_fragmenter =
2883  dynamic_cast<Fragmenter_Namespace::InsertOrderFragmenter*>(fragmenter.get());
2884  CHECK(io_fragmenter);
2885  io_fragmenter->alterColumnGeoType(geo_src_dst_cds);
2886 }
2887 
2889  const TypePairs& src_dst_cds) {
2890  auto& catalog = session_ptr_->getCatalog();
2891 
2892  ChunkKey column_key{catalog.getCurrentDB().dbId, td->tableId, 0};
2893  Executor::clearExternalCaches(true, td, catalog.getDatabaseId());
2894  column_key.resize(3);
2895  for (auto& [src_cd, _] : src_dst_cds) {
2896  column_key[2] = src_cd->columnId;
2897  catalog.getDataMgr().deleteChunksWithPrefix(column_key, MemoryLevel::GPU_LEVEL);
2898  catalog.getDataMgr().deleteChunksWithPrefix(column_key, MemoryLevel::CPU_LEVEL);
2899  }
2900 
2901  catalog.removeFragmenterForTable(td->tableId);
2902 }
2903 
2905  const TableDescriptor* td,
2906  const AlterTableAlterColumnCommand::TypePairs& src_dst_cds) {
2907  auto& catalog = session_ptr_->getCatalog();
2908 
2909  auto column_id_start = catalog.getNextAddedColumnId(*td);
2910  auto current_column_id = column_id_start;
2911 
2912  // Simulate operations required for geo changes
2913  for (auto& [src_cd, dst_cd] : src_dst_cds) {
2914  if (dst_cd->columnType.is_geometry()) {
2915  recovery_info_.renamed_columns.push_back(*src_cd);
2916 
2917  std::list<ColumnDescriptor> phy_geo_columns;
2918  catalog.expandGeoColumn(*dst_cd, phy_geo_columns);
2919 
2920  auto col_to_add = *dst_cd;
2921  col_to_add.tableId = td->tableId;
2922  col_to_add.columnId = current_column_id++;
2923  recovery_info_.added_columns.push_back(col_to_add);
2924 
2925  for (auto& cd : phy_geo_columns) {
2926  ColumnDescriptor phys_col_to_add = cd;
2927  phys_col_to_add.tableId = td->tableId;
2928  phys_col_to_add.columnId = current_column_id++;
2929  recovery_info_.added_columns.push_back(phys_col_to_add);
2930  }
2931  } else if (dst_cd->columnType.is_dict_encoded_type()) {
2933  .sql_types_match) {
2934  recovery_info_.updated_dict_cds.push_back(*src_cd);
2935  }
2936  }
2937  }
2938 
2939  for (auto& [src_cd, dst_cd] : src_dst_cds) {
2940  if (dst_cd->columnType.is_geometry()) {
2941  continue;
2942  }
2943  auto compare_result =
2945  CHECK(!compare_result.sql_types_match || !compare_result.defaults_match);
2946  recovery_info_.altered_columns.emplace_back(*src_cd, *dst_cd);
2947  }
2948 }
2949 
2951  auto recovery_file_info = recovery_mgr_.getRecoveryFilepathInfo(td->tableId);
2952  auto recovery_filepath = recovery_mgr_.recoveryFilepath(recovery_file_info);
2953 
2954  if (std::filesystem::exists(recovery_filepath)) {
2955  std::filesystem::remove(recovery_filepath);
2956  }
2957 }
2958 
2960  const TableDescriptor* td,
2961  const TypePairs& src_dst_cds) {
2962  auto& catalog = session_ptr_->getCatalog();
2963 
2964  auto table_epochs = catalog.getTableEpochs(catalog.getDatabaseId(), td->tableId);
2965  CHECK_GT(table_epochs.size(), 0UL);
2966  recovery_info_.table_epoch = table_epochs[0].table_epoch;
2968 
2969  collectExpectedCatalogChanges(td, src_dst_cds);
2970 
2971  for (const auto& [src_cd, dst_cd] : src_dst_cds) {
2972  recovery_info_.src_dst_cds.emplace_back(*src_cd, *dst_cd);
2973  }
2974 
2975  auto recovery_file_info = recovery_mgr_.getRecoveryFilepathInfo(td->tableId);
2976  auto recovery_filepath = recovery_mgr_.recoveryFilepath(recovery_file_info);
2978 }
2979 
2981  const TypePairs& src_dst_cds) {
2982  auto& catalog = session_ptr_->getCatalog();
2983 
2984  auto table_epochs = catalog.getTableEpochs(catalog.getDatabaseId(), td->tableId);
2985 
2986  populateAndWriteRecoveryInfo(td, src_dst_cds);
2987 
2988  try {
2989  // Apply a vacuum operation prior to alter column when applicable
2990  vacuum_table_if_required(catalog, td);
2991 
2992  auto physical_columns = prepareGeoColumns(td, src_dst_cds);
2993  auto geo_src_dst_column_pairs =
2995  physical_columns);
2996 
2997  auto non_geo_cds = prepareColumns(td, src_dst_cds);
2998 
2999  alterGeoColumnData(td, geo_src_dst_column_pairs);
3000  alterNonGeoColumnData(td, non_geo_cds);
3001 
3002  alterColumns(td, src_dst_cds);
3003 
3004  // First checkpoint is for added/altered data, rollback is possible
3005  recovery_mgr_.checkpoint(td, src_dst_cds);
3006 
3007  } catch (std::exception& except) {
3008  catalog.setTableEpochs(catalog.getDatabaseId(), table_epochs);
3009  clearInMemoryData(td, src_dst_cds);
3011  cleanupRecoveryInfo(td);
3012  throw std::runtime_error("Alter column type: " + std::string(except.what()));
3013  }
3014 
3015  // After the last checkpoint, the following operations are non-reversible,
3016  // when recovering from a crash will be required to finish
3017  try {
3018  recovery_mgr_.cleanup(td, src_dst_cds);
3019  } catch (std::exception& except) {
3020  // Any exception encountered during the last steps is unexpected and will cause a
3021  // crash, relying on the recovery process to fix resulting issues
3022  LOG(FATAL) << "Alter column type: encountered fatal error during finalizing: "
3023  << except.what();
3024  }
3025 
3026  clearInMemoryData(td, src_dst_cds);
3027  cleanupRecoveryInfo(td);
3028 }
3029 
3031  auto& ddl_payload = extractPayload(ddl_data_);
3032  const auto tableName = std::string(ddl_payload["tableName"].GetString());
3033 
3034  auto columns = Parser::get_columns_from_json_payload("alterData", ddl_payload);
3035 
3036  auto& catalog = session_ptr_->getCatalog();
3037  const auto td_with_lock =
3039  catalog, tableName, true);
3040  const auto td = td_with_lock();
3041 
3042  if (!td) {
3043  throw std::runtime_error("Table " + tableName + " does not exist.");
3044  } else {
3045  if (td->isView) {
3046  throw std::runtime_error("Altering columns in a view is not supported.");
3047  }
3049  if (table_is_temporary(td)) {
3050  throw std::runtime_error("Altering columns in temporary tables is not supported.");
3051  }
3052  }
3053 
3055 
3056  for (const auto& coldef : columns) {
3057  const auto& column_name = *coldef.get_column_name();
3058  if (catalog.getMetadataForColumn(td->tableId, column_name) == nullptr) {
3059  throw std::runtime_error("Column " + column_name + " does not exist.");
3060  }
3061  }
3062 
3063  CHECK(td->fragmenter);
3064  if (td->sortedColumnId) {
3065  throw std::runtime_error(
3066  "Altering columns to a table is not supported when using the \"sort_column\" "
3067  "option.");
3068  }
3069 
3070  auto [src_cds, dst_cds] = get_alter_column_src_dst_cds(columns, catalog, td);
3072 }
3073 
3075  if (g_cluster) {
3076  throw std::runtime_error(
3077  "ALTER TABLE ALTER COLUMN is unsupported in distributed mode.");
3078  }
3079 
3080  // NOTE: read_only_mode is validated at a higher level in AlterTableCommand
3081 
3082  // TODO: Refactor this lock when refactoring other ALTER TABLE commands
3083  const auto execute_read_lock = legacylockmgr::getExecuteReadLock();
3084 
3085  // There are a few major cases to consider when alter column is invoked.
3086  // Below non variable length column is abbreviated as NVL and a variable
3087  // length column is abbreviated as VL.
3088  //
3089  // 1. A NVL -> NVL or VL -> VL column conversion.
3090  //
3091  // 2. A NVL -> VL or VL -> NVL column conversion.
3092  //
3093  // 3. A VL/NVL column converted to a Geo column.
3094  //
3095  // Case (1) is the simplest since chunks do not change their chunk keys.
3096  //
3097  // Case (2) requires that the chunk keys are added or removed (typically the
3098  // index chunk), and this requires special treatment.
3099  //
3100  // Case (3) requires temporarily renaming the source column, creating new Geo
3101  // columns, populating the destination Geo columns and dropping the source
3102  // column.
3103 
3104  alterColumn();
3105  return {};
3106 }
3107 
3109  if (read_only_mode) {
3110  throw std::runtime_error("ALTER TABLE invalid in read only mode.");
3111  }
3112 
3113  auto& ddl_payload = extractPayload(ddl_data_);
3114  const auto tableName = std::string(ddl_payload["tableName"].GetString());
3115 
3116  CHECK(ddl_payload.HasMember("alterType"));
3117  auto type = json_str(ddl_payload["alterType"]);
3118 
3119  if (type == "RENAME_TABLE") {
3120  CHECK(ddl_payload.HasMember("newTableName"));
3121  auto newTableName = json_str(ddl_payload["newTableName"]);
3122  std::unique_ptr<Parser::DDLStmt>(
3123  new Parser::RenameTableStmt(new std::string(tableName),
3124  new std::string(newTableName)))
3125  ->execute(*session_ptr_, read_only_mode);
3126  return {};
3127 
3128  } else if (type == "RENAME_COLUMN") {
3129  CHECK(ddl_payload.HasMember("columnName"));
3130  auto columnName = json_str(ddl_payload["columnName"]);
3131  CHECK(ddl_payload.HasMember("newColumnName"));
3132  auto newColumnName = json_str(ddl_payload["newColumnName"]);
3133  std::unique_ptr<Parser::DDLStmt>(
3134  new Parser::RenameColumnStmt(new std::string(tableName),
3135  new std::string(columnName),
3136  new std::string(newColumnName)))
3137  ->execute(*session_ptr_, read_only_mode);
3138  return {};
3139 
3140  } else if (type == "ALTER_COLUMN") {
3141  return AlterTableAlterColumnCommand{ddl_data_, session_ptr_}.execute(read_only_mode);
3142  } else if (type == "ADD_COLUMN") {
3143  CHECK(ddl_payload.HasMember("columnData"));
3144  CHECK(ddl_payload["columnData"].IsArray());
3145 
3146  // New Columns go into this list
3147  std::list<Parser::ColumnDef*>* table_element_list_ =
3148  new std::list<Parser::ColumnDef*>;
3149 
3150  const auto elements = ddl_payload["columnData"].GetArray();
3151  for (const auto& element : elements) {
3152  CHECK(element.IsObject());
3153  CHECK(element.HasMember("type"));
3154  if (json_str(element["type"]) == "SQL_COLUMN_DECLARATION") {
3155  auto col_def = Parser::column_from_json(element);
3156  table_element_list_->emplace_back(col_def.release());
3157  } else {
3158  LOG(FATAL) << "Unsupported element type for ALTER TABLE: "
3159  << element["type"].GetString();
3160  }
3161  }
3162 
3163  std::unique_ptr<Parser::DDLStmt>(
3164  new Parser::AddColumnStmt(new std::string(tableName), table_element_list_))
3165  ->execute(*session_ptr_, read_only_mode);
3166  return {};
3167 
3168  } else if (type == "DROP_COLUMN") {
3169  CHECK(ddl_payload.HasMember("columnData"));
3170  auto columnData = json_str(ddl_payload["columnData"]);
3171  // Convert columnData to std::list<std::string*>*
3172  // allocate std::list<> as DropColumnStmt will delete it;
3173  std::list<std::string*>* cols = new std::list<std::string*>;
3174  std::vector<std::string> cols1;
3175  boost::split(cols1, columnData, boost::is_any_of(","));
3176  for (auto s : cols1) {
3177  // strip leading/trailing spaces/quotes/single quotes
3178  boost::algorithm::trim_if(s, boost::is_any_of(" \"'`"));
3179  std::string* str = new std::string(s);
3180  cols->emplace_back(str);
3181  }
3182 
3183  std::unique_ptr<Parser::DDLStmt>(
3184  new Parser::DropColumnStmt(new std::string(tableName), cols))
3185  ->execute(*session_ptr_, read_only_mode);
3186  return {};
3187 
3188  } else if (type == "ALTER_OPTIONS") {
3189  CHECK(ddl_payload.HasMember("options"));
3190  const auto& options = ddl_payload["options"];
3191  if (options.IsObject()) {
3192  for (auto itr = options.MemberBegin(); itr != options.MemberEnd(); ++itr) {
3193  std::string* option_name = new std::string(json_str(itr->name));
3194  Parser::Literal* literal_value;
3195  if (itr->value.IsString()) {
3196  std::string literal_string = json_str(itr->value);
3197 
3198  // iff this string can be converted to INT
3199  // ... do so because it is necessary for AlterTableParamStmt
3200  std::size_t sz;
3201  int iVal = std::stoi(literal_string, &sz);
3202  if (sz == literal_string.size()) {
3203  literal_value = new Parser::IntLiteral(iVal);
3204  } else {
3205  literal_value = new Parser::StringLiteral(&literal_string);
3206  }
3207  } else if (itr->value.IsInt() || itr->value.IsInt64()) {
3208  literal_value = new Parser::IntLiteral(json_i64(itr->value));
3209  } else if (itr->value.IsNull()) {
3210  literal_value = new Parser::NullLiteral();
3211  } else {
3212  throw std::runtime_error("Unable to handle literal for " + *option_name);
3213  }
3214  CHECK(literal_value);
3216  new Parser::NameValueAssign(option_name, literal_value);
3217  std::unique_ptr<Parser::DDLStmt>(
3218  new Parser::AlterTableParamStmt(new std::string(tableName), nv))
3219  ->execute(*session_ptr_, read_only_mode);
3220  return {};
3221  }
3222  } else {
3223  CHECK(options.IsNull());
3224  }
3225  }
3226 
3227  return ExecutionResult();
3228 }
3229 
3231  const DdlCommandData& ddl_data,
3232  std::shared_ptr<const Catalog_Namespace::SessionInfo> session_ptr)
3233  : DdlCommand(ddl_data, session_ptr) {
3234  if (!g_enable_fsi) {
3235  throw std::runtime_error("Unsupported command: ALTER FOREIGN TABLE");
3236  }
3237  auto& ddl_payload = extractPayload(ddl_data_);
3238  CHECK(ddl_payload.HasMember("tableName"));
3239  CHECK(ddl_payload["tableName"].IsString());
3240  CHECK(ddl_payload.HasMember("alterType"));
3241  CHECK(ddl_payload["alterType"].IsString());
3242  if (ddl_payload["alterType"] == "RENAME_TABLE") {
3243  CHECK(ddl_payload.HasMember("newTableName"));
3244  CHECK(ddl_payload["newTableName"].IsString());
3245  } else if (ddl_payload["alterType"] == "RENAME_COLUMN") {
3246  CHECK(ddl_payload.HasMember("oldColumnName"));
3247  CHECK(ddl_payload["oldColumnName"].IsString());
3248  CHECK(ddl_payload.HasMember("newColumnName"));
3249  CHECK(ddl_payload["newColumnName"].IsString());
3250  } else if (ddl_payload["alterType"] == "ALTER_OPTIONS") {
3251  CHECK(ddl_payload.HasMember("options"));
3252  CHECK(ddl_payload["options"].IsObject());
3253  } else {
3254  UNREACHABLE() << "Not a valid alter foreign table command: "
3255  << ddl_payload["alterType"].GetString();
3256  }
3257 }
3258 
3260  if (read_only_mode) {
3261  throw std::runtime_error("ALTER FOREIGN TABLE invalid in read only mode.");
3262  }
3263 
3264  auto& ddl_payload = extractPayload(ddl_data_);
3265  std::string alter_type = ddl_payload["alterType"].GetString();
3266 
3267  // We only need a write lock if we are renaming a table, otherwise a read lock will do.
3270 
3271  if (alter_type == "RENAME_TABLE") {
3272  write_lock = legacylockmgr::getExecuteWriteLock();
3273  } else {
3274  read_lock = legacylockmgr::getExecuteReadLock();
3275  }
3276 
3277  auto& catalog = session_ptr_->getCatalog();
3278  const std::string& table_name = ddl_payload["tableName"].GetString();
3279  auto [td, td_with_lock] =
3280  get_table_descriptor_with_lock<lockmgr::WriteLock>(catalog, table_name, false);
3281 
3283 
3284  if (!session_ptr_->checkDBAccessPrivileges(
3286  throw std::runtime_error(
3287  "Current user does not have the privilege to alter foreign table: " + table_name);
3288  }
3289 
3290  auto table_data_write_lock =
3292  auto foreign_table = dynamic_cast<const foreign_storage::ForeignTable*>(td);
3293  CHECK(foreign_table);
3294 
3295  // std::string alter_type = ddl_payload["alterType"].GetString();
3296  if (alter_type == "RENAME_TABLE") {
3297  renameTable(foreign_table);
3298  } else if (alter_type == "RENAME_COLUMN") {
3299  renameColumn(foreign_table);
3300  } else if (alter_type == "ALTER_OPTIONS") {
3301  alterOptions(*foreign_table);
3302  }
3303 
3304  return ExecutionResult();
3305 }
3306 
3308  const foreign_storage::ForeignTable* foreign_table) {
3309  auto& ddl_payload = extractPayload(ddl_data_);
3310  auto& cat = session_ptr_->getCatalog();
3311  const std::string& table_name = ddl_payload["tableName"].GetString();
3312  const std::string& new_table_name = ddl_payload["newTableName"].GetString();
3313  if (cat.getForeignTable(new_table_name)) {
3314  throw std::runtime_error("Foreign table with name \"" + table_name +
3315  "\" can not be renamed to \"" + new_table_name + "\". " +
3316  "A different table with name \"" + new_table_name +
3317  "\" already exists.");
3318  }
3319  cat.renameTable(foreign_table, new_table_name);
3320 }
3321 
3323  const foreign_storage::ForeignTable* foreign_table) {
3324  auto& ddl_payload = extractPayload(ddl_data_);
3325  auto& cat = session_ptr_->getCatalog();
3326  const std::string& old_column_name = ddl_payload["oldColumnName"].GetString();
3327  const std::string& new_column_name = ddl_payload["newColumnName"].GetString();
3328  auto column = cat.getMetadataForColumn(foreign_table->tableId, old_column_name);
3329  if (!column) {
3330  throw std::runtime_error("Column with name \"" + old_column_name +
3331  "\" can not be renamed to \"" + new_column_name + "\". " +
3332  "Column with name \"" + old_column_name +
3333  "\" does not exist.");
3334  }
3335  if (cat.getMetadataForColumn(foreign_table->tableId, new_column_name)) {
3336  throw std::runtime_error("Column with name \"" + old_column_name +
3337  "\" can not be renamed to \"" + new_column_name + "\". " +
3338  "A column with name \"" + new_column_name +
3339  "\" already exists.");
3340  }
3341  cat.renameColumn(foreign_table, column, new_column_name);
3342 }
3343 
3345  const foreign_storage::ForeignTable& foreign_table) {
3346  auto& ddl_payload = extractPayload(ddl_data_);
3347  const std::string& table_name = ddl_payload["tableName"].GetString();
3348  auto& cat = session_ptr_->getCatalog();
3349  auto new_options_map =
3350  foreign_storage::ForeignTable::createOptionsMap(ddl_payload["options"]);
3351  foreign_table.validateSupportedOptionKeys(new_options_map);
3352  foreign_table.validateAlterOptions(new_options_map);
3353  cat.setForeignTableOptions(table_name, new_options_map, false);
3354 }
3355 
3357  const DdlCommandData& ddl_data,
3358  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
3359  : DdlCommand(ddl_data, session_ptr) {
3360  auto& ddl_payload = extractPayload(ddl_data_);
3361  if (ddl_payload.HasMember("tableNames")) {
3362  CHECK(ddl_payload["tableNames"].IsArray());
3363  for (auto const& tablename_def : ddl_payload["tableNames"].GetArray()) {
3364  CHECK(tablename_def.IsString());
3365  }
3366  }
3367 }
3368 
3370  auto table_names = session_ptr_->get_catalog_ptr()->getTableNamesForUser(
3371  session_ptr_->get_currentUser(), GET_PHYSICAL_TABLES);
3372 
3373  auto& ddl_payload = extractPayload(ddl_data_);
3374  if (ddl_payload.HasMember("tableNames")) {
3375  std::vector<std::string> filtered_names;
3376  for (const auto& tablename_def : ddl_payload["tableNames"].GetArray()) {
3377  std::string filter_name = tablename_def.GetString();
3378  if (std::find(table_names.begin(), table_names.end(), filter_name) !=
3379  table_names.end()) {
3380  filtered_names.emplace_back(filter_name);
3381  } else {
3382  throw std::runtime_error("Can not show disk cache usage for table: " +
3383  filter_name + ". Table does not exist.");
3384  }
3385  }
3386  return filtered_names;
3387  } else {
3388  return table_names;
3389  }
3390 }
3391 
3393  auto execute_read_lock = legacylockmgr::getExecuteReadLock();
3394 
3395  // valid in read_only_mode
3396 
3397  auto cat_ptr = session_ptr_->get_catalog_ptr();
3398  auto table_names = getFilteredTableNames();
3399 
3400  const auto disk_cache = cat_ptr->getDataMgr().getPersistentStorageMgr()->getDiskCache();
3401  if (!disk_cache) {
3402  throw std::runtime_error{"Disk cache not enabled. Cannot show disk cache usage."};
3403  }
3404 
3405  // label_infos -> column labels
3406  std::vector<std::string> labels{"table name", "current cache size"};
3407  std::vector<TargetMetaInfo> label_infos;
3408  label_infos.emplace_back(labels[0], SQLTypeInfo(kTEXT, true));
3409  label_infos.emplace_back(labels[1], SQLTypeInfo(kBIGINT, true));
3410 
3411  std::vector<RelLogicalValues::RowValues> logical_values;
3412 
3414  table_names,
3415  cat_ptr.get(),
3416  [&logical_values, &disk_cache, &cat_ptr](const TableDescriptor* td,
3417  const std::string& table_name) {
3418  auto table_cache_size =
3419  disk_cache->getSpaceReservedByTable(cat_ptr->getDatabaseId(), td->tableId);
3420  // logical_values -> table data
3421  logical_values.emplace_back(RelLogicalValues::RowValues{});
3422  logical_values.back().emplace_back(genLiteralStr(table_name));
3423  logical_values.back().emplace_back(genLiteralBigInt(table_cache_size));
3424  });
3425 
3426  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
3427  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
3428 
3429  return ExecutionResult(rSet, label_infos);
3430 }
3431 
3433  const DdlCommandData& ddl_data,
3434  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
3435  : DdlCommand(ddl_data, session_ptr) {
3436  auto& ddl_payload = extractPayload(ddl_data);
3437  if (ddl_payload.HasMember("userNames")) {
3438  CHECK(ddl_payload["userNames"].IsArray());
3439  for (const auto& user_name : ddl_payload["userNames"].GetArray()) {
3440  CHECK(user_name.IsString());
3441  }
3442  }
3443  CHECK(ddl_payload.HasMember("all"));
3444  CHECK(ddl_payload["all"].IsBool());
3445 }
3446 
3448  auto execute_read_lock = legacylockmgr::getExecuteReadLock();
3449 
3450  // valid in read_only_mode
3451 
3452  auto& ddl_payload = extractPayload(ddl_data_);
3453  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
3454 
3455  Catalog_Namespace::UserMetadata self = session_ptr_->get_currentUser();
3456  bool all = ddl_payload.HasMember("all") ? ddl_payload["all"].GetBool() : false;
3457  if (all && !self.isSuper) {
3458  throw std::runtime_error(
3459  "SHOW ALL USER DETAILS is only available to superusers. (Try SHOW USER "
3460  "DETAILS instead?)");
3461  }
3462 
3463  // label_infos -> column labels
3464  std::vector<TargetMetaInfo> label_infos;
3465  label_infos.emplace_back("NAME", SQLTypeInfo(kTEXT, true));
3466  label_infos.emplace_back("ID", SQLTypeInfo(kBIGINT, true));
3467  if (all) {
3468  label_infos.emplace_back("IS_SUPER", SQLTypeInfo(kBOOLEAN, true));
3469  }
3470  label_infos.emplace_back("DEFAULT_DB", SQLTypeInfo(kTEXT, true));
3471  if (self.isSuper) {
3472  label_infos.emplace_back("CAN_LOGIN", SQLTypeInfo(kBOOLEAN, true));
3473  }
3474  std::vector<RelLogicalValues::RowValues> logical_values;
3475 
3476  auto cat = session_ptr_->get_catalog_ptr();
3477  DBObject dbObject(cat->name(), DatabaseDBObjectType);
3478  dbObject.loadKey();
3479  dbObject.setPrivileges(AccessPrivileges::ACCESS);
3480 
3481  std::map<std::string, Catalog_Namespace::UserMetadata> user_map;
3482  auto user_list = !all ? sys_cat.getAllUserMetadata(cat->getDatabaseId())
3483  : sys_cat.getAllUserMetadata();
3484  for (auto& user : user_list) {
3485  if (user.can_login || self.isSuper) { // hide users who have disabled accounts
3486  user_map[user.userName] = user;
3487  }
3488  }
3489 
3490  if (ddl_payload.HasMember("userNames")) {
3491  std::map<std::string, Catalog_Namespace::UserMetadata> user_map2;
3492  for (const auto& user_name_json : ddl_payload["userNames"].GetArray()) {
3493  std::string user_name = user_name_json.GetString();
3494  auto uit = user_map.find(user_name);
3495  if (uit == user_map.end()) {
3496  throw std::runtime_error("User \"" + user_name + "\" not found. ");
3497  }
3498  user_map2[uit->first] = uit->second;
3499  }
3500  user_map = user_map2;
3501  }
3502 
3503  Catalog_Namespace::DBSummaryList dbsums = sys_cat.getDatabaseListForUser(self);
3504  std::unordered_set<std::string> visible_databases;
3505  if (!self.isSuper) {
3506  for (const auto& dbsum : dbsums) {
3507  visible_databases.insert(dbsum.dbName);
3508  }
3509  }
3510 
3511  for (const auto& [user_name, user] : user_map) {
3512  // database
3513  std::string dbname;
3515  if (sys_cat.getMetadataForDBById(user.defaultDbId, db)) {
3516  if (self.isSuper || visible_databases.count(db.dbName)) {
3517  dbname = db.dbName;
3518  }
3519  }
3520  if (self.isSuper) {
3521  dbname += "(" + std::to_string(user.defaultDbId) + ")";
3522  }
3523 
3524  // logical_values -> table data
3525  logical_values.emplace_back(RelLogicalValues::RowValues{});
3526  logical_values.back().emplace_back(genLiteralStr(user.userName));
3527  logical_values.back().emplace_back(genLiteralBigInt(user.userId));
3528  if (all) {
3529  logical_values.back().emplace_back(genLiteralBoolean(user.isSuper));
3530  }
3531  logical_values.back().emplace_back(genLiteralStr(dbname));
3532  if (self.isSuper) {
3533  logical_values.back().emplace_back(genLiteralBoolean(user.can_login));
3534  }
3535  }
3536 
3537  // Create ResultSet
3538  CHECK_EQ(logical_values.size(), user_map.size());
3539  if (logical_values.size() >= 1U) {
3540  CHECK_EQ(logical_values[0].size(), label_infos.size());
3541  }
3542  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
3543  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
3544 
3545  return ExecutionResult(rSet, label_infos);
3546 }
3547 
3549  const DdlCommandData& ddl_data,
3550  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
3551  : DdlCommand(ddl_data, session_ptr) {
3552  auto& ddl_payload = extractPayload(ddl_data);
3553  CHECK(ddl_payload["userName"].IsString());
3554  CHECK(ddl_payload["effective"].IsBool());
3555 }
3556 
3558  auto execute_read_lock = legacylockmgr::getExecuteReadLock();
3559 
3560  // valid in read_only_mode
3561 
3562  auto& ddl_payload = extractPayload(ddl_data_);
3563  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
3564 
3565  // label_infos -> column labels
3566  std::vector<TargetMetaInfo> label_infos;
3567  std::vector<std::string> labels{"ROLES"};
3568  label_infos.emplace_back(labels[0], SQLTypeInfo(kTEXT, true));
3569 
3570  // logical_values -> table data
3571  std::vector<RelLogicalValues::RowValues> logical_values;
3572  std::vector<std::string> roles_list;
3573  Catalog_Namespace::UserMetadata self = session_ptr_->get_currentUser();
3574  std::string user_name = ddl_payload["userName"].GetString();
3575  bool effective = ddl_payload["effective"].GetBool();
3576  if (user_name.empty()) {
3577  user_name = self.userName;
3578  }
3580  bool is_user = sys_cat.getMetadataForUser(user_name, user);
3581  if (!self.isSuper) {
3582  if (is_user) {
3583  if (self.userId != user.userId) {
3584  throw std::runtime_error(
3585  "Only a superuser is authorized to request list of roles granted to another "
3586  "user.");
3587  }
3588  } else {
3589  if (!sys_cat.isRoleGrantedToGrantee(
3590  self.userName, user_name, /*only_direct=*/false)) {
3591  throw std::runtime_error(
3592  "Only a superuser is authorized to request list of roles granted to a role "
3593  "they don't have.");
3594  }
3595  }
3596  }
3597  if (user.isSuper) {
3598  auto s = sys_cat.getCreatedRoles();
3599  roles_list.insert(roles_list.end(), s.begin(), s.end());
3600  } else {
3601  roles_list = sys_cat.getRoles(user_name, effective);
3602  }
3603  for (const std::string& role_name : roles_list) {
3604  logical_values.emplace_back(RelLogicalValues::RowValues{});
3605  logical_values.back().emplace_back(genLiteralStr(role_name));
3606  }
3607 
3608  // Create ResultSet
3609  std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
3610  ResultSetLogicalValuesBuilder::create(label_infos, logical_values));
3611 
3612  return ExecutionResult(rSet, label_infos);
3613 }
3614 
3616  const DdlCommandData& ddl_data,
3617  std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
3618  : DdlCommand(ddl_data, session_ptr) {
3619  auto& ddl_payload = extractPayload(ddl_data_);
3620  CHECK(ddl_payload.HasMember("all"));
3621  CHECK(ddl_payload["all"].IsBool());
3622  CHECK(ddl_payload.HasMember("oldOwners"));
3623  CHECK(ddl_payload["oldOwners"].IsArray());
3624  for (const auto& old_owner : ddl_payload["oldOwners"].GetArray()) {
3625  CHECK(old_owner.IsString());
3626  old_owners_.emplace(old_owner.GetString());
3627  }
3628  CHECK(ddl_payload.HasMember("newOwner"));
3629  CHECK(ddl_payload["newOwner"].IsString());
3630  new_owner_ = ddl_payload["newOwner"].GetString();
3631  all_ = ddl_payload["all"].GetBool();
3632 }
3633 
3635  auto execute_write_lock = legacylockmgr::getExecuteWriteLock();
3636 
3637  if (read_only_mode) {
3638  throw std::runtime_error("REASSIGN OWNER invalid in read only mode.");
3639  }
3640  if (!session_ptr_->get_currentUser().isSuper) {
3641  throw std::runtime_error{
3642  "Only super users can reassign ownership of database objects."};
3643  }
3644  if (all_) {
3646  for (auto& catalog : catalogs) {
3647  catalog->reassignOwners(old_owners_, new_owner_);
3648  }
3649  } else {
3650  const auto catalog = session_ptr_->get_catalog_ptr();
3651  catalog->reassignOwners(old_owners_, new_owner_);
3652  }
3653  return ExecutionResult();
3654 }
ExecutionResult execute(bool read_only_mode) override
bool contains(const T &container, const U &element)
Definition: misc.h:195
int32_t maxRollbackEpochs
ShowForeignServersCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
static constexpr const char * WS_SERVER_ACCESS_LOGS_SYS_TABLE_NAME
Definition: Catalog.h:128
void alterGeoColumnData(const TableDescriptor *td, const std::list< std::pair< const ColumnDescriptor *, std::list< const ColumnDescriptor * >>> &geo_src_dst_cds)
void set_size(int s)
Definition: sqltypes.h:476
ExecutionResult execute(bool read_only_mode) override
#define CHECK_EQ(x, y)
Definition: Logger.h:301
ExecutionResult execute(bool read_only_mode) override
std::string partitions
std::vector< int > ChunkKey
Definition: types.h:36
ShowRolesCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
static constexpr const char * SERVER_LOGS_SYS_TABLE_NAME
Definition: Catalog.h:125
ExecutionResult execute(bool read_only_mode) override
std::vector< std::string > getFilteredModelNames()
AlterForeignServerCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
void cleanupRecoveryInfo(const TableDescriptor *td)
static std::vector< TableFunction > get_table_funcs()
std::pair< std::vector< double >, std::vector< std::vector< double > > > extractExtraMetadata(std::shared_ptr< AbstractMLModel > model, std::vector< TargetMetaInfo > &label_infos) const
AlterTableAlterColumnCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
void alterOptions(const foreign_storage::ForeignTable &foreign_table)
const std::string getTargetQuerySessionToKill() const
declare this class scoped local to avoid exposing rapidjson in the header file
std::vector< Catalog * > getCatalogsForAllDbs()
ShowCreateTableCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
static const AccessPrivileges DROP_SERVER
Definition: DBObject.h:189
std::string cat(Ts &&...args)
ShowCreateServerCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
void validate_alter_type_allowed(const std::string &colname, const SQLTypeInfo &src, const SQLTypeInfo &dst)
std::unique_ptr< DdlCommandData > ddl_data_
std::string getOptionsAsJsonString() const
static std::vector< ExtensionFunction > get_ext_funcs(const std::string &name)
class for a per-database catalog. also includes metadata for the current database and the current use...
Definition: Catalog.h:143
Definition: sqltypes.h:76
SQLTypes
Definition: sqltypes.h:65
const std::string commandStr() const
void clearInMemoryData(const TableDescriptor *td, const TypePairs &src_dst_cds)
std::string tableName
ExecutionResult execute(bool read_only_mode) override
static TimeT::rep execution(F func, Args &&...args)
Definition: sample.cpp:29
ExecutionResult execute(bool read_only_mode) override
CompareResult compare_column_descriptors(const ColumnDescriptor *lhs, const ColumnDescriptor *rhs)
Definition: DdlUtils.cpp:52
void set_column_descriptor(ColumnDescriptor &cd, const ColumnDef *coldef)
ExecutionResult execute(bool read_only_mode) override
static const AccessPrivileges ALTER_TABLE
Definition: DBObject.h:165
ExecutionResult execute(bool read_only_mode) override
AlterTableAlterColumnCommandRecoveryMgr::RecoveryInfo recovery_info_
auto getExecuteReadLock()
CreateForeignServerCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
RecoveryParamFilepathInfo getRecoveryFilepathInfo(const int32_t table_id=-1)
Data_Namespace::DataMgr & getDataMgr() const
Definition: Catalog.h:266
std::unique_ptr< RexLiteral > genLiteralDouble(double val)
void validateAlterOptions(const OptionsMap &options_map) const
Verifies that the given options map only contains options that can be legally altered.
ExecutionResult execute(bool read_only_mode) override
#define NULL_BIGINT
std::pair< std::list< ColumnDescriptor >, std::list< ColumnDescriptor > > get_alter_column_src_dst_cds(const std::list< Parser::ColumnDef > &columns, Catalog_Namespace::Catalog &catalog, const TableDescriptor *td)
#define LOG(tag)
Definition: Logger.h:285
static WriteLock getWriteLockForTable(const Catalog_Namespace::Catalog &cat, const std::string &table_name)
Definition: LockMgrImpl.h:225
ShowDatabasesCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
ExecutionResult execute(bool read_only_mode) override
std::vector< MLModelMetadata > getModelMetadata() const
Definition: MLModel.h:83
ExecutionResult execute(bool read_only_mode) override
std::string storageType
void revokeDBObjectPrivilegesFromAll(DBObject object, Catalog *catalog)
const std::string json_str(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:46
static const AccessPrivileges SERVER_USAGE
Definition: DBObject.h:191
static std::shared_ptr< QueryState > create(ARGS &&...args)
Definition: QueryState.h:148
std::string join(T const &container, std::string const &delim)
DropForeignTableCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
#define UNREACHABLE()
Definition: Logger.h:338
ExecutionResult execute(bool read_only_mode) override
const std::vector< std::string > & getFeatures() const
Driver for running cleanup processes on a table. TableOptimizer provides functions for various cleanu...
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...
The InsertOrderFragmenter is a child class of AbstractFragmenter, and fragments data in insert order...
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:119
void refresh_foreign_table(Catalog_Namespace::Catalog &catalog, const std::string &table_name, const bool evict_cached_entries)
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)
bool isForeignTable() const
#define CHECK_GT(x, y)
Definition: Logger.h:305
AggregatedResult query(QueryStateProxy, std::string &sql_query_string, std::vector< size_t > outer_frag_indices, bool validate_only, bool allow_interrupt)
ExecutionResult execute(bool read_only_mode) override
void createDBObject(const UserMetadata &user, const std::string &objectName, DBObjectType type, const Catalog_Namespace::Catalog &catalog, int32_t objectId=-1)
std::string sourceName
void alterColumns(const TableDescriptor *td, const TypePairs &src_dst_cds)
std::string to_string(char const *&&v)
std::vector< std::string > split(std::string_view str, std::string_view delim, std::optional< size_t > maxsplit)
split apart a string into a vector of substrings
void set_headers_with_type(std::vector< TargetMetaInfo > &label_infos, const std::vector< std::tuple< std::string, SQLTypes, bool >> &headers)
DistributedExecutionDetails getDistributedExecutionDetails() const
std::pair< std::string, std::string > getSessionParameter() const
EvaluateModelCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
std::unique_lock< WrapperType< std::shared_mutex >> ExecutorWriteLock
ExecutionResult execute(bool read_only_mode) override
void validate_non_duplicate_column(const std::string &column_name, std::unordered_set< std::string > &upper_column_names)
Definition: DdlUtils.cpp:728
ExecutionResult execute(bool read_only_mode) override
std::string chunks
std::set< std::string > old_owners_
static constexpr const char * REQUEST_LOGS_SYS_TABLE_NAME
Definition: Catalog.h:126
void alterNonGeoColumnData(const TableDescriptor *td, const std::list< const ColumnDescriptor * > &cds)
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:698
static std::shared_ptr< Executor > getExecutor(const ExecutorId id, const std::string &debug_dir="", const std::string &debug_file="", const SystemParameters &system_parameters=SystemParameters())
Definition: Execute.cpp:509
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:190
std::unique_ptr< RexLiteral > genLiteralBigInt(int64_t val)
This file contains the class specification and related data structures for Catalog.
bool g_restrict_ml_model_metadata_to_superusers
Definition: Execute.cpp:119
ExecutionResult execute(bool read_only_mode) override
void setTableDetails(const std::string &table_name, TableDescriptor &td, const std::list< ColumnDescriptor > &columns)
bool isAlterSystemClear() const
ExecutionResult execute(bool read_only_mode) override
const DdlCommandData & ddl_data_
std::list< std::pair< const ColumnDescriptor *, std::list< const ColumnDescriptor * > > > get_alter_column_geo_pairs_from_src_dst_pairs_phys_cds(const AlterTableAlterColumnCommand::TypePairs &src_dst_cds, const std::list< std::list< ColumnDescriptor >> &phys_cds)
bool is_default_server(const std::string &server_name)
ShowModelFeatureDetailsCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
std::shared_lock< WrapperType< std::shared_mutex >> ExecutorReadLock
static SysCatalog & instance()
Definition: SysCatalog.h:343
This file contains the class specification and related data structures for SysCatalog.
std::vector< TargetMetaInfo > prepareLabelInfos() const
int32_t validate_and_get_fragment_size(const std::string &fragment_size_str)
void populateAndWriteRecoveryInfo(const TableDescriptor *td, const TypePairs &src_dst_cds)
std::list< std::pair< ColumnDescriptor, ColumnDescriptor > > src_dst_cds
Classes representing a parse tree.
void checkpoint(const TableDescriptor *td, const TypePairs &src_dst_cds)
ExecutionResult execute(bool read_only_mode) override
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:159
std::optional< uint64_t > total_free_metadata_page_count
Definition: FileMgr.h:115
ExecutionResult execute(bool read_only_mode) override
void populateOptionsMap(OptionsMap &&options_map, bool clear=false)
void getChunkMetadataVecForKeyPrefix(ChunkMetadataVector &chunkMetadataVec, const ChunkKey &keyPrefix)
Definition: DataMgr.cpp:496
const int64_t json_i64(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:41
std::list< ColumnDef > get_columns_from_json_payload(const std::string &payload_key, const rapidjson::Value &payload)
std::list< const ColumnDescriptor * > prepareColumns(const TableDescriptor *td, const TypePairs &src_dst_cds)
const rapidjson::Value & extractPayload(const DdlCommandData &ddl_data)
static std::unordered_set< std::string > get_udfs_name(const bool is_runtime)
std::unique_ptr< RexLiteral > genLiteralTimestamp(time_t val)
AlterDatabaseCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
bool isShowUserSessions() const
const ColumnDescriptor * getMetadataForColumn(int tableId, const std::string &colName) const
ExecutionResult execute(bool read_only_mode) override
DBSummaryList getDatabaseListForUser(const UserMetadata &user)
Checked json field retrieval.
std::vector< std::pair< ChunkKey, std::shared_ptr< ChunkMetadata >>> ChunkMetadataVector
bool g_enable_watchdog
int getDatabaseId() const
Definition: Catalog.h:326
uint64_t total_metadata_page_count
Definition: FileMgr.h:114
static const AccessPrivileges CREATE_SERVER
Definition: DBObject.h:188
void updateResultSet(const std::string &query_ra, RType type, bool success=true)
void vacuumDeletedRows() const
Compacts fragments to remove deleted rows. When a row is deleted, a boolean deleted system column is ...
std::string recoveryFilepath(const RecoveryParamFilepathInfo &filepath_info)
bool is_dict_encoded_type() const
Definition: sqltypes.h:653
std::unique_ptr< RexLiteral > genLiteralBoolean(bool val)
void validate_non_reserved_keyword(const std::string &column_name)
Definition: DdlUtils.cpp:737
specifies the content in-memory of a row in the column metadata table
OUTPUT transform(INPUT const &input, FUNC const &func)
Definition: misc.h:320
void collectExpectedCatalogChanges(const TableDescriptor *td, const TypePairs &src_dst_cds)
void alterColumnTypes(const TableDescriptor *td, const TypePairs &src_dst_cds)
std::list< std::list< ColumnDescriptor > > prepareGeoColumns(const TableDescriptor *td, const TypePairs &src_dst_cds)
std::shared_ptr< AbstractMLModel > getModel(const std::string &model_name) const
Definition: MLModel.h:50
static const AccessPrivileges CREATE_TABLE
Definition: DBObject.h:158
std::vector< const TableDescriptor * > getPhysicalTablesDescriptors(const TableDescriptor *logical_table_desc, bool populate_fragmenter=true) const
Definition: Catalog.cpp:4869
std::string keyMetainfo
ExecutionResult execute(bool read_only_mode) override
void set_default_table_attributes(const std::string &table_name, TableDescriptor &td, const int32_t column_count)
Definition: DdlUtils.cpp:714
std::shared_ptr< Fragmenter_Namespace::AbstractFragmenter > fragmenter
File_Namespace::GlobalFileMgr * getGlobalFileMgr() const
Definition: DataMgr.cpp:649
std::string to_upper(const std::string &str)
static ResultSet * create(std::vector< TargetMetaInfo > &label_infos, std::vector< RelLogicalValues::RowValues > &logical_values)
void set_comp_param(int p)
Definition: sqltypes.h:480
MLModelMap g_ml_models
Definition: MLModel.h:124
void loadKey()
Definition: DBObject.cpp:190
bool isAlterSessionSet() const
Definition: sqltypes.h:79
Definition: sqltypes.h:80
std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr_
void check_alter_table_privilege(const Catalog_Namespace::SessionInfo &session, const TableDescriptor *td)
std::vector< std::string > getFilteredTableNames()
DdlCommandExecutor(const std::string &ddl_statement, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
ShowModelDetailsCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
ExecutionResult execute(bool read_only_mode)
AggregratedStorageStats get_agg_storage_stats(const TableDescriptor *td, const Catalog_Namespace::Catalog *catalog)
#define CHECK_LE(x, y)
Definition: Logger.h:304
ExecutionResult execute(bool read_only_mode) override
uint64_t total_metadata_file_size
Definition: FileMgr.h:113
bool isTemporaryTable() const
std::string returnQueueAction() const
AlterTableAlterColumnCommandRecoveryMgr recovery_mgr_
bool table_is_temporary(const TableDescriptor *const td)
AlterTableCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
static ReadLock getReadLockForTable(Catalog_Namespace::Catalog &cat, const std::string &table_name)
Definition: LockMgrImpl.h:238
ExecutionResult execute(bool read_only_mode) override
void setStringDictKey(const shared::StringDictKey &dict_key)
Definition: sqltypes.h:1061
Basic constructors and methods of the row set interface.
std::tuple< const TableDescriptor *, std::unique_ptr< lockmgr::TableSchemaLockContainer< LockType > > > get_table_descriptor_with_lock(Catalog_Namespace::Catalog &cat, const std::string &table_name, const bool populate_fragmenter)
void renameDatabase(std::string const &old_name, std::string const &new_name)
AlterTableAlterColumnCommand::TypePairs get_alter_column_pairs_from_src_dst_cds(std::list< ColumnDescriptor > &src_cds, std::list< ColumnDescriptor > &dst_cds)
static const AccessPrivileges ACCESS
Definition: DBObject.h:153
ReassignOwnedCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
std::vector< std::string > getFilteredTableNames()
bool g_enable_ml_functions
Definition: Execute.cpp:118
void validate_alter_type_metadata(const Catalog_Namespace::Catalog &catalog, const TableDescriptor *td, const ColumnDescriptor &cd)
HOST DEVICE int get_comp_param() const
Definition: sqltypes.h:402
static std::unique_ptr< RexLiteral > genLiteralStr(std::string val)
Definition: DBHandler.cpp:7752
ExecutionResult execute(bool read_only_mode) override
std::string returnCacheType() const
void validate_table_type(const TableDescriptor *td, const TableType expected_table_type, const std::string &command)
Definition: DdlUtils.cpp:745
const ForeignServer * foreign_server
Definition: ForeignTable.h:57
void cleanup(const TableDescriptor *td, const TypePairs &src_dst_cds)
void renameTable(const foreign_storage::ForeignTable *foreign_table)
ShowFunctionsCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
const std::vector< double > & getCoefs() const
Definition: MLModel.h:145
#define CHECK(condition)
Definition: Logger.h:291
alter_column_shared::TypePairs TypePairs
#define DEBUG_TIMER(name)
Definition: Logger.h:412
const std::vector< double > & getEigenvalues() const
Definition: MLModel.h:370
ExecutionResult execute(bool read_only_mode) override
std::unique_ptr< ColumnDef > column_from_json(const rapidjson::Value &element)
std::vector< std::string > getModelNames() const
Definition: MLModel.h:74
static void clearExternalCaches(bool for_update, const TableDescriptor *td, const int current_db_id)
Definition: Execute.h:438
void exec_for_tables_which_exist(const std::vector< std::string > &table_names, Catalog_Namespace::Catalog *cat_ptr, Func func)
ExecutionResult execute(bool read_only_mode) override
bool g_cluster
std::vector< RelLogicalValues::RowValues > prepareLogicalValues(const MLModelMetadata &model_metadata, const std::vector< std::vector< std::string >> &cat_sub_features, std::vector< double > &extra_metadata, const std::vector< std::vector< double >> &eigenvectors, const std::vector< int64_t > &inverse_permutations) const
auto getExecuteWriteLock()
void vacuum_table_if_required(const Catalog_Namespace::Catalog &catalog, const TableDescriptor *td)
list header
Definition: report.py:113
bool is_regression_model(const MLModelType model_type)
Definition: MLModelType.h:69
std::list< DBSummary > DBSummaryList
Definition: SysCatalog.h:145
std::string viewSQL
std::list< ColumnDescriptor > getColumnDescriptors(AggregatedResult &result, bool for_create)
bool is_dict_encoded_string() const
Definition: sqltypes.h:641
Definition: sqltypes.h:72
SQLTypeInfo columnType
AggregratedStorageStats(const File_Namespace::StorageStats &storage_stats)
bool any_of(std::vector< Analyzer::Expr * > const &target_exprs)
const TableDescriptor * getMetadataForTable(const std::string &tableName, const bool populateFragmenter=true) const
Returns a pointer to a const TableDescriptor struct matching the provided tableName.
std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr_
static constexpr ExecutorId UNITARY_EXECUTOR_ID
Definition: Execute.h:423
std::vector< std::unique_ptr< const RexScalar >> RowValues
Definition: RelAlgDag.h:2656
ExecutionResult execute(bool read_only_mode) override
bool is_string() const
Definition: sqltypes.h:559
ExecutionLocation execution_location
bool isAlterSystemControlExecutorQueue() const
string name
Definition: setup.in.py:72
void rollback(const TableDescriptor *td, const RecoveryInfo &param)
const rapidjson::Value * extractFilters(const rapidjson::Value &payload)
AlterForeignTableCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:398
const MLModelType getModelType() const
void renameColumn(const foreign_storage::ForeignTable *foreign_table)
const std::array< std::string, 3 > kReservedServerPrefixes
void writeSerializedRecoveryInformation(const RecoveryInfo &param, const RecoveryParamFilepathInfo &filepath_info)
static constexpr char const * FOREIGN_TABLE
bool g_enable_fsi
Definition: Catalog.cpp:96
ShowRuntimeFunctionsCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
std::string columnName
static constexpr const char * WS_SERVER_LOGS_SYS_TABLE_NAME
Definition: Catalog.h:127
ShowUserDetailsCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
#define IS_GEO(T)
Definition: sqltypes.h:310
#define VLOG(n)
Definition: Logger.h:388
std::atomic< bool > isSuper
Definition: SysCatalog.h:107
ShowRuntimeTableFunctionsCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
RefreshForeignTablesCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
ExecutionResult execute(bool read_only_mode) override
ShowModelsCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
ShowTableFunctionsCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)