OmniSciDB  eb3a3d0a03
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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 1342 of file ParserNode.h.

Constructor & Destructor Documentation

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

Definition at line 1344 of file ParserNode.h.

1344 : table_(tab), coldef_(coldef) {}
std::unique_ptr< std::string > table_
Definition: ParserNode.h:1357
std::unique_ptr< ColumnDef > coldef_
Definition: ParserNode.h:1358
Parser::AddColumnStmt::AddColumnStmt ( std::string *  tab,
std::list< ColumnDef * > *  coldefs 
)
inline

Definition at line 1345 of file ParserNode.h.

References coldefs_.

1345  : table_(tab) {
1346  for (const auto coldef : *coldefs) {
1347  this->coldefs_.emplace_back(coldef);
1348  }
1349  delete coldefs;
1350  }
std::unique_ptr< std::string > table_
Definition: ParserNode.h:1357
std::list< std::unique_ptr< ColumnDef > > coldefs_
Definition: ParserNode.h:1359

Member Function Documentation

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

Definition at line 4261 of file ParserNode.cpp.

References Parser::check_alter_table_privilege(), coldef_, coldefs_, Catalog_Namespace::SessionInfo::getCatalog(), TableDescriptor::isView, ddl_utils::TABLE, table_, table_is_temporary(), TableDescriptor::tableId, and ddl_utils::validate_table_type().

Referenced by execute().

4262  {
4263  auto& catalog = session.getCatalog();
4264  if (!td) {
4265  throw std::runtime_error("Table " + *table_ + " does not exist.");
4266  } else {
4267  if (td->isView) {
4268  throw std::runtime_error("Adding columns to a view is not supported.");
4269  }
4271  if (table_is_temporary(td)) {
4272  throw std::runtime_error(
4273  "Adding columns to temporary tables is not yet supported.");
4274  }
4275  };
4276 
4277  check_alter_table_privilege(session, td);
4278 
4279  if (0 == coldefs_.size()) {
4280  coldefs_.push_back(std::move(coldef_));
4281  }
4282 
4283  for (const auto& coldef : coldefs_) {
4284  auto& new_column_name = *coldef->get_column_name();
4285  if (catalog.getMetadataForColumn(td->tableId, new_column_name) != nullptr) {
4286  throw std::runtime_error("Column " + new_column_name + " already exists.");
4287  }
4288  }
4289 }
std::unique_ptr< std::string > table_
Definition: ParserNode.h:1357
std::list< std::unique_ptr< ColumnDef > > coldefs_
Definition: ParserNode.h:1359
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:67
void validate_table_type(const TableDescriptor *td, const TableType expected_table_type, const std::string &command)
Definition: DdlUtils.cpp:650
std::unique_ptr< ColumnDef > coldef_
Definition: ParserNode.h:1358

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Implements Parser::DDLStmt.

Definition at line 4291 of file ParserNode.cpp.

References anonymous_namespace{Utm.h}::a, CHECK, check_executable(), coldefs_, ColumnDescriptor::columnId, ColumnDescriptor::columnName, ColumnDescriptor::columnType, legacylockmgr::ExecutorOuterLock, TableDescriptor::fragmenter, Catalog_Namespace::SessionInfo::getCatalog(), Geospatial::GeoTypesFactory::getGeoColumns(), legacylockmgr::LockMgr< MutexType, KeyType >::getMutex(), SQLTypeInfo::is_geometry(), is_null(), TableDescriptor::nShards, import_export::Importer::set_geo_physical_import_buffer(), Parser::DDLStmt::setColumnDescriptor(), gpu_enabled::sort(), table_, and TableDescriptor::tableId.

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

4291  {
4292  auto& catalog = session.getCatalog();
4293 
4294  // TODO(adb): the catalog should be handling this locking.
4295  const auto execute_write_lock = mapd_unique_lock<mapd_shared_mutex>(
4298 
4299  const auto td_with_lock =
4301  catalog, *table_, true);
4302  const auto td = td_with_lock();
4303 
4304  check_executable(session, td);
4305 
4306  CHECK(td->fragmenter);
4307  if (std::dynamic_pointer_cast<Fragmenter_Namespace::SortedOrderFragmenter>(
4308  td->fragmenter)) {
4309  throw std::runtime_error(
4310  "Adding columns to a table is not supported when using the \"sort_column\" "
4311  "option.");
4312  }
4313 
4314  // Do not take a data write lock, as the fragmenter may call `deleteFragments`
4315  // during a cap operation. Note that the schema write lock will prevent concurrent
4316  // inserts along with all other queries.
4317 
4318  catalog.getSqliteConnector().query("BEGIN TRANSACTION");
4319  try {
4320  std::map<const std::string, const ColumnDescriptor> cds;
4321  std::map<const int, const ColumnDef*> cid_coldefs;
4322  for (const auto& coldef : coldefs_) {
4323  ColumnDescriptor cd;
4324  setColumnDescriptor(cd, coldef.get());
4325  catalog.addColumn(*td, cd);
4326  cds.emplace(*coldef->get_column_name(), cd);
4327  cid_coldefs.emplace(cd.columnId, coldef.get());
4328 
4329  // expand geo column to phy columns
4330  if (cd.columnType.is_geometry()) {
4331  std::list<ColumnDescriptor> phy_geo_columns;
4332  catalog.expandGeoColumn(cd, phy_geo_columns);
4333  for (auto& cd : phy_geo_columns) {
4334  catalog.addColumn(*td, cd);
4335  cds.emplace(cd.columnName, cd);
4336  cid_coldefs.emplace(cd.columnId, nullptr);
4337  }
4338  }
4339  }
4340 
4341  std::unique_ptr<import_export::Loader> loader(new import_export::Loader(catalog, td));
4342  std::vector<std::unique_ptr<import_export::TypedImportBuffer>> import_buffers;
4343  for (const auto& cd : cds) {
4344  import_buffers.emplace_back(std::make_unique<import_export::TypedImportBuffer>(
4345  &cd.second, loader->getStringDict(&cd.second)));
4346  }
4347  loader->setAddingColumns(true);
4348 
4349  // set_geo_physical_import_buffer below needs a sorted import_buffers
4350  std::sort(import_buffers.begin(),
4351  import_buffers.end(),
4352  [](decltype(import_buffers[0])& a, decltype(import_buffers[0])& b) {
4353  return a->getColumnDesc()->columnId < b->getColumnDesc()->columnId;
4354  });
4355 
4356  size_t nrows = td->fragmenter->getNumRows();
4357  // if sharded, get total nrows from all sharded tables
4358  if (td->nShards > 0) {
4359  const auto physical_tds = catalog.getPhysicalTablesDescriptors(td);
4360  nrows = 0;
4361  std::for_each(physical_tds.begin(), physical_tds.end(), [&nrows](const auto& td) {
4362  nrows += td->fragmenter->getNumRows();
4363  });
4364  }
4365  if (nrows > 0) {
4366  int skip_physical_cols = 0;
4367  for (const auto cit : cid_coldefs) {
4368  const auto cd = catalog.getMetadataForColumn(td->tableId, cit.first);
4369  const auto coldef = cit.second;
4370  const bool is_null = !cd->default_value.has_value();
4371 
4372  if (cd->columnType.get_notnull() && is_null) {
4373  throw std::runtime_error("Default value required for column " + cd->columnName +
4374  " because of NOT NULL constraint");
4375  }
4376 
4377  for (auto it = import_buffers.begin(); it < import_buffers.end(); ++it) {
4378  auto& import_buffer = *it;
4379  if (cd->columnId == import_buffer->getColumnDesc()->columnId) {
4380  if (coldef != nullptr ||
4381  skip_physical_cols-- <= 0) { // skip non-null phy col
4382  import_buffer->add_value(cd,
4383  cd->default_value.value_or("NULL"),
4384  is_null,
4386  if (cd->columnType.is_geometry()) {
4387  std::vector<double> coords, bounds;
4388  std::vector<int> ring_sizes, poly_rings;
4389  int render_group = 0;
4390  SQLTypeInfo tinfo{cd->columnType};
4392  cd->default_value.value_or("NULL"),
4393  tinfo,
4394  coords,
4395  bounds,
4396  ring_sizes,
4397  poly_rings,
4398  false)) {
4399  throw std::runtime_error("Bad geometry data: '" +
4400  cd->default_value.value_or("NULL") + "'");
4401  }
4402  size_t col_idx = 1 + std::distance(import_buffers.begin(), it);
4404  cd,
4405  import_buffers,
4406  col_idx,
4407  coords,
4408  bounds,
4409  ring_sizes,
4410  poly_rings,
4411  render_group);
4412  // skip following phy cols
4413  skip_physical_cols = cd->columnType.get_physical_cols();
4414  }
4415  }
4416  break;
4417  }
4418  }
4419  }
4420  }
4421 
4422  if (!loader->loadNoCheckpoint(import_buffers, nrows, &session)) {
4423  throw std::runtime_error("loadNoCheckpoint failed!");
4424  }
4425  catalog.roll(true);
4426  loader->checkpoint();
4427  catalog.getSqliteConnector().query("END TRANSACTION");
4428  } catch (...) {
4429  catalog.roll(false);
4430  catalog.getSqliteConnector().query("ROLLBACK TRANSACTION");
4431  throw;
4432  }
4433 }
void setColumnDescriptor(ColumnDescriptor &cd, const ColumnDef *coldef)
DEVICE void sort(ARGS &&...args)
Definition: gpu_enabled.h:105
constexpr double a
Definition: Utm.h:32
std::unique_ptr< std::string > table_
Definition: ParserNode.h:1357
int get_physical_cols() const
Definition: sqltypes.h:350
CONSTEXPR DEVICE bool is_null(const T &value)
std::list< std::unique_ptr< ColumnDef > > coldefs_
Definition: ParserNode.h:1359
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)
Definition: Importer.cpp:1639
specifies the content in-memory of a row in the column metadata table
void check_executable(const Catalog_Namespace::SessionInfo &session, const TableDescriptor *td)
static bool getGeoColumns(const std::string &wkt_or_wkb_hex, 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: Types.cpp:937
std::optional< std::string > default_value
Catalog & getCatalog() const
Definition: SessionInfo.h:67
static std::shared_ptr< MutexType > getMutex(const LockType lockType, const KeyType &key)
Definition: LegacyLockMgr.h:51
#define CHECK(condition)
Definition: Logger.h:209
bool is_geometry() const
Definition: sqltypes.h:516
SQLTypeInfo columnType
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:336
std::string columnName

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 1354 of file ParserNode.h.

References table_.

1354 { return table_.get(); }
std::unique_ptr< std::string > table_
Definition: ParserNode.h:1357

Member Data Documentation

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

Definition at line 1358 of file ParserNode.h.

Referenced by check_executable().

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

Definition at line 1359 of file ParserNode.h.

Referenced by AddColumnStmt(), check_executable(), and execute().

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

Definition at line 1357 of file ParserNode.h.

Referenced by check_executable(), execute(), and get_table().


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