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

#include <Planner.h>

+ Collaboration diagram for Planner::Optimizer:

Public Member Functions

 Optimizer (const Analyzer::Query &q, const Catalog_Namespace::Catalog &c)
 
RootPlanoptimize ()
 

Private Member Functions

Planoptimize_query ()
 
void optimize_current_query ()
 
void optimize_scans ()
 
void optimize_aggs ()
 
void optimize_orderby ()
 
void process_targetlist ()
 

Private Attributes

std::vector< Scan * > base_scans
 
std::list< const Analyzer::Expr * > join_predicates
 
std::list< const Analyzer::Expr * > const_predicates
 
const Analyzer::Querycur_query
 
Plancur_plan
 
const Analyzer::Queryquery
 
const Catalog_Namespace::Catalogcatalog
 

Detailed Description

Definition at line 322 of file Planner.h.

Constructor & Destructor Documentation

Planner::Optimizer::Optimizer ( const Analyzer::Query q,
const Catalog_Namespace::Catalog c 
)
inline

Definition at line 324 of file Planner.h.

325  : cur_query(nullptr), cur_plan(nullptr), query(q), catalog(c) {}
const Analyzer::Query & query
Definition: Planner.h:351
const Analyzer::Query * cur_query
Definition: Planner.h:349
const Catalog_Namespace::Catalog & catalog
Definition: Planner.h:352

Member Function Documentation

RootPlan * Planner::Optimizer::optimize ( )

Definition at line 43 of file Planner.cpp.

References catalog, Analyzer::Query::get_limit(), Analyzer::Query::get_offset(), Analyzer::Query::get_result_col_list(), Analyzer::Query::get_result_table_id(), Analyzer::Query::get_stmt_type(), kDELETE, kINSERT, kSELECT, kUPDATE, optimize_query(), query, and UNREACHABLE.

Referenced by MapDHandler::parse_to_plan_legacy(), QueryRunner::QueryRunner::parsePlanLegacy(), and MapDHandler::sql_execute_impl().

43  {
44  Plan* plan;
45  SQLStmtType stmt_type = query.get_stmt_type();
46  int result_table_id = 0;
47  std::list<int> result_col_list;
48  switch (stmt_type) {
49  case kSELECT:
50  // nothing to do for SELECT for now
51  break;
52  case kINSERT:
53  result_table_id = query.get_result_table_id();
54  result_col_list = query.get_result_col_list();
55  break;
56  case kUPDATE:
57  case kDELETE:
58  // should have been rejected by the Analyzer for now
59  UNREACHABLE();
60  break;
61  default:
62  UNREACHABLE();
63  }
64  plan = optimize_query();
65  return new RootPlan(plan,
66  stmt_type,
67  result_table_id,
68  result_col_list,
69  catalog,
70  query.get_limit(),
71  query.get_offset());
72 }
const Analyzer::Query & query
Definition: Planner.h:351
#define UNREACHABLE()
Definition: Logger.h:234
int64_t get_offset() const
Definition: Analyzer.h:1561
int64_t get_limit() const
Definition: Analyzer.h:1559
Plan * optimize_query()
Definition: Planner.cpp:74
int get_result_table_id() const
Definition: Analyzer.h:1542
SQLStmtType
Definition: sqldefs.h:92
const Catalog_Namespace::Catalog & catalog
Definition: Planner.h:352
SQLStmtType get_stmt_type() const
Definition: Analyzer.h:1540
const std::list< int > & get_result_col_list() const
Definition: Analyzer.h:1543

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Planner::Optimizer::optimize_aggs ( )
private

Definition at line 215 of file Planner.cpp.

References Analyzer::ColumnVar::colvar_comp(), const_predicates, cur_plan, cur_query, Analyzer::Expr::find_expr(), Analyzer::Query::get_group_by(), Analyzer::Query::get_having_predicate(), Planner::anonymous_namespace{Planner.cpp}::get_join_target_list(), Planner::Plan::get_targetlist(), Analyzer::Query::get_targetlist(), Analyzer::Expr::group_predicates(), anonymous_namespace{RelAlgExecutor.cpp}::is_agg(), Analyzer::Var::kGROUPBY, and process_targetlist().

Referenced by optimize_current_query().

215  {
216  std::vector<std::shared_ptr<Analyzer::TargetEntry>> agg_tlist;
217  const Analyzer::Expr* having_pred = cur_query->get_having_predicate();
218  bool (*fn_pt)(const Analyzer::ColumnVar*, const Analyzer::ColumnVar*) =
220  std::set<const Analyzer::ColumnVar*,
221  bool (*)(const Analyzer::ColumnVar*, const Analyzer::ColumnVar*)>
222  colvar_set(fn_pt);
223  auto is_agg = [](const Analyzer::Expr* e) -> bool {
224  return typeid(*e) == typeid(Analyzer::AggExpr);
225  };
226  std::list<const Analyzer::Expr*> aggexpr_list;
227  // need to determine if the final targetlist involves expressions over
228  // the group by columns and/or aggregates, e.g., sum(x) + sum(y).
229  // see no_expression to false if an expression is found.
230  bool no_expression = true;
231  for (auto tle : cur_query->get_targetlist()) {
232  // collect all the aggregate functions from targetlist
233  tle->get_expr()->find_expr(is_agg, aggexpr_list);
234  if (!dynamic_cast<Analyzer::ColumnVar*>(tle->get_expr()) &&
235  !dynamic_cast<Analyzer::Var*>(tle->get_expr()) &&
236  !dynamic_cast<Analyzer::AggExpr*>(tle->get_expr())) {
237  no_expression = false;
238  }
239  }
240  // collect all the group by columns in having clause
241  if (having_pred != nullptr) {
242  having_pred->find_expr(is_agg, aggexpr_list);
243  }
244 
245  std::list<std::shared_ptr<Analyzer::Expr>> groupby_list;
246  auto target_list = cur_plan->get_targetlist();
247  if (dynamic_cast<const Planner::Join*>(cur_plan)) {
248  target_list = get_join_target_list(static_cast<const Planner::Join*>(cur_plan));
249  }
250  if (!cur_query->get_group_by().empty()) {
251  for (auto e : cur_query->get_group_by()) {
252  groupby_list.push_back(e->rewrite_with_child_targetlist(target_list));
253  }
254  }
255 
256  // form the AggPlan targetlist with the group by columns followed by aggregates
257  int varno = 1;
258  for (auto e : groupby_list) {
259  std::shared_ptr<Analyzer::TargetEntry> new_tle;
260  std::shared_ptr<Analyzer::Expr> expr;
261  auto c = std::dynamic_pointer_cast<Analyzer::ColumnVar>(e);
262  if (c != nullptr) {
263  expr = makeExpr<Analyzer::Var>(c->get_type_info(),
264  c->get_table_id(),
265  c->get_column_id(),
266  c->get_rte_idx(),
268  varno);
269  } else {
270  expr = makeExpr<Analyzer::Var>(e->get_type_info(), Analyzer::Var::kGROUPBY, varno);
271  }
272  new_tle = std::make_shared<Analyzer::TargetEntry>("", expr, false);
273  agg_tlist.push_back(new_tle);
274  varno++;
275  }
276  for (auto e : aggexpr_list) {
277  std::shared_ptr<Analyzer::TargetEntry> new_tle;
278  new_tle = std::make_shared<Analyzer::TargetEntry>(
279  "", e->rewrite_with_child_targetlist(target_list), false);
280  agg_tlist.push_back(new_tle);
281  }
282 
283  std::list<std::shared_ptr<Analyzer::Expr>> having_quals;
284  if (having_pred != nullptr) {
285  std::list<const Analyzer::Expr*> preds;
286  having_pred->group_predicates(preds, preds, preds);
287  for (auto p : preds) {
288  having_quals.push_back(p->rewrite_agg_to_var(agg_tlist));
289  }
290  }
291 
292  cur_plan = new AggPlan(agg_tlist, 0.0, cur_plan, groupby_list);
293  if (no_expression && having_pred == nullptr) {
294  // in this case, no need to add a Result node on top
296  } else {
297  std::vector<std::shared_ptr<Analyzer::TargetEntry>> result_tlist;
298  for (auto tle : cur_query->get_targetlist()) {
299  result_tlist.emplace_back(
300  new Analyzer::TargetEntry(tle->get_resname(),
301  tle->get_expr()->rewrite_agg_to_var(agg_tlist),
302  tle->get_unnest()));
303  }
304  std::list<std::shared_ptr<Analyzer::Expr>> const_quals;
305  for (auto p : const_predicates) {
306  const_quals.push_back(p->deep_copy());
307  }
308  cur_plan = new Result(result_tlist, having_quals, 0.0, cur_plan, const_quals);
309  }
310 }
bool is_agg(const Analyzer::Expr *expr)
Definition: Analyzer.h:1483
static bool colvar_comp(const ColumnVar *l, const ColumnVar *r)
Definition: Analyzer.h:208
void process_targetlist()
Definition: Planner.cpp:330
const Analyzer::Query * cur_query
Definition: Planner.h:349
std::vector< std::shared_ptr< Analyzer::TargetEntry > > get_join_target_list(const Planner::Join *join_plan)
Definition: Planner.cpp:200
const std::vector< std::shared_ptr< Analyzer::TargetEntry > > & get_targetlist() const
Definition: Planner.h:52
virtual void find_expr(bool(*f)(const Expr *), std::list< const Expr * > &expr_list) const
Definition: Analyzer.h:159
const Expr * get_having_predicate() const
Definition: Analyzer.h:1537
virtual void group_predicates(std::list< const Expr * > &scan_predicates, std::list< const Expr * > &join_predicates, std::list< const Expr * > &const_predicates) const
Definition: Analyzer.h:102
const std::list< std::shared_ptr< Analyzer::Expr > > & get_group_by() const
Definition: Analyzer.h:1534
const std::vector< std::shared_ptr< TargetEntry > > & get_targetlist() const
Definition: Analyzer.h:1526
std::list< const Analyzer::Expr * > const_predicates
Definition: Planner.h:348

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Planner::Optimizer::optimize_current_query ( )
private

Definition at line 109 of file Planner.cpp.

References const_predicates, cur_plan, cur_query, Analyzer::Query::get_group_by(), Analyzer::Query::get_having_predicate(), Analyzer::Query::get_num_aggs(), Analyzer::Query::get_targetlist(), Analyzer::Var::kINPUT_OUTER, optimize_aggs(), and process_targetlist().

Referenced by optimize_query().

109  {
110  if (cur_query->get_num_aggs() > 0 || cur_query->get_having_predicate() != nullptr ||
111  !cur_query->get_group_by().empty()) {
112  optimize_aggs();
113  } else {
115  if (!const_predicates.empty()) {
116  // add result node to evaluate constant predicates
117  std::vector<std::shared_ptr<Analyzer::TargetEntry>> tlist;
118  int i = 1;
119  for (auto tle : cur_query->get_targetlist()) {
120  tlist.emplace_back(new Analyzer::TargetEntry(
121  tle->get_resname(),
122  makeExpr<Analyzer::Var>(
123  tle->get_expr()->get_type_info(), Analyzer::Var::kINPUT_OUTER, i++),
124  false));
125  }
126  std::list<std::shared_ptr<Analyzer::Expr>> const_quals;
127  for (auto p : const_predicates) {
128  const_quals.push_back(p->deep_copy());
129  }
130  cur_plan = new Result(tlist, {}, 0.0, cur_plan, const_quals);
131  }
132  }
133 }
Definition: Analyzer.h:1483
void process_targetlist()
Definition: Planner.cpp:330
const Analyzer::Query * cur_query
Definition: Planner.h:349
int get_num_aggs() const
Definition: Analyzer.h:1525
void optimize_aggs()
Definition: Planner.cpp:215
const Expr * get_having_predicate() const
Definition: Analyzer.h:1537
const std::list< std::shared_ptr< Analyzer::Expr > > & get_group_by() const
Definition: Analyzer.h:1534
const std::vector< std::shared_ptr< TargetEntry > > & get_targetlist() const
Definition: Analyzer.h:1526
std::list< const Analyzer::Expr * > const_predicates
Definition: Planner.h:348

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Planner::Optimizer::optimize_orderby ( )
private

Definition at line 312 of file Planner.cpp.

References cur_plan, Analyzer::Query::get_is_distinct(), Analyzer::Query::get_order_by(), Planner::Plan::get_targetlist(), Analyzer::Var::kINPUT_OUTER, and query.

Referenced by optimize_query().

312  {
313  if (query.get_order_by() == nullptr) {
314  return;
315  }
316  std::vector<std::shared_ptr<Analyzer::TargetEntry>> tlist;
317  int varno = 1;
318  for (auto tle : cur_plan->get_targetlist()) {
319  tlist.emplace_back(new Analyzer::TargetEntry(
320  tle->get_resname(),
321  makeExpr<Analyzer::Var>(
322  tle->get_expr()->get_type_info(), Analyzer::Var::kINPUT_OUTER, varno),
323  false));
324  varno++;
325  }
326  cur_plan =
327  new Sort(tlist, 0.0, cur_plan, *query.get_order_by(), query.get_is_distinct());
328 }
const Analyzer::Query & query
Definition: Planner.h:351
Definition: Analyzer.h:1483
const std::list< OrderEntry > * get_order_by() const
Definition: Analyzer.h:1538
const std::vector< std::shared_ptr< Analyzer::TargetEntry > > & get_targetlist() const
Definition: Planner.h:52
bool get_is_distinct() const
Definition: Analyzer.h:1524

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Plan * Planner::Optimizer::optimize_query ( )
private

Definition at line 74 of file Planner.cpp.

References base_scans, cur_plan, cur_query, Analyzer::Query::get_next_query(), Analyzer::Query::get_order_by(), Planner::Plan::get_targetlist(), join_predicates, optimize_current_query(), optimize_orderby(), optimize_scans(), and query.

Referenced by optimize().

74  {
75  //@TODO add support for union queries
76  if (query.get_next_query() != nullptr) {
77  throw std::runtime_error("UNION queries are not supported yet.");
78  }
79  cur_query = &query;
81  cur_plan = nullptr;
82  if (base_scans.size() > 2) {
83  throw std::runtime_error("More than two tables in a join not supported yet.");
84  }
85  for (auto base_scan : base_scans) {
86  if (cur_plan) {
87  std::list<std::shared_ptr<Analyzer::Expr>> shared_join_predicates;
88  for (auto join_pred : join_predicates) {
89  shared_join_predicates.emplace_back(join_pred->deep_copy());
90  }
91  std::vector<std::shared_ptr<Analyzer::TargetEntry>> join_targetlist;
92  for (const auto tle : cur_plan->get_targetlist()) {
93  join_targetlist.emplace_back(new Analyzer::TargetEntry(
94  tle->get_resname(), tle->get_expr()->deep_copy(), tle->get_unnest()));
95  }
96  cur_plan =
97  new Join(join_targetlist, shared_join_predicates, 0, cur_plan, base_scan);
98  } else {
99  cur_plan = base_scan;
100  }
101  }
103  if (query.get_order_by() != nullptr) {
105  }
106  return cur_plan;
107 }
const Analyzer::Query & query
Definition: Planner.h:351
Definition: Analyzer.h:1483
const std::list< OrderEntry > * get_order_by() const
Definition: Analyzer.h:1538
const Analyzer::Query * cur_query
Definition: Planner.h:349
void optimize_scans()
Definition: Planner.cpp:135
const Query * get_next_query() const
Definition: Analyzer.h:1539
const std::vector< std::shared_ptr< Analyzer::TargetEntry > > & get_targetlist() const
Definition: Planner.h:52
std::list< const Analyzer::Expr * > join_predicates
Definition: Planner.h:347
void optimize_orderby()
Definition: Planner.cpp:312
void optimize_current_query()
Definition: Planner.cpp:109
std::vector< Scan * > base_scans
Definition: Planner.h:346

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Planner::Optimizer::optimize_scans ( )
private

Definition at line 135 of file Planner.cpp.

References base_scans, Analyzer::Expr::collect_column_var(), Analyzer::ColumnVar::collect_column_var(), Analyzer::ColumnVar::colvar_comp(), const_predicates, cur_query, Analyzer::Query::get_group_by(), Analyzer::Query::get_having_predicate(), Analyzer::Query::get_rangetable(), Analyzer::Query::get_targetlist(), Analyzer::Query::get_where_predicate(), Analyzer::Expr::group_predicates(), and join_predicates.

Referenced by optimize_query().

135  {
136  const std::vector<Analyzer::RangeTableEntry*>& rt = cur_query->get_rangetable();
137  for (auto rte : rt) {
138  base_scans.push_back(new Scan(*rte));
139  }
140  const Analyzer::Expr* where_pred = cur_query->get_where_predicate();
141  std::list<const Analyzer::Expr*> scan_predicates;
142  if (where_pred != nullptr) {
143  where_pred->group_predicates(scan_predicates, join_predicates, const_predicates);
144  }
145  for (auto p : scan_predicates) {
146  int rte_idx;
147  auto simple_pred = p->normalize_simple_predicate(rte_idx);
148  if (simple_pred != nullptr) {
149  base_scans[rte_idx]->add_simple_predicate(simple_pred);
150  } else {
151  std::set<int> rte_idx_set;
152  p->collect_rte_idx(rte_idx_set);
153  for (auto x : rte_idx_set) {
154  rte_idx = x;
155  break; // grab rte_idx out of the singleton set
156  }
157  base_scans[rte_idx]->add_predicate(p->deep_copy());
158  }
159  }
160  const std::vector<std::shared_ptr<Analyzer::TargetEntry>>& tlist =
162  bool (*fn_pt)(const Analyzer::ColumnVar*, const Analyzer::ColumnVar*) =
164  std::set<const Analyzer::ColumnVar*,
165  bool (*)(const Analyzer::ColumnVar*, const Analyzer::ColumnVar*)>
166  colvar_set(fn_pt);
167  for (auto tle : tlist) {
168  tle->get_expr()->collect_column_var(colvar_set, true);
169  }
170  for (auto p : join_predicates) {
171  p->collect_column_var(colvar_set, true);
172  }
173  const auto group_by = cur_query->get_group_by();
174  if (!group_by.empty()) {
175  for (auto e : group_by) {
176  e->collect_column_var(colvar_set, true);
177  }
178  }
179  const Analyzer::Expr* having_pred = cur_query->get_having_predicate();
180  if (having_pred != nullptr) {
181  having_pred->collect_column_var(colvar_set, true);
182  }
183  for (auto colvar : colvar_set) {
184  if (dynamic_cast<const Analyzer::Var*>(colvar) == nullptr) {
185  // only run omptimizations on true ColumnVars. Skip over Var exprs.
186  auto tle = std::make_shared<Analyzer::TargetEntry>("", colvar->deep_copy(), false);
187  base_scans[colvar->get_rte_idx()]->add_tle(tle);
188  }
189  };
190 }
static bool colvar_comp(const ColumnVar *l, const ColumnVar *r)
Definition: Analyzer.h:208
void collect_column_var(std::set< const ColumnVar *, bool(*)(const ColumnVar *, const ColumnVar *)> &colvar_set, bool include_agg) const override
Definition: Analyzer.h:213
const Analyzer::Query * cur_query
Definition: Planner.h:349
const Expr * get_where_predicate() const
Definition: Analyzer.h:1533
virtual void collect_column_var(std::set< const ColumnVar *, bool(*)(const ColumnVar *, const ColumnVar *)> &colvar_set, bool include_agg) const
Definition: Analyzer.h:116
std::list< const Analyzer::Expr * > join_predicates
Definition: Planner.h:347
const Expr * get_having_predicate() const
Definition: Analyzer.h:1537
virtual void group_predicates(std::list< const Expr * > &scan_predicates, std::list< const Expr * > &join_predicates, std::list< const Expr * > &const_predicates) const
Definition: Analyzer.h:102
const std::list< std::shared_ptr< Analyzer::Expr > > & get_group_by() const
Definition: Analyzer.h:1534
const std::vector< std::shared_ptr< TargetEntry > > & get_targetlist() const
Definition: Analyzer.h:1526
std::list< const Analyzer::Expr * > const_predicates
Definition: Planner.h:348
const std::vector< RangeTableEntry * > & get_rangetable() const
Definition: Analyzer.h:1532
std::vector< Scan * > base_scans
Definition: Planner.h:346

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Planner::Optimizer::process_targetlist ( )
private

Definition at line 330 of file Planner.cpp.

References cur_plan, Planner::anonymous_namespace{Planner.cpp}::get_join_target_list(), Planner::Plan::get_targetlist(), Analyzer::Query::get_targetlist(), query, and Planner::Plan::set_targetlist().

Referenced by optimize_aggs(), and optimize_current_query().

330  {
331  std::vector<std::shared_ptr<Analyzer::TargetEntry>> final_tlist;
332  for (auto tle : query.get_targetlist()) {
333  std::shared_ptr<Analyzer::TargetEntry> new_tle;
334  if (cur_plan == nullptr) {
335  new_tle = std::make_shared<Analyzer::TargetEntry>(
336  tle->get_resname(), tle->get_expr()->deep_copy(), tle->get_unnest());
337  } else {
338  auto target_list = cur_plan->get_targetlist();
339  if (dynamic_cast<const Planner::Join*>(cur_plan)) {
340  target_list = get_join_target_list(static_cast<const Planner::Join*>(cur_plan));
341  }
342  new_tle = std::make_shared<Analyzer::TargetEntry>(
343  tle->get_resname(),
344  tle->get_expr()->rewrite_with_targetlist(target_list),
345  tle->get_unnest());
346  }
347  final_tlist.push_back(new_tle);
348  }
349  if (cur_plan == nullptr) {
350  cur_plan = new ValuesScan(final_tlist);
351  } else {
352  cur_plan->set_targetlist(final_tlist);
353  }
354 }
const Analyzer::Query & query
Definition: Planner.h:351
std::vector< std::shared_ptr< Analyzer::TargetEntry > > get_join_target_list(const Planner::Join *join_plan)
Definition: Planner.cpp:200
const std::vector< std::shared_ptr< Analyzer::TargetEntry > > & get_targetlist() const
Definition: Planner.h:52
void set_targetlist(const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &t)
Definition: Planner.h:59
const std::vector< std::shared_ptr< TargetEntry > > & get_targetlist() const
Definition: Analyzer.h:1526

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

std::vector<Scan*> Planner::Optimizer::base_scans
private

Definition at line 346 of file Planner.h.

Referenced by optimize_query(), and optimize_scans().

const Catalog_Namespace::Catalog& Planner::Optimizer::catalog
private

Definition at line 352 of file Planner.h.

Referenced by optimize().

std::list<const Analyzer::Expr*> Planner::Optimizer::const_predicates
private

Definition at line 348 of file Planner.h.

Referenced by optimize_aggs(), optimize_current_query(), and optimize_scans().

Plan* Planner::Optimizer::cur_plan
private
const Analyzer::Query* Planner::Optimizer::cur_query
private

Definition at line 349 of file Planner.h.

Referenced by optimize_aggs(), optimize_current_query(), optimize_query(), and optimize_scans().

std::list<const Analyzer::Expr*> Planner::Optimizer::join_predicates
private

Definition at line 347 of file Planner.h.

Referenced by optimize_query(), and optimize_scans().

const Analyzer::Query& Planner::Optimizer::query
private

Definition at line 351 of file Planner.h.

Referenced by optimize(), optimize_orderby(), optimize_query(), and process_targetlist().


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