OmniSciDB  eb3a3d0a03
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Parser::CreateTableAsSelectStmt Class Reference

#include <ParserNode.h>

+ Inheritance diagram for Parser::CreateTableAsSelectStmt:
+ Collaboration diagram for Parser::CreateTableAsSelectStmt:

Public Member Functions

 CreateTableAsSelectStmt (const rapidjson::Value &payload)
 
 CreateTableAsSelectStmt (const std::string *table_name, const std::string *select_query, const bool is_temporary, const bool if_not_exists, std::list< NameValueAssign * > *s)
 
void execute (const Catalog_Namespace::SessionInfo &session) override
 
- Public Member Functions inherited from Parser::InsertIntoTableAsSelectStmt
 InsertIntoTableAsSelectStmt (const rapidjson::Value &payload)
 
 InsertIntoTableAsSelectStmt (const std::string *table_name, const std::string *select_query, std::list< std::string * > *c)
 
void populateData (QueryStateProxy, const TableDescriptor *td, bool validate_table, bool for_CTAS=false)
 
std::string & get_table ()
 
std::string & get_select_query ()
 
- Public Member Functions inherited from Parser::DDLStmt
void setColumnDescriptor (ColumnDescriptor &cd, const ColumnDef *coldef)
 
- Public Member Functions inherited from Parser::Node
virtual ~Node ()
 

Private Attributes

bool is_temporary_
 
bool if_not_exists_
 
std::list< std::unique_ptr
< NameValueAssign > > 
storage_options_
 

Additional Inherited Members

- Public Attributes inherited from Parser::InsertIntoTableAsSelectStmt
DistributedConnectorleafs_connector_ = nullptr
 
- Protected Attributes inherited from Parser::InsertIntoTableAsSelectStmt
std::vector< std::unique_ptr
< std::string > > 
column_list_
 
std::string table_name_
 
std::string select_query_
 

Detailed Description

Definition at line 1151 of file ParserNode.h.

Constructor & Destructor Documentation

Parser::CreateTableAsSelectStmt::CreateTableAsSelectStmt ( const rapidjson::Value &  payload)

Definition at line 3488 of file ParserNode.cpp.

References if_not_exists_, is_temporary_, json_bool(), Parser::anonymous_namespace{ParserNode.cpp}::parse_options(), and storage_options_.

3489  : InsertIntoTableAsSelectStmt(payload) {
3490  if (payload.HasMember("temporary")) {
3491  is_temporary_ = json_bool(payload["temporary"]);
3492  } else {
3493  is_temporary_ = false;
3494  }
3495 
3496  if (payload.HasMember("ifNotExists")) {
3497  if_not_exists_ = json_bool(payload["ifNotExists"]);
3498  } else {
3499  if_not_exists_ = false;
3500  }
3501 
3502  parse_options(payload, storage_options_);
3503 }
const bool json_bool(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:49
std::list< std::unique_ptr< NameValueAssign > > storage_options_
Definition: ParserNode.h:1175
void parse_options(const rapidjson::Value &payload, std::list< std::unique_ptr< NameValueAssign >> &nameValueList, bool stringToNull=false, bool stringToInteger=false)
InsertIntoTableAsSelectStmt(const rapidjson::Value &payload)

+ Here is the call graph for this function:

Parser::CreateTableAsSelectStmt::CreateTableAsSelectStmt ( const std::string *  table_name,
const std::string *  select_query,
const bool  is_temporary,
const bool  if_not_exists,
std::list< NameValueAssign * > *  s 
)
inline

Definition at line 1154 of file ParserNode.h.

References storage_options_.

1159  : InsertIntoTableAsSelectStmt(table_name, select_query, nullptr)
1160  , is_temporary_(is_temporary)
1161  , if_not_exists_(if_not_exists) {
1162  if (s) {
1163  for (const auto& e : *s) {
1164  storage_options_.emplace_back(e);
1165  }
1166  delete s;
1167  }
1168  }
std::list< std::unique_ptr< NameValueAssign > > storage_options_
Definition: ParserNode.h:1175
InsertIntoTableAsSelectStmt(const rapidjson::Value &payload)

Member Function Documentation

void Parser::CreateTableAsSelectStmt::execute ( const Catalog_Namespace::SessionInfo session)
overridevirtual

Reimplemented from Parser::InsertIntoTableAsSelectStmt.

Definition at line 3505 of file ParserNode.cpp.

References anonymous_namespace{Utm.h}::a, CHECK, CHECK_EQ, Catalog_Namespace::SessionInfo::checkDBAccessPrivileges(), Data_Namespace::CPU_LEVEL, query_state::QueryState::create(), bench_batch_streaming_ingest::create_table(), AccessPrivileges::CREATE_TABLE, DEFAULT_FRAGMENT_ROWS, DEFAULT_MAX_CHUNK_SIZE, DEFAULT_MAX_ROLLBACK_EPOCHS, DEFAULT_MAX_ROWS, DEFAULT_PAGE_SIZE, Data_Namespace::DISK_LEVEL, legacylockmgr::ExecutorOuterLock, TableDescriptor::fragmenter, TableDescriptor::fragPageSize, TableDescriptor::fragType, g_cluster, Catalog_Namespace::SessionInfo::get_currentUser(), Parser::StringLiteral::get_stringval(), Parser::anonymous_namespace{ParserNode.cpp}::get_table_definitions_for_ctas(), Catalog_Namespace::SessionInfo::getCatalog(), Parser::LocalConnector::getColumnDescriptors(), legacylockmgr::LockMgr< MutexType, KeyType >::getMutex(), if_not_exists_, logger::INFO, Fragmenter_Namespace::INSERT_ORDER, is_temporary_, TableDescriptor::isView, kENCODING_DICT, TableDescriptor::keyMetainfo, Parser::InsertIntoTableAsSelectStmt::leafs_connector_, LOG, TableDescriptor::maxChunkSize, TableDescriptor::maxFragRows, TableDescriptor::maxRollbackEpochs, TableDescriptor::maxRows, TableDescriptor::nColumns, TableDescriptor::persistenceLevel, pg_shim(), Parser::InsertIntoTableAsSelectStmt::populateData(), Parser::LocalConnector::query(), run_benchmark_import::result, Parser::InsertIntoTableAsSelectStmt::select_query_, Parser::anonymous_namespace{ParserNode.cpp}::serialize_key_metainfo(), gpu_enabled::sort(), STDLOG, storage_options_, Parser::InsertIntoTableAsSelectStmt::table_name_, TableDBObjectType, TableDescriptor::tableName, run_benchmark_import::tables, TableDescriptor::userId, and Catalog_Namespace::UserMetadata::userId.

Referenced by omnisci.cursor.Cursor::executemany(), and QueryRunner::QueryRunner::runSQL().

3505  {
3506  auto session_copy = session;
3507  auto session_ptr = std::shared_ptr<Catalog_Namespace::SessionInfo>(
3508  &session_copy, boost::null_deleter());
3509  auto query_state = query_state::QueryState::create(session_ptr, select_query_);
3510  auto stdlog = STDLOG(query_state);
3511  LocalConnector local_connector;
3512  auto& catalog = session.getCatalog();
3513  bool create_table = nullptr == leafs_connector_;
3514 
3515  std::set<std::string> select_tables;
3516  if (create_table) {
3517  const auto execute_write_lock = mapd_unique_lock<mapd_shared_mutex>(
3520 
3521  // check access privileges
3524  throw std::runtime_error("CTAS failed. Table " + table_name_ +
3525  " will not be created. User has no create privileges.");
3526  }
3527 
3528  if (catalog.getMetadataForTable(table_name_) != nullptr) {
3529  if (if_not_exists_) {
3530  return;
3531  }
3532  throw std::runtime_error("Table " + table_name_ +
3533  " already exists and no data was loaded.");
3534  }
3535 
3536  // get the table info
3537  auto calcite_mgr = catalog.getCalciteMgr();
3538 
3539  // TODO MAT this should actually get the global or the session parameter for
3540  // view optimization
3541  const auto result = calcite_mgr->process(query_state->createQueryStateProxy(),
3543  {},
3544  true,
3545  false,
3546  false,
3547  true);
3548 
3549  // TODO 12 Apr 2021 MAT schema change need to keep schema in future
3550  // just keeping it moving for now
3551  for (auto& tab : result.resolved_accessed_objects.tables_selected_from) {
3552  select_tables.insert(tab[0]);
3553  }
3554 
3555  // only validate the select query so we get the target types
3556  // correctly, but do not populate the result set
3557  // we currently have exclusive access to the system so this is safe
3558  auto validate_result = local_connector.query(
3559  query_state->createQueryStateProxy(), select_query_, {}, true, false);
3560 
3561  const auto column_descriptors_for_create =
3562  local_connector.getColumnDescriptors(validate_result, true);
3563 
3564  // some validation as the QE might return some out of range column types
3565  for (auto& cd : column_descriptors_for_create) {
3566  if (cd.columnType.is_decimal() && cd.columnType.get_precision() > 18) {
3567  throw std::runtime_error(cd.columnName + ": Precision too high, max 18.");
3568  }
3569  }
3570 
3571  TableDescriptor td;
3572  td.tableName = table_name_;
3573  td.userId = session.get_currentUser().userId;
3574  td.nColumns = column_descriptors_for_create.size();
3575  td.isView = false;
3576  td.fragmenter = nullptr;
3583  if (is_temporary_) {
3585  } else {
3587  }
3588 
3589  bool use_shared_dictionaries = true;
3590 
3591  if (!storage_options_.empty()) {
3592  for (auto& p : storage_options_) {
3593  if (boost::to_lower_copy<std::string>(*p->get_name()) ==
3594  "use_shared_dictionaries") {
3595  const StringLiteral* literal =
3596  dynamic_cast<const StringLiteral*>(p->get_value());
3597  if (nullptr == literal) {
3598  throw std::runtime_error(
3599  "USE_SHARED_DICTIONARIES must be a string parameter");
3600  }
3601  std::string val = boost::to_lower_copy<std::string>(*literal->get_stringval());
3602  use_shared_dictionaries = val == "true" || val == "1" || val == "t";
3603  } else {
3604  get_table_definitions_for_ctas(td, p, column_descriptors_for_create);
3605  }
3606  }
3607  }
3608 
3609  std::vector<SharedDictionaryDef> sharedDictionaryRefs;
3610 
3611  if (use_shared_dictionaries) {
3612  const auto source_column_descriptors =
3613  local_connector.getColumnDescriptors(validate_result, false);
3614  const auto mapping = catalog.getDictionaryToColumnMapping();
3615 
3616  for (auto& source_cd : source_column_descriptors) {
3617  const auto& ti = source_cd.columnType;
3618  if (ti.is_string()) {
3619  if (ti.get_compression() == kENCODING_DICT) {
3620  int dict_id = ti.get_comp_param();
3621  auto it = mapping.find(dict_id);
3622  if (mapping.end() != it) {
3623  const auto targetColumn = it->second;
3624  auto targetTable =
3625  catalog.getMetadataForTable(targetColumn->tableId, false);
3626  CHECK(targetTable);
3627  LOG(INFO) << "CTAS: sharing text dictionary on column "
3628  << source_cd.columnName << " with " << targetTable->tableName
3629  << "." << targetColumn->columnName;
3630  sharedDictionaryRefs.push_back(
3631  SharedDictionaryDef(source_cd.columnName,
3632  targetTable->tableName,
3633  targetColumn->columnName));
3634  }
3635  }
3636  }
3637  }
3638  }
3639 
3640  // currently no means of defining sharding in CTAS
3641  td.keyMetainfo = serialize_key_metainfo(nullptr, sharedDictionaryRefs);
3642 
3643  catalog.createTable(td, column_descriptors_for_create, sharedDictionaryRefs, true);
3644  // TODO (max): It's transactionally unsafe, should be fixed: we may create object
3645  // w/o privileges
3646  SysCatalog::instance().createDBObject(
3647  session.get_currentUser(), td.tableName, TableDBObjectType, catalog);
3648  }
3649 
3650  // note there is a time where we do not have any executor outer lock here. someone could
3651  // come along and mess with the data or other tables.
3652  const auto execute_read_lock = mapd_shared_lock<mapd_shared_mutex>(
3655 
3657  std::vector<std::string> tables;
3658  tables.insert(tables.end(), select_tables.begin(), select_tables.end());
3659  CHECK_EQ(tables.size(), select_tables.size());
3660  tables.emplace_back(table_name_);
3661  // force sort into tableid order in case of name change to guarantee fixed order of
3662  // mutex access
3663  std::sort(tables.begin(),
3664  tables.end(),
3665  [&catalog](const std::string& a, const std::string& b) {
3666  return catalog.getMetadataForTable(a, false)->tableId <
3667  catalog.getMetadataForTable(b, false)->tableId;
3668  });
3669  tables.erase(unique(tables.begin(), tables.end()), tables.end());
3670  for (const auto& table : tables) {
3671  locks.emplace_back(
3674  catalog, table)));
3675  if (table == table_name_) {
3676  // Aquire an insert data lock for updates/deletes, consistent w/ insert. The
3677  // table data lock will be aquired in the fragmenter during checkpoint.
3678  locks.emplace_back(
3681  catalog.getDatabaseId(), (*locks.back())())));
3682  } else {
3683  locks.emplace_back(
3686  catalog.getDatabaseId(), (*locks.back())())));
3687  }
3688  }
3689 
3690  const TableDescriptor* td = catalog.getMetadataForTable(table_name_);
3691 
3692  try {
3693  populateData(query_state->createQueryStateProxy(), td, false, true);
3694  } catch (...) {
3695  if (!g_cluster) {
3696  const TableDescriptor* created_td = catalog.getMetadataForTable(table_name_);
3697  if (created_td) {
3698  catalog.dropTable(created_td);
3699  }
3700  }
3701  throw;
3702  }
3703 }
int32_t maxRollbackEpochs
#define CHECK_EQ(x, y)
Definition: Logger.h:217
std::vector< std::unique_ptr< lockmgr::AbstractLockContainer< const TableDescriptor * >>> LockedTableDescriptors
Definition: LockMgr.h:270
std::string tableName
#define LOG(tag)
Definition: Logger.h:203
void populateData(QueryStateProxy, const TableDescriptor *td, bool validate_table, bool for_CTAS=false)
static std::shared_ptr< QueryState > create(ARGS &&...args)
Definition: QueryState.h:145
#define DEFAULT_MAX_CHUNK_SIZE
DEVICE void sort(ARGS &&...args)
Definition: gpu_enabled.h:105
void get_table_definitions_for_ctas(TableDescriptor &td, const std::unique_ptr< NameValueAssign > &p, const std::list< ColumnDescriptor > &columns)
constexpr double a
Definition: Utm.h:32
#define DEFAULT_MAX_ROWS
std::list< std::unique_ptr< NameValueAssign > > storage_options_
Definition: ParserNode.h:1175
#define DEFAULT_MAX_ROLLBACK_EPOCHS
specifies the content in-memory of a row in the table metadata table
static const AccessPrivileges CREATE_TABLE
Definition: DBObject.h:160
std::string keyMetainfo
std::shared_ptr< Fragmenter_Namespace::AbstractFragmenter > fragmenter
#define DEFAULT_PAGE_SIZE
Catalog & getCatalog() const
Definition: SessionInfo.h:67
#define DEFAULT_FRAGMENT_ROWS
Fragmenter_Namespace::FragmenterType fragType
Data_Namespace::MemoryLevel persistenceLevel
static std::shared_ptr< MutexType > getMutex(const LockType lockType, const KeyType &key)
Definition: LegacyLockMgr.h:51
DistributedConnector * leafs_connector_
Definition: ParserNode.h:1139
#define CHECK(condition)
Definition: Logger.h:209
bool g_cluster
bool checkDBAccessPrivileges(const DBObjectType &permissionType, const AccessPrivileges &privs, const std::string &objectName="") const
Definition: SessionInfo.cpp:24
const UserMetadata & get_currentUser() const
Definition: SessionInfo.h:73
std::string pg_shim(const std::string &query)
#define STDLOG(...)
Definition: QueryState.h:235
std::string serialize_key_metainfo(const ShardKeyDef *shard_key_def, const std::vector< SharedDictionaryDef > &shared_dict_defs)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

bool Parser::CreateTableAsSelectStmt::if_not_exists_
private

Definition at line 1174 of file ParserNode.h.

Referenced by CreateTableAsSelectStmt(), and execute().

bool Parser::CreateTableAsSelectStmt::is_temporary_
private

Definition at line 1173 of file ParserNode.h.

Referenced by CreateTableAsSelectStmt(), and execute().

std::list<std::unique_ptr<NameValueAssign> > Parser::CreateTableAsSelectStmt::storage_options_
private

Definition at line 1175 of file ParserNode.h.

Referenced by CreateTableAsSelectStmt(), and execute().


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