OmniSciDB  b24e664e58
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Parser::InsertValuesStmt Class Reference

#include <ParserNode.h>

+ Inheritance diagram for Parser::InsertValuesStmt:
+ Collaboration diagram for Parser::InsertValuesStmt:

Public Member Functions

 InsertValuesStmt (std::string *t, std::list< std::string * > *c, std::list< Expr * > *v)
 
const std::list
< std::unique_ptr< Expr > > & 
get_value_list () const
 
void analyze (const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const override
 
size_t determineLeafIndex (const Catalog_Namespace::Catalog &catalog, size_t num_leafs)
 
- Public Member Functions inherited from Parser::InsertStmt
 InsertStmt (std::string *t, std::list< std::string * > *c)
 
const std::string * get_table () const
 
const std::list
< std::unique_ptr< std::string > > & 
get_column_list () const
 
- Public Member Functions inherited from Parser::Node
virtual ~Node ()
 

Private Attributes

std::list< std::unique_ptr
< Expr > > 
value_list
 

Additional Inherited Members

- Protected Attributes inherited from Parser::InsertStmt
std::unique_ptr< std::string > table
 
std::list< std::unique_ptr
< std::string > > 
column_list
 

Detailed Description

Definition at line 1927 of file ParserNode.h.

Constructor & Destructor Documentation

Parser::InsertValuesStmt::InsertValuesStmt ( std::string *  t,
std::list< std::string * > *  c,
std::list< Expr * > *  v 
)
inline

Definition at line 1929 of file ParserNode.h.

References CHECK(), and value_list.

1930  : InsertStmt(t, c) {
1931  CHECK(v);
1932  for (const auto e : *v) {
1933  value_list.emplace_back(e);
1934  }
1935  delete v;
1936  }
InsertStmt(std::string *t, std::list< std::string * > *c)
Definition: ParserNode.h:1903
CHECK(cgen_state)
std::list< std::unique_ptr< Expr > > value_list
Definition: ParserNode.h:1944

+ Here is the call graph for this function:

Member Function Documentation

void Parser::InsertValuesStmt::analyze ( const Catalog_Namespace::Catalog catalog,
Analyzer::Query query 
) const
overridevirtual

Implements Parser::InsertStmt.

Definition at line 1698 of file ParserNode.cpp.

References CHECK(), CHECK_EQ, ColumnDescriptor::columnId, ColumnDescriptor::columnName, ColumnDescriptor::columnType, Importer_NS::compress_coords(), Datum::doubleval, Analyzer::Constant::get_constval(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_notnull(), Analyzer::Query::get_result_col_list(), Analyzer::Query::get_result_table_id(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_subtype(), Analyzer::Query::get_targetlist_nonconst(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_type(), Catalog_Namespace::Catalog::getAllColumnMetadataForTable(), Geo_namespace::GeoTypesFactory::getGeoColumns(), Catalog_Namespace::Catalog::getMetadataForColumn(), Datum::intval, SQLTypeInfoCore< TYPE_FACET_PACK >::is_geometry(), kARRAY, kCAST, kDOUBLE, kINT, kLINESTRING, kMULTIPOLYGON, kPOLYGON, kTINYINT, Datum::stringval, and Datum::tinyintval.

1699  {
1700  InsertStmt::analyze(catalog, query);
1701  std::vector<std::shared_ptr<Analyzer::TargetEntry>>& tlist =
1702  query.get_targetlist_nonconst();
1703  const auto tableId = query.get_result_table_id();
1704  const std::list<const ColumnDescriptor*> non_phys_cols =
1705  catalog.getAllColumnMetadataForTable(tableId, false, false, false);
1706  if (non_phys_cols.size() != value_list.size()) {
1707  throw std::runtime_error("Insert has more target columns than expressions.");
1708  }
1709  std::list<int>::const_iterator it = query.get_result_col_list().begin();
1710  for (auto& v : value_list) {
1711  auto e = v->analyze(catalog, query);
1712  const ColumnDescriptor* cd =
1713  catalog.getMetadataForColumn(query.get_result_table_id(), *it);
1714  CHECK(cd);
1715  if (cd->columnType.get_notnull()) {
1716  auto c = std::dynamic_pointer_cast<Analyzer::Constant>(e);
1717  if (c != nullptr && c->get_is_null()) {
1718  throw std::runtime_error("Cannot insert NULL into column " + cd->columnName);
1719  }
1720  }
1721  e = e->add_cast(cd->columnType);
1722  tlist.emplace_back(new Analyzer::TargetEntry("", e, false));
1723  ++it;
1724 
1725  const auto& col_ti = cd->columnType;
1726  if (col_ti.get_physical_cols() > 0) {
1727  CHECK(cd->columnType.is_geometry());
1728  std::string* wkt{nullptr};
1729  auto c = std::dynamic_pointer_cast<Analyzer::Constant>(e);
1730  if (c) {
1731  wkt = c->get_constval().stringval;
1732  } else {
1733  auto uoper = std::dynamic_pointer_cast<Analyzer::UOper>(e);
1734  if (uoper && uoper->get_optype() == kCAST) {
1735  auto c = dynamic_cast<const Analyzer::Constant*>(uoper->get_operand());
1736  if (c) {
1737  wkt = c->get_constval().stringval;
1738  }
1739  }
1740  }
1741  if (!wkt) {
1742  throw std::runtime_error("Expecting a WKT string for column " + cd->columnName);
1743  }
1744  std::vector<double> coords;
1745  std::vector<double> bounds;
1746  std::vector<int> ring_sizes;
1747  std::vector<int> poly_rings;
1748  int render_group =
1749  0; // @TODO simon.eves where to get render_group from in this context?!
1750  SQLTypeInfo import_ti;
1752  *wkt, import_ti, coords, bounds, ring_sizes, poly_rings)) {
1753  throw std::runtime_error("Cannot read geometry to insert into column " +
1754  cd->columnName);
1755  }
1756  if (cd->columnType.get_type() != import_ti.get_type()) {
1757  // allow POLYGON to be inserted into MULTIPOLYGON column
1758  if (!(import_ti.get_type() == SQLTypes::kPOLYGON &&
1760  throw std::runtime_error("Imported geometry doesn't match the type of column " +
1761  cd->columnName);
1762  }
1763  }
1764  // TODO: check if import SRID matches columns SRID, may need to transform before
1765  // inserting
1766 
1767  int nextColumnOffset = 1;
1768 
1769  const ColumnDescriptor* cd_coords = catalog.getMetadataForColumn(
1770  query.get_result_table_id(), cd->columnId + nextColumnOffset);
1771  CHECK(cd_coords);
1772  CHECK_EQ(cd_coords->columnType.get_type(), kARRAY);
1773  CHECK_EQ(cd_coords->columnType.get_subtype(), kTINYINT);
1774  auto compressed_coords = Importer_NS::compress_coords(coords, col_ti);
1775  std::list<std::shared_ptr<Analyzer::Expr>> value_exprs;
1776  for (auto cc : compressed_coords) {
1777  Datum d;
1778  d.tinyintval = cc;
1779  auto e = makeExpr<Analyzer::Constant>(kTINYINT, false, d);
1780  value_exprs.push_back(e);
1781  }
1782  tlist.emplace_back(new Analyzer::TargetEntry(
1783  "",
1784  makeExpr<Analyzer::Constant>(cd_coords->columnType, false, value_exprs),
1785  false));
1786  ++it;
1787  nextColumnOffset++;
1788 
1789  if (cd->columnType.get_type() == kPOLYGON ||
1790  cd->columnType.get_type() == kMULTIPOLYGON) {
1791  // Put ring sizes array into separate physical column
1792  const ColumnDescriptor* cd_ring_sizes = catalog.getMetadataForColumn(
1793  query.get_result_table_id(), cd->columnId + nextColumnOffset);
1794  CHECK(cd_ring_sizes);
1795  CHECK_EQ(cd_ring_sizes->columnType.get_type(), kARRAY);
1796  CHECK_EQ(cd_ring_sizes->columnType.get_subtype(), kINT);
1797  std::list<std::shared_ptr<Analyzer::Expr>> value_exprs;
1798  for (auto c : ring_sizes) {
1799  Datum d;
1800  d.intval = c;
1801  auto e = makeExpr<Analyzer::Constant>(kINT, false, d);
1802  value_exprs.push_back(e);
1803  }
1804  tlist.emplace_back(new Analyzer::TargetEntry(
1805  "",
1806  makeExpr<Analyzer::Constant>(cd_ring_sizes->columnType, false, value_exprs),
1807  false));
1808  ++it;
1809  nextColumnOffset++;
1810 
1811  if (cd->columnType.get_type() == kMULTIPOLYGON) {
1812  // Put poly_rings array into separate physical column
1813  const ColumnDescriptor* cd_poly_rings = catalog.getMetadataForColumn(
1814  query.get_result_table_id(), cd->columnId + nextColumnOffset);
1815  CHECK(cd_poly_rings);
1816  CHECK_EQ(cd_poly_rings->columnType.get_type(), kARRAY);
1817  CHECK_EQ(cd_poly_rings->columnType.get_subtype(), kINT);
1818  std::list<std::shared_ptr<Analyzer::Expr>> value_exprs;
1819  for (auto c : poly_rings) {
1820  Datum d;
1821  d.intval = c;
1822  auto e = makeExpr<Analyzer::Constant>(kINT, false, d);
1823  value_exprs.push_back(e);
1824  }
1825  tlist.emplace_back(new Analyzer::TargetEntry(
1826  "",
1827  makeExpr<Analyzer::Constant>(cd_poly_rings->columnType, false, value_exprs),
1828  false));
1829  ++it;
1830  nextColumnOffset++;
1831  }
1832  }
1833 
1834  if (cd->columnType.get_type() == kLINESTRING ||
1835  cd->columnType.get_type() == kPOLYGON ||
1836  cd->columnType.get_type() == kMULTIPOLYGON) {
1837  const ColumnDescriptor* cd_bounds = catalog.getMetadataForColumn(
1838  query.get_result_table_id(), cd->columnId + nextColumnOffset);
1839  CHECK(cd_bounds);
1840  CHECK_EQ(cd_bounds->columnType.get_type(), kARRAY);
1841  CHECK_EQ(cd_bounds->columnType.get_subtype(), kDOUBLE);
1842  std::list<std::shared_ptr<Analyzer::Expr>> value_exprs;
1843  for (auto b : bounds) {
1844  Datum d;
1845  d.doubleval = b;
1846  auto e = makeExpr<Analyzer::Constant>(kDOUBLE, false, d);
1847  value_exprs.push_back(e);
1848  }
1849  tlist.emplace_back(new Analyzer::TargetEntry(
1850  "",
1851  makeExpr<Analyzer::Constant>(cd_bounds->columnType, false, value_exprs),
1852  false));
1853  ++it;
1854  nextColumnOffset++;
1855  }
1856 
1857  if (cd->columnType.get_type() == kPOLYGON ||
1858  cd->columnType.get_type() == kMULTIPOLYGON) {
1859  // Put render group into separate physical column
1860  const ColumnDescriptor* cd_render_group = catalog.getMetadataForColumn(
1861  query.get_result_table_id(), cd->columnId + nextColumnOffset);
1862  CHECK(cd_render_group);
1863  CHECK_EQ(cd_render_group->columnType.get_type(), kINT);
1864  Datum d;
1865  d.intval = render_group;
1866  tlist.emplace_back(new Analyzer::TargetEntry(
1867  "",
1868  makeExpr<Analyzer::Constant>(cd_render_group->columnType, false, d),
1869  false));
1870  ++it;
1871  nextColumnOffset++;
1872  }
1873  }
1874  }
1875 }
int8_t tinyintval
Definition: sqltypes.h:126
#define CHECK_EQ(x, y)
Definition: Logger.h:198
Definition: Analyzer.h:1483
std::vector< uint8_t > compress_coords(std::vector< double > &coords, const SQLTypeInfo &ti)
Definition: Importer.cpp:1422
Definition: sqldefs.h:49
void analyze(const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const override=0
int32_t intval
Definition: sqltypes.h:128
CHECK(cgen_state)
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:326
const ColumnDescriptor * getMetadataForColumn(int tableId, const std::string &colName) const
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:333
specifies the content in-memory of a row in the column metadata table
bool is_geometry() const
Definition: sqltypes.h:489
std::string * stringval
Definition: sqltypes.h:134
int get_result_table_id() const
Definition: Analyzer.h:1542
std::list< const ColumnDescriptor * > getAllColumnMetadataForTable(const int tableId, const bool fetchSystemColumns, const bool fetchVirtualColumns, const bool fetchPhysicalColumns) const
Returns a list of pointers to constant ColumnDescriptor structs for all the columns from a particular...
Definition: Catalog.cpp:1581
std::vector< std::shared_ptr< TargetEntry > > & get_targetlist_nonconst()
Definition: Analyzer.h:1529
Datum get_constval() const
Definition: Analyzer.h:329
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
HOST DEVICE SQLTypes get_subtype() const
Definition: sqltypes.h:327
std::list< std::unique_ptr< Expr > > value_list
Definition: ParserNode.h:1944
Definition: sqltypes.h:48
SQLTypeInfo columnType
const std::list< int > & get_result_col_list() const
Definition: Analyzer.h:1543
std::string columnName
double doubleval
Definition: sqltypes.h:131

+ Here is the call graph for this function:

size_t Parser::InsertValuesStmt::determineLeafIndex ( const Catalog_Namespace::Catalog catalog,
size_t  num_leafs 
)

Definition at line 1587 of file ParserNode.cpp.

References Datum::bigintval, CHECK(), CHECK_EQ, ColumnDescriptor::columnName, ColumnDescriptor::columnType, run_benchmark_import::con, SQLTypeInfoCore< TYPE_FACET_PACK >::get_comp_param(), Analyzer::Constant::get_constval(), Analyzer::Constant::get_is_null(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_logical_size(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_size(), Catalog_Namespace::Catalog::getAllColumnMetadataForTable(), Catalog_Namespace::Catalog::getMetadataForDict(), Catalog_Namespace::Catalog::getMetadataForTable(), Catalog_Namespace::Catalog::getShardColumnMetadataForTable(), inline_fixed_encoding_null_val(), Datum::intval, SQLTypeInfoCore< TYPE_FACET_PACK >::is_string(), TableDescriptor::isView, kCAST, TableDescriptor::nShards, TableDescriptor::partitions, SHARD_FOR_KEY, Datum::smallintval, DictDescriptor::stringDict, Datum::stringval, TableDescriptor::tableId, and Datum::tinyintval.

1588  {
1589  const TableDescriptor* td = catalog.getMetadataForTable(*table);
1590  if (td == nullptr) {
1591  throw std::runtime_error("Table " + *table + " does not exist.");
1592  }
1593  if (td->isView) {
1594  throw std::runtime_error("Insert to views is not supported yet.");
1595  }
1596 
1597  if (td->partitions == "REPLICATED") {
1598  throw std::runtime_error("Cannot determine leaf on replicated table.");
1599  }
1600 
1601  if (0 == td->nShards) {
1602  std::random_device rd;
1603  std::mt19937_64 gen(rd());
1604  std::uniform_int_distribution<size_t> dis;
1605  const auto leaf_idx = dis(gen) % num_leafs;
1606  return leaf_idx;
1607  }
1608 
1609  size_t indexOfShardColumn = 0;
1610  const ColumnDescriptor* shardColumn = catalog.getShardColumnMetadataForTable(td);
1611  CHECK(shardColumn);
1612 
1613  if (column_list.empty()) {
1614  auto all_cols =
1615  catalog.getAllColumnMetadataForTable(td->tableId, false, false, false);
1616  auto iter = std::find(all_cols.begin(), all_cols.end(), shardColumn);
1617  CHECK(iter != all_cols.end());
1618  indexOfShardColumn = std::distance(all_cols.begin(), iter);
1619  } else {
1620  for (auto& c : column_list) {
1621  if (*c == shardColumn->columnName) {
1622  break;
1623  }
1624  indexOfShardColumn++;
1625  }
1626 
1627  if (indexOfShardColumn == column_list.size()) {
1628  throw std::runtime_error("No value defined for shard column.");
1629  }
1630  }
1631 
1632  if (indexOfShardColumn >= value_list.size()) {
1633  throw std::runtime_error("No value defined for shard column.");
1634  }
1635 
1636  auto& shardColumnValueExpr = *(std::next(value_list.begin(), indexOfShardColumn));
1637 
1638  Analyzer::Query query;
1639  auto e = shardColumnValueExpr->analyze(catalog, query);
1640  e = e->add_cast(shardColumn->columnType);
1641  const Analyzer::Constant* con = dynamic_cast<Analyzer::Constant*>(e.get());
1642  if (!con) {
1643  auto col_cast = dynamic_cast<const Analyzer::UOper*>(e.get());
1644  CHECK(col_cast);
1645  CHECK_EQ(kCAST, col_cast->get_optype());
1646  con = dynamic_cast<const Analyzer::Constant*>(col_cast->get_operand());
1647  }
1648  CHECK(con);
1649 
1650  Datum d = con->get_constval();
1651 
1652  auto shard_count = td->nShards * num_leafs;
1653  int64_t shardId = 0;
1654 
1655  if (con->get_is_null()) {
1657  shard_count);
1658  } else if (shardColumn->columnType.is_string()) {
1659  auto dictDesc =
1660  catalog.getMetadataForDict(shardColumn->columnType.get_comp_param(), true);
1661  auto str_id = dictDesc->stringDict->getOrAdd(*d.stringval);
1662  bool invalid = false;
1663 
1664  if (4 == shardColumn->columnType.get_size()) {
1665  invalid = str_id > max_valid_int_value<int32_t>();
1666  } else if (2 == shardColumn->columnType.get_size()) {
1667  invalid = str_id > max_valid_int_value<uint16_t>();
1668  } else if (1 == shardColumn->columnType.get_size()) {
1669  invalid = str_id > max_valid_int_value<uint8_t>();
1670  }
1671 
1672  if (invalid || str_id == inline_int_null_value<int32_t>()) {
1673  str_id = inline_fixed_encoding_null_val(shardColumn->columnType);
1674  }
1675  shardId = SHARD_FOR_KEY(str_id, shard_count);
1676  } else {
1677  switch (shardColumn->columnType.get_logical_size()) {
1678  case 8:
1679  shardId = SHARD_FOR_KEY(d.bigintval, shard_count);
1680  break;
1681  case 4:
1682  shardId = SHARD_FOR_KEY(d.intval, shard_count);
1683  break;
1684  case 2:
1685  shardId = SHARD_FOR_KEY(d.smallintval, shard_count);
1686  break;
1687  case 1:
1688  shardId = SHARD_FOR_KEY(d.tinyintval, shard_count);
1689  break;
1690  default:
1691  CHECK(false);
1692  }
1693  }
1694 
1695  return shardId / td->nShards;
1696 }
int8_t tinyintval
Definition: sqltypes.h:126
#define CHECK_EQ(x, y)
Definition: Logger.h:198
std::string partitions
std::unique_ptr< std::string > table
Definition: ParserNode.h:1919
HOST DEVICE int get_comp_param() const
Definition: sqltypes.h:335
HOST DEVICE int get_size() const
Definition: sqltypes.h:336
Definition: sqldefs.h:49
const ColumnDescriptor * getShardColumnMetadataForTable(const TableDescriptor *td) const
Definition: Catalog.cpp:2881
int32_t intval
Definition: sqltypes.h:128
std::shared_ptr< StringDictionary > stringDict
CHECK(cgen_state)
int get_logical_size() const
Definition: sqltypes.h:337
int64_t bigintval
Definition: sqltypes.h:129
int16_t smallintval
Definition: sqltypes.h:127
std::list< std::unique_ptr< std::string > > column_list
Definition: ParserNode.h:1920
const DictDescriptor * getMetadataForDict(int dict_ref, bool loadDict=true) const
Definition: Catalog.cpp:1350
specifies the content in-memory of a row in the column metadata table
std::string * stringval
Definition: sqltypes.h:134
std::list< const ColumnDescriptor * > getAllColumnMetadataForTable(const int tableId, const bool fetchSystemColumns, const bool fetchVirtualColumns, const bool fetchPhysicalColumns) const
Returns a list of pointers to constant ColumnDescriptor structs for all the columns from a particular...
Definition: Catalog.cpp:1581
bool is_string() const
Definition: sqltypes.h:477
int64_t inline_fixed_encoding_null_val(const SQL_TYPE_INFO &ti)
std::list< std::unique_ptr< Expr > > value_list
Definition: ParserNode.h:1944
SQLTypeInfo columnType
const TableDescriptor * getMetadataForTable(const std::string &tableName, const bool populateFragmenter=true) const
Returns a pointer to a const TableDescriptor struct matching the provided tableName.
specifies the content in-memory of a row in the table metadata table
std::string columnName
#define SHARD_FOR_KEY(key, num_shards)
Definition: shard_key.h:20

+ Here is the call graph for this function:

const std::list<std::unique_ptr<Expr> >& Parser::InsertValuesStmt::get_value_list ( ) const
inline

Definition at line 1937 of file ParserNode.h.

References value_list.

1937 { return value_list; }
std::list< std::unique_ptr< Expr > > value_list
Definition: ParserNode.h:1944

Member Data Documentation

std::list<std::unique_ptr<Expr> > Parser::InsertValuesStmt::value_list
private

Definition at line 1944 of file ParserNode.h.

Referenced by get_value_list(), and InsertValuesStmt().


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