OmniSciDB  72c90bc290
 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 5352 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().

5353  {
5354  auto& catalog = session.getCatalog();
5355  if (!td) {
5356  throw std::runtime_error("Table " + *table_ + " does not exist.");
5357  } else {
5358  if (td->isView) {
5359  throw std::runtime_error("Adding columns to a view is not supported.");
5360  }
5362  if (table_is_temporary(td)) {
5363  throw std::runtime_error(
5364  "Adding columns to temporary tables is not yet supported.");
5365  }
5366  }
5367 
5368  check_alter_table_privilege(session, td);
5369 
5370  if (0 == coldefs_.size()) {
5371  coldefs_.push_back(std::move(coldef_));
5372  }
5373 
5374  for (const auto& coldef : coldefs_) {
5375  auto& new_column_name = *coldef->get_column_name();
5376  if (catalog.getMetadataForColumn(td->tableId, new_column_name) != nullptr) {
5377  throw std::runtime_error("Column " + new_column_name + " already exists.");
5378  }
5379  }
5380 }
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 5382 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().

5383  {
5384  if (read_only_mode) {
5385  throw std::runtime_error("ADD COLUMN invalid in read only mode.");
5386  }
5387  // TODO: Review add and drop column implementation
5388  const auto execute_write_lock = legacylockmgr::getExecuteWriteLock();
5389  auto& catalog = session.getCatalog();
5390  const auto td_with_lock =
5392  catalog, *table_, true);
5393  const auto td = td_with_lock();
5394 
5395  check_executable(session, td);
5396 
5397  CHECK(td->fragmenter);
5398  if (std::dynamic_pointer_cast<Fragmenter_Namespace::SortedOrderFragmenter>(
5399  td->fragmenter)) {
5400  throw std::runtime_error(
5401  "Adding columns to a table is not supported when using the \"sort_column\" "
5402  "option.");
5403  }
5404 
5405  // invalidate cached item
5406  Executor::clearExternalCaches(true, td, catalog.getDatabaseId());
5407 
5408  // Do not take a data write lock, as the fragmenter may call `deleteFragments`
5409  // during a cap operation. Note that the schema write lock will prevent concurrent
5410  // inserts along with all other queries.
5411 
5412  catalog.getSqliteConnector().query("BEGIN TRANSACTION");
5413  try {
5414  std::map<const std::string, const ColumnDescriptor> cds;
5415  std::map<const int, const ColumnDef*> cid_coldefs;
5416  for (const auto& coldef : coldefs_) {
5417  ColumnDescriptor cd;
5418  setColumnDescriptor(cd, coldef.get());
5419  catalog.addColumn(*td, cd);
5420  cds.emplace(*coldef->get_column_name(), cd);
5421  cid_coldefs.emplace(cd.columnId, coldef.get());
5422 
5423  // expand geo column to phy columns
5424  if (cd.columnType.is_geometry()) {
5425  std::list<ColumnDescriptor> phy_geo_columns;
5426  catalog.expandGeoColumn(cd, phy_geo_columns);
5427  for (auto& cd : phy_geo_columns) {
5428  catalog.addColumn(*td, cd);
5429  cds.emplace(cd.columnName, cd);
5430  cid_coldefs.emplace(cd.columnId, nullptr);
5431  }
5432  }
5433  }
5434 
5435  std::unique_ptr<import_export::Loader> loader(new import_export::Loader(catalog, td));
5436  std::vector<std::unique_ptr<import_export::TypedImportBuffer>> import_buffers;
5437  for (const auto& cd : cds) {
5438  import_buffers.emplace_back(std::make_unique<import_export::TypedImportBuffer>(
5439  &cd.second, loader->getStringDict(&cd.second)));
5440  }
5441  loader->setAddingColumns(true);
5442 
5443  // set_geo_physical_import_buffer below needs a sorted import_buffers
5444  std::sort(import_buffers.begin(),
5445  import_buffers.end(),
5446  [](decltype(import_buffers[0])& a, decltype(import_buffers[0])& b) {
5447  return a->getColumnDesc()->columnId < b->getColumnDesc()->columnId;
5448  });
5449 
5450  size_t nrows = td->fragmenter->getNumRows();
5451  // if sharded, get total nrows from all sharded tables
5452  if (td->nShards > 0) {
5453  const auto physical_tds = catalog.getPhysicalTablesDescriptors(td);
5454  nrows = 0;
5455  std::for_each(physical_tds.begin(), physical_tds.end(), [&nrows](const auto& td) {
5456  nrows += td->fragmenter->getNumRows();
5457  });
5458  }
5459  if (nrows > 0) {
5460  int skip_physical_cols = 0;
5461  for (const auto cit : cid_coldefs) {
5462  const auto cd = catalog.getMetadataForColumn(td->tableId, cit.first);
5463  const auto coldef = cit.second;
5464  const bool is_null = !cd->default_value.has_value();
5465 
5466  if (cd->columnType.get_notnull() && is_null) {
5467  throw std::runtime_error("Default value required for column " + cd->columnName +
5468  " because of NOT NULL constraint");
5469  }
5470 
5471  for (auto it = import_buffers.begin(); it < import_buffers.end(); ++it) {
5472  auto& import_buffer = *it;
5473  if (cd->columnId == import_buffer->getColumnDesc()->columnId) {
5474  if (coldef != nullptr ||
5475  skip_physical_cols-- <= 0) { // skip non-null phy col
5476  import_buffer->add_value(cd,
5477  cd->default_value.value_or("NULL"),
5478  is_null,
5480  if (cd->columnType.is_geometry()) {
5481  std::vector<double> coords, bounds;
5482  std::vector<int> ring_sizes, poly_rings;
5483  SQLTypeInfo tinfo{cd->columnType};
5484  const bool validate_with_geos_if_available = false;
5486  cd->default_value.value_or("NULL"),
5487  tinfo,
5488  coords,
5489  bounds,
5490  ring_sizes,
5491  poly_rings,
5492  validate_with_geos_if_available)) {
5493  throw std::runtime_error("Bad geometry data: '" +
5494  cd->default_value.value_or("NULL") + "'");
5495  }
5496  size_t col_idx = 1 + std::distance(import_buffers.begin(), it);
5498  cd,
5499  import_buffers,
5500  col_idx,
5501  coords,
5502  bounds,
5503  ring_sizes,
5504  poly_rings);
5505  // skip following phy cols
5506  skip_physical_cols = cd->columnType.get_physical_cols();
5507  }
5508  }
5509  break;
5510  }
5511  }
5512  }
5513  }
5514 
5515  if (!loader->loadNoCheckpoint(import_buffers, nrows, &session)) {
5516  throw std::runtime_error("loadNoCheckpoint failed!");
5517  }
5518  catalog.rollLegacy(true);
5519  catalog.resetTableEpochFloor(td->tableId);
5520  loader->checkpoint();
5521  catalog.getSqliteConnector().query("END TRANSACTION");
5522  } catch (...) {
5523  catalog.rollLegacy(false);
5524  catalog.getSqliteConnector().query("ROLLBACK TRANSACTION");
5525  throw;
5526  }
5527 }
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:430
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:595
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: