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

#include <ParserNode.h>

+ Inheritance diagram for Parser::CreateTableStmt:
+ Collaboration diagram for Parser::CreateTableStmt:

Public Member Functions

 CreateTableStmt (std::string *tab, const std::string *storage, std::list< TableElement * > *table_elems, bool is_temporary, bool if_not_exists, std::list< NameValueAssign * > *s)
 
 CreateTableStmt (const rapidjson::Value &payload)
 
const std::string * get_table () const override
 
const std::list
< std::unique_ptr
< TableElement > > & 
get_table_element_list () const override
 
void execute (const Catalog_Namespace::SessionInfo &session) override
 
void executeDryRun (const Catalog_Namespace::SessionInfo &session, TableDescriptor &td, std::list< ColumnDescriptor > &columns, std::vector< SharedDictionaryDef > &shared_dict_defs)
 
- 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

std::unique_ptr< std::string > table_
 
std::list< std::unique_ptr
< TableElement > > 
table_element_list_
 
bool is_temporary_
 
bool if_not_exists_
 
std::list< std::unique_ptr
< NameValueAssign > > 
storage_options_
 

Detailed Description

Definition at line 956 of file ParserNode.h.

Constructor & Destructor Documentation

Parser::CreateTableStmt::CreateTableStmt ( std::string *  tab,
const std::string *  storage,
std::list< TableElement * > *  table_elems,
bool  is_temporary,
bool  if_not_exists,
std::list< NameValueAssign * > *  s 
)
inline

Definition at line 958 of file ParserNode.h.

References CHECK, storage_options_, and table_element_list_.

964  : table_(tab), is_temporary_(is_temporary), if_not_exists_(if_not_exists) {
965  CHECK(table_elems);
966  for (const auto e : *table_elems) {
967  table_element_list_.emplace_back(e);
968  }
969  delete table_elems;
970  if (s) {
971  for (const auto e : *s) {
972  storage_options_.emplace_back(e);
973  }
974  delete s;
975  }
976  }
std::list< std::unique_ptr< TableElement > > table_element_list_
Definition: ParserNode.h:994
std::list< std::unique_ptr< NameValueAssign > > storage_options_
Definition: ParserNode.h:997
#define CHECK(condition)
Definition: Logger.h:206
std::unique_ptr< std::string > table_
Definition: ParserNode.h:993
Parser::CreateTableStmt::CreateTableStmt ( const rapidjson::Value &  payload)

Definition at line 2249 of file ParserNode.cpp.

References CHECK, logger::FATAL, json_bool(), json_i64(), json_str(), LOG, generate_TableFunctionsFactory_init::sql_types, and to_sql_type().

2249  {
2250  CHECK(payload.HasMember("name"));
2251  table_ = std::make_unique<std::string>(json_str(payload["name"]));
2252  CHECK(payload.HasMember("elements"));
2253  CHECK(payload["elements"].IsArray());
2254 
2255  // TODO: support temporary tables
2256  is_temporary_ = false;
2257 
2258  if_not_exists_ = false;
2259  if (payload.HasMember("ifNotExists")) {
2260  if_not_exists_ = json_bool(payload["ifNotExists"]);
2261  }
2262 
2263  const auto elements = payload["elements"].GetArray();
2264  for (const auto& element : elements) {
2265  CHECK(element.IsObject());
2266  CHECK(element.HasMember("type"));
2267  if (json_str(element["type"]) == "SQL_COLUMN_DECLARATION") {
2268  CHECK(element.HasMember("name"));
2269  auto col_name = std::make_unique<std::string>(json_str(element["name"]));
2270  CHECK(element.HasMember("sqltype"));
2271  const auto sql_types = to_sql_type(json_str(element["sqltype"]));
2272 
2273  // decimal / numeric precision / scale
2274  int precision = -1;
2275  int scale = -1;
2276  if (element.HasMember("precision")) {
2277  precision = json_i64(element["precision"]);
2278  }
2279  if (element.HasMember("scale")) {
2280  scale = json_i64(element["scale"]);
2281  }
2282 
2283  std::optional<int64_t> array_size;
2284  if (element.HasMember("arraySize")) {
2285  // We do not yet support geo arrays
2286  array_size = json_i64(element["arraySize"]);
2287  }
2288  std::unique_ptr<SQLType> sql_type;
2289  if (element.HasMember("subtype")) {
2290  CHECK(element.HasMember("coordinateSystem"));
2291  const auto subtype_sql_types = to_sql_type(json_str(element["subtype"]));
2292  sql_type = std::make_unique<SQLType>(
2293  subtype_sql_types,
2294  static_cast<int>(sql_types),
2295  static_cast<int>(json_i64(element["coordinateSystem"])),
2296  false);
2297  } else if (precision > 0 && scale > 0) {
2298  sql_type = std::make_unique<SQLType>(sql_types,
2299  precision,
2300  scale,
2301  /*is_array=*/array_size.has_value(),
2302  array_size ? *array_size : -1);
2303  } else if (precision > 0) {
2304  sql_type = std::make_unique<SQLType>(sql_types,
2305  precision,
2306  0,
2307  /*is_array=*/array_size.has_value(),
2308  array_size ? *array_size : -1);
2309  } else {
2310  sql_type = std::make_unique<SQLType>(sql_types,
2311  /*is_array=*/array_size.has_value(),
2312  array_size ? *array_size : -1);
2313  }
2314  CHECK(sql_type);
2315 
2316  CHECK(element.HasMember("nullable"));
2317  const auto nullable = json_bool(element["nullable"]);
2318  std::unique_ptr<ColumnConstraintDef> constraint_def;
2319  if (!nullable) {
2320  constraint_def = std::make_unique<ColumnConstraintDef>(/*notnull=*/true,
2321  /*unique=*/false,
2322  /*primarykey=*/false,
2323  /*defaultval=*/nullptr);
2324  }
2325  std::unique_ptr<CompressDef> compress_def;
2326  if (element.HasMember("encodingType") && !element["encodingType"].IsNull()) {
2327  std::string encoding_type = json_str(element["encodingType"]);
2328  CHECK(element.HasMember("encodingSize"));
2329  auto encoding_name =
2330  std::make_unique<std::string>(json_str(element["encodingType"]));
2331  compress_def = std::make_unique<CompressDef>(encoding_name.release(),
2332  json_i64(element["encodingSize"]));
2333  }
2334  auto col_def = std::make_unique<ColumnDef>(
2335  col_name.release(),
2336  sql_type.release(),
2337  compress_def ? compress_def.release() : nullptr,
2338  constraint_def ? constraint_def.release() : nullptr);
2339  table_element_list_.emplace_back(std::move(col_def));
2340  } else if (json_str(element["type"]) == "SQL_COLUMN_CONSTRAINT") {
2341  CHECK(element.HasMember("name"));
2342  if (json_str(element["name"]) == "SHARD_KEY") {
2343  CHECK(element.HasMember("columns"));
2344  CHECK(element["columns"].IsArray());
2345  const auto& columns = element["columns"].GetArray();
2346  if (columns.Size() != size_t(1)) {
2347  throw std::runtime_error("Only one shard column is currently supported.");
2348  }
2349  auto shard_key_def = std::make_unique<ShardKeyDef>(json_str(columns[0]));
2350  table_element_list_.emplace_back(std::move(shard_key_def));
2351  } else if (json_str(element["name"]) == "SHARED_DICT") {
2352  CHECK(element.HasMember("columns"));
2353  CHECK(element["columns"].IsArray());
2354  const auto& columns = element["columns"].GetArray();
2355  if (columns.Size() != size_t(1)) {
2356  throw std::runtime_error(
2357  R"(Only one column per shared dictionary entry is currently supported. Use multiple SHARED DICT statements to share dictionaries from multiple columns.)");
2358  }
2359  CHECK(element.HasMember("references") && element["references"].IsObject());
2360  const auto& references = element["references"].GetObject();
2361  std::string references_table_name;
2362  if (references.HasMember("table")) {
2363  references_table_name = json_str(references["table"]);
2364  } else {
2365  references_table_name = *table_;
2366  }
2367  CHECK(references.HasMember("column"));
2368 
2369  auto shared_dict_def = std::make_unique<SharedDictionaryDef>(
2370  json_str(columns[0]), references_table_name, json_str(references["column"]));
2371  table_element_list_.emplace_back(std::move(shared_dict_def));
2372 
2373  } else {
2374  LOG(FATAL) << "Unsupported type for SQL_COLUMN_CONSTRAINT: "
2375  << json_str(element["name"]);
2376  }
2377  } else {
2378  LOG(FATAL) << "Unsupported element type for CREATE TABLE: "
2379  << element["type"].GetString();
2380  }
2381  }
2382 
2383  CHECK(payload.HasMember("options"));
2384  if (payload["options"].IsObject()) {
2385  for (const auto& option : payload["options"].GetObject()) {
2386  auto option_name = std::make_unique<std::string>(json_str(option.name));
2387  std::unique_ptr<Literal> literal_value;
2388  if (option.value.IsString()) {
2389  auto literal_string = std::make_unique<std::string>(json_str(option.value));
2390  literal_value = std::make_unique<StringLiteral>(literal_string.release());
2391  } else if (option.value.IsInt() || option.value.IsInt64()) {
2392  literal_value = std::make_unique<IntLiteral>(json_i64(option.value));
2393  } else if (option.value.IsNull()) {
2394  literal_value = std::make_unique<NullLiteral>();
2395  } else {
2396  throw std::runtime_error("Unable to handle literal for " + *option_name);
2397  }
2398  CHECK(literal_value);
2399 
2400  storage_options_.emplace_back(std::make_unique<NameValueAssign>(
2401  option_name.release(), literal_value.release()));
2402  }
2403  } else {
2404  CHECK(payload["options"].IsNull());
2405  }
2406 }
SQLTypes to_sql_type(const std::string &type_name)
std::list< std::unique_ptr< TableElement > > table_element_list_
Definition: ParserNode.h:994
#define LOG(tag)
Definition: Logger.h:200
const bool json_bool(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:49
const std::string json_str(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:44
const int64_t json_i64(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:39
std::list< std::unique_ptr< NameValueAssign > > storage_options_
Definition: ParserNode.h:997
#define CHECK(condition)
Definition: Logger.h:206
std::unique_ptr< std::string > table_
Definition: ParserNode.h:993

+ Here is the call graph for this function:

Member Function Documentation

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

Implements Parser::DDLStmt.

Definition at line 2466 of file ParserNode.cpp.

References Catalog_Namespace::SessionInfo::checkDBAccessPrivileges(), AccessPrivileges::CREATE_TABLE, legacylockmgr::ExecutorOuterLock, Catalog_Namespace::SessionInfo::get_currentUser(), Catalog_Namespace::SessionInfo::getCatalog(), legacylockmgr::LockMgr< MutexType, KeyType >::getMutex(), TableDBObjectType, TableDescriptor::tableName, TableDescriptor::userId, and Catalog_Namespace::UserMetadata::userId.

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

2466  {
2467  auto& catalog = session.getCatalog();
2468 
2469  const auto execute_write_lock = mapd_unique_lock<mapd_shared_mutex>(
2472 
2473  // check access privileges
2476  throw std::runtime_error("Table " + *table_ +
2477  " will not be created. User has no create privileges.");
2478  }
2479 
2480  if (!catalog.validateNonExistentTableOrView(*table_, if_not_exists_)) {
2481  return;
2482  }
2483 
2484  TableDescriptor td;
2485  std::list<ColumnDescriptor> columns;
2486  std::vector<SharedDictionaryDef> shared_dict_defs;
2487 
2488  executeDryRun(session, td, columns, shared_dict_defs);
2489  td.userId = session.get_currentUser().userId;
2490 
2491  catalog.createShardedTable(td, columns, shared_dict_defs);
2492  // TODO (max): It's transactionally unsafe, should be fixed: we may create object w/o
2493  // privileges
2494  SysCatalog::instance().createDBObject(
2495  session.get_currentUser(), td.tableName, TableDBObjectType, catalog);
2496 }
std::string tableName
void executeDryRun(const Catalog_Namespace::SessionInfo &session, TableDescriptor &td, std::list< ColumnDescriptor > &columns, std::vector< SharedDictionaryDef > &shared_dict_defs)
static const AccessPrivileges CREATE_TABLE
Definition: DBObject.h:160
Catalog & getCatalog() const
Definition: SessionInfo.h:67
static std::shared_ptr< MutexType > getMutex(const LockType lockType, const KeyType &key)
Definition: LegacyLockMgr.h:51
bool checkDBAccessPrivileges(const DBObjectType &permissionType, const AccessPrivileges &privs, const std::string &objectName="") const
Definition: SessionInfo.cpp:24
std::unique_ptr< std::string > table_
Definition: ParserNode.h:993
const UserMetadata & get_currentUser() const
Definition: SessionInfo.h:73

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Parser::CreateTableStmt::executeDryRun ( const Catalog_Namespace::SessionInfo session,
TableDescriptor td,
std::list< ColumnDescriptor > &  columns,
std::vector< SharedDictionaryDef > &  shared_dict_defs 
)

Definition at line 2408 of file ParserNode.cpp.

References ColumnDescriptor::columnName, Data_Namespace::CPU_LEVEL, Data_Namespace::DISK_LEVEL, Parser::ColumnDef::get_column_name(), Parser::anonymous_namespace{ParserNode.cpp}::get_table_definitions(), Catalog_Namespace::SessionInfo::getCatalog(), TableDescriptor::keyMetainfo, TableDescriptor::nShards, TableDescriptor::persistenceLevel, Parser::anonymous_namespace{ParserNode.cpp}::serialize_key_metainfo(), ddl_utils::set_default_table_attributes(), Parser::anonymous_namespace{ParserNode.cpp}::shard_column_index(), TableDescriptor::shardedColumnId, ddl_utils::validate_non_duplicate_column(), and validate_shared_dictionary().

2411  {
2412  std::unordered_set<std::string> uc_col_names;
2413  const auto& catalog = session.getCatalog();
2414  const ShardKeyDef* shard_key_def{nullptr};
2415  for (auto& e : table_element_list_) {
2416  if (dynamic_cast<SharedDictionaryDef*>(e.get())) {
2417  auto shared_dict_def = static_cast<SharedDictionaryDef*>(e.get());
2419  this, shared_dict_def, columns, shared_dict_defs, catalog);
2420  shared_dict_defs.push_back(*shared_dict_def);
2421  continue;
2422  }
2423  if (dynamic_cast<ShardKeyDef*>(e.get())) {
2424  if (shard_key_def) {
2425  throw std::runtime_error("Specified more than one shard key");
2426  }
2427  shard_key_def = static_cast<const ShardKeyDef*>(e.get());
2428  continue;
2429  }
2430  if (!dynamic_cast<ColumnDef*>(e.get())) {
2431  throw std::runtime_error("Table constraints are not supported yet.");
2432  }
2433  ColumnDef* coldef = static_cast<ColumnDef*>(e.get());
2434  ColumnDescriptor cd;
2435  cd.columnName = *coldef->get_column_name();
2437  setColumnDescriptor(cd, coldef);
2438  columns.push_back(cd);
2439  }
2440 
2441  ddl_utils::set_default_table_attributes(*table_, td, columns.size());
2442 
2443  if (shard_key_def) {
2444  td.shardedColumnId = shard_column_index(shard_key_def->get_column(), columns);
2445  if (!td.shardedColumnId) {
2446  throw std::runtime_error("Specified shard column " + shard_key_def->get_column() +
2447  " doesn't exist");
2448  }
2449  }
2450  if (is_temporary_) {
2452  } else {
2454  }
2455  if (!storage_options_.empty()) {
2456  for (auto& p : storage_options_) {
2457  get_table_definitions(td, p, columns);
2458  }
2459  }
2460  if (td.shardedColumnId && !td.nShards) {
2461  throw std::runtime_error("SHARD_COUNT needs to be specified with SHARD_KEY.");
2462  }
2463  td.keyMetainfo = serialize_key_metainfo(shard_key_def, shared_dict_defs);
2464 }
size_t shard_column_index(const std::string &name, const std::list< ColumnDescriptor > &columns)
void setColumnDescriptor(ColumnDescriptor &cd, const ColumnDef *coldef)
std::list< std::unique_ptr< TableElement > > table_element_list_
Definition: ParserNode.h:994
void validate_non_duplicate_column(const std::string &column_name, std::unordered_set< std::string > &upper_column_names)
Definition: DdlUtils.cpp:537
specifies the content in-memory of a row in the column metadata table
std::string keyMetainfo
void set_default_table_attributes(const std::string &table_name, TableDescriptor &td, const int32_t column_count)
Definition: DdlUtils.cpp:523
Catalog & getCatalog() const
Definition: SessionInfo.h:67
Data_Namespace::MemoryLevel persistenceLevel
std::list< std::unique_ptr< NameValueAssign > > storage_options_
Definition: ParserNode.h:997
void validate_shared_dictionary(const Parser::CreateTableBaseStmt *stmt, const Parser::SharedDictionaryDef *shared_dict_def, const std::list< ColumnDescriptor > &columns, const std::vector< Parser::SharedDictionaryDef > &shared_dict_defs_so_far, const Catalog_Namespace::Catalog &catalog)
void get_table_definitions(TableDescriptor &td, const std::unique_ptr< NameValueAssign > &p, const std::list< ColumnDescriptor > &columns)
std::string columnName
std::unique_ptr< std::string > table_
Definition: ParserNode.h:993
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:

const std::string* Parser::CreateTableStmt::get_table ( ) const
inlineoverridevirtual

Implements Parser::CreateTableBaseStmt.

Definition at line 980 of file ParserNode.h.

References table_.

980 { return table_.get(); }
std::unique_ptr< std::string > table_
Definition: ParserNode.h:993
const std::list<std::unique_ptr<TableElement> >& Parser::CreateTableStmt::get_table_element_list ( ) const
inlineoverridevirtual

Implements Parser::CreateTableBaseStmt.

Definition at line 981 of file ParserNode.h.

References table_element_list_.

982  {
983  return table_element_list_;
984  }
std::list< std::unique_ptr< TableElement > > table_element_list_
Definition: ParserNode.h:994

Member Data Documentation

bool Parser::CreateTableStmt::if_not_exists_
private

Definition at line 996 of file ParserNode.h.

bool Parser::CreateTableStmt::is_temporary_
private

Definition at line 995 of file ParserNode.h.

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

Definition at line 997 of file ParserNode.h.

Referenced by CreateTableStmt().

std::unique_ptr<std::string> Parser::CreateTableStmt::table_
private

Definition at line 993 of file ParserNode.h.

Referenced by get_table().

std::list<std::unique_ptr<TableElement> > Parser::CreateTableStmt::table_element_list_
private

Definition at line 994 of file ParserNode.h.

Referenced by CreateTableStmt(), and get_table_element_list().


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