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

Constructor & Destructor Documentation

◆ InsertValuesStmt()

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

Definition at line 1828 of file ParserNode.h.

References CHECK, and v().

1829  : InsertStmt(t, c) {
1830  CHECK(v);
1831  for (const auto e : *v) {
1832  value_list.emplace_back(e);
1833  }
1834  delete v;
1835  }
void c(const std::string &query_string, const ExecutorDeviceType device_type)
T v(const TargetValue &r)
#define CHECK(condition)
Definition: Logger.h:187
InsertStmt(std::string *t, std::list< std::string *> *c)
Definition: ParserNode.h:1802
std::list< std::unique_ptr< Expr > > value_list
Definition: ParserNode.h:1843
+ Here is the call graph for this function:

Member Function Documentation

◆ analyze()

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

Implements Parser::InsertStmt.

Definition at line 1683 of file ParserNode.cpp.

References anonymous_namespace{ExecuteTest.cpp}::c(), CHECK, CHECK_EQ, ColumnDescriptor::columnId, ColumnDescriptor::columnName, ColumnDescriptor::columnType, Importer_NS::compress_coords(), anonymous_namespace{ImportTest.cpp}::d(), Datum::doubleval, 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::tinyintval, and v().

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

◆ determineLeafIndex()

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

Definition at line 1572 of file ParserNode.cpp.

References Datum::bigintval, anonymous_namespace{ExecuteTest.cpp}::c(), CHECK, CHECK_EQ, ColumnDescriptor::columnName, ColumnDescriptor::columnType, run-benchmark-import::con, anonymous_namespace{ImportTest.cpp}::d(), 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, anonymous_namespace{UpdateMetadataTest.cpp}::query, SHARD_FOR_KEY, Datum::smallintval, DictDescriptor::stringDict, Datum::stringval, TableDescriptor::tableId, and Datum::tinyintval.

1573  {
1574  const TableDescriptor* td = catalog.getMetadataForTable(*table);
1575  if (td == nullptr) {
1576  throw std::runtime_error("Table " + *table + " does not exist.");
1577  }
1578  if (td->isView) {
1579  throw std::runtime_error("Insert to views is not supported yet.");
1580  }
1581 
1582  if (td->partitions == "REPLICATED") {
1583  throw std::runtime_error("Cannot determine leaf on replicated table.");
1584  }
1585 
1586  if (0 == td->nShards) {
1587  std::random_device rd;
1588  std::mt19937_64 gen(rd());
1589  std::uniform_int_distribution<size_t> dis;
1590  const auto leaf_idx = dis(gen) % num_leafs;
1591  return leaf_idx;
1592  }
1593 
1594  size_t indexOfShardColumn = 0;
1595  const ColumnDescriptor* shardColumn = catalog.getShardColumnMetadataForTable(td);
1596  CHECK(shardColumn);
1597 
1598  if (column_list.empty()) {
1599  auto all_cols =
1600  catalog.getAllColumnMetadataForTable(td->tableId, false, false, false);
1601  auto iter = std::find(all_cols.begin(), all_cols.end(), shardColumn);
1602  CHECK(iter != all_cols.end());
1603  indexOfShardColumn = std::distance(all_cols.begin(), iter);
1604  } else {
1605  for (auto& c : column_list) {
1606  if (*c == shardColumn->columnName) {
1607  break;
1608  }
1609  indexOfShardColumn++;
1610  }
1611 
1612  if (indexOfShardColumn == column_list.size()) {
1613  throw std::runtime_error("No value defined for shard column.");
1614  }
1615  }
1616 
1617  if (indexOfShardColumn >= value_list.size()) {
1618  throw std::runtime_error("No value defined for shard column.");
1619  }
1620 
1621  auto& shardColumnValueExpr = *(std::next(value_list.begin(), indexOfShardColumn));
1622 
1624  auto e = shardColumnValueExpr->analyze(catalog, query);
1625  e = e->add_cast(shardColumn->columnType);
1626  const Analyzer::Constant* con = dynamic_cast<Analyzer::Constant*>(e.get());
1627  if (!con) {
1628  auto col_cast = dynamic_cast<const Analyzer::UOper*>(e.get());
1629  CHECK(col_cast);
1630  CHECK_EQ(kCAST, col_cast->get_optype());
1631  con = dynamic_cast<const Analyzer::Constant*>(col_cast->get_operand());
1632  }
1633  CHECK(con);
1634 
1635  Datum d = con->get_constval();
1636 
1637  auto shard_count = td->nShards * num_leafs;
1638  int64_t shardId = 0;
1639 
1640  if (con->get_is_null()) {
1642  shard_count);
1643  } else if (shardColumn->columnType.is_string()) {
1644  auto dictDesc =
1645  catalog.getMetadataForDict(shardColumn->columnType.get_comp_param(), true);
1646  auto str_id = dictDesc->stringDict->getOrAdd(*d.stringval);
1647  bool invalid = false;
1648 
1649  if (4 == shardColumn->columnType.get_size()) {
1650  invalid = str_id > max_valid_int_value<int32_t>();
1651  } else if (2 == shardColumn->columnType.get_size()) {
1652  invalid = str_id > max_valid_int_value<uint16_t>();
1653  } else if (1 == shardColumn->columnType.get_size()) {
1654  invalid = str_id > max_valid_int_value<uint8_t>();
1655  }
1656 
1657  if (invalid || str_id == inline_int_null_value<int32_t>()) {
1658  str_id = inline_fixed_encoding_null_val(shardColumn->columnType);
1659  }
1660  shardId = SHARD_FOR_KEY(str_id, shard_count);
1661  } else {
1662  switch (shardColumn->columnType.get_logical_size()) {
1663  case 8:
1664  shardId = SHARD_FOR_KEY(d.bigintval, shard_count);
1665  break;
1666  case 4:
1667  shardId = SHARD_FOR_KEY(d.intval, shard_count);
1668  break;
1669  case 2:
1670  shardId = SHARD_FOR_KEY(d.smallintval, shard_count);
1671  break;
1672  case 1:
1673  shardId = SHARD_FOR_KEY(d.tinyintval, shard_count);
1674  break;
1675  default:
1676  CHECK(false);
1677  }
1678  }
1679 
1680  return shardId / td->nShards;
1681 }
int8_t tinyintval
Definition: sqltypes.h:123
#define CHECK_EQ(x, y)
Definition: Logger.h:195
std::string partitions
std::unique_ptr< std::string > table
Definition: ParserNode.h:1818
void d(const SQLTypes expected_type, const std::string &str)
Definition: ImportTest.cpp:268
HOST DEVICE int get_size() const
Definition: sqltypes.h:329
const TableDescriptor * getMetadataForTable(const std::string &tableName, const bool populateFragmenter=true) const
Returns a pointer to a const TableDescriptor struct matching the provided tableName.
void c(const std::string &query_string, const ExecutorDeviceType device_type)
Definition: sqldefs.h:49
int32_t intval
Definition: sqltypes.h:125
std::shared_ptr< StringDictionary > stringDict
const ColumnDescriptor * getShardColumnMetadataForTable(const TableDescriptor *td) const
Definition: Catalog.cpp:2879
int64_t bigintval
Definition: sqltypes.h:126
int16_t smallintval
Definition: sqltypes.h:124
std::list< std::unique_ptr< std::string > > column_list
Definition: ParserNode.h:1819
specifies the content in-memory of a row in the column metadata table
const DictDescriptor * getMetadataForDict(int dict_ref, bool loadDict=true) const
Definition: Catalog.cpp:1348
std::string * stringval
Definition: sqltypes.h:131
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:1579
int get_logical_size() const
Definition: sqltypes.h:330
HOST DEVICE int get_comp_param() const
Definition: sqltypes.h:328
#define CHECK(condition)
Definition: Logger.h:187
int64_t inline_fixed_encoding_null_val(const SQL_TYPE_INFO &ti)
std::list< std::unique_ptr< Expr > > value_list
Definition: ParserNode.h:1843
SQLTypeInfo columnType
specifies the content in-memory of a row in the table metadata table
std::string columnName
bool is_string() const
Definition: sqltypes.h:446
#define SHARD_FOR_KEY(key, num_shards)
Definition: shard_key.h:20
+ Here is the call graph for this function:

◆ get_value_list()

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

Definition at line 1836 of file ParserNode.h.

References anonymous_namespace{UpdateMetadataTest.cpp}::query.

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

Member Data Documentation

◆ value_list

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

Definition at line 1843 of file ParserNode.h.


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