OmniSciDB  d2f719934e
 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 () 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 Member Functions inherited from DdlCommand
bool isDefaultServer (const std::string &server_name)
 
- Protected Attributes inherited from DdlCommand
const DdlCommandDataddl_data_
 
std::shared_ptr
< Catalog_Namespace::SessionInfo
const
session_ptr_
 

Detailed Description

Definition at line 91 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 986 of file DdlCommandExecutor.cpp.

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

989  : DdlCommand(ddl_data, session_ptr) {
990  auto& ddl_payload = extractPayload(ddl_data);
991  CHECK(ddl_payload.HasMember("serverName"));
992  CHECK(ddl_payload["serverName"].IsString());
993  CHECK(ddl_payload.HasMember("tableName"));
994  CHECK(ddl_payload["tableName"].IsString());
995  CHECK(ddl_payload.HasMember("ifNotExists"));
996  CHECK(ddl_payload["ifNotExists"].IsBool());
997  CHECK(ddl_payload.HasMember("columns"));
998  CHECK(ddl_payload["columns"].IsArray());
999 }
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:211

+ Here is the call graph for this function:

Member Function Documentation

ExecutionResult CreateForeignTableCommand::execute ( )
overridevirtual

Executes the DDL command corresponding to provided JSON payload.

Parameters
_returnresult of DDL command execution (if applicable)

Implements DdlCommand.

Definition at line 1001 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 omnisci.cursor.Cursor::executemany().

1001  {
1002  auto& catalog = session_ptr_->getCatalog();
1003  auto& ddl_payload = extractPayload(ddl_data_);
1004 
1005  const std::string& table_name = ddl_payload["tableName"].GetString();
1006  if (!session_ptr_->checkDBAccessPrivileges(DBObjectType::TableDBObjectType,
1008  throw std::runtime_error(
1009  "Foreign table \"" + table_name +
1010  "\" will not be created. User has no CREATE TABLE privileges.");
1011  }
1012 
1013  bool if_not_exists = ddl_payload["ifNotExists"].GetBool();
1014  if (!catalog.validateNonExistentTableOrView(table_name, if_not_exists)) {
1015  return ExecutionResult();
1016  }
1017 
1018  foreign_storage::ForeignTable foreign_table{};
1019  std::list<ColumnDescriptor> columns{};
1020  setColumnDetails(columns);
1021  setTableDetails(table_name, foreign_table, columns);
1022  catalog.createTable(foreign_table, columns, {}, true);
1023 
1024  // TODO (max): It's transactionally unsafe, should be fixed: we may create object w/o
1025  // privileges
1027  session_ptr_->get_currentUser(),
1028  foreign_table.tableName,
1030  catalog);
1031 
1032  return ExecutionResult();
1033 }
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:326
void setColumnDetails(std::list< ColumnDescriptor > &columns)
const rapidjson::Value & extractPayload(const DdlCommandData &ddl_data)
static const AccessPrivileges CREATE_TABLE
Definition: DBObject.h:160
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 1084 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().

1084  {
1085  auto& ddl_payload = extractPayload(ddl_data_);
1086  std::unordered_set<std::string> column_names{};
1087  for (auto& column_def : ddl_payload["columns"].GetArray()) {
1088  CHECK(column_def.IsObject());
1089  CHECK(column_def.HasMember("name"));
1090  CHECK(column_def["name"].IsString());
1091  const std::string& column_name = column_def["name"].GetString();
1092 
1093  CHECK(column_def.HasMember("dataType"));
1094  CHECK(column_def["dataType"].IsObject());
1095 
1096  JsonColumnSqlType sql_type{column_def["dataType"]};
1097  const auto& data_type = column_def["dataType"].GetObject();
1098  CHECK(data_type.HasMember("notNull"));
1099  CHECK(data_type["notNull"].IsBool());
1100 
1101  std::unique_ptr<JsonColumnEncoding> encoding;
1102  if (data_type.HasMember("encoding") && !data_type["encoding"].IsNull()) {
1103  CHECK(data_type["encoding"].IsObject());
1104  encoding = std::make_unique<JsonColumnEncoding>(column_def["dataType"]);
1105  }
1106 
1107  ColumnDescriptor cd;
1108  ddl_utils::validate_non_duplicate_column(column_name, column_names);
1111  cd,
1112  &sql_type,
1113  data_type["notNull"].GetBool(),
1114  encoding.get(),
1115  nullptr);
1116  columns.emplace_back(cd);
1117  }
1118 }
void validate_non_duplicate_column(const std::string &column_name, std::unordered_set< std::string > &upper_column_names)
Definition: DdlUtils.cpp:675
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:645
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:684
specifies the content in-memory of a row in the column metadata table
#define CHECK(condition)
Definition: Logger.h:211

+ 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 1035 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, DdlCommand::isDefaultServer(), 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().

1038  {
1039  ddl_utils::set_default_table_attributes(table_name, td, columns.size());
1040  td.userId = session_ptr_->get_currentUser().userId;
1042  td.hasDeletedCol = false;
1043  td.keyMetainfo = "[]";
1044  td.fragments = "";
1045  td.partitions = "";
1046 
1047  auto& ddl_payload = extractPayload(ddl_data_);
1048  auto& foreign_table = dynamic_cast<foreign_storage::ForeignTable&>(td);
1049  const std::string server_name = ddl_payload["serverName"].GetString();
1050  foreign_table.foreign_server = session_ptr_->getCatalog().getForeignServer(server_name);
1051  if (!foreign_table.foreign_server) {
1052  throw std::runtime_error{
1053  "Foreign Table with name \"" + table_name +
1054  "\" can not be created. Associated foreign server with name \"" + server_name +
1055  "\" does not exist."};
1056  }
1057 
1058  // check server usage privileges
1059  if (!isDefaultServer(server_name) &&
1060  !session_ptr_->checkDBAccessPrivileges(DBObjectType::ServerDBObjectType,
1062  server_name)) {
1063  throw std::runtime_error(
1064  "Current user does not have USAGE privilege on foreign server: " + server_name);
1065  }
1066 
1067  if (ddl_payload.HasMember("options") && !ddl_payload["options"].IsNull()) {
1068  CHECK(ddl_payload["options"].IsObject());
1069  foreign_table.initializeOptions(ddl_payload["options"]);
1070  } else {
1071  // Initialize options even if none were provided to verify a legal state.
1072  // This is necessary because some options (like "file_path") are optional only if a
1073  // paired option ("base_path") exists in the server.
1074  foreign_table.initializeOptions();
1075  }
1076  foreign_table.validateSchema(columns);
1077 
1078  if (const auto it = foreign_table.options.find("FRAGMENT_SIZE");
1079  it != foreign_table.options.end()) {
1080  foreign_table.maxFragRows = std::stoi(it->second);
1081  }
1082 }
std::string partitions
std::string storageType
static const AccessPrivileges SERVER_USAGE
Definition: DBObject.h:193
std::string fragments
const DdlCommandData & ddl_data_
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:661
const ForeignServer * foreign_server
Definition: ForeignTable.h:54
#define CHECK(condition)
Definition: Logger.h:211
bool isDefaultServer(const std::string &server_name)
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: