OmniSciDB  340b00dbf6
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 1683 of file ParserNode.h.

Constructor & Destructor Documentation

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 1685 of file ParserNode.h.

References CHECK, from_clause, groupby_clause, and select_clause.

1691  : is_distinct(d), where_clause(w), having_clause(h) {
1692  if (s) {
1693  for (const auto e : *s) {
1694  select_clause.emplace_back(e);
1695  }
1696  delete s;
1697  }
1698  CHECK(f);
1699  for (const auto e : *f) {
1700  from_clause.emplace_back(e);
1701  }
1702  delete f;
1703  if (g) {
1704  for (const auto e : *g) {
1705  groupby_clause.emplace_back(e);
1706  }
1707  delete g;
1708  }
1709  }
std::unique_ptr< Expr > where_clause
Definition: ParserNode.h:1730
std::list< std::unique_ptr< TableRef > > from_clause
Definition: ParserNode.h:1729
std::list< std::unique_ptr< SelectEntry > > select_clause
Definition: ParserNode.h:1728
std::list< std::unique_ptr< Expr > > groupby_clause
Definition: ParserNode.h:1731
#define CHECK(condition)
Definition: Logger.h:197
std::unique_ptr< Expr > having_clause
Definition: ParserNode.h:1732

Member Function Documentation

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

Implements Parser::QueryExpr.

Definition at line 1196 of file ParserNode.cpp.

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

1197  {
1199  analyze_from_clause(catalog, query);
1200  analyze_select_clause(catalog, query);
1201  analyze_where_clause(catalog, query);
1202  analyze_group_by(catalog, query);
1203  analyze_having_clause(catalog, query);
1204 }
void analyze_having_clause(const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const
void analyze_where_clause(const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const
void set_is_distinct(bool d)
Definition: Analyzer.h:1630
void analyze_select_clause(const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const
void analyze_from_clause(const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const
void analyze_group_by(const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query) const

+ Here is the call graph for this function:

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

Definition at line 1176 of file ParserNode.cpp.

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

1177  {
1179  for (auto& p : from_clause) {
1180  const TableDescriptor* table_desc;
1181  table_desc = catalog.getMetadataForTable(*p->get_table_name());
1182  if (table_desc == nullptr) {
1183  throw std::runtime_error("Table " + *p->get_table_name() + " does not exist.");
1184  }
1185  std::string range_var;
1186  if (p->get_range_var() == nullptr) {
1187  range_var = *p->get_table_name();
1188  } else {
1189  range_var = *p->get_range_var();
1190  }
1191  rte = new Analyzer::RangeTableEntry(range_var, table_desc, nullptr);
1192  query.add_rte(rte);
1193  }
1194 }
std::list< std::unique_ptr< TableRef > > from_clause
Definition: ParserNode.h:1729
void add_rte(RangeTableEntry *rte)
Definition: Analyzer.cpp:1347
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:

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

Definition at line 1039 of file ParserNode.cpp.

References Analyzer::Expr::add_cast(), SQLTypeInfo::get_compression(), Parser::IntLiteral::get_intval(), Analyzer::Query::get_num_aggs(), Analyzer::Query::get_targetlist(), Analyzer::Var::get_varno(), SQLTypeInfo::is_string(), kENCODING_DICT, kENCODING_NONE, Analyzer::Var::kGROUPBY, Analyzer::Var::kOUTPUT, SQLTypeInfo::set_comp_param(), SQLTypeInfo::set_compression(), SQLTypeInfo::set_fixed_size(), Analyzer::Query::set_group_by(), and TRANSIENT_DICT_ID.

1040  {
1041  std::list<std::shared_ptr<Analyzer::Expr>> groupby;
1042  if (!groupby_clause.empty()) {
1043  int gexpr_no = 1;
1044  std::shared_ptr<Analyzer::Expr> gexpr;
1045  const std::vector<std::shared_ptr<Analyzer::TargetEntry>>& tlist =
1046  query.get_targetlist();
1047  for (auto& c : groupby_clause) {
1048  // special-case ordinal numbers in GROUP BY
1049  if (dynamic_cast<Literal*>(c.get())) {
1050  IntLiteral* i = dynamic_cast<IntLiteral*>(c.get());
1051  if (!i) {
1052  throw std::runtime_error("Invalid literal in GROUP BY clause.");
1053  }
1054  int varno = (int)i->get_intval();
1055  if (varno <= 0 || varno > static_cast<int>(tlist.size())) {
1056  throw std::runtime_error("Invalid ordinal number in GROUP BY clause.");
1057  }
1058  if (tlist[varno - 1]->get_expr()->get_contains_agg()) {
1059  throw std::runtime_error(
1060  "Ordinal number in GROUP BY cannot reference an expression containing "
1061  "aggregate "
1062  "functions.");
1063  }
1064  gexpr = makeExpr<Analyzer::Var>(
1065  tlist[varno - 1]->get_expr()->get_type_info(), Analyzer::Var::kOUTPUT, varno);
1066  } else {
1067  gexpr = c->analyze(catalog, query, Expr::TlistRefType::TLIST_REF);
1068  }
1069  const SQLTypeInfo gti = gexpr->get_type_info();
1070  bool set_new_type = false;
1071  SQLTypeInfo ti(gti);
1072  if (gti.is_string() && gti.get_compression() == kENCODING_NONE) {
1073  set_new_type = true;
1074  ti.set_compression(kENCODING_DICT);
1075  ti.set_comp_param(TRANSIENT_DICT_ID);
1076  ti.set_fixed_size();
1077  }
1078  std::shared_ptr<Analyzer::Var> v;
1079  if (std::dynamic_pointer_cast<Analyzer::Var>(gexpr)) {
1080  v = std::static_pointer_cast<Analyzer::Var>(gexpr);
1081  int n = v->get_varno();
1082  gexpr = tlist[n - 1]->get_own_expr();
1083  auto cv = std::dynamic_pointer_cast<Analyzer::ColumnVar>(gexpr);
1084  if (cv != nullptr) {
1085  // inherit all ColumnVar info for lineage.
1086  *std::static_pointer_cast<Analyzer::ColumnVar>(v) = *cv;
1087  }
1088  v->set_which_row(Analyzer::Var::kGROUPBY);
1089  v->set_varno(gexpr_no);
1090  tlist[n - 1]->set_expr(v);
1091  }
1092  if (set_new_type) {
1093  auto new_e = gexpr->add_cast(ti);
1094  groupby.push_back(new_e);
1095  if (v != nullptr) {
1096  v->set_type_info(new_e->get_type_info());
1097  }
1098  } else {
1099  groupby.push_back(gexpr);
1100  }
1101  gexpr_no++;
1102  }
1103  }
1104  if (query.get_num_aggs() > 0 || !groupby.empty()) {
1105  for (auto t : query.get_targetlist()) {
1106  auto e = t->get_expr();
1107  e->check_group_by(groupby);
1108  }
1109  }
1110  query.set_group_by(groupby);
1111 }
int get_num_aggs() const
Definition: Analyzer.h:1609
int get_varno() const
Definition: Analyzer.h:275
void set_group_by(std::list< std::shared_ptr< Analyzer::Expr >> &g)
Definition: Analyzer.h:1632
std::list< std::unique_ptr< Expr > > groupby_clause
Definition: ParserNode.h:1731
#define TRANSIENT_DICT_ID
Definition: sqltypes.h:269
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:338
virtual std::shared_ptr< Analyzer::Expr > add_cast(const SQLTypeInfo &new_type_info)
Definition: Analyzer.cpp:687
bool is_string() const
Definition: sqltypes.h:487
const std::vector< std::shared_ptr< TargetEntry > > & get_targetlist() const
Definition: Analyzer.h:1610

+ Here is the call graph for this function:

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

Definition at line 1026 of file ParserNode.cpp.

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

1027  {
1028  std::shared_ptr<Analyzer::Expr> p;
1029  if (having_clause != nullptr) {
1030  p = having_clause->analyze(catalog, query, Expr::TlistRefType::TLIST_COPY);
1031  if (p->get_type_info().get_type() != kBOOLEAN) {
1032  throw std::runtime_error("Only boolean expressions can be in HAVING clause.");
1033  }
1034  p->check_group_by(query.get_group_by());
1035  }
1036  query.set_having_predicate(p);
1037 }
void set_having_predicate(std::shared_ptr< Analyzer::Expr > p)
Definition: Analyzer.h:1633
const std::list< std::shared_ptr< Analyzer::Expr > > & get_group_by() const
Definition: Analyzer.h:1618
std::unique_ptr< Expr > having_clause
Definition: ParserNode.h:1732

+ Here is the call graph for this function:

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

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

1127  {
1128  std::vector<std::shared_ptr<Analyzer::TargetEntry>>& tlist =
1129  query.get_targetlist_nonconst();
1130  if (select_clause.empty()) {
1131  // this means SELECT *
1132  int rte_idx = 0;
1133  for (auto rte : query.get_rangetable()) {
1134  rte->expand_star_in_targetlist(catalog, tlist, rte_idx++);
1135  }
1136  } else {
1137  for (auto& p : select_clause) {
1138  const Parser::Expr* select_expr = p->get_select_expr();
1139  // look for the case of range_var.*
1140  if (typeid(*select_expr) == typeid(ColumnRef) &&
1141  dynamic_cast<const ColumnRef*>(select_expr)->get_column() == nullptr) {
1142  const std::string* range_var_name =
1143  dynamic_cast<const ColumnRef*>(select_expr)->get_table();
1144  int rte_idx = query.get_rte_idx(*range_var_name);
1145  if (rte_idx < 0) {
1146  throw std::runtime_error("invalid range variable name: " + *range_var_name);
1147  }
1148  Analyzer::RangeTableEntry* rte = query.get_rte(rte_idx);
1149  rte->expand_star_in_targetlist(catalog, tlist, rte_idx);
1150  } else {
1151  auto e = select_expr->analyze(catalog, query);
1152  std::string resname;
1153 
1154  if (p->get_alias() != nullptr) {
1155  resname = *p->get_alias();
1156  } else if (std::dynamic_pointer_cast<Analyzer::ColumnVar>(e) &&
1157  !std::dynamic_pointer_cast<Analyzer::Var>(e)) {
1158  auto colvar = std::static_pointer_cast<Analyzer::ColumnVar>(e);
1159  const ColumnDescriptor* col_desc = catalog.getMetadataForColumn(
1160  colvar->get_table_id(), colvar->get_column_id());
1161  resname = col_desc->columnName;
1162  }
1163  if (e->get_type_info().get_type() == kNULLT) {
1164  throw std::runtime_error(
1165  "Untyped NULL in SELECT clause. Use CAST to specify a type.");
1166  }
1167  auto o = std::static_pointer_cast<Analyzer::UOper>(e);
1168  bool unnest = (o != nullptr && o->get_optype() == kUNNEST);
1169  auto tle = std::make_shared<Analyzer::TargetEntry>(resname, e, unnest);
1170  tlist.push_back(tle);
1171  }
1172  }
1173  }
1174 }
void expand_star_in_targetlist(const Catalog_Namespace::Catalog &catalog, std::vector< std::shared_ptr< TargetEntry >> &tlist, int rte_idx)
int get_rte_idx(const std::string &range_var_name) const
Definition: Analyzer.cpp:1336
std::list< std::unique_ptr< SelectEntry > > select_clause
Definition: ParserNode.h:1728
RangeTableEntry * get_rte(int rte_idx) const
Definition: Analyzer.h:1640
const ColumnDescriptor * getMetadataForColumn(int tableId, const std::string &colName) const
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:1613
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
const std::vector< RangeTableEntry * > & get_rangetable() const
Definition: Analyzer.h:1616

+ Here is the call graph for this function:

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

Definition at line 1113 of file ParserNode.cpp.

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

1114  {
1115  if (where_clause == nullptr) {
1116  query.set_where_predicate(nullptr);
1117  return;
1118  }
1119  auto p = where_clause->analyze(catalog, query, Expr::TlistRefType::TLIST_COPY);
1120  if (p->get_type_info().get_type() != kBOOLEAN) {
1121  throw std::runtime_error("Only boolean expressions can be in WHERE clause.");
1122  }
1123  query.set_where_predicate(p);
1124 }
std::unique_ptr< Expr > where_clause
Definition: ParserNode.h:1730
void set_where_predicate(std::shared_ptr< Analyzer::Expr > p)
Definition: Analyzer.h:1631

+ Here is the call graph for this function:

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

Definition at line 1714 of file ParserNode.h.

References from_clause.

1714  {
1715  return from_clause;
1716  }
std::list< std::unique_ptr< TableRef > > from_clause
Definition: ParserNode.h:1729
const std::list<std::unique_ptr<Expr> >& Parser::QuerySpec::get_groupby_clause ( ) const
inline

Definition at line 1718 of file ParserNode.h.

References groupby_clause.

1718  {
1719  return groupby_clause;
1720  }
std::list< std::unique_ptr< Expr > > groupby_clause
Definition: ParserNode.h:1731
const Expr* Parser::QuerySpec::get_having_clause ( ) const
inline

Definition at line 1721 of file ParserNode.h.

References having_clause.

1721 { return having_clause.get(); }
std::unique_ptr< Expr > having_clause
Definition: ParserNode.h:1732
bool Parser::QuerySpec::get_is_distinct ( ) const
inline

Definition at line 1710 of file ParserNode.h.

References is_distinct.

1710 { return is_distinct; }
const std::list<std::unique_ptr<SelectEntry> >& Parser::QuerySpec::get_select_clause ( ) const
inline

Definition at line 1711 of file ParserNode.h.

References select_clause.

1711  {
1712  return select_clause;
1713  }
std::list< std::unique_ptr< SelectEntry > > select_clause
Definition: ParserNode.h:1728
const Expr* Parser::QuerySpec::get_where_clause ( ) const
inline

Definition at line 1717 of file ParserNode.h.

References where_clause.

1717 { return where_clause.get(); }
std::unique_ptr< Expr > where_clause
Definition: ParserNode.h:1730
std::string Parser::QuerySpec::to_string ( ) const

Definition at line 1439 of file ParserNode.cpp.

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

1439  {
1440  std::string query_str = "SELECT ";
1441  if (is_distinct) {
1442  query_str += "DISTINCT ";
1443  }
1444  if (select_clause.empty()) {
1445  query_str += "* ";
1446  } else {
1447  bool notfirst = false;
1448  for (auto& p : select_clause) {
1449  if (notfirst) {
1450  query_str += ", ";
1451  } else {
1452  notfirst = true;
1453  }
1454  query_str += p->to_string();
1455  }
1456  }
1457  query_str += " FROM ";
1458  bool notfirst = false;
1459  for (auto& p : from_clause) {
1460  if (notfirst) {
1461  query_str += ", ";
1462  } else {
1463  notfirst = true;
1464  }
1465  query_str += p->to_string();
1466  }
1467  if (where_clause) {
1468  query_str += " WHERE " + where_clause->to_string();
1469  }
1470  if (!groupby_clause.empty()) {
1471  query_str += " GROUP BY ";
1472  bool notfirst = false;
1473  for (auto& p : groupby_clause) {
1474  if (notfirst) {
1475  query_str += ", ";
1476  } else {
1477  notfirst = true;
1478  }
1479  query_str += p->to_string();
1480  }
1481  }
1482  if (having_clause) {
1483  query_str += " HAVING " + having_clause->to_string();
1484  }
1485  query_str += ";";
1486  return query_str;
1487 }
std::unique_ptr< Expr > where_clause
Definition: ParserNode.h:1730
std::list< std::unique_ptr< TableRef > > from_clause
Definition: ParserNode.h:1729
std::list< std::unique_ptr< SelectEntry > > select_clause
Definition: ParserNode.h:1728
std::list< std::unique_ptr< Expr > > groupby_clause
Definition: ParserNode.h:1731
std::unique_ptr< Expr > having_clause
Definition: ParserNode.h:1732

+ Here is the call graph for this function:

Member Data Documentation

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

Definition at line 1729 of file ParserNode.h.

Referenced by get_from_clause(), and QuerySpec().

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

Definition at line 1731 of file ParserNode.h.

Referenced by get_groupby_clause(), and QuerySpec().

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

Definition at line 1732 of file ParserNode.h.

Referenced by get_having_clause().

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

Definition at line 1728 of file ParserNode.h.

Referenced by get_select_clause(), and QuerySpec().

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

Definition at line 1730 of file ParserNode.h.

Referenced by get_where_clause().


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