OmniSciDB  29e35f4d58
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 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 1253 of file ParserNode.h.

Constructor & Destructor Documentation

◆ AddColumnStmt() [1/2]

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

Definition at line 1255 of file ParserNode.h.

1255 : table(tab), coldef(coldef) {}
std::unique_ptr< std::string > table
Definition: ParserNode.h:1267
std::unique_ptr< ColumnDef > coldef
Definition: ParserNode.h:1268

◆ AddColumnStmt() [2/2]

Parser::AddColumnStmt::AddColumnStmt ( std::string *  tab,
std::list< ColumnDef *> *  coldefs 
)
inline

Definition at line 1256 of file ParserNode.h.

1256  : table(tab) {
1257  for (const auto coldef : *coldefs) {
1258  this->coldefs.emplace_back(coldef);
1259  }
1260  delete coldefs;
1261  }
std::list< std::unique_ptr< ColumnDef > > coldefs
Definition: ParserNode.h:1269
std::unique_ptr< std::string > table
Definition: ParserNode.h:1267
std::unique_ptr< ColumnDef > coldef
Definition: ParserNode.h:1268

Member Function Documentation

◆ check_executable()

void Parser::AddColumnStmt::check_executable ( const Catalog_Namespace::SessionInfo session)

Definition at line 3238 of file ParserNode.cpp.

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

Referenced by MapDHandler::sql_execute_impl().

3238  {
3239  auto& catalog = session.getCatalog();
3240  const TableDescriptor* td = catalog.getMetadataForTable(*table);
3241  if (nullptr == td) {
3242  throw std::runtime_error("Table " + *table + " does not exist.");
3243  } else {
3244  if (td->isView) {
3245  throw std::runtime_error("Expecting a table , found view " + *table);
3246  }
3247  };
3248 
3249  check_alter_table_privilege(session, td);
3250 
3251  if (0 == coldefs.size()) {
3252  coldefs.push_back(std::move(coldef));
3253  }
3254 
3255  for (const auto& coldef : coldefs) {
3256  auto& new_column_name = *coldef->get_column_name();
3257  if (catalog.getMetadataForColumn(td->tableId, new_column_name) != nullptr) {
3258  throw std::runtime_error("Column " + new_column_name + " already exists.");
3259  }
3260  if (reserved_keywords.find(boost::to_upper_copy<std::string>(new_column_name)) !=
3261  reserved_keywords.end()) {
3262  throw std::runtime_error("Cannot add column with reserved keyword '" +
3263  new_column_name + "'");
3264  }
3265  }
3266 }
std::list< std::unique_ptr< ColumnDef > > coldefs
Definition: ParserNode.h:1269
static std::set< std::string > reserved_keywords
std::unique_ptr< std::string > table
Definition: ParserNode.h:1267
Catalog & getCatalog() const
Definition: SessionInfo.h:90
void check_alter_table_privilege(const Catalog_Namespace::SessionInfo &session, const TableDescriptor *td)
std::unique_ptr< ColumnDef > coldef
Definition: ParserNode.h:1268
specifies the content in-memory of a row in the table metadata table
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ execute()

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

Implements Parser::DDLStmt.

Definition at line 3268 of file ParserNode.cpp.

References ColumnDescriptor::columnId, ColumnDescriptor::columnName, ColumnDescriptor::columnType, TableDescriptor::fragmenter, Catalog_Namespace::SessionInfo::get_mapdHandler(), Catalog_Namespace::SessionInfo::get_session_id(), Parser::StringLiteral::get_stringval(), Catalog_Namespace::SessionInfo::getCatalog(), Geo_namespace::GeoTypesFactory::getGeoColumns(), Fragmenter_Namespace::AbstractFragmenter::getNumRows(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_geometry(), TableDescriptor::nColumns, TableDescriptor::nShards, Catalog_Namespace::MapDHandler::prepare_columnar_loader(), Importer_NS::Importer::set_geo_physical_import_buffer(), TableDescriptor::tableId, and TableDescriptor::tableName.

3268  {
3269  auto& catalog = session.getCatalog();
3270  const TableDescriptor* td = catalog.getMetadataForTable(*table);
3271  check_executable(session);
3272 
3273  catalog.getSqliteConnector().query("BEGIN TRANSACTION");
3274  try {
3275  std::map<const std::string, const ColumnDescriptor> cds;
3276  std::map<const int, const ColumnDef*> cid_coldefs;
3277  for (const auto& coldef : coldefs) {
3278  ColumnDescriptor cd;
3279  setColumnDescriptor(cd, coldef.get());
3280  catalog.addColumn(*td, cd);
3281  cds.emplace(*coldef->get_column_name(), cd);
3282  cid_coldefs.emplace(cd.columnId, coldef.get());
3283 
3284  // expand geo column to phy columns
3285  if (cd.columnType.is_geometry()) {
3286  std::list<ColumnDescriptor> phy_geo_columns;
3287  catalog.expandGeoColumn(cd, phy_geo_columns);
3288  for (auto& cd : phy_geo_columns) {
3289  catalog.addColumn(*td, cd);
3290  cds.emplace(cd.columnName, cd);
3291  cid_coldefs.emplace(cd.columnId, nullptr);
3292  }
3293  }
3294  }
3295 
3296  std::unique_ptr<Importer_NS::Loader> loader(new Importer_NS::Loader(catalog, td));
3297  std::vector<std::unique_ptr<Importer_NS::TypedImportBuffer>> import_buffers;
3298 
3299  // a call of Catalog_Namespace::MapDHandler::prepare_columnar_loader
3301  td->tableName,
3302  td->nColumns - 1,
3303  &loader,
3304  &import_buffers);
3305  loader->setReplicating(true);
3306 
3307  // set_geo_physical_import_buffer below needs a sorted import_buffers
3308  std::sort(import_buffers.begin(),
3309  import_buffers.end(),
3310  [](decltype(import_buffers[0])& a, decltype(import_buffers[0])& b) {
3311  return a->getColumnDesc()->columnId < b->getColumnDesc()->columnId;
3312  });
3313 
3314  size_t nrows = td->fragmenter->getNumRows();
3315  // if sharded, get total nrows from all sharded tables
3316  if (td->nShards > 0) {
3317  const auto physical_tds = catalog.getPhysicalTablesDescriptors(td);
3318  nrows = 0;
3319  std::for_each(physical_tds.begin(), physical_tds.end(), [&nrows](const auto& td) {
3320  nrows += td->fragmenter->getNumRows();
3321  });
3322  }
3323  if (nrows > 0) {
3324  int skip_physical_cols = 0;
3325  for (const auto cit : cid_coldefs) {
3326  const auto cd = catalog.getMetadataForColumn(td->tableId, cit.first);
3327  const auto coldef = cit.second;
3328  const auto column_constraint = coldef ? coldef->get_column_constraint() : nullptr;
3329  std::string defaultval = "";
3330  if (column_constraint) {
3331  auto defaultlp = column_constraint->get_defaultval();
3332  auto defaultsp = dynamic_cast<const StringLiteral*>(defaultlp);
3333  defaultval = defaultsp ? *defaultsp->get_stringval()
3334  : defaultlp ? defaultlp->to_string() : "";
3335  }
3336  bool isnull = column_constraint ? (0 == defaultval.size()) : true;
3337  if (boost::to_upper_copy<std::string>(defaultval) == "NULL") {
3338  isnull = true;
3339  }
3340 
3341  // TODO: remove is_geometry below once if null is allowed for geo
3342  if (isnull) {
3343  if (cd->columnType.is_geometry() ||
3344  (column_constraint && column_constraint->get_notnull())) {
3345  throw std::runtime_error("Default value required for column " +
3346  cd->columnName + " (NULL value not supported)");
3347  }
3348  }
3349 
3350  for (auto it = import_buffers.begin(); it < import_buffers.end(); ++it) {
3351  auto& import_buffer = *it;
3352  if (cd->columnId == import_buffer->getColumnDesc()->columnId) {
3353  if (coldef != nullptr ||
3354  skip_physical_cols-- <= 0) { // skip non-null phy col
3355  import_buffer->add_value(
3356  cd, defaultval, isnull, Importer_NS::CopyParams(), nrows);
3357  // tedious non-null geo default value ...
3358  if (cd->columnType.is_geometry() && !isnull) {
3359  std::vector<double> coords, bounds;
3360  std::vector<int> ring_sizes, poly_rings;
3361  int render_group = 0;
3362  SQLTypeInfo tinfo;
3364  tinfo,
3365  coords,
3366  bounds,
3367  ring_sizes,
3368  poly_rings,
3369  false)) {
3370  throw std::runtime_error("Bad geometry data: '" + defaultval + "'");
3371  }
3372  size_t col_idx = 1 + std::distance(import_buffers.begin(), it);
3374  cd,
3375  import_buffers,
3376  col_idx,
3377  coords,
3378  bounds,
3379  ring_sizes,
3380  poly_rings,
3381  render_group,
3382  nrows);
3383  // skip following phy cols
3384  skip_physical_cols = cd->columnType.get_physical_cols();
3385  }
3386  }
3387  break;
3388  }
3389  }
3390  }
3391  }
3392 
3393  if (!loader->loadNoCheckpoint(import_buffers, nrows)) {
3394  throw std::runtime_error("loadNoCheckpoint failed!");
3395  }
3396  loader->checkpoint();
3397  } catch (...) {
3398  catalog.roll(false);
3399  catalog.getSqliteConnector().query("ROLLBACK TRANSACTION");
3400  throw;
3401  }
3402  catalog.getSqliteConnector().query("END TRANSACTION");
3403  catalog.roll(true);
3404 }
std::list< std::unique_ptr< ColumnDef > > coldefs
Definition: ParserNode.h:1269
void setColumnDescriptor(ColumnDescriptor &cd, const ColumnDef *coldef)
std::string tableName
std::unique_ptr< std::string > table
Definition: ParserNode.h:1267
virtual void prepare_columnar_loader(const std::string &session, const std::string &table_name, size_t num_cols, std::unique_ptr< Importer_NS::Loader > *loader, std::vector< std::unique_ptr< Importer_NS::TypedImportBuffer >> *import_buffers)
std::string get_session_id() const
Definition: SessionInfo.h:98
Catalog & getCatalog() const
Definition: SessionInfo.h:90
void check_executable(const Catalog_Namespace::SessionInfo &session)
specifies the content in-memory of a row in the column metadata table
MapDHandler * get_mapdHandler() const
Definition: SessionInfo.h:89
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:1457
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:459
std::unique_ptr< ColumnDef > coldef
Definition: ParserNode.h:1268
int get_physical_cols() const
Definition: sqltypes.h:347
bool is_geometry() const
Definition: sqltypes.h:489
SQLTypeInfo columnType
specifies the content in-memory of a row in the table metadata table
Fragmenter_Namespace::AbstractFragmenter * fragmenter
std::string columnName
+ Here is the call graph for this function:

◆ get_table()

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

Definition at line 1264 of file ParserNode.h.

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

Member Data Documentation

◆ coldef

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

Definition at line 1268 of file ParserNode.h.

◆ coldefs

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

Definition at line 1269 of file ParserNode.h.

◆ table

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

Definition at line 1267 of file ParserNode.h.


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