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

#include <ParserNode.h>

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

Public Member Functions

 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

const bool is_temporary_
 
const 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 1123 of file ParserNode.h.

Constructor & Destructor Documentation

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 1125 of file ParserNode.h.

References storage_options_.

1130  : InsertIntoTableAsSelectStmt(table_name, select_query, nullptr)
1131  , is_temporary_(is_temporary)
1132  , if_not_exists_(if_not_exists) {
1133  if (s) {
1134  for (const auto& e : *s) {
1135  storage_options_.emplace_back(e);
1136  }
1137  delete s;
1138  }
1139  }
std::list< std::unique_ptr< NameValueAssign > > storage_options_
Definition: ParserNode.h:1146
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 3385 of file ParserNode.cpp.

References 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(), logger::INFO, Fragmenter_Namespace::INSERT_ORDER, TableDescriptor::isView, kENCODING_DICT, TableDescriptor::keyMetainfo, LOG, TableDescriptor::maxChunkSize, TableDescriptor::maxFragRows, TableDescriptor::maxRollbackEpochs, TableDescriptor::maxRows, TableDescriptor::nColumns, TableDescriptor::persistenceLevel, pg_shim(), Parser::LocalConnector::query(), run_benchmark_import::result, Parser::anonymous_namespace{ParserNode.cpp}::serialize_key_metainfo(), gpu_enabled::sort(), STDLOG, test_readcsv::table, TableDBObjectType, TableDescriptor::tableName, run_benchmark_import::tables, TableDescriptor::userId, and Catalog_Namespace::UserMetadata::userId.

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

3385  {
3386  auto session_copy = session;
3387  auto session_ptr = std::shared_ptr<Catalog_Namespace::SessionInfo>(
3388  &session_copy, boost::null_deleter());
3389  auto query_state = query_state::QueryState::create(session_ptr, select_query_);
3390  auto stdlog = STDLOG(query_state);
3391  LocalConnector local_connector;
3392  auto& catalog = session.getCatalog();
3393  bool create_table = nullptr == leafs_connector_;
3394 
3395  std::set<std::string> select_tables;
3396  if (create_table) {
3397  const auto execute_write_lock = mapd_unique_lock<mapd_shared_mutex>(
3400 
3401  // check access privileges
3404  throw std::runtime_error("CTAS failed. Table " + table_name_ +
3405  " will not be created. User has no create privileges.");
3406  }
3407 
3408  if (catalog.getMetadataForTable(table_name_) != nullptr) {
3409  if (if_not_exists_) {
3410  return;
3411  }
3412  throw std::runtime_error("Table " + table_name_ +
3413  " already exists and no data was loaded.");
3414  }
3415 
3416  // get the table info
3417  auto calcite_mgr = catalog.getCalciteMgr();
3418 
3419  // TODO MAT this should actually get the global or the session parameter for
3420  // view optimization
3421  const auto result = calcite_mgr->process(query_state->createQueryStateProxy(),
3423  {},
3424  true,
3425  false,
3426  false,
3427  true);
3428 
3429  // TODO 12 Apr 2021 MAT schema change need to keep schema in future
3430  // just keeping it moving for now
3431  for (auto& tab : result.resolved_accessed_objects.tables_selected_from) {
3432  select_tables.insert(tab[0]);
3433  }
3434 
3435  // only validate the select query so we get the target types
3436  // correctly, but do not populate the result set
3437  // we currently have exclusive access to the system so this is safe
3438  auto validate_result = local_connector.query(
3439  query_state->createQueryStateProxy(), select_query_, {}, true, false);
3440 
3441  const auto column_descriptors_for_create =
3442  local_connector.getColumnDescriptors(validate_result, true);
3443 
3444  // some validation as the QE might return some out of range column types
3445  for (auto& cd : column_descriptors_for_create) {
3446  if (cd.columnType.is_decimal() && cd.columnType.get_precision() > 18) {
3447  throw std::runtime_error(cd.columnName + ": Precision too high, max 18.");
3448  }
3449  }
3450 
3451  TableDescriptor td;
3452  td.tableName = table_name_;
3453  td.userId = session.get_currentUser().userId;
3454  td.nColumns = column_descriptors_for_create.size();
3455  td.isView = false;
3456  td.fragmenter = nullptr;
3463  if (is_temporary_) {
3465  } else {
3467  }
3468 
3469  bool use_shared_dictionaries = true;
3470 
3471  if (!storage_options_.empty()) {
3472  for (auto& p : storage_options_) {
3473  if (boost::to_lower_copy<std::string>(*p->get_name()) ==
3474  "use_shared_dictionaries") {
3475  const StringLiteral* literal =
3476  dynamic_cast<const StringLiteral*>(p->get_value());
3477  if (nullptr == literal) {
3478  throw std::runtime_error(
3479  "USE_SHARED_DICTIONARIES must be a string parameter");
3480  }
3481  std::string val = boost::to_lower_copy<std::string>(*literal->get_stringval());
3482  use_shared_dictionaries = val == "true" || val == "1" || val == "t";
3483  } else {
3484  get_table_definitions_for_ctas(td, p, column_descriptors_for_create);
3485  }
3486  }
3487  }
3488 
3489  std::vector<SharedDictionaryDef> sharedDictionaryRefs;
3490 
3491  if (use_shared_dictionaries) {
3492  const auto source_column_descriptors =
3493  local_connector.getColumnDescriptors(validate_result, false);
3494  const auto mapping = catalog.getDictionaryToColumnMapping();
3495 
3496  for (auto& source_cd : source_column_descriptors) {
3497  const auto& ti = source_cd.columnType;
3498  if (ti.is_string()) {
3499  if (ti.get_compression() == kENCODING_DICT) {
3500  int dict_id = ti.get_comp_param();
3501  auto it = mapping.find(dict_id);
3502  if (mapping.end() != it) {
3503  const auto targetColumn = it->second;
3504  auto targetTable =
3505  catalog.getMetadataForTable(targetColumn->tableId, false);
3506  CHECK(targetTable);
3507  LOG(INFO) << "CTAS: sharing text dictionary on column "
3508  << source_cd.columnName << " with " << targetTable->tableName
3509  << "." << targetColumn->columnName;
3510  sharedDictionaryRefs.push_back(
3511  SharedDictionaryDef(source_cd.columnName,
3512  targetTable->tableName,
3513  targetColumn->columnName));
3514  }
3515  }
3516  }
3517  }
3518  }
3519 
3520  // currently no means of defining sharding in CTAS
3521  td.keyMetainfo = serialize_key_metainfo(nullptr, sharedDictionaryRefs);
3522 
3523  catalog.createTable(td, column_descriptors_for_create, sharedDictionaryRefs, true);
3524  // TODO (max): It's transactionally unsafe, should be fixed: we may create object
3525  // w/o privileges
3526  SysCatalog::instance().createDBObject(
3527  session.get_currentUser(), td.tableName, TableDBObjectType, catalog);
3528  }
3529 
3530  // note there is a time where we do not have any executor outer lock here. someone could
3531  // come along and mess with the data or other tables.
3532  const auto execute_read_lock = mapd_shared_lock<mapd_shared_mutex>(
3535 
3537  std::vector<std::string> tables;
3538  tables.insert(tables.end(), select_tables.begin(), select_tables.end());
3539  CHECK_EQ(tables.size(), select_tables.size());
3540  tables.emplace_back(table_name_);
3541  // force sort into tableid order in case of name change to guarantee fixed order of
3542  // mutex access
3543  std::sort(tables.begin(),
3544  tables.end(),
3545  [&catalog](const std::string& a, const std::string& b) {
3546  return catalog.getMetadataForTable(a, false)->tableId <
3547  catalog.getMetadataForTable(b, false)->tableId;
3548  });
3549  tables.erase(unique(tables.begin(), tables.end()), tables.end());
3550  for (const auto& table : tables) {
3551  locks.emplace_back(
3554  catalog, table)));
3555  if (table == table_name_) {
3556  // Aquire an insert data lock for updates/deletes, consistent w/ insert. The
3557  // table data lock will be aquired in the fragmenter during checkpoint.
3558  locks.emplace_back(
3561  catalog.getDatabaseId(), (*locks.back())())));
3562  } else {
3563  locks.emplace_back(
3566  catalog.getDatabaseId(), (*locks.back())())));
3567  }
3568  }
3569 
3570  const TableDescriptor* td = catalog.getMetadataForTable(table_name_);
3571 
3572  try {
3573  populateData(query_state->createQueryStateProxy(), td, false, true);
3574  } catch (...) {
3575  if (!g_cluster) {
3576  const TableDescriptor* created_td = catalog.getMetadataForTable(table_name_);
3577  if (created_td) {
3578  catalog.dropTable(created_td);
3579  }
3580  }
3581  throw;
3582  }
3583 }
int32_t maxRollbackEpochs
#define CHECK_EQ(x, y)
Definition: Logger.h:214
std::vector< std::unique_ptr< lockmgr::AbstractLockContainer< const TableDescriptor * >>> LockedTableDescriptors
Definition: LockMgr.h:270
std::string tableName
#define LOG(tag)
Definition: Logger.h:200
void populateData(QueryStateProxy, const TableDescriptor *td, bool validate_table, bool for_CTAS=false)
static std::shared_ptr< QueryState > create(ARGS &&...args)
Definition: QueryState.h:141
#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)
#define DEFAULT_MAX_ROWS
std::list< std::unique_ptr< NameValueAssign > > storage_options_
Definition: ParserNode.h:1146
#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:1111
#define CHECK(condition)
Definition: Logger.h:206
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:229
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

const bool Parser::CreateTableAsSelectStmt::if_not_exists_
private

Definition at line 1145 of file ParserNode.h.

const bool Parser::CreateTableAsSelectStmt::is_temporary_
private

Definition at line 1144 of file ParserNode.h.

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

Definition at line 1146 of file ParserNode.h.

Referenced by CreateTableAsSelectStmt().


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