OmniSciDB  c07336695a
Parser::QuerySpec Class Reference

#include <ParserNode.h>

+ Inheritance diagram for Parser::QuerySpec:
+ Collaboration diagram for Parser::QuerySpec:

Public Member Functions

 QuerySpec (bool d, std::list< SelectEntry *> *s, std::list< TableRef *> *f, Expr *w, std::list< Expr *> *g, Expr *h)
 
bool get_is_distinct () const
 
const std::list< std::unique_ptr< SelectEntry > > & get_select_clause () const
 
const std::list< std::unique_ptr< TableRef > > & get_from_clause () const
 
const Exprget_where_clause () const
 
const std::list< std::unique_ptr< Expr > > & get_groupby_clause () const
 
const Exprget_having_clause () const
 
void analyze (const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const override
 
std::string to_string () const
 
- Public Member Functions inherited from Parser::Node
virtual ~Node ()
 

Private Member Functions

void analyze_from_clause (const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const
 
void analyze_select_clause (const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const
 
void analyze_where_clause (const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const
 
void analyze_group_by (const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const
 
void analyze_having_clause (const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const
 

Private Attributes

bool is_distinct
 
std::list< std::unique_ptr< SelectEntry > > select_clause
 
std::list< std::unique_ptr< TableRef > > from_clause
 
std::unique_ptr< Exprwhere_clause
 
std::list< std::unique_ptr< Expr > > groupby_clause
 
std::unique_ptr< Exprhaving_clause
 

Detailed Description

Definition at line 1515 of file ParserNode.h.

Constructor & Destructor Documentation

◆ QuerySpec()

Parser::QuerySpec::QuerySpec ( bool  d,
std::list< SelectEntry *> *  s,
std::list< TableRef *> *  f,
Expr w,
std::list< Expr *> *  g,
Expr h 
)
inline

Definition at line 1517 of file ParserNode.h.

References CHECK, and TestHelpers::g().

1524  if (s) {
1525  for (const auto e : *s) {
1526  select_clause.emplace_back(e);
1527  }
1528  delete s;
1529  }
1530  CHECK(f);
1531  for (const auto e : *f) {
1532  from_clause.emplace_back(e);
1533  }
1534  delete f;
1535  if (g) {
1536  for (const auto e : *g) {
1537  groupby_clause.emplace_back(e);
1538  }
1539  delete g;
1540  }
1541  }
std::unique_ptr< Expr > where_clause
Definition: ParserNode.h:1562
void d(const SQLTypes expected_type, const std::string &str)
Definition: ImportTest.cpp:268
std::list< std::unique_ptr< TableRef > > from_clause
Definition: ParserNode.h:1561
T g(const TargetValue &r)
Definition: TestHelpers.h:118
std::list< std::unique_ptr< SelectEntry > > select_clause
Definition: ParserNode.h:1560
std::list< std::unique_ptr< Expr > > groupby_clause
Definition: ParserNode.h:1563
#define CHECK(condition)
Definition: Logger.h:187
std::unique_ptr< Expr > having_clause
Definition: ParserNode.h:1564
+ Here is the call graph for this function:

Member Function Documentation

◆ analyze()

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

Implements Parser::QueryExpr.

Definition at line 1157 of file ParserNode.cpp.

References anonymous_namespace{RelAlgOptimizer.cpp}::is_distinct(), and Analyzer::Query::set_is_distinct().

1158  {
1160  analyze_from_clause(catalog, query);
1161  analyze_select_clause(catalog, query);
1162  analyze_where_clause(catalog, query);
1163  analyze_group_by(catalog, query);
1164  analyze_having_clause(catalog, query);
1165 }
void analyze_select_clause(const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const
void analyze_group_by(const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const
void analyze_where_clause(const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const
void analyze_having_clause(const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const
Definition: ParserNode.cpp:987
void analyze_from_clause(const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const
void set_is_distinct(bool d)
Definition: Analyzer.h:1469
+ Here is the call graph for this function:

◆ analyze_from_clause()

void Parser::QuerySpec::analyze_from_clause ( const Catalog_Namespace::Catalog catalog,
Analyzer::Query query 
) const
private

Definition at line 1137 of file ParserNode.cpp.

References Analyzer::Query::add_rte(), and Catalog_Namespace::Catalog::getMetadataForTable().

1138  {
1140  for (auto& p : from_clause) {
1141  const TableDescriptor* table_desc;
1142  table_desc = catalog.getMetadataForTable(*p->get_table_name());
1143  if (table_desc == nullptr) {
1144  throw std::runtime_error("Table " + *p->get_table_name() + " does not exist.");
1145  }
1146  std::string range_var;
1147  if (p->get_range_var() == nullptr) {
1148  range_var = *p->get_table_name();
1149  } else {
1150  range_var = *p->get_range_var();
1151  }
1152  rte = new Analyzer::RangeTableEntry(range_var, table_desc, nullptr);
1153  query.add_rte(rte);
1154  }
1155 }
std::list< std::unique_ptr< TableRef > > from_clause
Definition: ParserNode.h:1561
void add_rte(RangeTableEntry *rte)
Definition: Analyzer.cpp:1266
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
+ Here is the call graph for this function:

◆ analyze_group_by()

void Parser::QuerySpec::analyze_group_by ( const Catalog_Namespace::Catalog catalog,
Analyzer::Query query 
) const
private

Definition at line 1000 of file ParserNode.cpp.

References Analyzer::Expr::add_cast(), anonymous_namespace{ExecuteTest.cpp}::c(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_compression(), Parser::IntLiteral::get_intval(), Analyzer::Query::get_num_aggs(), Analyzer::Query::get_targetlist(), Analyzer::Var::get_varno(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_string(), kENCODING_DICT, kENCODING_NONE, Analyzer::Var::kGROUPBY, Analyzer::Var::kOUTPUT, SQLTypeInfoCore< TYPE_FACET_PACK >::set_comp_param(), SQLTypeInfoCore< TYPE_FACET_PACK >::set_compression(), SQLTypeInfoCore< TYPE_FACET_PACK >::set_fixed_size(), Analyzer::Query::set_group_by(), TRANSIENT_DICT_ID, and v().

1001  {
1002  std::list<std::shared_ptr<Analyzer::Expr>> groupby;
1003  if (!groupby_clause.empty()) {
1004  int gexpr_no = 1;
1005  std::shared_ptr<Analyzer::Expr> gexpr;
1006  const std::vector<std::shared_ptr<Analyzer::TargetEntry>>& tlist =
1007  query.get_targetlist();
1008  for (auto& c : groupby_clause) {
1009  // special-case ordinal numbers in GROUP BY
1010  if (dynamic_cast<Literal*>(c.get())) {
1011  IntLiteral* i = dynamic_cast<IntLiteral*>(c.get());
1012  if (!i) {
1013  throw std::runtime_error("Invalid literal in GROUP BY clause.");
1014  }
1015  int varno = (int)i->get_intval();
1016  if (varno <= 0 || varno > static_cast<int>(tlist.size())) {
1017  throw std::runtime_error("Invalid ordinal number in GROUP BY clause.");
1018  }
1019  if (tlist[varno - 1]->get_expr()->get_contains_agg()) {
1020  throw std::runtime_error(
1021  "Ordinal number in GROUP BY cannot reference an expression containing "
1022  "aggregate "
1023  "functions.");
1024  }
1025  gexpr = makeExpr<Analyzer::Var>(
1026  tlist[varno - 1]->get_expr()->get_type_info(), Analyzer::Var::kOUTPUT, varno);
1027  } else {
1028  gexpr = c->analyze(catalog, query, Expr::TlistRefType::TLIST_REF);
1029  }
1030  const SQLTypeInfo gti = gexpr->get_type_info();
1031  bool set_new_type = false;
1032  SQLTypeInfo ti(gti);
1033  if (gti.is_string() && gti.get_compression() == kENCODING_NONE) {
1034  set_new_type = true;
1035  ti.set_compression(kENCODING_DICT);
1036  ti.set_comp_param(TRANSIENT_DICT_ID);
1037  ti.set_fixed_size();
1038  }
1039  std::shared_ptr<Analyzer::Var> v;
1040  if (std::dynamic_pointer_cast<Analyzer::Var>(gexpr)) {
1041  v = std::static_pointer_cast<Analyzer::Var>(gexpr);
1042  int n = v->get_varno();
1043  gexpr = tlist[n - 1]->get_own_expr();
1044  auto cv = std::dynamic_pointer_cast<Analyzer::ColumnVar>(gexpr);
1045  if (cv != nullptr) {
1046  // inherit all ColumnVar info for lineage.
1047  *std::static_pointer_cast<Analyzer::ColumnVar>(v) = *cv;
1048  }
1049  v->set_which_row(Analyzer::Var::kGROUPBY);
1050  v->set_varno(gexpr_no);
1051  tlist[n - 1]->set_expr(v);
1052  }
1053  if (set_new_type) {
1054  auto new_e = gexpr->add_cast(ti);
1055  groupby.push_back(new_e);
1056  if (v != nullptr) {
1057  v->set_type_info(new_e->get_type_info());
1058  }
1059  } else {
1060  groupby.push_back(gexpr);
1061  }
1062  gexpr_no++;
1063  }
1064  }
1065  if (query.get_num_aggs() > 0 || !groupby.empty()) {
1066  for (auto t : query.get_targetlist()) {
1067  auto e = t->get_expr();
1068  e->check_group_by(groupby);
1069  }
1070  }
1071  query.set_group_by(groupby);
1072 }
const std::vector< std::shared_ptr< TargetEntry > > & get_targetlist() const
Definition: Analyzer.h:1449
void c(const std::string &query_string, const ExecutorDeviceType device_type)
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:327
T v(const TargetValue &r)
void set_group_by(std::list< std::shared_ptr< Analyzer::Expr >> &g)
Definition: Analyzer.h:1471
std::list< std::unique_ptr< Expr > > groupby_clause
Definition: ParserNode.h:1563
#define TRANSIENT_DICT_ID
Definition: sqltypes.h:187
virtual std::shared_ptr< Analyzer::Expr > add_cast(const SQLTypeInfo &new_type_info)
Definition: Analyzer.cpp:663
int get_varno() const
Definition: Analyzer.h:274
int get_num_aggs() const
Definition: Analyzer.h:1448
bool is_string() const
Definition: sqltypes.h:446
+ Here is the call graph for this function:

◆ analyze_having_clause()

void Parser::QuerySpec::analyze_having_clause ( const Catalog_Namespace::Catalog catalog,
Analyzer::Query query 
) const
private

Definition at line 987 of file ParserNode.cpp.

References Analyzer::Query::get_group_by(), kBOOLEAN, and Analyzer::Query::set_having_predicate().

988  {
989  std::shared_ptr<Analyzer::Expr> p;
990  if (having_clause != nullptr) {
991  p = having_clause->analyze(catalog, query, Expr::TlistRefType::TLIST_COPY);
992  if (p->get_type_info().get_type() != kBOOLEAN) {
993  throw std::runtime_error("Only boolean expressions can be in HAVING clause.");
994  }
995  p->check_group_by(query.get_group_by());
996  }
997  query.set_having_predicate(p);
998 }
const std::list< std::shared_ptr< Analyzer::Expr > > & get_group_by() const
Definition: Analyzer.h:1457
void set_having_predicate(std::shared_ptr< Analyzer::Expr > p)
Definition: Analyzer.h:1472
std::unique_ptr< Expr > having_clause
Definition: ParserNode.h:1564
+ Here is the call graph for this function:

◆ analyze_select_clause()

void Parser::QuerySpec::analyze_select_clause ( const Catalog_Namespace::Catalog catalog,
Analyzer::Query query 
) const
private

Definition at line 1087 of file ParserNode.cpp.

References Parser::Expr::analyze(), ColumnDescriptor::columnName, Analyzer::RangeTableEntry::expand_star_in_targetlist(), Analyzer::Query::get_rangetable(), Analyzer::Query::get_rte(), Analyzer::Query::get_rte_idx(), Analyzer::Query::get_targetlist_nonconst(), Catalog_Namespace::Catalog::getMetadataForColumn(), kNULLT, and kUNNEST.

1088  {
1089  std::vector<std::shared_ptr<Analyzer::TargetEntry>>& tlist =
1090  query.get_targetlist_nonconst();
1091  if (select_clause.empty()) {
1092  // this means SELECT *
1093  int rte_idx = 0;
1094  for (auto rte : query.get_rangetable()) {
1095  rte->expand_star_in_targetlist(catalog, tlist, rte_idx++);
1096  }
1097  } else {
1098  for (auto& p : select_clause) {
1099  const Parser::Expr* select_expr = p->get_select_expr();
1100  // look for the case of range_var.*
1101  if (typeid(*select_expr) == typeid(ColumnRef) &&
1102  dynamic_cast<const ColumnRef*>(select_expr)->get_column() == nullptr) {
1103  const std::string* range_var_name =
1104  dynamic_cast<const ColumnRef*>(select_expr)->get_table();
1105  int rte_idx = query.get_rte_idx(*range_var_name);
1106  if (rte_idx < 0) {
1107  throw std::runtime_error("invalid range variable name: " + *range_var_name);
1108  }
1109  Analyzer::RangeTableEntry* rte = query.get_rte(rte_idx);
1110  rte->expand_star_in_targetlist(catalog, tlist, rte_idx);
1111  } else {
1112  auto e = select_expr->analyze(catalog, query);
1113  std::string resname;
1114 
1115  if (p->get_alias() != nullptr) {
1116  resname = *p->get_alias();
1117  } else if (std::dynamic_pointer_cast<Analyzer::ColumnVar>(e) &&
1118  !std::dynamic_pointer_cast<Analyzer::Var>(e)) {
1119  auto colvar = std::static_pointer_cast<Analyzer::ColumnVar>(e);
1120  const ColumnDescriptor* col_desc = catalog.getMetadataForColumn(
1121  colvar->get_table_id(), colvar->get_column_id());
1122  resname = col_desc->columnName;
1123  }
1124  if (e->get_type_info().get_type() == kNULLT) {
1125  throw std::runtime_error(
1126  "Untyped NULL in SELECT clause. Use CAST to specify a type.");
1127  }
1128  auto o = std::static_pointer_cast<Analyzer::UOper>(e);
1129  bool unnest = (o != nullptr && o->get_optype() == kUNNEST);
1130  auto tle = std::make_shared<Analyzer::TargetEntry>(resname, e, unnest);
1131  tlist.push_back(tle);
1132  }
1133  }
1134  }
1135 }
void expand_star_in_targetlist(const Catalog_Namespace::Catalog &catalog, std::vector< std::shared_ptr< TargetEntry >> &tlist, int rte_idx)
const ColumnDescriptor * getMetadataForColumn(int tableId, const std::string &colName) const
RangeTableEntry * get_rte(int rte_idx) const
Definition: Analyzer.h:1479
std::list< std::unique_ptr< SelectEntry > > select_clause
Definition: ParserNode.h:1560
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
int get_rte_idx(const std::string &range_var_name) const
Definition: Analyzer.cpp:1255
const std::vector< RangeTableEntry * > & get_rangetable() const
Definition: Analyzer.h:1455
virtual std::shared_ptr< Analyzer::Expr > analyze(const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query, TlistRefType allow_tlist_ref=TLIST_NONE) const =0
std::string columnName
+ Here is the call graph for this function:

◆ analyze_where_clause()

void Parser::QuerySpec::analyze_where_clause ( const Catalog_Namespace::Catalog catalog,
Analyzer::Query query 
) const
private

Definition at line 1074 of file ParserNode.cpp.

References kBOOLEAN, and Analyzer::Query::set_where_predicate().

1075  {
1076  if (where_clause == nullptr) {
1077  query.set_where_predicate(nullptr);
1078  return;
1079  }
1080  auto p = where_clause->analyze(catalog, query, Expr::TlistRefType::TLIST_COPY);
1081  if (p->get_type_info().get_type() != kBOOLEAN) {
1082  throw std::runtime_error("Only boolean expressions can be in WHERE clause.");
1083  }
1084  query.set_where_predicate(p);
1085 }
std::unique_ptr< Expr > where_clause
Definition: ParserNode.h:1562
void set_where_predicate(std::shared_ptr< Analyzer::Expr > p)
Definition: Analyzer.h:1470
+ Here is the call graph for this function:

◆ get_from_clause()

const std::list<std::unique_ptr<TableRef> >& Parser::QuerySpec::get_from_clause ( ) const
inline

Definition at line 1546 of file ParserNode.h.

1546  {
1547  return from_clause;
1548  }
std::list< std::unique_ptr< TableRef > > from_clause
Definition: ParserNode.h:1561

◆ get_groupby_clause()

const std::list<std::unique_ptr<Expr> >& Parser::QuerySpec::get_groupby_clause ( ) const
inline

Definition at line 1550 of file ParserNode.h.

1550  {
1551  return groupby_clause;
1552  }
std::list< std::unique_ptr< Expr > > groupby_clause
Definition: ParserNode.h:1563

◆ get_having_clause()

const Expr* Parser::QuerySpec::get_having_clause ( ) const
inline

Definition at line 1553 of file ParserNode.h.

References anonymous_namespace{UpdateMetadataTest.cpp}::query, and to_string().

1553 { return having_clause.get(); }
std::unique_ptr< Expr > having_clause
Definition: ParserNode.h:1564
+ Here is the call graph for this function:

◆ get_is_distinct()

bool Parser::QuerySpec::get_is_distinct ( ) const
inline

Definition at line 1542 of file ParserNode.h.

References anonymous_namespace{RelAlgOptimizer.cpp}::is_distinct().

1542 { return is_distinct; }
+ Here is the call graph for this function:

◆ get_select_clause()

const std::list<std::unique_ptr<SelectEntry> >& Parser::QuerySpec::get_select_clause ( ) const
inline

Definition at line 1543 of file ParserNode.h.

1543  {
1544  return select_clause;
1545  }
std::list< std::unique_ptr< SelectEntry > > select_clause
Definition: ParserNode.h:1560

◆ get_where_clause()

const Expr* Parser::QuerySpec::get_where_clause ( ) const
inline

Definition at line 1549 of file ParserNode.h.

1549 { return where_clause.get(); }
std::unique_ptr< Expr > where_clause
Definition: ParserNode.h:1562

◆ to_string()

std::string Parser::QuerySpec::to_string ( ) const

Definition at line 1476 of file ParserNode.cpp.

References anonymous_namespace{RelAlgOptimizer.cpp}::is_distinct().

1476  {
1477  std::string query_str = "SELECT ";
1478  if (is_distinct) {
1479  query_str += "DISTINCT ";
1480  }
1481  if (select_clause.empty()) {
1482  query_str += "* ";
1483  } else {
1484  bool notfirst = false;
1485  for (auto& p : select_clause) {
1486  if (notfirst) {
1487  query_str += ", ";
1488  } else {
1489  notfirst = true;
1490  }
1491  query_str += p->to_string();
1492  }
1493  }
1494  query_str += " FROM ";
1495  bool notfirst = false;
1496  for (auto& p : from_clause) {
1497  if (notfirst) {
1498  query_str += ", ";
1499  } else {
1500  notfirst = true;
1501  }
1502  query_str += p->to_string();
1503  }
1504  if (where_clause) {
1505  query_str += " WHERE " + where_clause->to_string();
1506  }
1507  if (!groupby_clause.empty()) {
1508  query_str += " GROUP BY ";
1509  bool notfirst = false;
1510  for (auto& p : groupby_clause) {
1511  if (notfirst) {
1512  query_str += ", ";
1513  } else {
1514  notfirst = true;
1515  }
1516  query_str += p->to_string();
1517  }
1518  }
1519  if (having_clause) {
1520  query_str += " HAVING " + having_clause->to_string();
1521  }
1522  query_str += ";";
1523  return query_str;
1524 }
std::unique_ptr< Expr > where_clause
Definition: ParserNode.h:1562
std::list< std::unique_ptr< TableRef > > from_clause
Definition: ParserNode.h:1561
std::list< std::unique_ptr< SelectEntry > > select_clause
Definition: ParserNode.h:1560
std::list< std::unique_ptr< Expr > > groupby_clause
Definition: ParserNode.h:1563
std::unique_ptr< Expr > having_clause
Definition: ParserNode.h:1564
+ Here is the call graph for this function:

Member Data Documentation

◆ from_clause

std::list<std::unique_ptr<TableRef> > Parser::QuerySpec::from_clause
private

Definition at line 1561 of file ParserNode.h.

◆ groupby_clause

std::list<std::unique_ptr<Expr> > Parser::QuerySpec::groupby_clause
private

Definition at line 1563 of file ParserNode.h.

◆ having_clause

std::unique_ptr<Expr> Parser::QuerySpec::having_clause
private

Definition at line 1564 of file ParserNode.h.

◆ is_distinct

bool Parser::QuerySpec::is_distinct
private

Definition at line 1559 of file ParserNode.h.

◆ select_clause

std::list<std::unique_ptr<SelectEntry> > Parser::QuerySpec::select_clause
private

Definition at line 1560 of file ParserNode.h.

◆ where_clause

std::unique_ptr<Expr> Parser::QuerySpec::where_clause
private

Definition at line 1562 of file ParserNode.h.


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