OmniSciDB  c0231cc57d
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CreateForeignTableCommand Class Reference

#include <DdlCommandExecutor.h>

+ Inheritance diagram for CreateForeignTableCommand:
+ Collaboration diagram for CreateForeignTableCommand:

Public Member Functions

 CreateForeignTableCommand (const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
 
ExecutionResult execute (bool read_only_mode) override
 
- Public Member Functions inherited from DdlCommand
 DdlCommand (const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
 

Private Member Functions

void setTableDetails (const std::string &table_name, TableDescriptor &td, const std::list< ColumnDescriptor > &columns)
 
void setColumnDetails (std::list< ColumnDescriptor > &columns)
 

Additional Inherited Members

- Protected Attributes inherited from DdlCommand
const DdlCommandDataddl_data_
 
std::shared_ptr
< Catalog_Namespace::SessionInfo
const > 
session_ptr_
 

Detailed Description

Definition at line 90 of file DdlCommandExecutor.h.

Constructor & Destructor Documentation

CreateForeignTableCommand::CreateForeignTableCommand ( const DdlCommandData ddl_data,
std::shared_ptr< Catalog_Namespace::SessionInfo const >  session_ptr 
)

Definition at line 1154 of file DdlCommandExecutor.cpp.

References CHECK, anonymous_namespace{DdlCommandExecutor.cpp}::extractPayload(), and g_enable_fsi.

1157  : DdlCommand(ddl_data, session_ptr) {
1158  if (!g_enable_fsi) {
1159  throw std::runtime_error("Unsupported command: CREATE FOREIGN TABLE");
1160  }
1161  auto& ddl_payload = extractPayload(ddl_data);
1162  CHECK(ddl_payload.HasMember("serverName"));
1163  CHECK(ddl_payload["serverName"].IsString());
1164  CHECK(ddl_payload.HasMember("tableName"));
1165  CHECK(ddl_payload["tableName"].IsString());
1166  CHECK(ddl_payload.HasMember("ifNotExists"));
1167  CHECK(ddl_payload["ifNotExists"].IsBool());
1168  CHECK(ddl_payload.HasMember("columns"));
1169  CHECK(ddl_payload["columns"].IsArray());
1170 }
const rapidjson::Value & extractPayload(const DdlCommandData &ddl_data)
DdlCommand(const DdlCommandData &ddl_data, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
#define CHECK(condition)
Definition: Logger.h:222
bool g_enable_fsi
Definition: Catalog.cpp:96

+ Here is the call graph for this function:

Member Function Documentation

ExecutionResult CreateForeignTableCommand::execute ( bool  read_only_mode)
overridevirtual

Executes the DDL command corresponding to provided JSON payload.

Parameters
_returnresult of DDL command execution (if applicable)

Implements DdlCommand.

Definition at line 1172 of file DdlCommandExecutor.cpp.

References AccessPrivileges::CREATE_TABLE, Catalog_Namespace::SysCatalog::createDBObject(), DdlCommand::ddl_data_, anonymous_namespace{DdlCommandExecutor.cpp}::extractPayload(), Catalog_Namespace::SysCatalog::instance(), DdlCommand::session_ptr_, setColumnDetails(), setTableDetails(), and TableDBObjectType.

Referenced by heavydb.cursor.Cursor::executemany().

1172  {
1173  auto& catalog = session_ptr_->getCatalog();
1174  auto& ddl_payload = extractPayload(ddl_data_);
1175 
1176  if (read_only_mode) {
1177  throw std::runtime_error("CREATE FOREIGN TABLE invalid in read only mode.");
1178  }
1179  const std::string& table_name = ddl_payload["tableName"].GetString();
1180  if (!session_ptr_->checkDBAccessPrivileges(DBObjectType::TableDBObjectType,
1182  throw std::runtime_error(
1183  "Foreign table \"" + table_name +
1184  "\" will not be created. User has no CREATE TABLE privileges.");
1185  }
1186 
1187  bool if_not_exists = ddl_payload["ifNotExists"].GetBool();
1188  if (!catalog.validateNonExistentTableOrView(table_name, if_not_exists)) {
1189  return ExecutionResult();
1190  }
1191 
1192  foreign_storage::ForeignTable foreign_table{};
1193  std::list<ColumnDescriptor> columns{};
1194  setColumnDetails(columns);
1195  setTableDetails(table_name, foreign_table, columns);
1196  catalog.createTable(foreign_table, columns, {}, true);
1197 
1198  // TODO (max): It's transactionally unsafe, should be fixed: we may create object w/o
1199  // privileges
1201  session_ptr_->get_currentUser(),
1202  foreign_table.tableName,
1204  catalog);
1205 
1206  return ExecutionResult();
1207 }
void createDBObject(const UserMetadata &user, const std::string &objectName, DBObjectType type, const Catalog_Namespace::Catalog &catalog, int32_t objectId=-1)
void setTableDetails(const std::string &table_name, TableDescriptor &td, const std::list< ColumnDescriptor > &columns)
const DdlCommandData & ddl_data_
static SysCatalog & instance()
Definition: SysCatalog.h:341
void setColumnDetails(std::list< ColumnDescriptor > &columns)
const rapidjson::Value & extractPayload(const DdlCommandData &ddl_data)
static const AccessPrivileges CREATE_TABLE
Definition: DBObject.h:158
std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void CreateForeignTableCommand::setColumnDetails ( std::list< ColumnDescriptor > &  columns)
private

Definition at line 1268 of file DdlCommandExecutor.cpp.

References CHECK, DdlCommand::ddl_data_, anonymous_namespace{DdlCommandExecutor.cpp}::extractPayload(), ddl_utils::set_column_descriptor(), ddl_utils::validate_non_duplicate_column(), and ddl_utils::validate_non_reserved_keyword().

Referenced by execute().

1268  {
1269  auto& ddl_payload = extractPayload(ddl_data_);
1270  std::unordered_set<std::string> column_names{};
1271  for (auto& column_def : ddl_payload["columns"].GetArray()) {
1272  CHECK(column_def.IsObject());
1273  CHECK(column_def.HasMember("name"));
1274  CHECK(column_def["name"].IsString());
1275  const std::string& column_name = column_def["name"].GetString();
1276 
1277  CHECK(column_def.HasMember("dataType"));
1278  CHECK(column_def["dataType"].IsObject());
1279 
1280  JsonColumnSqlType sql_type{column_def["dataType"]};
1281  const auto& data_type = column_def["dataType"].GetObject();
1282  CHECK(data_type.HasMember("notNull"));
1283  CHECK(data_type["notNull"].IsBool());
1284 
1285  std::unique_ptr<JsonColumnEncoding> encoding;
1286  if (data_type.HasMember("encoding") && !data_type["encoding"].IsNull()) {
1287  CHECK(data_type["encoding"].IsObject());
1288  encoding = std::make_unique<JsonColumnEncoding>(column_def["dataType"]);
1289  }
1290 
1291  ColumnDescriptor cd;
1292  ddl_utils::validate_non_duplicate_column(column_name, column_names);
1295  cd,
1296  &sql_type,
1297  data_type["notNull"].GetBool(),
1298  encoding.get(),
1299  nullptr);
1300  columns.emplace_back(cd);
1301  }
1302 }
void validate_non_duplicate_column(const std::string &column_name, std::unordered_set< std::string > &upper_column_names)
Definition: DdlUtils.cpp:691
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:661
const DdlCommandData & ddl_data_
const rapidjson::Value & extractPayload(const DdlCommandData &ddl_data)
void validate_non_reserved_keyword(const std::string &column_name)
Definition: DdlUtils.cpp:700
specifies the content in-memory of a row in the column metadata table
#define CHECK(condition)
Definition: Logger.h:222

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void CreateForeignTableCommand::setTableDetails ( const std::string &  table_name,
TableDescriptor td,
const std::list< ColumnDescriptor > &  columns 
)
private

Definition at line 1209 of file DdlCommandExecutor.cpp.

References CHECK, DdlCommand::ddl_data_, anonymous_namespace{DdlCommandExecutor.cpp}::extractPayload(), foreign_storage::ForeignTable::foreign_server, StorageType::FOREIGN_TABLE, TableDescriptor::fragments, TableDescriptor::hasDeletedCol, anonymous_namespace{DdlCommandExecutor.cpp}::is_default_server(), TableDescriptor::keyMetainfo, TableDescriptor::partitions, AccessPrivileges::SERVER_USAGE, ServerDBObjectType, DdlCommand::session_ptr_, ddl_utils::set_default_table_attributes(), TableDescriptor::storageType, and TableDescriptor::userId.

Referenced by execute().

1212  {
1213  ddl_utils::set_default_table_attributes(table_name, td, columns.size());
1214  td.userId = session_ptr_->get_currentUser().userId;
1216  td.hasDeletedCol = false;
1217  td.keyMetainfo = "[]";
1218  td.fragments = "";
1219  td.partitions = "";
1220 
1221  auto& ddl_payload = extractPayload(ddl_data_);
1222  auto& foreign_table = dynamic_cast<foreign_storage::ForeignTable&>(td);
1223  const std::string server_name = ddl_payload["serverName"].GetString();
1224  foreign_table.foreign_server = session_ptr_->getCatalog().getForeignServer(server_name);
1225  if (!foreign_table.foreign_server) {
1226  throw std::runtime_error{
1227  "Foreign Table with name \"" + table_name +
1228  "\" can not be created. Associated foreign server with name \"" + server_name +
1229  "\" does not exist."};
1230  }
1231 
1232  // check server usage privileges
1233  if (!is_default_server(server_name) &&
1234  !session_ptr_->checkDBAccessPrivileges(DBObjectType::ServerDBObjectType,
1236  server_name)) {
1237  throw std::runtime_error(
1238  "Current user does not have USAGE privilege on foreign server: " + server_name);
1239  }
1240 
1241  if (ddl_payload.HasMember("options") && !ddl_payload["options"].IsNull()) {
1242  CHECK(ddl_payload["options"].IsObject());
1243  foreign_table.initializeOptions(ddl_payload["options"]);
1244  } else {
1245  // Initialize options even if none were provided to verify a legal state.
1246  // This is necessary because some options (like "file_path") are optional only if a
1247  // paired option ("base_path") exists in the server.
1248  foreign_table.initializeOptions();
1249  }
1250  foreign_table.validateSchema(columns);
1251 
1252  if (const auto it = foreign_table.options.find("FRAGMENT_SIZE");
1253  it != foreign_table.options.end()) {
1254  foreign_table.maxFragRows = std::stoi(it->second);
1255  }
1256 
1257  if (const auto it = foreign_table.options.find("MAX_CHUNK_SIZE");
1258  it != foreign_table.options.end()) {
1259  foreign_table.maxChunkSize = std::stol(it->second);
1260  }
1261 
1262  if (const auto it = foreign_table.options.find("PARTITIONS");
1263  it != foreign_table.options.end()) {
1264  foreign_table.partitions = it->second;
1265  }
1266 }
std::string partitions
std::string storageType
static const AccessPrivileges SERVER_USAGE
Definition: DBObject.h:191
std::string fragments
const DdlCommandData & ddl_data_
bool is_default_server(const std::string &server_name)
const rapidjson::Value & extractPayload(const DdlCommandData &ddl_data)
std::string keyMetainfo
void set_default_table_attributes(const std::string &table_name, TableDescriptor &td, const int32_t column_count)
Definition: DdlUtils.cpp:677
const ForeignServer * foreign_server
Definition: ForeignTable.h:56
#define CHECK(condition)
Definition: Logger.h:222
std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr_
static constexpr char const * FOREIGN_TABLE

+ Here is the call graph for this function:

+ Here is the caller graph for this function:


The documentation for this class was generated from the following files: