OmniSciDB  a5dc49c757
 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, bool read_only_mode) 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 1358 of file ParserNode.h.

Constructor & Destructor Documentation

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

Definition at line 1360 of file ParserNode.h.

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

Definition at line 1361 of file ParserNode.h.

References coldefs_.

1361  : table_(tab) {
1362  for (const auto coldef : *coldefs) {
1363  this->coldefs_.emplace_back(coldef);
1364  }
1365  delete coldefs;
1366  }
std::unique_ptr< std::string > table_
Definition: ParserNode.h:1374
std::list< std::unique_ptr< ColumnDef > > coldefs_
Definition: ParserNode.h:1376

Member Function Documentation

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

Definition at line 5373 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().

5374  {
5375  auto& catalog = session.getCatalog();
5376  if (!td) {
5377  throw std::runtime_error("Table " + *table_ + " does not exist.");
5378  } else {
5379  if (td->isView) {
5380  throw std::runtime_error("Adding columns to a view is not supported.");
5381  }
5383  if (table_is_temporary(td)) {
5384  throw std::runtime_error(
5385  "Adding columns to temporary tables is not yet supported.");
5386  }
5387  }
5388 
5389  check_alter_table_privilege(session, td);
5390 
5391  if (0 == coldefs_.size()) {
5392  coldefs_.push_back(std::move(coldef_));
5393  }
5394 
5395  for (const auto& coldef : coldefs_) {
5396  auto& new_column_name = *coldef->get_column_name();
5397  if (catalog.getMetadataForColumn(td->tableId, new_column_name) != nullptr) {
5398  throw std::runtime_error("Column " + new_column_name + " already exists.");
5399  }
5400  }
5401 }
std::unique_ptr< std::string > table_
Definition: ParserNode.h:1374
std::list< std::unique_ptr< ColumnDef > > coldefs_
Definition: ParserNode.h:1376
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:75
void validate_table_type(const TableDescriptor *td, const TableType expected_table_type, const std::string &command)
Definition: DdlUtils.cpp:745
std::unique_ptr< ColumnDef > coldef_
Definition: ParserNode.h:1375

+ 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,
bool  read_only_mode 
)
overridevirtual

Implements Parser::DDLStmt.

Definition at line 5403 of file ParserNode.cpp.

References anonymous_namespace{Utm.h}::a, CHECK, check_executable(), Executor::clearExternalCaches(), coldefs_, ColumnDescriptor::columnId, ColumnDescriptor::columnName, ColumnDescriptor::columnType, TableDescriptor::fragmenter, Catalog_Namespace::SessionInfo::getCatalog(), legacylockmgr::getExecuteWriteLock(), Geospatial::GeoTypesFactory::getGeoColumns(), 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 heavydb.cursor.Cursor::executemany().

5404  {
5405  if (read_only_mode) {
5406  throw std::runtime_error("ADD COLUMN invalid in read only mode.");
5407  }
5408  // TODO: Review add and drop column implementation
5409  const auto execute_write_lock = legacylockmgr::getExecuteWriteLock();
5410  auto& catalog = session.getCatalog();
5411  const auto td_with_lock =
5413  catalog, *table_, true);
5414  const auto td = td_with_lock();
5415 
5416  check_executable(session, td);
5417 
5418  CHECK(td->fragmenter);
5419  if (std::dynamic_pointer_cast<Fragmenter_Namespace::SortedOrderFragmenter>(
5420  td->fragmenter)) {
5421  throw std::runtime_error(
5422  "Adding columns to a table is not supported when using the \"sort_column\" "
5423  "option.");
5424  }
5425 
5426  // invalidate cached item
5427  Executor::clearExternalCaches(true, td, catalog.getDatabaseId());
5428 
5429  // Do not take a data write lock, as the fragmenter may call `deleteFragments`
5430  // during a cap operation. Note that the schema write lock will prevent concurrent
5431  // inserts along with all other queries.
5432 
5433  catalog.getSqliteConnector().query("BEGIN TRANSACTION");
5434  try {
5435  std::map<const std::string, const ColumnDescriptor> cds;
5436  std::map<const int, const ColumnDef*> cid_coldefs;
5437  for (const auto& coldef : coldefs_) {
5438  ColumnDescriptor cd;
5439  setColumnDescriptor(cd, coldef.get());
5440  catalog.addColumn(*td, cd);
5441  cds.emplace(*coldef->get_column_name(), cd);
5442  cid_coldefs.emplace(cd.columnId, coldef.get());
5443 
5444  // expand geo column to phy columns
5445  if (cd.columnType.is_geometry()) {
5446  std::list<ColumnDescriptor> phy_geo_columns;
5447  catalog.expandGeoColumn(cd, phy_geo_columns);
5448  for (auto& cd : phy_geo_columns) {
5449  catalog.addColumn(*td, cd);
5450  cds.emplace(cd.columnName, cd);
5451  cid_coldefs.emplace(cd.columnId, nullptr);
5452  }
5453  }
5454  }
5455 
5456  std::unique_ptr<import_export::Loader> loader(new import_export::Loader(catalog, td));
5457  std::vector<std::unique_ptr<import_export::TypedImportBuffer>> import_buffers;
5458  for (const auto& cd : cds) {
5459  import_buffers.emplace_back(std::make_unique<import_export::TypedImportBuffer>(
5460  &cd.second, loader->getStringDict(&cd.second)));
5461  }
5462  loader->setAddingColumns(true);
5463 
5464  // set_geo_physical_import_buffer below needs a sorted import_buffers
5465  std::sort(import_buffers.begin(),
5466  import_buffers.end(),
5467  [](decltype(import_buffers[0])& a, decltype(import_buffers[0])& b) {
5468  return a->getColumnDesc()->columnId < b->getColumnDesc()->columnId;
5469  });
5470 
5471  size_t nrows = td->fragmenter->getNumRows();
5472  // if sharded, get total nrows from all sharded tables
5473  if (td->nShards > 0) {
5474  const auto physical_tds = catalog.getPhysicalTablesDescriptors(td);
5475  nrows = 0;
5476  std::for_each(physical_tds.begin(), physical_tds.end(), [&nrows](const auto& td) {
5477  nrows += td->fragmenter->getNumRows();
5478  });
5479  }
5480  if (nrows > 0) {
5481  int skip_physical_cols = 0;
5482  for (const auto cit : cid_coldefs) {
5483  const auto cd = catalog.getMetadataForColumn(td->tableId, cit.first);
5484  const auto coldef = cit.second;
5485  const bool is_null = !cd->default_value.has_value();
5486 
5487  if (cd->columnType.get_notnull() && is_null) {
5488  throw std::runtime_error("Default value required for column " + cd->columnName +
5489  " because of NOT NULL constraint");
5490  }
5491 
5492  for (auto it = import_buffers.begin(); it < import_buffers.end(); ++it) {
5493  auto& import_buffer = *it;
5494  if (cd->columnId == import_buffer->getColumnDesc()->columnId) {
5495  if (coldef != nullptr ||
5496  skip_physical_cols-- <= 0) { // skip non-null phy col
5497  import_buffer->add_value(cd,
5498  cd->default_value.value_or("NULL"),
5499  is_null,
5501  if (cd->columnType.is_geometry()) {
5502  std::vector<double> coords, bounds;
5503  std::vector<int> ring_sizes, poly_rings;
5504  SQLTypeInfo tinfo{cd->columnType};
5505  const bool validate_with_geos_if_available = false;
5507  cd->default_value.value_or("NULL"),
5508  tinfo,
5509  coords,
5510  bounds,
5511  ring_sizes,
5512  poly_rings,
5513  validate_with_geos_if_available)) {
5514  throw std::runtime_error("Bad geometry data: '" +
5515  cd->default_value.value_or("NULL") + "'");
5516  }
5517  size_t col_idx = 1 + std::distance(import_buffers.begin(), it);
5519  cd,
5520  import_buffers,
5521  col_idx,
5522  coords,
5523  bounds,
5524  ring_sizes,
5525  poly_rings);
5526  // skip following phy cols
5527  skip_physical_cols = cd->columnType.get_physical_cols();
5528  }
5529  }
5530  break;
5531  }
5532  }
5533  }
5534  }
5535 
5536  if (!loader->loadNoCheckpoint(import_buffers, nrows, &session)) {
5537  throw std::runtime_error("loadNoCheckpoint failed!");
5538  }
5539  catalog.rollLegacy(true);
5540  catalog.resetTableEpochFloor(td->tableId);
5541  loader->checkpoint();
5542  catalog.getSqliteConnector().query("END TRANSACTION");
5543  } catch (...) {
5544  catalog.rollLegacy(false);
5545  catalog.getSqliteConnector().query("ROLLBACK TRANSACTION");
5546  throw;
5547  }
5548 }
void setColumnDescriptor(ColumnDescriptor &cd, const ColumnDef *coldef)
DEVICE void sort(ARGS &&...args)
Definition: gpu_enabled.h:105
constexpr double a
Definition: Utm.h:32
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, const bool force_null=false)
Definition: Importer.cpp:1636
std::unique_ptr< std::string > table_
Definition: ParserNode.h:1374
int get_physical_cols() const
Definition: sqltypes.h:432
CONSTEXPR DEVICE bool is_null(const T &value)
std::list< std::unique_ptr< ColumnDef > > coldefs_
Definition: ParserNode.h:1376
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 validate_with_geos_if_available)
Definition: Types.cpp:1121
specifies the content in-memory of a row in the column metadata table
void check_executable(const Catalog_Namespace::SessionInfo &session, const TableDescriptor *td)
std::optional< std::string > default_value
Catalog & getCatalog() const
Definition: SessionInfo.h:75
#define CHECK(condition)
Definition: Logger.h:291
bool is_geometry() const
Definition: sqltypes.h:597
static void clearExternalCaches(bool for_update, const TableDescriptor *td, const int current_db_id)
Definition: Execute.h:438
auto getExecuteWriteLock()
SQLTypeInfo columnType
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:398
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 1371 of file ParserNode.h.

References table_.

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

Member Data Documentation

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

Definition at line 1375 of file ParserNode.h.

Referenced by check_executable().

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

Definition at line 1376 of file ParserNode.h.

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

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

Definition at line 1374 of file ParserNode.h.

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


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