OmniSciDB  c07336695a
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 1247 of file ParserNode.h.

Constructor & Destructor Documentation

◆ AddColumnStmt() [1/2]

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

Definition at line 1249 of file ParserNode.h.

1249 : table(tab), coldef(coldef) {}
std::unique_ptr< std::string > table
Definition: ParserNode.h:1261
std::unique_ptr< ColumnDef > coldef
Definition: ParserNode.h:1262

◆ AddColumnStmt() [2/2]

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

Definition at line 1250 of file ParserNode.h.

References session.

1250  : table(tab) {
1251  for (const auto coldef : *coldefs) {
1252  this->coldefs.emplace_back(coldef);
1253  }
1254  delete coldefs;
1255  }
std::list< std::unique_ptr< ColumnDef > > coldefs
Definition: ParserNode.h:1263
std::unique_ptr< std::string > table
Definition: ParserNode.h:1261
std::unique_ptr< ColumnDef > coldef
Definition: ParserNode.h:1262

Member Function Documentation

◆ check_executable()

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

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

3136  {
3137  auto& catalog = session.getCatalog();
3138  const TableDescriptor* td = catalog.getMetadataForTable(*table);
3139  if (nullptr == td) {
3140  throw std::runtime_error("Table " + *table + " does not exist.");
3141  } else {
3142  if (td->isView) {
3143  throw std::runtime_error("Expecting a table , found view " + *table);
3144  }
3145  };
3146 
3147  check_alter_table_privilege(session, td);
3148 
3149  if (0 == coldefs.size()) {
3150  coldefs.push_back(std::move(coldef));
3151  }
3152 
3153  for (const auto& coldef : coldefs) {
3154  auto& new_column_name = *coldef->get_column_name();
3155  if (catalog.getMetadataForColumn(td->tableId, new_column_name) != nullptr) {
3156  throw std::runtime_error("Column " + new_column_name + " already exists.");
3157  }
3158  if (reserved_keywords.find(boost::to_upper_copy<std::string>(new_column_name)) !=
3159  reserved_keywords.end()) {
3160  throw std::runtime_error("Cannot add column with reserved keyword '" +
3161  new_column_name + "'");
3162  }
3163  }
3164 }
std::list< std::unique_ptr< ColumnDef > > coldefs
Definition: ParserNode.h:1263
static std::set< std::string > reserved_keywords
std::unique_ptr< std::string > table
Definition: ParserNode.h:1261
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:1262
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 3166 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.

3166  {
3167  auto& catalog = session.getCatalog();
3168  const TableDescriptor* td = catalog.getMetadataForTable(*table);
3169  check_executable(session);
3170 
3171  catalog.getSqliteConnector().query("BEGIN TRANSACTION");
3172  try {
3173  std::map<const std::string, const ColumnDescriptor> cds;
3174  std::map<const int, const ColumnDef*> cid_coldefs;
3175  for (const auto& coldef : coldefs) {
3176  ColumnDescriptor cd;
3177  setColumnDescriptor(cd, coldef.get());
3178  catalog.addColumn(*td, cd);
3179  cds.emplace(*coldef->get_column_name(), cd);
3180  cid_coldefs.emplace(cd.columnId, coldef.get());
3181 
3182  // expand geo column to phy columns
3183  if (cd.columnType.is_geometry()) {
3184  std::list<ColumnDescriptor> phy_geo_columns;
3185  catalog.expandGeoColumn(cd, phy_geo_columns);
3186  for (auto& cd : phy_geo_columns) {
3187  catalog.addColumn(*td, cd);
3188  cds.emplace(cd.columnName, cd);
3189  cid_coldefs.emplace(cd.columnId, nullptr);
3190  }
3191  }
3192  }
3193 
3194  std::unique_ptr<Importer_NS::Loader> loader(new Importer_NS::Loader(catalog, td));
3195  std::vector<std::unique_ptr<Importer_NS::TypedImportBuffer>> import_buffers;
3196 
3197  // a call of Catalog_Namespace::MapDHandler::prepare_columnar_loader
3199  td->tableName,
3200  td->nColumns - 1,
3201  &loader,
3202  &import_buffers);
3203  loader->setReplicating(true);
3204 
3205  // set_geo_physical_import_buffer below needs a sorted import_buffers
3206  std::sort(import_buffers.begin(),
3207  import_buffers.end(),
3208  [](decltype(import_buffers[0])& a, decltype(import_buffers[0])& b) {
3209  return a->getColumnDesc()->columnId < b->getColumnDesc()->columnId;
3210  });
3211 
3212  size_t nrows = td->fragmenter->getNumRows();
3213  // if sharded, get total nrows from all sharded tables
3214  if (td->nShards > 0) {
3215  const auto physical_tds = catalog.getPhysicalTablesDescriptors(td);
3216  nrows = 0;
3217  std::for_each(physical_tds.begin(), physical_tds.end(), [&nrows](const auto& td) {
3218  nrows += td->fragmenter->getNumRows();
3219  });
3220  }
3221  if (nrows > 0) {
3222  int skip_physical_cols = 0;
3223  for (const auto cit : cid_coldefs) {
3224  const auto cd = catalog.getMetadataForColumn(td->tableId, cit.first);
3225  const auto coldef = cit.second;
3226  const auto column_constraint = coldef ? coldef->get_column_constraint() : nullptr;
3227  std::string defaultval = "";
3228  if (column_constraint) {
3229  auto defaultlp = column_constraint->get_defaultval();
3230  auto defaultsp = dynamic_cast<const StringLiteral*>(defaultlp);
3231  defaultval = defaultsp ? *defaultsp->get_stringval()
3232  : defaultlp ? defaultlp->to_string() : "";
3233  }
3234  bool isnull = column_constraint ? (0 == defaultval.size()) : true;
3235  if (boost::to_upper_copy<std::string>(defaultval) == "NULL") {
3236  isnull = true;
3237  }
3238 
3239  // TODO: remove is_geometry below once if null is allowed for geo
3240  if (isnull) {
3241  if (cd->columnType.is_geometry() ||
3242  (column_constraint && column_constraint->get_notnull())) {
3243  throw std::runtime_error("Default value required for column " +
3244  cd->columnName + " (NULL value not supported)");
3245  }
3246  }
3247 
3248  for (auto it = import_buffers.begin(); it < import_buffers.end(); ++it) {
3249  auto& import_buffer = *it;
3250  if (cd->columnId == import_buffer->getColumnDesc()->columnId) {
3251  if (coldef != nullptr ||
3252  skip_physical_cols-- <= 0) { // skip non-null phy col
3253  import_buffer->add_value(
3254  cd, defaultval, isnull, Importer_NS::CopyParams(), nrows);
3255  // tedious non-null geo default value ...
3256  if (cd->columnType.is_geometry() && !isnull) {
3257  std::vector<double> coords, bounds;
3258  std::vector<int> ring_sizes, poly_rings;
3259  int render_group = 0;
3260  SQLTypeInfo tinfo;
3262  tinfo,
3263  coords,
3264  bounds,
3265  ring_sizes,
3266  poly_rings,
3267  false)) {
3268  throw std::runtime_error("Bad geometry data: '" + defaultval + "'");
3269  }
3270  size_t col_idx = 1 + std::distance(import_buffers.begin(), it);
3272  cd,
3273  import_buffers,
3274  col_idx,
3275  coords,
3276  bounds,
3277  ring_sizes,
3278  poly_rings,
3279  render_group,
3280  nrows);
3281  // skip following phy cols
3282  skip_physical_cols = cd->columnType.get_physical_cols();
3283  }
3284  }
3285  break;
3286  }
3287  }
3288  }
3289  }
3290 
3291  if (!loader->loadNoCheckpoint(import_buffers, nrows)) {
3292  throw std::runtime_error("loadNoCheckpoint failed!");
3293  }
3294  loader->checkpoint();
3295  } catch (...) {
3296  catalog.roll(false);
3297  catalog.getSqliteConnector().query("ROLLBACK TRANSACTION");
3298  throw;
3299  }
3300  catalog.getSqliteConnector().query("END TRANSACTION");
3301  catalog.roll(true);
3302 }
std::list< std::unique_ptr< ColumnDef > > coldefs
Definition: ParserNode.h:1263
void setColumnDescriptor(ColumnDescriptor &cd, const ColumnDef *coldef)
std::string tableName
std::unique_ptr< std::string > table
Definition: ParserNode.h:1261
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:1581
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:1262
int get_physical_cols() const
Definition: sqltypes.h:340
bool is_geometry() const
Definition: sqltypes.h:458
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 1258 of file ParserNode.h.

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

Member Data Documentation

◆ coldef

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

Definition at line 1262 of file ParserNode.h.

◆ coldefs

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

Definition at line 1263 of file ParserNode.h.

◆ table

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

Definition at line 1261 of file ParserNode.h.


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