OmniSciDB  72c90bc290
 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 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 1373 of file DdlCommandExecutor.cpp.

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

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 }
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:291
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 1391 of file DdlCommandExecutor.cpp.

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

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

1391  {
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 }
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:343
void setColumnDetails(std::list< ColumnDescriptor > &columns)
const rapidjson::Value & extractPayload(const DdlCommandData &ddl_data)
static const AccessPrivileges CREATE_TABLE
Definition: DBObject.h:158
auto getExecuteWriteLock()
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 1490 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().

1490  {
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 }
void validate_non_duplicate_column(const std::string &column_name, std::unordered_set< std::string > &upper_column_names)
Definition: DdlUtils.cpp:728
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
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:737
specifies the content in-memory of a row in the column metadata table
#define CHECK(condition)
Definition: Logger.h:291

+ 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 1431 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, TableDescriptor::userId, and Parser::validate_and_get_fragment_size().

Referenced by execute().

1434  {
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 }
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)
int32_t validate_and_get_fragment_size(const std::string &fragment_size_str)
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:714
const ForeignServer * foreign_server
Definition: ForeignTable.h:57
#define CHECK(condition)
Definition: Logger.h:291
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: