19 #include <boost/algorithm/string/predicate.hpp>
21 #include "rapidjson/document.h"
39 return boost::iequals(server_name.substr(0, 7),
"omnisci");
43 template <
class LockType>
45 std::unique_ptr<lockmgr::TableSchemaLockContainer<LockType>>>
47 const std::string& table_name,
48 const bool populate_fragmenter) {
49 const TableDescriptor* td{
nullptr};
50 std::unique_ptr<lockmgr::TableSchemaLockContainer<LockType>> td_with_lock =
51 std::make_unique<lockmgr::TableSchemaLockContainer<LockType>>(
53 cat, table_name, populate_fragmenter));
55 td = (*td_with_lock)();
57 return std::make_tuple(td, std::move(td_with_lock));
67 : File_Namespace::StorageStats(storage_stats)
68 , min_epoch(storage_stats.epoch)
69 , max_epoch(storage_stats.epoch)
70 , min_epoch_floor(storage_stats.epoch_floor)
71 , max_epoch_floor(storage_stats.epoch_floor) {}
78 if (total_free_metadata_page_count) {
79 total_free_metadata_page_count.value() +=
89 if (total_free_data_page_count) {
90 total_free_data_page_count.value() +=
96 min_epoch = std::min(min_epoch, storage_stats.
epoch);
97 max_epoch = std::max(max_epoch, storage_stats.
epoch);
98 min_epoch_floor = std::min(min_epoch_floor, storage_stats.
epoch_floor);
99 max_epoch_floor = std::max(max_epoch_floor, storage_stats.
epoch_floor);
106 std::optional<AggregratedStorageStats> agg_storage_stats;
111 for (
const auto physical_table : physical_tables) {
112 auto storage_stats = global_file_mgr->getStorageStats(catalog->
getDatabaseId(),
113 physical_table->tableId);
114 if (agg_storage_stats) {
115 agg_storage_stats.value().aggregate(storage_stats);
117 agg_storage_stats = storage_stats;
124 CHECK(agg_storage_stats.has_value());
125 return agg_storage_stats.value();
129 return std::unique_ptr<RexLiteral>(
134 return std::unique_ptr<RexLiteral>(
new RexLiteral(
139 return std::unique_ptr<RexLiteral>(
144 return std::unique_ptr<RexLiteral>(
151 std::vector<TargetMetaInfo>& label_infos,
152 const std::vector<std::tuple<std::string, SQLTypes, bool>>& headers) {
153 for (
const auto& header : headers) {
154 auto [_val, _type, _notnull] = header;
156 label_infos.emplace_back(_val,
SQLTypeInfo(_type, _notnull));
158 UNREACHABLE() <<
"Unsupported type provided for header. SQL type: "
165 const TableDescriptor* logical_table,
167 bool is_sharded_table = (logical_table->
nShards > 0);
181 logical_values.back().emplace_back(
183 logical_values.back().emplace_back(
185 logical_values.back().emplace_back(
189 logical_values.back().emplace_back(
196 logical_values.back().emplace_back(
198 logical_values.back().emplace_back(
202 logical_values.back().emplace_back(
218 : ddl_utils::SqlType(getSqlType(data_type),
219 getParam1(data_type),
220 getParam2(data_type),
222 getArraySize(data_type)) {}
225 static SQLTypes getSqlType(
const rapidjson::Value& data_type);
227 static int getParam1(
const rapidjson::Value& data_type);
228 static int getParam2(
const rapidjson::Value& data_type);
229 static bool isArray(
const rapidjson::Value& data_type);
230 static int getArraySize(
const rapidjson::Value& data_type);
236 : ddl_utils::Encoding(getEncodingName(data_type), getEncodingParam(data_type)) {}
239 static std::string* getEncodingName(
const rapidjson::Value& data_type);
240 static int getEncodingParam(
const rapidjson::Value& data_type);
256 const rapidjson::Value& query()
const;
259 const rapidjson::Value& payload()
const;
262 virtual std::string commandStr()
override;
267 DdlCommandDataImpl::DdlCommandDataImpl(
const std::string& ddl_statement)
288 if (
payload.HasMember(
"command") &&
payload[
"command"].IsString()) {
289 return payload[
"command"].GetString();
302 const rapidjson::Value* filters =
nullptr;
303 if (payload.HasMember(
"filters") && payload[
"filters"].IsArray()) {
304 filters = &payload[
"filters"];
312 const std::string& ddl_statement,
313 std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
314 : session_ptr_(session_ptr) {
315 CHECK(!ddl_statement.empty());
321 DdlCommandDataImpl* ddl_query_data =
new DdlCommandDataImpl(ddl_statement);
322 ddl_data_ = std::unique_ptr<DdlCommandData>(ddl_query_data);
324 VLOG(2) <<
"Parsing JSON DDL from Calcite: " << ddl_statement;
325 auto& ddl_query = ddl_query_data->query();
326 CHECK(ddl_query.IsObject()) << ddl_statement;
327 CHECK(ddl_query.HasMember(
"payload"));
328 CHECK(ddl_query[
"payload"].IsObject());
329 const auto& payload = ddl_query[
"payload"].GetObject();
330 CHECK(payload.HasMember(
"command"));
331 CHECK(payload[
"command"].IsString());
359 auto execute_write_lock = mapd_unique_lock<mapd_shared_mutex>(
387 LOG(
ERROR) <<
"SHOW QUERIES DDL is not ready yet!\n";
392 CHECK(ddl_payload.HasMember(
"querySession"));
393 const std::string& querySessionPayload = ddl_payload[
"querySession"].GetString();
394 auto querySession = querySessionPayload.substr(1, 8);
397 LOG(
ERROR) <<
"TRY TO KILL QUERY " << querySession
398 <<
" BUT KILL QUERY DDL is not ready yet!\n";
400 throw std::runtime_error(
"Unsupported DDL command");
431 return execution_details;
439 CHECK(ddl_payload.HasMember(
"querySession"));
440 const std::string& query_session = ddl_payload[
"querySession"].GetString();
442 boost::regex session_id_regex{R
"([0-9]{3}-[a-zA-Z0-9]{4})",
443 boost::regex::extended | boost::regex::icase};
444 if (!boost::regex_match(query_session, session_id_regex)) {
445 throw std::runtime_error(
446 "Please provide the correct session ID of the query that you want to interrupt.");
448 return query_session;
457 std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
460 CHECK(ddl_payload.HasMember(
"serverName"));
461 CHECK(ddl_payload[
"serverName"].IsString());
462 CHECK(ddl_payload.HasMember(
"dataWrapper"));
463 CHECK(ddl_payload[
"dataWrapper"].IsString());
464 CHECK(ddl_payload.HasMember(
"options"));
465 CHECK(ddl_payload[
"options"].IsObject());
466 CHECK(ddl_payload.HasMember(
"ifNotExists"));
467 CHECK(ddl_payload[
"ifNotExists"].IsBool());
474 std::string server_name = ddl_payload[
"serverName"].GetString();
476 throw std::runtime_error{
"Server names cannot start with \"omnisci\"."};
478 bool if_not_exists = ddl_payload[
"ifNotExists"].GetBool();
479 if (
session_ptr_->getCatalog().getForeignServer(server_name)) {
483 throw std::runtime_error{
"A foreign server with name \"" + server_name +
484 "\" already exists."};
490 throw std::runtime_error(
"Server " + std::string(server_name) +
491 " will not be created. User has no create privileges.");
495 auto foreign_server = std::make_unique<foreign_storage::ForeignServer>();
496 foreign_server->data_wrapper_type =
to_upper(ddl_payload[
"dataWrapper"].GetString());
497 foreign_server->name = server_name;
498 foreign_server->user_id = current_user.userId;
499 foreign_server->populateOptionsMap(ddl_payload[
"options"]);
500 foreign_server->validate();
503 catalog.createForeignServer(std::move(foreign_server),
504 ddl_payload[
"ifNotExists"].GetBool());
513 std::shared_ptr<const Catalog_Namespace::SessionInfo> session_ptr)
516 CHECK(ddl_payload.HasMember(
"serverName"));
517 CHECK(ddl_payload[
"serverName"].IsString());
518 CHECK(ddl_payload.HasMember(
"alterType"));
519 CHECK(ddl_payload[
"alterType"].IsString());
520 if (ddl_payload[
"alterType"] ==
"SET_OPTIONS") {
521 CHECK(ddl_payload.HasMember(
"options"));
522 CHECK(ddl_payload[
"options"].IsObject());
523 }
else if (ddl_payload[
"alterType"] ==
"SET_DATA_WRAPPER") {
524 CHECK(ddl_payload.HasMember(
"dataWrapper"));
525 CHECK(ddl_payload[
"dataWrapper"].IsString());
526 }
else if (ddl_payload[
"alterType"] ==
"RENAME_SERVER") {
527 CHECK(ddl_payload.HasMember(
"newServerName"));
528 CHECK(ddl_payload[
"newServerName"].IsString());
529 }
else if (ddl_payload[
"alterType"] ==
"CHANGE_OWNER") {
530 CHECK(ddl_payload.HasMember(
"newOwner"));
531 CHECK(ddl_payload[
"newOwner"].IsString());
539 std::string server_name = ddl_payload[
"serverName"].GetString();
541 throw std::runtime_error{
"OmniSci default servers cannot be altered."};
543 if (!
session_ptr_->getCatalog().getForeignServer(server_name)) {
544 throw std::runtime_error{
"Foreign server with name \"" + server_name +
545 "\" does not exist and can not be altered."};
548 throw std::runtime_error(
"Server " + server_name +
549 " can not be altered. User has no ALTER SERVER privileges.");
551 std::string alter_type = ddl_payload[
"alterType"].GetString();
552 if (alter_type ==
"CHANGE_OWNER") {
554 }
else if (alter_type ==
"SET_DATA_WRAPPER") {
556 }
else if (alter_type ==
"SET_OPTIONS") {
558 }
else if (alter_type ==
"RENAME_SERVER") {
567 std::string server_name = ddl_payload[
"serverName"].GetString();
568 std::string new_owner = ddl_payload[
"newOwner"].GetString();
571 throw std::runtime_error(
572 "Only a super user can change a foreign server's owner. "
573 "Current user is not a super-user. "
574 "Foreign server with name \"" +
575 server_name +
"\" will not have owner changed.");
578 if (!sys_cat.getMetadataForUser(new_owner, user)) {
579 throw std::runtime_error(
"User with username \"" + new_owner +
"\" does not exist. " +
580 "Foreign server with name \"" + server_name +
581 "\" can not have owner changed.");
585 bool original_owner_exists = sys_cat.getMetadataForUserById(
586 cat.getForeignServer(server_name)->user_id, original_owner);
588 cat.changeForeignServerOwner(server_name, user.
userId);
592 sys_cat.changeDBObjectOwnership(
593 user, original_owner, db_object,
cat, original_owner_exists);
594 }
catch (
const std::runtime_error& e) {
596 cat.changeForeignServerOwner(server_name, original_owner.
userId);
603 std::string server_name = ddl_payload[
"serverName"].GetString();
604 std::string new_server_name = ddl_payload[
"newServerName"].GetString();
606 throw std::runtime_error{
"OmniSci prefix can not be used for new name of server."};
610 if (
cat.getForeignServer(new_server_name)) {
611 throw std::runtime_error(
"Foreign server with name \"" + server_name +
612 "\" can not be renamed to \"" + new_server_name +
"\"." +
613 "Foreign server with name \"" + new_server_name +
617 cat.renameForeignServer(server_name, new_server_name);
621 sys_cat.renameDBObject(server_name,
624 cat.getForeignServer(new_server_name)->id,
626 }
catch (
const std::runtime_error& e) {
628 cat.renameForeignServer(new_server_name, server_name);
635 std::string server_name = ddl_payload[
"serverName"].GetString();
638 const auto foreign_server =
cat.getForeignServer(server_name);
647 std::string server_name = ddl_payload[
"serverName"].GetString();
648 std::string data_wrapper = ddl_payload[
"dataWrapper"].GetString();
651 cat.setForeignServerDataWrapper(server_name, data_wrapper);
657 std::string server_name = ddl_payload[
"serverName"].GetString();
664 std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
667 CHECK(ddl_payload.HasMember(
"serverName"));
668 CHECK(ddl_payload[
"serverName"].IsString());
669 CHECK(ddl_payload.HasMember(
"ifExists"));
670 CHECK(ddl_payload[
"ifExists"].IsBool());
675 std::string server_name = ddl_payload[
"serverName"].GetString();
677 throw std::runtime_error{
"OmniSci default servers cannot be dropped."};
679 bool if_exists = ddl_payload[
"ifExists"].GetBool();
680 if (!
session_ptr_->getCatalog().getForeignServer(server_name)) {
684 throw std::runtime_error{
"Foreign server with name \"" + server_name +
685 "\" can not be dropped. Server does not exist."};
691 throw std::runtime_error(
"Server " + server_name +
692 " will not be dropped. User has no DROP SERVER privileges.");
696 session_ptr_->getCatalog().dropForeignServer(ddl_payload[
"serverName"].GetString());
701 SQLTypes JsonColumnSqlType::getSqlType(
const rapidjson::Value& data_type) {
702 CHECK(data_type.IsObject());
703 CHECK(data_type.HasMember(
"type"));
704 CHECK(data_type[
"type"].IsString());
706 std::string
type = data_type[
"type"].GetString();
707 if (boost::iequals(type,
"ARRAY")) {
708 CHECK(data_type.HasMember(
"array"));
709 CHECK(data_type[
"array"].IsObject());
711 const auto& array = data_type[
"array"].GetObject();
712 CHECK(array.HasMember(
"elementType"));
713 CHECK(array[
"elementType"].IsString());
714 type = array[
"elementType"].GetString();
716 return getSqlType(type);
720 if (boost::iequals(type,
"BIGINT")) {
723 if (boost::iequals(type,
"BOOLEAN")) {
726 if (boost::iequals(type,
"DATE")) {
729 if (boost::iequals(type,
"DECIMAL")) {
732 if (boost::iequals(type,
"DOUBLE")) {
735 if (boost::iequals(type,
"FLOAT")) {
738 if (boost::iequals(type,
"INTEGER")) {
741 if (boost::iequals(type,
"LINESTRING")) {
744 if (boost::iequals(type,
"MULTIPOLYGON")) {
747 if (boost::iequals(type,
"POINT")) {
750 if (boost::iequals(type,
"POLYGON")) {
753 if (boost::iequals(type,
"SMALLINT")) {
756 if (boost::iequals(type,
"TEXT")) {
759 if (boost::iequals(type,
"TIME")) {
762 if (boost::iequals(type,
"TIMESTAMP")) {
765 if (boost::iequals(type,
"TINYINT")) {
769 throw std::runtime_error{
"Unsupported type \"" + type +
"\" specified."};
772 int JsonColumnSqlType::getParam1(
const rapidjson::Value& data_type) {
774 CHECK(data_type.IsObject());
775 if (data_type.HasMember(
"precision") && !data_type[
"precision"].IsNull()) {
776 CHECK(data_type[
"precision"].IsInt());
777 param1 = data_type[
"precision"].GetInt();
784 int JsonColumnSqlType::getParam2(
const rapidjson::Value& data_type) {
786 CHECK(data_type.IsObject());
787 if (data_type.HasMember(
"scale") && !data_type[
"scale"].IsNull()) {
788 CHECK(data_type[
"scale"].IsInt());
789 param2 = data_type[
"scale"].GetInt();
791 data_type.HasMember(
"coordinateSystem") &&
792 !data_type[
"coordinateSystem"].IsNull()) {
793 CHECK(data_type[
"coordinateSystem"].IsInt());
794 param2 = data_type[
"coordinateSystem"].GetInt();
799 bool JsonColumnSqlType::isArray(
const rapidjson::Value& data_type) {
800 CHECK(data_type.IsObject());
801 CHECK(data_type.HasMember(
"type"));
802 CHECK(data_type[
"type"].IsString());
803 return boost::iequals(data_type[
"type"].GetString(),
"ARRAY");
806 int JsonColumnSqlType::getArraySize(
const rapidjson::Value& data_type) {
808 if (isArray(data_type)) {
809 CHECK(data_type.HasMember(
"array"));
810 CHECK(data_type[
"array"].IsObject());
812 const auto& array = data_type[
"array"].GetObject();
813 if (array.HasMember(
"size") && !array[
"size"].IsNull()) {
814 CHECK(array[
"size"].IsInt());
815 size = array[
"size"].GetInt();
821 std::string* JsonColumnEncoding::getEncodingName(
const rapidjson::Value& data_type) {
822 CHECK(data_type.IsObject());
823 CHECK(data_type.HasMember(
"encoding"));
824 CHECK(data_type[
"encoding"].IsObject());
826 const auto& encoding = data_type[
"encoding"].GetObject();
827 CHECK(encoding.HasMember(
"type"));
828 CHECK(encoding[
"type"].IsString());
829 return new std::string(encoding[
"type"].GetString());
832 int JsonColumnEncoding::getEncodingParam(
const rapidjson::Value& data_type) {
833 CHECK(data_type.IsObject());
834 CHECK(data_type.HasMember(
"encoding"));
835 CHECK(data_type[
"encoding"].IsObject());
837 int encoding_size = 0;
838 const auto& encoding = data_type[
"encoding"].GetObject();
839 if (encoding.HasMember(
"size") && !encoding[
"size"].IsNull()) {
840 CHECK(encoding[
"size"].IsInt());
841 encoding_size = encoding[
"size"].GetInt();
843 return encoding_size;
848 std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
851 CHECK(ddl_payload.HasMember(
"serverName"));
852 CHECK(ddl_payload[
"serverName"].IsString());
853 CHECK(ddl_payload.HasMember(
"tableName"));
854 CHECK(ddl_payload[
"tableName"].IsString());
855 CHECK(ddl_payload.HasMember(
"ifNotExists"));
856 CHECK(ddl_payload[
"ifNotExists"].IsBool());
857 CHECK(ddl_payload.HasMember(
"columns"));
858 CHECK(ddl_payload[
"columns"].IsArray());
865 const std::string& table_name = ddl_payload[
"tableName"].GetString();
868 throw std::runtime_error(
869 "Foreign table \"" + table_name +
870 "\" will not be created. User has no CREATE TABLE privileges.");
873 bool if_not_exists = ddl_payload[
"ifNotExists"].GetBool();
874 if (!catalog.validateNonExistentTableOrView(table_name, if_not_exists)) {
879 std::list<ColumnDescriptor> columns{};
882 catalog.createTable(foreign_table, columns, {},
true);
888 foreign_table.tableName,
897 const size_t column_count) {
908 const std::string server_name = ddl_payload[
"serverName"].GetString();
910 if (!foreign_table.foreign_server) {
911 throw std::runtime_error{
912 "Foreign Table with name \"" + table_name +
913 "\" can not be created. Associated foreign server with name \"" + server_name +
914 "\" does not exist."};
917 if (ddl_payload.HasMember(
"options") && !ddl_payload[
"options"].IsNull()) {
918 CHECK(ddl_payload[
"options"].IsObject());
919 foreign_table.initializeOptions(ddl_payload[
"options"]);
924 foreign_table.initializeOptions();
927 if (
const auto it = foreign_table.options.find(
"FRAGMENT_SIZE");
928 it != foreign_table.options.end()) {
929 foreign_table.maxFragRows = std::stoi(it->second);
935 std::unordered_set<std::string> column_names{};
936 for (
auto& column_def : ddl_payload[
"columns"].GetArray()) {
937 CHECK(column_def.IsObject());
938 CHECK(column_def.HasMember(
"name"));
939 CHECK(column_def[
"name"].IsString());
940 const std::string& column_name = column_def[
"name"].GetString();
942 CHECK(column_def.HasMember(
"dataType"));
943 CHECK(column_def[
"dataType"].IsObject());
945 JsonColumnSqlType sql_type{column_def[
"dataType"]};
946 const auto& data_type = column_def[
"dataType"].GetObject();
947 CHECK(data_type.HasMember(
"notNull"));
948 CHECK(data_type[
"notNull"].IsBool());
950 std::unique_ptr<JsonColumnEncoding> encoding;
951 if (data_type.HasMember(
"encoding") && !data_type[
"encoding"].IsNull()) {
952 CHECK(data_type[
"encoding"].IsObject());
953 encoding = std::make_unique<JsonColumnEncoding>(column_def[
"dataType"]);
960 column_name, cd, &sql_type, data_type[
"notNull"].GetBool(), encoding.get());
961 columns.emplace_back(cd);
967 std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
970 CHECK(ddl_payload.HasMember(
"tableName"));
971 CHECK(ddl_payload[
"tableName"].IsString());
972 CHECK(ddl_payload.HasMember(
"ifExists"));
973 CHECK(ddl_payload[
"ifExists"].IsBool());
980 const std::string& table_name = ddl_payload[
"tableName"].GetString();
982 std::unique_ptr<lockmgr::TableSchemaLockContainer<lockmgr::WriteLock>> td_with_lock;
986 std::make_unique<lockmgr::TableSchemaLockContainer<lockmgr::WriteLock>>(
988 catalog, table_name,
false));
990 td = (*td_with_lock)();
991 }
catch (
const std::runtime_error& e) {
994 if (ddl_payload[
"ifExists"].GetBool()) {
1005 throw std::runtime_error(
1006 "Foreign table \"" + table_name +
1007 "\" will not be dropped. User has no DROP TABLE privileges.");
1011 auto table_data_write_lock =
1013 catalog.dropTable(td);
1020 std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1027 std::vector<std::string> labels{
"table_name"};
1028 std::vector<TargetMetaInfo> label_infos;
1029 for (
const auto&
label : labels) {
1039 std::vector<RelLogicalValues::RowValues> logical_values;
1040 for (
auto table_name : table_names) {
1042 logical_values.back().emplace_back(
genLiteralStr(table_name));
1046 std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1054 std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1057 if (ddl_payload.HasMember(
"tableNames")) {
1058 CHECK(ddl_payload[
"tableNames"].IsArray());
1059 for (
const auto& table_name : ddl_payload[
"tableNames"].GetArray()) {
1060 CHECK(table_name.IsString());
1069 std::vector<TargetMetaInfo> label_infos;
1073 {
"table_name",
kTEXT,
true},
1074 {
"column_count",
kBIGINT,
true},
1075 {
"is_sharded_table",
kBOOLEAN,
true},
1076 {
"shard_count",
kBIGINT,
true},
1078 {
"fragment_size",
kBIGINT,
true},
1079 {
"max_rollback_epochs",
kBIGINT,
true},
1082 {
"min_epoch_floor",
kBIGINT,
true},
1083 {
"max_epoch_floor",
kBIGINT,
true},
1084 {
"metadata_file_count",
kBIGINT,
true},
1085 {
"total_metadata_file_size",
kBIGINT,
true},
1086 {
"total_metadata_page_count",
kBIGINT,
true},
1087 {
"total_free_metadata_page_count",
kBIGINT,
false},
1088 {
"data_file_count",
kBIGINT,
true},
1089 {
"total_data_file_size",
kBIGINT,
true},
1090 {
"total_data_page_count",
kBIGINT,
true},
1091 {
"total_free_data_page_count",
kBIGINT,
false}});
1093 std::vector<RelLogicalValues::RowValues> logical_values;
1094 for (
const auto& table_name : filtered_table_names) {
1095 auto [td, td_with_lock] =
1096 get_table_descriptor_with_lock<lockmgr::ReadLock>(*catalog, table_name,
false);
1102 std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1111 auto all_table_names =
1113 std::vector<std::string> filtered_table_names;
1114 if (ddl_payload.HasMember(
"tableNames")) {
1115 std::set<std::string> all_table_names_set(all_table_names.begin(),
1116 all_table_names.end());
1117 for (
const auto& table_name_json : ddl_payload[
"tableNames"].GetArray()) {
1118 std::string table_name = table_name_json.GetString();
1119 if (all_table_names_set.find(table_name) == all_table_names_set.end()) {
1120 throw std::runtime_error{
"Unable to show table details for table: " + table_name +
1121 ". Table does not exist."};
1123 auto [td, td_with_lock] =
1124 get_table_descriptor_with_lock<lockmgr::ReadLock>(*catalog, table_name,
false);
1125 if (td->isForeignTable()) {
1126 throw std::runtime_error{
1127 "SHOW TABLE DETAILS is not supported for foreign tables. Table name: " +
1130 if (td->isTemporaryTable()) {
1131 throw std::runtime_error{
1132 "SHOW TABLE DETAILS is not supported for temporary tables. Table name: " +
1135 filtered_table_names.emplace_back(table_name);
1138 for (
const auto& table_name : all_table_names) {
1139 auto [td, td_with_lock] =
1140 get_table_descriptor_with_lock<lockmgr::ReadLock>(*catalog, table_name,
false);
1141 if (td->isForeignTable() || td->isTemporaryTable()) {
1144 filtered_table_names.emplace_back(table_name);
1147 return filtered_table_names;
1152 std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1157 std::vector<std::string> labels{
"Database",
"Owner"};
1158 std::vector<TargetMetaInfo> label_infos;
1159 for (
const auto&
label : labels) {
1169 std::vector<RelLogicalValues::RowValues> logical_values;
1170 for (
const auto& db_summary : db_summaries) {
1172 logical_values.back().emplace_back(
genLiteralStr(db_summary.dbName));
1173 logical_values.back().emplace_back(
genLiteralStr(db_summary.dbOwnerName));
1177 std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1185 std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1188 throw std::runtime_error(
"Unsupported command: SHOW FOREIGN SERVERS");
1192 CHECK(ddl_payload.HasMember(
"command"));
1193 if (ddl_payload.HasMember(
"filters")) {
1194 CHECK(ddl_payload[
"filters"].IsArray());
1195 int num_filters = 0;
1196 for (
auto const& filter_def : ddl_payload[
"filters"].GetArray()) {
1197 CHECK(filter_def.IsObject());
1198 CHECK(filter_def.HasMember(
"attribute"));
1199 CHECK(filter_def[
"attribute"].IsString());
1200 CHECK(filter_def.HasMember(
"value"));
1201 CHECK(filter_def[
"value"].IsString());
1202 CHECK(filter_def.HasMember(
"operation"));
1203 CHECK(filter_def[
"operation"].IsString());
1204 if (num_filters > 0) {
1205 CHECK(filter_def.HasMember(
"chain"));
1206 CHECK(filter_def[
"chain"].IsString());
1208 CHECK(!filter_def.HasMember(
"chain"));
1216 std::vector<TargetMetaInfo> label_infos;
1220 std::vector<std::string> labels{
"server_name",
"data_wrapper",
"created_at",
"options"};
1229 std::vector<const foreign_storage::ForeignServer*> results;
1235 std::vector<RelLogicalValues::RowValues> logical_values;
1236 for (
auto const& server_ptr : results) {
1238 logical_values.back().emplace_back(
genLiteralStr(server_ptr->name));
1239 logical_values.back().emplace_back(
genLiteralStr(server_ptr->data_wrapper_type));
1241 logical_values.back().emplace_back(
1245 std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
1253 std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1256 CHECK(ddl_payload.HasMember(
"tableNames"));
1257 CHECK(ddl_payload[
"tableNames"].IsArray());
1258 for (
auto const& tablename_def : ddl_payload[
"tableNames"].GetArray()) {
1259 CHECK(tablename_def.IsString());
1264 bool evict_cached_entries{
false};
1267 if (ddl_payload.HasMember(
"options") && !ddl_payload[
"options"].IsNull()) {
1269 for (
const auto& entry : opt.
options) {
1270 if (entry.first !=
"EVICT") {
1271 throw std::runtime_error{
1272 "Invalid option \"" + entry.first +
1273 "\" provided for refresh command. Only \"EVICT\" option is supported."};
1278 if (boost::iequals(opt.
options[
"EVICT"],
"true") ||
1279 boost::iequals(opt.
options[
"EVICT"],
"false")) {
1280 if (boost::iequals(opt.
options[
"EVICT"],
"true")) {
1281 evict_cached_entries =
true;
1284 throw std::runtime_error{
1285 "Invalid value \"" + opt.
options[
"EVICT"] +
1286 "\" provided for EVICT option. Value must be either \"true\" or \"false\"."};
1291 const auto& current_user =
session_ptr_->get_currentUser();
1293 if (!current_user.isSuper) {
1294 for (
const auto& table_name_json : ddl_payload[
"tableNames"].GetArray()) {
1295 std::string table_name = table_name_json.GetString();
1298 throw std::runtime_error(
1299 std::string(
"REFRESH FOREIGN TABLES failed on table \"") + table_name +
1300 "\". It can only be executed by super user or "
1307 for (
const auto& table_name_json : ddl_payload[
"tableNames"].GetArray()) {
1308 std::string table_name = table_name_json.GetString();
1317 std::shared_ptr<const Catalog_Namespace::SessionInfo> session_ptr)
1320 CHECK(ddl_payload.HasMember(
"tableName"));
1321 CHECK(ddl_payload[
"tableName"].IsString());
1322 CHECK(ddl_payload.HasMember(
"alterType"));
1323 CHECK(ddl_payload[
"alterType"].IsString());
1324 if (ddl_payload[
"alterType"] ==
"RENAME_TABLE") {
1325 CHECK(ddl_payload.HasMember(
"newTableName"));
1326 CHECK(ddl_payload[
"newTableName"].IsString());
1327 }
else if (ddl_payload[
"alterType"] ==
"RENAME_COLUMN") {
1328 CHECK(ddl_payload.HasMember(
"oldColumnName"));
1329 CHECK(ddl_payload[
"oldColumnName"].IsString());
1330 CHECK(ddl_payload.HasMember(
"newColumnName"));
1331 CHECK(ddl_payload[
"newColumnName"].IsString());
1332 }
else if (ddl_payload[
"alterType"] ==
"ALTER_OPTIONS") {
1333 CHECK(ddl_payload.HasMember(
"options"));
1334 CHECK(ddl_payload[
"options"].IsObject());
1336 UNREACHABLE() <<
"Not a valid alter foreign table command: "
1337 << ddl_payload[
"alterType"].GetString();
1344 const std::string& table_name = ddl_payload[
"tableName"].GetString();
1345 auto [td, td_with_lock] =
1346 get_table_descriptor_with_lock<lockmgr::WriteLock>(catalog, table_name,
false);
1352 throw std::runtime_error(
1353 "Current user does not have the privilege to alter foreign table: " + table_name);
1356 auto table_data_write_lock =
1359 CHECK(foreign_table);
1361 std::string alter_type = ddl_payload[
"alterType"].GetString();
1362 if (alter_type ==
"RENAME_TABLE") {
1364 }
else if (alter_type ==
"RENAME_COLUMN") {
1366 }
else if (alter_type ==
"ALTER_OPTIONS") {
1377 const std::string& table_name = ddl_payload[
"tableName"].GetString();
1378 const std::string& new_table_name = ddl_payload[
"newTableName"].GetString();
1379 if (
cat.getForeignTable(new_table_name)) {
1380 throw std::runtime_error(
"Foreign table with name \"" + table_name +
1381 "\" can not be renamed to \"" + new_table_name +
"\". " +
1382 "A different table with name \"" + new_table_name +
1383 "\" already exists.");
1385 cat.renameTable(foreign_table, new_table_name);
1392 const std::string& table_name = ddl_payload[
"tableName"].GetString();
1393 const std::string& old_column_name = ddl_payload[
"oldColumnName"].GetString();
1394 const std::string& new_column_name = ddl_payload[
"newColumnName"].GetString();
1395 auto column =
cat.getMetadataForColumn(foreign_table->
tableId, old_column_name);
1397 throw std::runtime_error(
"Column with name \"" + old_column_name +
1398 "\" can not be renamed to \"" + new_column_name +
"\". " +
1399 "Column with name \"" + old_column_name +
1400 "\" does not exist.");
1402 if (
cat.getMetadataForColumn(foreign_table->
tableId, new_column_name)) {
1403 throw std::runtime_error(
"Column with name \"" + old_column_name +
1404 "\" can not be renamed to \"" + new_column_name +
"\". " +
1405 "A column with name \"" + new_column_name +
1406 "\" already exists.");
1408 cat.renameColumn(foreign_table, column, new_column_name);
1414 const std::string& table_name = ddl_payload[
"tableName"].GetString();
1416 auto new_options_map =
1420 cat.setForeignTableOptions(table_name, new_options_map,
false);
1425 std::shared_ptr<Catalog_Namespace::SessionInfo const> session_ptr)
1428 if (ddl_payload.HasMember(
"tableNames")) {
1429 CHECK(ddl_payload[
"tableNames"].IsArray());
1430 for (
auto const& tablename_def : ddl_payload[
"tableNames"].GetArray()) {
1431 CHECK(tablename_def.IsString());
1437 auto table_names =
session_ptr_->get_catalog_ptr()->getTableNamesForUser(
1441 if (ddl_payload.HasMember(
"tableNames")) {
1442 std::vector<std::string> filtered_names;
1443 for (
const auto& tablename_def : ddl_payload[
"tableNames"].GetArray()) {
1444 std::string filter_name = tablename_def.GetString();
1445 if (std::find(table_names.begin(), table_names.end(), filter_name) !=
1446 table_names.end()) {
1447 filtered_names.emplace_back(filter_name);
1449 throw std::runtime_error(
"Can not show disk cache usage for table: " +
1450 filter_name +
". Table does not exist.");
1453 return filtered_names;
1463 const auto disk_cache = cat_ptr->getDataMgr().getPersistentStorageMgr()->getDiskCache();
1465 throw std::runtime_error{
"Disk cache not enabled. Cannot show disk cache usage."};
1469 std::vector<std::string> labels{
"table name",
"current cache size"};
1470 std::vector<TargetMetaInfo> label_infos;
1474 std::vector<RelLogicalValues::RowValues> logical_values;
1476 for (
auto& table_name : table_names) {
1477 auto [td, td_with_lock] =
1478 get_table_descriptor_with_lock<lockmgr::ReadLock>(*cat_ptr, table_name,
false);
1481 disk_cache->getGlobalFileMgr()->findFileMgr(cat_ptr->getDatabaseId(),
1491 logical_values.back().emplace_back(
genLiteralStr(table_name));
1495 std::shared_ptr<ResultSet> rSet = std::shared_ptr<ResultSet>(
int32_t maxRollbackEpochs
ShowForeignServersCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
ExecutionResult execute() override
AlterForeignServerCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
uint64_t total_data_page_count
declare this class scoped local to avoid exposing rapidjson in the header file
JsonColumnSqlType(const rapidjson::Value &data_type)
static const AccessPrivileges DROP_SERVER
std::unique_ptr< DdlCommandData > ddl_data_
std::string getOptionsAsJsonString() const
class for a per-database catalog. also includes metadata for the current database and the current use...
uint64_t metadata_file_count
static const AccessPrivileges ALTER_TABLE
CreateForeignServerCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
Data_Namespace::DataMgr & getDataMgr() const
void renameForeignServer()
static WriteLock getWriteLockForTable(const Catalog_Namespace::Catalog &cat, const std::string &table_name)
ShowDatabasesCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
std::vector< const TableDescriptor * > getPhysicalTablesDescriptors(const TableDescriptor *logicalTableDesc) const
uint64_t getTotalFileSize() const
void revokeDBObjectPrivilegesFromAll(DBObject object, Catalog *catalog)
DropForeignTableCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
CreateForeignTableCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
void validateSupportedOptionKeys(const OptionsMap &options_map) const
Verifies that the options_map contains the keys required by a foreign table; including those specifie...
void add_table_details(std::vector< RelLogicalValues::RowValues > &logical_values, const TableDescriptor *logical_table, const AggregratedStorageStats &agg_storage_stats)
void aggregate(const File_Namespace::StorageStats &storage_stats)
std::optional< uint64_t > total_free_data_page_count
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)
void createDBObject(const UserMetadata &user, const std::string &objectName, DBObjectType type, const Catalog_Namespace::Catalog &catalog, int32_t objectId=-1)
void set_headers_with_type(std::vector< TargetMetaInfo > &label_infos, const std::vector< std::tuple< std::string, SQLTypes, bool >> &headers)
std::tuple< const TableDescriptor *, std::unique_ptr< lockmgr::TableSchemaLockContainer< LockType > > > get_table_descriptor_with_lock(const Catalog_Namespace::Catalog &cat, const std::string &table_name, const bool populate_fragmenter)
void validate_non_duplicate_column(const std::string &column_name, std::unordered_set< std::string > &upper_column_names)
static void validate_alter_options(const OptionsMap &options_map)
Verifies that the given options map only contains options that can be legally altered.
static const AccessPrivileges ALTER_SERVER
std::unique_ptr< RexLiteral > genLiteralBigInt(int64_t val)
This file contains the class specification and related data structures for Catalog.
const std::string getTargetQuerySessionToKill()
const DdlCommandData & ddl_data_
const std::string commandStr()
static SysCatalog & instance()
This file contains the class specification and related data structures for SysCatalog.
Classes representing a parse tree.
ShowTableDetailsCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
void setColumnDetails(std::list< ColumnDescriptor > &columns)
const rapidjson::Value & query() const
DropForeignServerCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
static const AccessPrivileges DROP_TABLE
ExecutionResult execute() override
std::string ddl_statement_
std::optional< uint64_t > total_free_metadata_page_count
void populateOptionsMap(OptionsMap &&options_map, bool clear=false)
bool hasAlterServerPrivileges()
const rapidjson::Value & extractPayload(const DdlCommandData &ddl_data)
std::unique_ptr< RexLiteral > genLiteralTimestamp(time_t val)
ExecutionResult execute() override
ExecutionResult execute() override
DBSummaryList getDatabaseListForUser(const UserMetadata &user)
void setForeignServerOptions()
int getDatabaseId() const
uint64_t total_metadata_page_count
static const AccessPrivileges CREATE_SERVER
ExecutionResult execute() override
std::unique_ptr< RexLiteral > genLiteralBoolean(bool val)
void validate_non_reserved_keyword(const std::string &column_name)
specifies the content in-memory of a row in the column metadata table
AggregationType aggregation_type
static const AccessPrivileges CREATE_TABLE
ExecutionResult execute() override
void set_default_table_attributes(const std::string &table_name, TableDescriptor &td, const int32_t column_count)
bool isShowUserSessions()
File_Namespace::GlobalFileMgr * getGlobalFileMgr() const
static ResultSet * create(std::vector< TargetMetaInfo > &label_infos, std::vector< RelLogicalValues::RowValues > &logical_values)
ExecutionResult execute() override
void alterOptions(const foreign_storage::ForeignTable *foreign_table)
DistributedExecutionDetails getDistributedExecutionDetails()
void set_column_descriptor(const std::string &column_name, ColumnDescriptor &cd, SqlType *column_type, const bool not_null, const Encoding *encoding)
ExecutionResult execute()
JsonColumnEncoding(const rapidjson::Value &data_type)
const rapidjson::Value & payload() const
std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr_
std::vector< std::string > getFilteredTableNames()
DdlCommandExecutor(const std::string &ddl_statement, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
AggregratedStorageStats get_agg_storage_stats(const TableDescriptor *td, const Catalog_Namespace::Catalog *catalog)
rapidjson::Document ddl_query
uint64_t total_metadata_file_size
void changeForeignServerOwner()
Basic constructors and methods of the row set interface.
uint64_t total_data_file_size
static OptionsMap create_options_map(const rapidjson::Value &json_options)
Creates an options map from given options. Converts options that must be upper case appropriately...
void setTableDetails(const std::string &table_name, TableDescriptor &td, const size_t column_count)
std::vector< std::string > getFilteredTableNames()
ExecutionResult execute() override
static std::unique_ptr< RexLiteral > genLiteralStr(std::string val)
ExecutionResult execute() override
static std::shared_ptr< MutexType > getMutex(const LockType lockType, const KeyType &key)
void validate_table_type(const TableDescriptor *td, const TableType expected_table_type, const std::string &command)
const ForeignServer * foreign_server
void renameTable(const foreign_storage::ForeignTable *foreign_table)
bool isDefaultServer(const std::string &server_name)
std::list< DBSummary > DBSummaryList
AggregratedStorageStats(const File_Namespace::StorageStats &storage_stats)
std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr_
std::vector< std::unique_ptr< const RexScalar >> RowValues
ExecutionLocation execution_location
const rapidjson::Value * extractFilters(const rapidjson::Value &payload)
AlterForeignTableCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
void renameColumn(const foreign_storage::ForeignTable *foreign_table)
virtual std::string commandStr() override
static constexpr char const * FOREIGN_TABLE
ExecutionResult execute() override
ExecutionResult execute() override
ExecutionResult execute() override
void setForeignServerDataWrapper()
RefreshForeignTablesCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)