OmniSciDB  a5dc49c757
 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, bool read_only_mode) 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
std::unique_ptr< QueryConnectorleafs_connector_
 
- 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 1169 of file ParserNode.h.

Constructor & Destructor Documentation

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

Definition at line 4699 of file ParserNode.cpp.

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

4700  : InsertIntoTableAsSelectStmt(payload) {
4701  if (payload.HasMember("temporary")) {
4702  is_temporary_ = json_bool(payload["temporary"]);
4703  } else {
4704  is_temporary_ = false;
4705  }
4706 
4707  if (payload.HasMember("ifNotExists")) {
4708  if_not_exists_ = json_bool(payload["ifNotExists"]);
4709  } else {
4710  if_not_exists_ = false;
4711  }
4712 
4713  parse_options(payload, storage_options_);
4714 }
const bool json_bool(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:51
std::list< std::unique_ptr< NameValueAssign > > storage_options_
Definition: ParserNode.h:1194
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 1172 of file ParserNode.h.

References storage_options_.

1177  : InsertIntoTableAsSelectStmt(table_name, select_query, nullptr)
1178  , is_temporary_(is_temporary)
1179  , if_not_exists_(if_not_exists) {
1180  if (s) {
1181  for (const auto& e : *s) {
1182  storage_options_.emplace_back(e);
1183  }
1184  delete s;
1185  }
1186  }
std::list< std::unique_ptr< NameValueAssign > > storage_options_
Definition: ParserNode.h:1194
InsertIntoTableAsSelectStmt(const rapidjson::Value &payload)

Member Function Documentation

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

Reimplemented from Parser::InsertIntoTableAsSelectStmt.

Definition at line 4716 of file ParserNode.cpp.

References Parser::anonymous_namespace{ParserNode.cpp}::acquire_query_table_locks(), CHECK, 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, 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::LocalQueryConnector::getColumnDescriptors(), legacylockmgr::getExecuteReadLock(), legacylockmgr::getExecuteWriteLock(), if_not_exists_, logger::INFO, Fragmenter_Namespace::INSERT_ORDER, lockmgr::instance(), is_temporary_, TableDescriptor::isView, kENCODING_DICT, kENCODING_GEOINT, TableDescriptor::keyMetainfo, sql_constants::kMaxNumericPrecision, Parser::InsertIntoTableAsSelectStmt::leafs_connector_, LOG, TableDescriptor::maxChunkSize, TableDescriptor::maxFragRows, TableDescriptor::maxRollbackEpochs, TableDescriptor::maxRows, TableDescriptor::nColumns, TableDescriptor::persistenceLevel, Parser::InsertIntoTableAsSelectStmt::populateData(), Parser::LocalQueryConnector::query(), Parser::InsertIntoTableAsSelectStmt::select_query_, Parser::anonymous_namespace{ParserNode.cpp}::serialize_key_metainfo(), STDLOG, storage_options_, Parser::InsertIntoTableAsSelectStmt::table_name_, TableDBObjectType, TableDescriptor::tableName, to_string(), TableDescriptor::userId, and Catalog_Namespace::UserMetadata::userId.

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

4717  {
4718  if (read_only_mode) {
4719  throw std::runtime_error("CREATE TABLE invalid in read only mode.");
4720  }
4721  auto session_copy = session;
4722  auto session_ptr = std::shared_ptr<Catalog_Namespace::SessionInfo>(
4723  &session_copy, boost::null_deleter());
4724  auto query_state = query_state::QueryState::create(session_ptr, select_query_);
4725  auto stdlog = STDLOG(query_state);
4726  LocalQueryConnector local_connector;
4727  auto& catalog = session.getCatalog();
4728  bool create_table = nullptr == leafs_connector_;
4729 
4730  std::set<std::string> select_tables;
4731  if (create_table) {
4732  const auto execute_write_lock = legacylockmgr::getExecuteWriteLock();
4733 
4734  // check access privileges
4737  throw std::runtime_error("CTAS failed. Table " + table_name_ +
4738  " will not be created. User has no create privileges.");
4739  }
4740 
4741  if (catalog.getMetadataForTable(table_name_) != nullptr) {
4742  if (if_not_exists_) {
4743  return;
4744  }
4745  throw std::runtime_error("Table " + table_name_ +
4746  " already exists and no data was loaded.");
4747  }
4748 
4749  // only validate the select query so we get the target types
4750  // correctly, but do not populate the result set
4751  // we currently have exclusive access to the system so this is safe
4752  auto validate_result = local_connector.query(
4753  query_state->createQueryStateProxy(), select_query_, {}, true, false);
4754 
4755  auto column_descriptors_for_create =
4756  local_connector.getColumnDescriptors(validate_result, true);
4757 
4758  // some validation as the QE might return some out of range column types
4759  for (auto& cd : column_descriptors_for_create) {
4760  if (cd.columnType.is_decimal() &&
4761  cd.columnType.get_precision() > sql_constants::kMaxNumericPrecision) {
4762  throw std::runtime_error(cd.columnName + ": Precision too high, max " +
4764  ".");
4765  }
4766  // flatbuffer storage in real tables is not implemented, so we
4767  // reset the flatbuffer storage flag for CTAS cases that select
4768  // from UDTF columns which may use flatbuffer storage:
4769  cd.columnType.setUsesFlatBuffer(false);
4770  }
4771 
4772  TableDescriptor td;
4773  td.tableName = table_name_;
4774  td.userId = session.get_currentUser().userId;
4775  td.nColumns = column_descriptors_for_create.size();
4776  td.isView = false;
4777  td.fragmenter = nullptr;
4784  if (is_temporary_) {
4786  } else {
4788  }
4789 
4790  bool use_shared_dictionaries = true;
4791  bool force_geo_compression = true;
4792 
4793  if (!storage_options_.empty()) {
4794  for (auto& p : storage_options_) {
4795  if (boost::to_lower_copy<std::string>(*p->get_name()) ==
4796  "use_shared_dictionaries") {
4797  const StringLiteral* literal =
4798  dynamic_cast<const StringLiteral*>(p->get_value());
4799  if (nullptr == literal) {
4800  throw std::runtime_error(
4801  "USE_SHARED_DICTIONARIES must be a string parameter");
4802  }
4803  std::string val = boost::to_lower_copy<std::string>(*literal->get_stringval());
4804  use_shared_dictionaries = val == "true" || val == "1" || val == "t";
4805  } else if (boost::to_lower_copy<std::string>(*p->get_name()) ==
4806  "force_geo_compression") {
4807  const StringLiteral* literal =
4808  dynamic_cast<const StringLiteral*>(p->get_value());
4809  if (nullptr == literal) {
4810  throw std::runtime_error("FORCE_GEO_COMPRESSION must be a string parameter");
4811  }
4812  std::string val = boost::to_lower_copy<std::string>(*literal->get_stringval());
4813  force_geo_compression = val == "true" || val == "1" || val == "t";
4814  } else {
4815  get_table_definitions_for_ctas(td, p, column_descriptors_for_create);
4816  }
4817  }
4818  }
4819 
4820  std::vector<SharedDictionaryDef> sharedDictionaryRefs;
4821 
4822  if (use_shared_dictionaries) {
4823  const auto source_column_descriptors =
4824  local_connector.getColumnDescriptors(validate_result, false);
4825  const auto mapping = catalog.getDictionaryToColumnMapping();
4826 
4827  for (auto& source_cd : source_column_descriptors) {
4828  const auto& ti = source_cd.columnType;
4829  if (ti.is_string()) {
4830  if (ti.get_compression() == kENCODING_DICT) {
4831  int dict_id = ti.get_comp_param();
4832  auto it = mapping.find(dict_id);
4833  if (mapping.end() != it) {
4834  const auto targetColumn = it->second;
4835  auto targetTable =
4836  catalog.getMetadataForTable(targetColumn->tableId, false);
4837  CHECK(targetTable);
4838  LOG(INFO) << "CTAS: sharing text dictionary on column "
4839  << source_cd.columnName << " with " << targetTable->tableName
4840  << "." << targetColumn->columnName;
4841  sharedDictionaryRefs.emplace_back(
4842  source_cd.columnName, targetTable->tableName, targetColumn->columnName);
4843  }
4844  }
4845  }
4846  }
4847  }
4848 
4849  if (force_geo_compression) {
4850  for (auto& cd_for_create : column_descriptors_for_create) {
4851  auto& ti = cd_for_create.columnType;
4852  if (ti.is_geometry() && ti.get_output_srid() == 4326) {
4853  // turn on GEOINT32 compression
4854  ti.set_compression(kENCODING_GEOINT);
4855  ti.set_comp_param(32);
4856  }
4857  }
4858  }
4859 
4860  // currently no means of defining sharding in CTAS
4861  td.keyMetainfo = serialize_key_metainfo(nullptr, sharedDictionaryRefs);
4862 
4863  catalog.createTable(td, column_descriptors_for_create, sharedDictionaryRefs, true);
4864  // TODO (max): It's transactionally unsafe, should be fixed: we may create object
4865  // w/o privileges
4866  SysCatalog::instance().createDBObject(
4867  session.get_currentUser(), td.tableName, TableDBObjectType, catalog);
4868  }
4869 
4870  // note there is a time where we do not have any executor outer lock here. someone could
4871  // come along and mess with the data or other tables.
4872  const auto execute_read_lock = legacylockmgr::getExecuteReadLock();
4873 
4874  auto locks = acquire_query_table_locks(
4875  catalog.name(), select_query_, query_state->createQueryStateProxy(), table_name_);
4876  const TableDescriptor* td = catalog.getMetadataForTable(table_name_);
4877  try {
4878  populateData(query_state->createQueryStateProxy(), td, false, true);
4879  } catch (...) {
4880  if (!g_cluster) {
4881  const TableDescriptor* created_td = catalog.getMetadataForTable(table_name_);
4882  if (created_td) {
4883  catalog.dropTable(created_td);
4884  }
4885  }
4886  throw;
4887  }
4888 }
int32_t maxRollbackEpochs
static constexpr int32_t kMaxNumericPrecision
Definition: sqltypes.h:58
std::string tableName
auto getExecuteReadLock()
#define LOG(tag)
Definition: Logger.h:285
void populateData(QueryStateProxy, const TableDescriptor *td, bool validate_table, bool for_CTAS=false)
static std::shared_ptr< QueryState > create(ARGS &&...args)
Definition: QueryState.h:148
#define DEFAULT_MAX_CHUNK_SIZE
void get_table_definitions_for_ctas(TableDescriptor &td, const std::unique_ptr< NameValueAssign > &p, const std::list< ColumnDescriptor > &columns)
std::string to_string(char const *&&v)
#define DEFAULT_MAX_ROWS
std::unique_ptr< QueryConnector > leafs_connector_
Definition: ParserNode.h:1157
std::list< std::unique_ptr< NameValueAssign > > storage_options_
Definition: ParserNode.h:1194
#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:158
lockmgr::LockedTableDescriptors acquire_query_table_locks(const std::string &insert_table_db_name, const std::string &query_str, const QueryStateProxy &query_state_proxy, const std::optional< std::string > &insert_table_name={})
std::string keyMetainfo
std::shared_ptr< Fragmenter_Namespace::AbstractFragmenter > fragmenter
#define DEFAULT_PAGE_SIZE
Catalog & getCatalog() const
Definition: SessionInfo.h:75
#define DEFAULT_FRAGMENT_ROWS
T & instance()
Definition: LockMgr.cpp:101
Fragmenter_Namespace::FragmenterType fragType
Data_Namespace::MemoryLevel persistenceLevel
#define CHECK(condition)
Definition: Logger.h:291
bool g_cluster
auto getExecuteWriteLock()
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:88
#define STDLOG(...)
Definition: QueryState.h:234
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 1193 of file ParserNode.h.

Referenced by CreateTableAsSelectStmt(), and execute().

bool Parser::CreateTableAsSelectStmt::is_temporary_
private

Definition at line 1192 of file ParserNode.h.

Referenced by CreateTableAsSelectStmt(), and execute().

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

Definition at line 1194 of file ParserNode.h.

Referenced by CreateTableAsSelectStmt(), and execute().


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