OmniSciDB  06b3bd477c
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Parser::AddColumnStmt Class Reference

#include <ParserNode.h>

+ Inheritance diagram for Parser::AddColumnStmt:
+ Collaboration diagram for Parser::AddColumnStmt:

Public Member Functions

 AddColumnStmt (std::string *tab, ColumnDef *coldef)
 
 AddColumnStmt (std::string *tab, std::list< ColumnDef * > *coldefs)
 
void execute (const Catalog_Namespace::SessionInfo &session) override
 
void check_executable (const Catalog_Namespace::SessionInfo &session, const TableDescriptor *td)
 
const std::string * get_table () const
 
- 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::unique_ptr< ColumnDefcoldef
 
std::list< std::unique_ptr
< ColumnDef > > 
coldefs
 

Detailed Description

Definition at line 1293 of file ParserNode.h.

Constructor & Destructor Documentation

Parser::AddColumnStmt::AddColumnStmt ( std::string *  tab,
ColumnDef coldef 
)
inline

Definition at line 1295 of file ParserNode.h.

1295 : table(tab), coldef(coldef) {}
std::unique_ptr< std::string > table
Definition: ParserNode.h:1308
std::unique_ptr< ColumnDef > coldef
Definition: ParserNode.h:1309
Parser::AddColumnStmt::AddColumnStmt ( std::string *  tab,
std::list< ColumnDef * > *  coldefs 
)
inline

Definition at line 1296 of file ParserNode.h.

References coldef, and coldefs.

1296  : table(tab) {
1297  for (const auto coldef : *coldefs) {
1298  this->coldefs.emplace_back(coldef);
1299  }
1300  delete coldefs;
1301  }
std::list< std::unique_ptr< ColumnDef > > coldefs
Definition: ParserNode.h:1310
std::unique_ptr< std::string > table
Definition: ParserNode.h:1308
std::unique_ptr< ColumnDef > coldef
Definition: ParserNode.h:1309

Member Function Documentation

void Parser::AddColumnStmt::check_executable ( const Catalog_Namespace::SessionInfo session,
const TableDescriptor td 
)

Definition at line 3281 of file ParserNode.cpp.

References Parser::check_alter_table_privilege(), Catalog_Namespace::SessionInfo::getCatalog(), TableDescriptor::isView, table_is_temporary(), and TableDescriptor::tableId.

3282  {
3283  auto& catalog = session.getCatalog();
3284  if (!td) {
3285  throw std::runtime_error("Table " + *table + " does not exist.");
3286  } else {
3287  if (td->isView) {
3288  throw std::runtime_error("Adding columns to a view is not supported.");
3289  }
3290  if (table_is_temporary(td)) {
3291  throw std::runtime_error(
3292  "Adding columns to temporary tables is not yet supported.");
3293  }
3294  };
3295 
3296  check_alter_table_privilege(session, td);
3297 
3298  if (0 == coldefs.size()) {
3299  coldefs.push_back(std::move(coldef));
3300  }
3301 
3302  for (const auto& coldef : coldefs) {
3303  auto& new_column_name = *coldef->get_column_name();
3304  if (catalog.getMetadataForColumn(td->tableId, new_column_name) != nullptr) {
3305  throw std::runtime_error("Column " + new_column_name + " already exists.");
3306  }
3307  }
3308 }
std::list< std::unique_ptr< ColumnDef > > coldefs
Definition: ParserNode.h:1310
std::unique_ptr< std::string > table
Definition: ParserNode.h:1308
void check_alter_table_privilege(const Catalog_Namespace::SessionInfo &session, const TableDescriptor *td)
bool table_is_temporary(const TableDescriptor *const td)
Catalog & getCatalog() const
Definition: SessionInfo.h:65
std::unique_ptr< ColumnDef > coldef
Definition: ParserNode.h:1309

+ Here is the call graph for this function:

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

Implements Parser::DDLStmt.

Definition at line 3310 of file ParserNode.cpp.

References CHECK(), ColumnDescriptor::columnId, ColumnDescriptor::columnName, ColumnDescriptor::columnType, legacylockmgr::ExecutorOuterLock, Parser::StringLiteral::get_stringval(), Catalog_Namespace::SessionInfo::getCatalog(), Geo_namespace::GeoTypesFactory::getGeoColumns(), legacylockmgr::LockMgr< MutexType, KeyType >::getMutex(), SQLTypeInfo::is_geometry(), import_export::Importer::set_geo_physical_import_buffer(), and import_export::setup_column_loaders().

3310  {
3311  auto& catalog = session.getCatalog();
3312 
3313  // TODO(adb): the catalog should be handling this locking.
3314  const auto execute_write_lock = mapd_unique_lock<mapd_shared_mutex>(
3317 
3318  const auto td_with_lock =
3320  catalog, *table, true);
3321  const auto td = td_with_lock();
3322 
3323  check_executable(session, td);
3324 
3325  CHECK(td->fragmenter);
3326  if (std::dynamic_pointer_cast<Fragmenter_Namespace::SortedOrderFragmenter>(
3327  td->fragmenter)) {
3328  throw std::runtime_error(
3329  "Adding columns to a table is not supported when using the \"sort_column\" "
3330  "option.");
3331  }
3332 
3333  // Do not take a data write lock, as the fragmenter may call `deleteFragments` during
3334  // a cap operation. Note that the schema write lock will prevent concurrent inserts
3335  // along with all other queries.
3336 
3337  catalog.getSqliteConnector().query("BEGIN TRANSACTION");
3338  try {
3339  std::map<const std::string, const ColumnDescriptor> cds;
3340  std::map<const int, const ColumnDef*> cid_coldefs;
3341  for (const auto& coldef : coldefs) {
3342  ColumnDescriptor cd;
3343  setColumnDescriptor(cd, coldef.get());
3344  catalog.addColumn(*td, cd);
3345  cds.emplace(*coldef->get_column_name(), cd);
3346  cid_coldefs.emplace(cd.columnId, coldef.get());
3347 
3348  // expand geo column to phy columns
3349  if (cd.columnType.is_geometry()) {
3350  std::list<ColumnDescriptor> phy_geo_columns;
3351  catalog.expandGeoColumn(cd, phy_geo_columns);
3352  for (auto& cd : phy_geo_columns) {
3353  catalog.addColumn(*td, cd);
3354  cds.emplace(cd.columnName, cd);
3355  cid_coldefs.emplace(cd.columnId, nullptr);
3356  }
3357  }
3358  }
3359 
3360  std::unique_ptr<import_export::Loader> loader(new import_export::Loader(catalog, td));
3361  auto import_buffers = import_export::setup_column_loaders(td, loader.get());
3362  loader->setReplicating(true);
3363 
3364  // set_geo_physical_import_buffer below needs a sorted import_buffers
3365  std::sort(import_buffers.begin(),
3366  import_buffers.end(),
3367  [](decltype(import_buffers[0])& a, decltype(import_buffers[0])& b) {
3368  return a->getColumnDesc()->columnId < b->getColumnDesc()->columnId;
3369  });
3370 
3371  size_t nrows = td->fragmenter->getNumRows();
3372  // if sharded, get total nrows from all sharded tables
3373  if (td->nShards > 0) {
3374  const auto physical_tds = catalog.getPhysicalTablesDescriptors(td);
3375  nrows = 0;
3376  std::for_each(physical_tds.begin(), physical_tds.end(), [&nrows](const auto& td) {
3377  nrows += td->fragmenter->getNumRows();
3378  });
3379  }
3380  if (nrows > 0) {
3381  int skip_physical_cols = 0;
3382  for (const auto cit : cid_coldefs) {
3383  const auto cd = catalog.getMetadataForColumn(td->tableId, cit.first);
3384  const auto coldef = cit.second;
3385  const auto column_constraint = coldef ? coldef->get_column_constraint() : nullptr;
3386  std::string defaultval = "";
3387  if (column_constraint) {
3388  auto defaultlp = column_constraint->get_defaultval();
3389  auto defaultsp = dynamic_cast<const StringLiteral*>(defaultlp);
3390  defaultval = defaultsp ? *defaultsp->get_stringval()
3391  : defaultlp ? defaultlp->to_string() : "";
3392  }
3393  bool isnull = column_constraint ? (0 == defaultval.size()) : true;
3394  if (boost::to_upper_copy<std::string>(defaultval) == "NULL") {
3395  isnull = true;
3396  }
3397 
3398  if (isnull) {
3399  if (column_constraint && column_constraint->get_notnull()) {
3400  throw std::runtime_error("Default value required for column " +
3401  cd->columnName + " (NULL value not supported)");
3402  }
3403  }
3404 
3405  for (auto it = import_buffers.begin(); it < import_buffers.end(); ++it) {
3406  auto& import_buffer = *it;
3407  if (cd->columnId == import_buffer->getColumnDesc()->columnId) {
3408  if (coldef != nullptr ||
3409  skip_physical_cols-- <= 0) { // skip non-null phy col
3410  import_buffer->add_value(
3411  cd, defaultval, isnull, import_export::CopyParams(), nrows);
3412  if (cd->columnType.is_geometry()) {
3413  std::vector<double> coords, bounds;
3414  std::vector<int> ring_sizes, poly_rings;
3415  int render_group = 0;
3416  SQLTypeInfo tinfo{cd->columnType};
3418  tinfo,
3419  coords,
3420  bounds,
3421  ring_sizes,
3422  poly_rings,
3423  false)) {
3424  throw std::runtime_error("Bad geometry data: '" + defaultval + "'");
3425  }
3426  size_t col_idx = 1 + std::distance(import_buffers.begin(), it);
3428  cd,
3429  import_buffers,
3430  col_idx,
3431  coords,
3432  bounds,
3433  ring_sizes,
3434  poly_rings,
3435  render_group,
3436  nrows);
3437  // skip following phy cols
3438  skip_physical_cols = cd->columnType.get_physical_cols();
3439  }
3440  }
3441  break;
3442  }
3443  }
3444  }
3445  }
3446 
3447  if (!loader->loadNoCheckpoint(import_buffers, nrows)) {
3448  throw std::runtime_error("loadNoCheckpoint failed!");
3449  }
3450  catalog.roll(true);
3451  loader->checkpoint();
3452  catalog.getSqliteConnector().query("END TRANSACTION");
3453  } catch (...) {
3454  catalog.roll(false);
3455  catalog.getSqliteConnector().query("ROLLBACK TRANSACTION");
3456  throw;
3457  }
3458 }
std::list< std::unique_ptr< ColumnDef > > coldefs
Definition: ParserNode.h:1310
void setColumnDescriptor(ColumnDescriptor &cd, const ColumnDef *coldef)
std::unique_ptr< std::string > table
Definition: ParserNode.h:1308
std::vector< std::unique_ptr< TypedImportBuffer > > setup_column_loaders(const TableDescriptor *td, Loader *loader)
Definition: Importer.cpp:5138
static void set_geo_physical_import_buffer(const Catalog_Namespace::Catalog &catalog, const ColumnDescriptor *cd, std::vector< std::unique_ptr< TypedImportBuffer >> &import_buffers, size_t &col_idx, std::vector< double > &coords, std::vector< double > &bounds, std::vector< int > &ring_sizes, std::vector< int > &poly_rings, int render_group, const int64_t replicate_count=0)
Definition: Importer.cpp:1421
int get_physical_cols() const
Definition: sqltypes.h:279
CHECK(cgen_state)
specifies the content in-memory of a row in the column metadata table
void check_executable(const Catalog_Namespace::SessionInfo &session, const TableDescriptor *td)
Catalog & getCatalog() const
Definition: SessionInfo.h:65
static bool getGeoColumns(const std::string &wkt, SQLTypeInfo &ti, std::vector< double > &coords, std::vector< double > &bounds, std::vector< int > &ring_sizes, std::vector< int > &poly_rings, const bool promote_poly_to_mpoly=false)
Definition: geo_types.cpp:637
static std::shared_ptr< MutexType > getMutex(const LockType lockType, const KeyType &key)
Definition: LegacyLockMgr.h:51
std::unique_ptr< ColumnDef > coldef
Definition: ParserNode.h:1309
bool is_geometry() const
Definition: sqltypes.h:427
SQLTypeInfo columnType
std::string columnName

+ Here is the call graph for this function:

const std::string* Parser::AddColumnStmt::get_table ( ) const
inline

Definition at line 1305 of file ParserNode.h.

References table.

1305 { return table.get(); }
std::unique_ptr< std::string > table
Definition: ParserNode.h:1308

Member Data Documentation

std::unique_ptr<ColumnDef> Parser::AddColumnStmt::coldef
private

Definition at line 1309 of file ParserNode.h.

Referenced by AddColumnStmt().

std::list<std::unique_ptr<ColumnDef> > Parser::AddColumnStmt::coldefs
private

Definition at line 1310 of file ParserNode.h.

Referenced by AddColumnStmt().

std::unique_ptr<std::string> Parser::AddColumnStmt::table
private

Definition at line 1308 of file ParserNode.h.

Referenced by get_table().


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