OmniSciDB  ba1bac9284
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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 858 of file DdlCommandExecutor.cpp.

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

861  : DdlCommand(ddl_data, session_ptr) {
862  auto& ddl_payload = extractPayload(ddl_data);
863  CHECK(ddl_payload.HasMember("serverName"));
864  CHECK(ddl_payload["serverName"].IsString());
865  CHECK(ddl_payload.HasMember("tableName"));
866  CHECK(ddl_payload["tableName"].IsString());
867  CHECK(ddl_payload.HasMember("ifNotExists"));
868  CHECK(ddl_payload["ifNotExists"].IsBool());
869  CHECK(ddl_payload.HasMember("columns"));
870  CHECK(ddl_payload["columns"].IsArray());
871 }
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:206

+ 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 873 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().

873  {
874  auto& catalog = session_ptr_->getCatalog();
875  auto& ddl_payload = extractPayload(ddl_data_);
876 
877  const std::string& table_name = ddl_payload["tableName"].GetString();
878  if (!session_ptr_->checkDBAccessPrivileges(DBObjectType::TableDBObjectType,
880  throw std::runtime_error(
881  "Foreign table \"" + table_name +
882  "\" will not be created. User has no CREATE TABLE privileges.");
883  }
884 
885  bool if_not_exists = ddl_payload["ifNotExists"].GetBool();
886  if (!catalog.validateNonExistentTableOrView(table_name, if_not_exists)) {
887  return ExecutionResult();
888  }
889 
890  foreign_storage::ForeignTable foreign_table{};
891  std::list<ColumnDescriptor> columns{};
892  setColumnDetails(columns);
893  setTableDetails(table_name, foreign_table, columns);
894  catalog.createTable(foreign_table, columns, {}, true);
895 
896  // TODO (max): It's transactionally unsafe, should be fixed: we may create object w/o
897  // privileges
899  session_ptr_->get_currentUser(),
900  foreign_table.tableName,
902  catalog);
903 
904  return ExecutionResult();
905 }
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:292
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 956 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().

956  {
957  auto& ddl_payload = extractPayload(ddl_data_);
958  std::unordered_set<std::string> column_names{};
959  for (auto& column_def : ddl_payload["columns"].GetArray()) {
960  CHECK(column_def.IsObject());
961  CHECK(column_def.HasMember("name"));
962  CHECK(column_def["name"].IsString());
963  const std::string& column_name = column_def["name"].GetString();
964 
965  CHECK(column_def.HasMember("dataType"));
966  CHECK(column_def["dataType"].IsObject());
967 
968  JsonColumnSqlType sql_type{column_def["dataType"]};
969  const auto& data_type = column_def["dataType"].GetObject();
970  CHECK(data_type.HasMember("notNull"));
971  CHECK(data_type["notNull"].IsBool());
972 
973  std::unique_ptr<JsonColumnEncoding> encoding;
974  if (data_type.HasMember("encoding") && !data_type["encoding"].IsNull()) {
975  CHECK(data_type["encoding"].IsObject());
976  encoding = std::make_unique<JsonColumnEncoding>(column_def["dataType"]);
977  }
978 
979  ColumnDescriptor cd;
980  ddl_utils::validate_non_duplicate_column(column_name, column_names);
983  column_name, cd, &sql_type, data_type["notNull"].GetBool(), encoding.get());
984  columns.emplace_back(cd);
985  }
986 }
void validate_non_duplicate_column(const std::string &column_name, std::unordered_set< std::string > &upper_column_names)
Definition: DdlUtils.cpp:537
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:546
specifies the content in-memory of a row in the column metadata table
void set_column_descriptor(const std::string &column_name, ColumnDescriptor &cd, SqlType *column_type, const bool not_null, const Encoding *encoding)
Definition: DdlUtils.cpp:509
#define CHECK(condition)
Definition: Logger.h:206

+ 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 907 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().

910  {
911  ddl_utils::set_default_table_attributes(table_name, td, columns.size());
912  td.userId = session_ptr_->get_currentUser().userId;
914  td.hasDeletedCol = false;
915  td.keyMetainfo = "[]";
916  td.fragments = "";
917  td.partitions = "";
918 
919  auto& ddl_payload = extractPayload(ddl_data_);
920  auto& foreign_table = dynamic_cast<foreign_storage::ForeignTable&>(td);
921  const std::string server_name = ddl_payload["serverName"].GetString();
922  foreign_table.foreign_server = session_ptr_->getCatalog().getForeignServer(server_name);
923  if (!foreign_table.foreign_server) {
924  throw std::runtime_error{
925  "Foreign Table with name \"" + table_name +
926  "\" can not be created. Associated foreign server with name \"" + server_name +
927  "\" does not exist."};
928  }
929 
930  // check server usage privileges
931  if (!isDefaultServer(server_name) &&
932  !session_ptr_->checkDBAccessPrivileges(DBObjectType::ServerDBObjectType,
934  server_name)) {
935  throw std::runtime_error(
936  "Current user does not have USAGE privilege on foreign server: " + server_name);
937  }
938 
939  if (ddl_payload.HasMember("options") && !ddl_payload["options"].IsNull()) {
940  CHECK(ddl_payload["options"].IsObject());
941  foreign_table.initializeOptions(ddl_payload["options"]);
942  } else {
943  // Initialize options even if none were provided to verify a legal state.
944  // This is necessary because some options (like "file_path") are optional only if a
945  // paired option ("base_path") exists in the server.
946  foreign_table.initializeOptions();
947  }
948  foreign_table.validateSchema(columns);
949 
950  if (const auto it = foreign_table.options.find("FRAGMENT_SIZE");
951  it != foreign_table.options.end()) {
952  foreign_table.maxFragRows = std::stoi(it->second);
953  }
954 }
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:523
const ForeignServer * foreign_server
Definition: ForeignTable.h:53
#define CHECK(condition)
Definition: Logger.h:206
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: