OmniSciDB  1dac507f6e
 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 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

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
Parser::AddColumnStmt::AddColumnStmt ( std::string *  tab,
std::list< ColumnDef * > *  coldefs 
)
inline

Definition at line 1256 of file ParserNode.h.

References coldef, and coldefs.

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

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

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

3239  {
3240  auto& catalog = session.getCatalog();
3241  const TableDescriptor* td = catalog.getMetadataForTable(*table);
3242  if (nullptr == td) {
3243  throw std::runtime_error("Table " + *table + " does not exist.");
3244  } else {
3245  if (td->isView) {
3246  throw std::runtime_error("Expecting a table , found view " + *table);
3247  }
3248  };
3249 
3250  check_alter_table_privilege(session, td);
3251 
3252  if (0 == coldefs.size()) {
3253  coldefs.push_back(std::move(coldef));
3254  }
3255 
3256  for (const auto& coldef : coldefs) {
3257  auto& new_column_name = *coldef->get_column_name();
3258  if (catalog.getMetadataForColumn(td->tableId, new_column_name) != nullptr) {
3259  throw std::runtime_error("Column " + new_column_name + " already exists.");
3260  }
3261  if (reserved_keywords.find(boost::to_upper_copy<std::string>(new_column_name)) !=
3262  reserved_keywords.end()) {
3263  throw std::runtime_error("Cannot add column with reserved keyword '" +
3264  new_column_name + "'");
3265  }
3266  }
3267 }
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
void check_alter_table_privilege(const Catalog_Namespace::SessionInfo &session, const TableDescriptor *td)
Catalog & getCatalog() const
Definition: SessionInfo.h:90
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:

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

Implements Parser::DDLStmt.

Definition at line 3269 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.

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

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

Definition at line 1264 of file ParserNode.h.

References table.

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

Member Data Documentation

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

Definition at line 1268 of file ParserNode.h.

Referenced by AddColumnStmt().

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

Definition at line 1269 of file ParserNode.h.

Referenced by AddColumnStmt().

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

Definition at line 1267 of file ParserNode.h.

Referenced by get_table().


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