OmniSciDB  06b3bd477c
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
QueryRewriter Class Reference

#include <QueryRewrite.h>

+ Collaboration diagram for QueryRewriter:

Public Member Functions

 QueryRewriter (const std::vector< InputTableInfo > &query_infos, Executor *executor)
 
RelAlgExecutionUnit rewrite (const RelAlgExecutionUnit &ra_exe_unit_in) const
 
RelAlgExecutionUnit rewriteColumnarUpdate (const RelAlgExecutionUnit &ra_exe_unit_in, std::shared_ptr< Analyzer::Expr > column_to_update) const
 
RelAlgExecutionUnit rewriteColumnarDelete (const RelAlgExecutionUnit &ra_exe_unit_in, std::shared_ptr< Analyzer::ColumnVar > delete_column) const
 

Private Member Functions

RelAlgExecutionUnit rewriteOverlapsJoin (const RelAlgExecutionUnit &ra_exe_unit_in) const
 
RelAlgExecutionUnit rewriteConstrainedByIn (const RelAlgExecutionUnit &ra_exe_unit_in) const
 
RelAlgExecutionUnit rewriteConstrainedByInImpl (const RelAlgExecutionUnit &ra_exe_unit_in, const std::shared_ptr< Analyzer::CaseExpr >, const Analyzer::InValues *) const
 

Static Private Member Functions

static std::shared_ptr
< Analyzer::CaseExpr
generateCaseForDomainValues (const Analyzer::InValues *)
 

Private Attributes

const std::vector
< InputTableInfo > & 
query_infos_
 
Executorexecutor_
 
std::vector< std::shared_ptr
< Analyzer::Expr > > 
target_exprs_owned_
 

Detailed Description

Definition at line 21 of file QueryRewrite.h.

Constructor & Destructor Documentation

QueryRewriter::QueryRewriter ( const std::vector< InputTableInfo > &  query_infos,
Executor executor 
)
inline

Definition at line 23 of file QueryRewrite.h.

24  : query_infos_(query_infos), executor_(executor) {}
Executor * executor_
Definition: QueryRewrite.h:51
const std::vector< InputTableInfo > & query_infos_
Definition: QueryRewrite.h:50

Member Function Documentation

std::shared_ptr< Analyzer::CaseExpr > QueryRewriter::generateCaseForDomainValues ( const Analyzer::InValues in_vals)
staticprivate

Definition at line 174 of file QueryRewrite.cpp.

References Analyzer::Expr::deep_copy(), Analyzer::InValues::get_arg(), Analyzer::InValues::get_value_list(), kBOOLEAN, kENCODING_DICT, kEQ, and kONE.

Referenced by rewriteConstrainedByIn().

175  {
176  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
177  case_expr_list;
178  auto in_val_arg = in_vals->get_arg()->deep_copy();
179  for (const auto& in_val : in_vals->get_value_list()) {
180  auto case_cond = makeExpr<Analyzer::BinOper>(
181  SQLTypeInfo(kBOOLEAN, true), false, kEQ, kONE, in_val_arg, in_val);
182  auto in_val_copy = in_val->deep_copy();
183  auto ti = in_val_copy->get_type_info();
184  if (ti.is_string() && ti.get_compression() == kENCODING_DICT) {
185  ti.set_comp_param(0);
186  }
187  in_val_copy->set_type_info(ti);
188  case_expr_list.emplace_back(case_cond, in_val_copy);
189  }
190  // TODO(alex): refine the expression range for case with empty else expression;
191  // for now, add a dummy else which should never be taken
192  auto else_expr = case_expr_list.front().second;
193  return makeExpr<Analyzer::CaseExpr>(
194  case_expr_list.front().second->get_type_info(), false, case_expr_list, else_expr);
195 }
Definition: sqldefs.h:30
Definition: sqldefs.h:69
const std::list< std::shared_ptr< Analyzer::Expr > > & get_value_list() const
Definition: Analyzer.h:587
virtual std::shared_ptr< Analyzer::Expr > deep_copy() const =0
const Expr * get_arg() const
Definition: Analyzer.h:585

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

RelAlgExecutionUnit QueryRewriter::rewrite ( const RelAlgExecutionUnit ra_exe_unit_in) const

Definition at line 28 of file QueryRewrite.cpp.

References rewriteConstrainedByIn(), and rewriteOverlapsJoin().

Referenced by rewriteConstrainedByInImpl().

29  {
30  auto rewritten_exe_unit = rewriteConstrainedByIn(ra_exe_unit_in);
31  return rewriteOverlapsJoin(rewritten_exe_unit);
32 }
RelAlgExecutionUnit rewriteOverlapsJoin(const RelAlgExecutionUnit &ra_exe_unit_in) const
RelAlgExecutionUnit rewriteConstrainedByIn(const RelAlgExecutionUnit &ra_exe_unit_in) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

RelAlgExecutionUnit QueryRewriter::rewriteColumnarDelete ( const RelAlgExecutionUnit ra_exe_unit_in,
std::shared_ptr< Analyzer::ColumnVar delete_column 
) const

Definition at line 380 of file QueryRewrite.cpp.

References Datum::boolval, CHECK(), CHECK_EQ, RelAlgExecutionUnit::estimator, RelAlgExecutionUnit::groupby_exprs, RelAlgExecutionUnit::input_col_descs, RelAlgExecutionUnit::input_descs, RelAlgExecutionUnit::join_quals, kAND, kONE, Parser::CaseExpr::normalize(), RelAlgExecutionUnit::quals, RelAlgExecutionUnit::query_state, RelAlgExecutionUnit::scan_limit, RelAlgExecutionUnit::simple_quals, RelAlgExecutionUnit::sort_info, RelAlgExecutionUnit::target_exprs, target_exprs_owned_, RelAlgExecutionUnit::union_all, and RelAlgExecutionUnit::use_bump_allocator.

382  {
383  CHECK_EQ(ra_exe_unit_in.target_exprs.size(), size_t(1));
384  CHECK(ra_exe_unit_in.groupby_exprs.size() == 1 &&
385  !ra_exe_unit_in.groupby_exprs.front());
386 
387  // TODO(adb): is this possible?
388  if (ra_exe_unit_in.join_quals.size() > 0) {
389  throw std::runtime_error("Delete via join not yet supported for temporary tables.");
390  }
391 
392  const auto true_datum = Datum{.boolval = true};
393  const auto deleted_constant =
394  makeExpr<Analyzer::Constant>(delete_column->get_type_info(), false, true_datum);
395 
396  auto input_col_descs = ra_exe_unit_in.input_col_descs;
397 
398  std::shared_ptr<Analyzer::Expr> filter;
399  std::vector<std::shared_ptr<Analyzer::Expr>> filter_exprs;
400  filter_exprs.insert(filter_exprs.end(),
401  ra_exe_unit_in.simple_quals.begin(),
402  ra_exe_unit_in.simple_quals.end());
403  filter_exprs.insert(
404  filter_exprs.end(), ra_exe_unit_in.quals.begin(), ra_exe_unit_in.quals.end());
405 
406  if (filter_exprs.size() > 0) {
407  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
408  case_expr_list;
409  if (filter_exprs.size() == 1) {
410  filter = filter_exprs.front();
411  } else {
412  filter = std::accumulate(
413  std::next(filter_exprs.begin()),
414  filter_exprs.end(),
415  filter_exprs.front(),
416  [](const std::shared_ptr<Analyzer::Expr> a,
417  const std::shared_ptr<Analyzer::Expr> b) {
418  CHECK_EQ(a->get_type_info().get_type(), b->get_type_info().get_type());
419  return makeExpr<Analyzer::BinOper>(a->get_type_info().get_type(),
420  SQLOps::kAND,
422  a->deep_copy(),
423  b->deep_copy());
424  });
425  }
426  std::shared_ptr<Analyzer::Expr> column_to_update{nullptr};
427  auto when_expr = filter; // only one filter, will be a BinOper if multiple filters
428  case_expr_list.emplace_back(std::make_pair(when_expr, deleted_constant));
429  auto case_expr = Parser::CaseExpr::normalize(case_expr_list, delete_column);
430 
431  // the delete column should not be projected, but check anyway
432  auto delete_col_desc_it = std::find_if(
433  input_col_descs.begin(),
434  input_col_descs.end(),
435  [&delete_column](const std::shared_ptr<const InputColDescriptor>& in) {
436  return in->getColId() == delete_column->get_column_id();
437  });
438  CHECK(delete_col_desc_it == input_col_descs.end());
439  auto delete_col_desc =
440  std::make_shared<const InputColDescriptor>(delete_column->get_column_id(),
441  delete_column->get_table_id(),
442  delete_column->get_rte_idx());
443  input_col_descs.push_back(delete_col_desc);
444  target_exprs_owned_.emplace_back(case_expr);
445  } else {
446  // no filters, simply project the deleted=true column value for all rows
447  auto delete_col_desc =
448  std::make_shared<const InputColDescriptor>(delete_column->get_column_id(),
449  delete_column->get_table_id(),
450  delete_column->get_rte_idx());
451  input_col_descs.push_back(delete_col_desc);
452  target_exprs_owned_.emplace_back(deleted_constant);
453  }
454 
455  std::vector<Analyzer::Expr*> target_exprs;
456  CHECK_EQ(target_exprs_owned_.size(), size_t(1));
457  target_exprs.emplace_back(target_exprs_owned_.front().get());
458 
459  RelAlgExecutionUnit rewritten_exe_unit{ra_exe_unit_in.input_descs,
460  input_col_descs,
461  {},
462  {},
463  ra_exe_unit_in.join_quals,
464  ra_exe_unit_in.groupby_exprs,
465  target_exprs,
466  ra_exe_unit_in.estimator,
467  ra_exe_unit_in.sort_info,
468  ra_exe_unit_in.scan_limit,
469  ra_exe_unit_in.use_bump_allocator,
470  ra_exe_unit_in.union_all,
471  ra_exe_unit_in.query_state};
472  return rewritten_exe_unit;
473 }
std::vector< Analyzer::Expr * > target_exprs
#define CHECK_EQ(x, y)
Definition: Logger.h:205
const std::optional< bool > union_all
bool boolval
Definition: sqltypes.h:133
std::vector< InputDescriptor > input_descs
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
static std::shared_ptr< Analyzer::Expr > normalize(const std::list< std::pair< std::shared_ptr< Analyzer::Expr >, std::shared_ptr< Analyzer::Expr >>> &, const std::shared_ptr< Analyzer::Expr >)
Definition: ParserNode.cpp:922
CHECK(cgen_state)
const SortInfo sort_info
const JoinQualsPerNestingLevel join_quals
Definition: sqldefs.h:37
const std::shared_ptr< Analyzer::Estimator > estimator
Definition: sqldefs.h:69
std::list< std::shared_ptr< Analyzer::Expr > > quals
std::shared_ptr< const query_state::QueryState > query_state
std::list< std::shared_ptr< const InputColDescriptor > > input_col_descs
std::list< std::shared_ptr< Analyzer::Expr > > simple_quals
std::vector< std::shared_ptr< Analyzer::Expr > > target_exprs_owned_
Definition: QueryRewrite.h:52

+ Here is the call graph for this function:

RelAlgExecutionUnit QueryRewriter::rewriteColumnarUpdate ( const RelAlgExecutionUnit ra_exe_unit_in,
std::shared_ptr< Analyzer::Expr column_to_update 
) const

Definition at line 221 of file QueryRewrite.cpp.

References cat(), CHECK(), CHECK_EQ, anonymous_namespace{QueryRewrite.cpp}::check_string_id_overflow(), RelAlgExecutionUnit::estimator, executor_, RelAlgExecutionUnit::groupby_exprs, inline_fixed_encoding_null_val(), RelAlgExecutionUnit::input_col_descs, RelAlgExecutionUnit::input_descs, RelAlgExecutionUnit::join_quals, kAND, kCAST, kONE, Parser::CaseExpr::normalize(), RelAlgExecutionUnit::quals, RelAlgExecutionUnit::query_state, RelAlgExecutionUnit::scan_limit, RelAlgExecutionUnit::simple_quals, RelAlgExecutionUnit::sort_info, Datum::stringval, RelAlgExecutionUnit::target_exprs, target_exprs_owned_, to_string(), RelAlgExecutionUnit::union_all, and RelAlgExecutionUnit::use_bump_allocator.

223  {
224  CHECK_EQ(ra_exe_unit_in.target_exprs.size(), size_t(2));
225  CHECK(ra_exe_unit_in.groupby_exprs.size() == 1 &&
226  !ra_exe_unit_in.groupby_exprs.front());
227 
228  if (ra_exe_unit_in.join_quals.size() > 0) {
229  throw std::runtime_error("Update via join not yet supported for temporary tables.");
230  }
231 
232  auto new_column_value = ra_exe_unit_in.target_exprs.front()->deep_copy();
233  const auto& new_column_ti = new_column_value->get_type_info();
234  if (column_to_update->get_type_info().is_dict_encoded_string()) {
235  CHECK(new_column_ti.is_dict_encoded_string());
236  if (new_column_ti.get_comp_param() > 0 &&
237  new_column_ti.get_comp_param() !=
238  column_to_update->get_type_info().get_comp_param()) {
239  throw std::runtime_error(
240  "Updating a dictionary encoded string using another dictionary encoded string "
241  "column is not yet supported, unless both columns share dictionaries.");
242  }
243  if (auto uoper = dynamic_cast<Analyzer::UOper*>(new_column_value.get())) {
244  if (uoper->get_optype() == kCAST &&
245  dynamic_cast<const Analyzer::Constant*>(uoper->get_operand())) {
246  const auto original_constant_expr =
247  dynamic_cast<const Analyzer::Constant*>(uoper->get_operand());
248  CHECK(original_constant_expr);
249  CHECK(original_constant_expr->get_type_info().is_string());
250  // extract the string, insert it into the dict for the table we are updating,
251  // and place the dictionary ID in the oper
252  auto cat = executor_->getCatalog();
253  CHECK(cat);
254 
255  CHECK(column_to_update->get_type_info().is_dict_encoded_string());
256  const auto dict_id = column_to_update->get_type_info().get_comp_param();
257  std::map<int, StringDictionary*> string_dicts;
258  const auto dd = cat->getMetadataForDict(dict_id, /*load_dict=*/true);
259  CHECK(dd);
260  auto string_dict = dd->stringDict;
261  CHECK(string_dict);
262 
263  auto string_id =
264  string_dict->getOrAdd(*original_constant_expr->get_constval().stringval);
265  if (check_string_id_overflow(string_id, column_to_update->get_type_info())) {
266  throw std::runtime_error(
267  "Ran out of space in dictionary, cannot update column with dictionary "
268  "encoded string value. Dictionary ID: " +
269  std::to_string(dict_id));
270  }
271  if (string_id == inline_int_null_value<int32_t>()) {
272  string_id = inline_fixed_encoding_null_val(column_to_update->get_type_info());
273  }
274 
275  // Codegen expects a string value. The string will be
276  // resolved to its ID during Constant codegen. Copy the string from the
277  // original expr
278  Datum new_string_datum{.stringval = new std::string(
279  *original_constant_expr->get_constval().stringval)};
280 
281  new_column_value =
282  makeExpr<Analyzer::Constant>(column_to_update->get_type_info(),
283  original_constant_expr->get_is_null(),
284  new_string_datum);
285 
286  // Roll the string dict generation forward, as we have added a string
287  if (executor_->string_dictionary_generations_.getGeneration(dict_id) > -1) {
288  executor_->string_dictionary_generations_.updateGeneration(
289  dict_id, string_dict->storageEntryCount());
290  } else {
291  // Simple update with no filters does not use a CASE, and therefore does not add
292  // a valid generation
293  executor_->string_dictionary_generations_.setGeneration(
294  dict_id, string_dict->storageEntryCount());
295  }
296  }
297  }
298  }
299 
300  auto input_col_descs = ra_exe_unit_in.input_col_descs;
301 
302  std::shared_ptr<Analyzer::Expr> filter;
303  std::vector<std::shared_ptr<Analyzer::Expr>> filter_exprs;
304  filter_exprs.insert(filter_exprs.end(),
305  ra_exe_unit_in.simple_quals.begin(),
306  ra_exe_unit_in.simple_quals.end());
307  filter_exprs.insert(
308  filter_exprs.end(), ra_exe_unit_in.quals.begin(), ra_exe_unit_in.quals.end());
309 
310  if (filter_exprs.size() > 0) {
311  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
312  case_expr_list;
313  if (filter_exprs.size() == 1) {
314  filter = filter_exprs.front();
315  } else {
316  filter = std::accumulate(
317  std::next(filter_exprs.begin()),
318  filter_exprs.end(),
319  filter_exprs.front(),
320  [](const std::shared_ptr<Analyzer::Expr> a,
321  const std::shared_ptr<Analyzer::Expr> b) {
322  CHECK_EQ(a->get_type_info().get_type(), b->get_type_info().get_type());
323  return makeExpr<Analyzer::BinOper>(a->get_type_info().get_type(),
324  SQLOps::kAND,
326  a->deep_copy(),
327  b->deep_copy());
328  });
329  }
330  auto when_expr = filter; // only one filter, will be a BinOper if multiple filters
331  case_expr_list.emplace_back(std::make_pair(when_expr, new_column_value));
332  auto case_expr = Parser::CaseExpr::normalize(case_expr_list, column_to_update);
333 
334  auto col_to_update_var =
335  std::dynamic_pointer_cast<Analyzer::ColumnVar>(column_to_update);
336  CHECK(col_to_update_var);
337  auto col_to_update_desc =
338  std::make_shared<const InputColDescriptor>(col_to_update_var->get_column_id(),
339  col_to_update_var->get_table_id(),
340  col_to_update_var->get_rte_idx());
341  auto existing_col_desc_it = std::find_if(
342  input_col_descs.begin(),
343  input_col_descs.end(),
344  [&col_to_update_desc](const std::shared_ptr<const InputColDescriptor>& in) {
345  return *in == *col_to_update_desc;
346  });
347  if (existing_col_desc_it == input_col_descs.end()) {
348  input_col_descs.push_back(col_to_update_desc);
349  }
350  target_exprs_owned_.emplace_back(case_expr);
351  } else {
352  // no filters, simply project the update value
353  target_exprs_owned_.emplace_back(new_column_value);
354  }
355 
356  std::vector<Analyzer::Expr*> target_exprs;
357  CHECK_EQ(target_exprs_owned_.size(), size_t(1));
358  target_exprs.emplace_back(target_exprs_owned_.front().get());
359 
360  RelAlgExecutionUnit rewritten_exe_unit{ra_exe_unit_in.input_descs,
361  input_col_descs,
362  {},
363  {},
364  ra_exe_unit_in.join_quals,
365  ra_exe_unit_in.groupby_exprs,
366  target_exprs,
367  ra_exe_unit_in.estimator,
368  ra_exe_unit_in.sort_info,
369  ra_exe_unit_in.scan_limit,
370  ra_exe_unit_in.use_bump_allocator,
371  ra_exe_unit_in.union_all,
372  ra_exe_unit_in.query_state};
373  return rewritten_exe_unit;
374 }
std::vector< Analyzer::Expr * > target_exprs
#define CHECK_EQ(x, y)
Definition: Logger.h:205
std::string cat(Ts &&...args)
const std::optional< bool > union_all
std::vector< InputDescriptor > input_descs
Definition: sqldefs.h:49
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
std::string to_string(char const *&&v)
static std::shared_ptr< Analyzer::Expr > normalize(const std::list< std::pair< std::shared_ptr< Analyzer::Expr >, std::shared_ptr< Analyzer::Expr >>> &, const std::shared_ptr< Analyzer::Expr >)
Definition: ParserNode.cpp:922
CHECK(cgen_state)
const SortInfo sort_info
const JoinQualsPerNestingLevel join_quals
Executor * executor_
Definition: QueryRewrite.h:51
Definition: sqldefs.h:37
const std::shared_ptr< Analyzer::Estimator > estimator
std::string * stringval
Definition: sqltypes.h:142
Definition: sqldefs.h:69
bool check_string_id_overflow(const int32_t string_id, const SQLTypeInfo &ti)
std::list< std::shared_ptr< Analyzer::Expr > > quals
int64_t inline_fixed_encoding_null_val(const SQL_TYPE_INFO &ti)
std::shared_ptr< const query_state::QueryState > query_state
std::list< std::shared_ptr< const InputColDescriptor > > input_col_descs
std::list< std::shared_ptr< Analyzer::Expr > > simple_quals
std::vector< std::shared_ptr< Analyzer::Expr > > target_exprs_owned_
Definition: QueryRewrite.h:52

+ Here is the call graph for this function:

RelAlgExecutionUnit QueryRewriter::rewriteConstrainedByIn ( const RelAlgExecutionUnit ra_exe_unit_in) const
private

Definition at line 83 of file QueryRewrite.cpp.

References generateCaseForDomainValues(), RelAlgExecutionUnit::groupby_exprs, RelAlgExecutionUnit::quals, rewrite_expr(), rewriteConstrainedByInImpl(), and RelAlgExecutionUnit::simple_quals.

Referenced by rewrite().

84  {
85  if (ra_exe_unit_in.groupby_exprs.empty()) {
86  return ra_exe_unit_in;
87  }
88  if (ra_exe_unit_in.groupby_exprs.size() == 1 && !ra_exe_unit_in.groupby_exprs.front()) {
89  return ra_exe_unit_in;
90  }
91  if (!ra_exe_unit_in.simple_quals.empty()) {
92  return ra_exe_unit_in;
93  }
94  if (ra_exe_unit_in.quals.size() != 1) {
95  return ra_exe_unit_in;
96  }
97  auto in_vals =
98  std::dynamic_pointer_cast<Analyzer::InValues>(ra_exe_unit_in.quals.front());
99  if (!in_vals) {
100  in_vals = std::dynamic_pointer_cast<Analyzer::InValues>(
101  rewrite_expr(ra_exe_unit_in.quals.front().get()));
102  }
103  if (!in_vals || in_vals->get_value_list().empty()) {
104  return ra_exe_unit_in;
105  }
106  for (const auto& in_val : in_vals->get_value_list()) {
107  if (!std::dynamic_pointer_cast<Analyzer::Constant>(in_val)) {
108  break;
109  }
110  }
111  if (dynamic_cast<const Analyzer::CaseExpr*>(in_vals->get_arg())) {
112  return ra_exe_unit_in;
113  }
114  auto case_expr = generateCaseForDomainValues(in_vals.get());
115  return rewriteConstrainedByInImpl(ra_exe_unit_in, case_expr, in_vals.get());
116 }
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
Analyzer::ExpressionPtr rewrite_expr(const Analyzer::Expr *expr)
std::list< std::shared_ptr< Analyzer::Expr > > quals
static std::shared_ptr< Analyzer::CaseExpr > generateCaseForDomainValues(const Analyzer::InValues *)
std::list< std::shared_ptr< Analyzer::Expr > > simple_quals
RelAlgExecutionUnit rewriteConstrainedByInImpl(const RelAlgExecutionUnit &ra_exe_unit_in, const std::shared_ptr< Analyzer::CaseExpr >, const Analyzer::InValues *) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

RelAlgExecutionUnit QueryRewriter::rewriteConstrainedByInImpl ( const RelAlgExecutionUnit ra_exe_unit_in,
const std::shared_ptr< Analyzer::CaseExpr case_expr,
const Analyzer::InValues in_vals 
) const
private

Definition at line 118 of file QueryRewrite.cpp.

References CHECK(), executor_, g_constrained_by_in_threshold, Analyzer::InValues::get_arg(), getExpressionRange(), ExpressionRange::getIntMax(), RelAlgExecutionUnit::groupby_exprs, RelAlgExecutionUnit::input_col_descs, RelAlgExecutionUnit::input_descs, Integer, RelAlgExecutionUnit::join_quals, Analyzer::Var::kGROUPBY, RelAlgExecutionUnit::quals, query_infos_, rewrite(), RelAlgExecutionUnit::scan_limit, RelAlgExecutionUnit::simple_quals, RelAlgExecutionUnit::sort_info, RelAlgExecutionUnit::target_exprs, and target_exprs_owned_.

Referenced by rewriteConstrainedByIn().

121  {
122  std::list<std::shared_ptr<Analyzer::Expr>> new_groupby_list;
123  std::vector<Analyzer::Expr*> new_target_exprs;
124  bool rewrite{false};
125  size_t groupby_idx{0};
126  auto it = ra_exe_unit_in.groupby_exprs.begin();
127  for (const auto& group_expr : ra_exe_unit_in.groupby_exprs) {
128  CHECK(group_expr);
129  ++groupby_idx;
130  if (*group_expr == *in_vals->get_arg()) {
131  const auto expr_range = getExpressionRange(it->get(), query_infos_, executor_);
132  if (expr_range.getType() != ExpressionRangeType::Integer) {
133  ++it;
134  continue;
135  }
136  const size_t range_sz = expr_range.getIntMax() - expr_range.getIntMin() + 1;
137  if (range_sz <= in_vals->get_value_list().size() * g_constrained_by_in_threshold) {
138  ++it;
139  continue;
140  }
141  new_groupby_list.push_back(case_expr);
142  for (size_t i = 0; i < ra_exe_unit_in.target_exprs.size(); ++i) {
143  const auto target = ra_exe_unit_in.target_exprs[i];
144  if (*target == *in_vals->get_arg()) {
145  auto var_case_expr = makeExpr<Analyzer::Var>(
146  case_expr->get_type_info(), Analyzer::Var::kGROUPBY, groupby_idx);
147  target_exprs_owned_.push_back(var_case_expr);
148  new_target_exprs.push_back(var_case_expr.get());
149  } else {
150  new_target_exprs.push_back(target);
151  }
152  }
153  rewrite = true;
154  } else {
155  new_groupby_list.push_back(group_expr);
156  }
157  ++it;
158  }
159  if (!rewrite) {
160  return ra_exe_unit_in;
161  }
162  return {ra_exe_unit_in.input_descs,
163  ra_exe_unit_in.input_col_descs,
164  ra_exe_unit_in.simple_quals,
165  ra_exe_unit_in.quals,
166  ra_exe_unit_in.join_quals,
167  new_groupby_list,
168  new_target_exprs,
169  nullptr,
170  ra_exe_unit_in.sort_info,
171  ra_exe_unit_in.scan_limit};
172 }
std::vector< Analyzer::Expr * > target_exprs
size_t g_constrained_by_in_threshold
Definition: Execute.cpp:96
std::vector< InputDescriptor > input_descs
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
CHECK(cgen_state)
RelAlgExecutionUnit rewrite(const RelAlgExecutionUnit &ra_exe_unit_in) const
const SortInfo sort_info
const JoinQualsPerNestingLevel join_quals
Executor * executor_
Definition: QueryRewrite.h:51
ExpressionRange getExpressionRange(const Analyzer::BinOper *expr, const std::vector< InputTableInfo > &query_infos, const Executor *, boost::optional< std::list< std::shared_ptr< Analyzer::Expr >>> simple_quals)
const std::vector< InputTableInfo > & query_infos_
Definition: QueryRewrite.h:50
std::list< std::shared_ptr< Analyzer::Expr > > quals
int64_t getIntMax() const
std::list< std::shared_ptr< const InputColDescriptor > > input_col_descs
const Expr * get_arg() const
Definition: Analyzer.h:585
std::list< std::shared_ptr< Analyzer::Expr > > simple_quals
std::vector< std::shared_ptr< Analyzer::Expr > > target_exprs_owned_
Definition: QueryRewrite.h:52

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

RelAlgExecutionUnit QueryRewriter::rewriteOverlapsJoin ( const RelAlgExecutionUnit ra_exe_unit_in) const
private

Definition at line 34 of file QueryRewrite.cpp.

References RelAlgExecutionUnit::estimator, g_enable_overlaps_hashjoin, RelAlgExecutionUnit::groupby_exprs, RelAlgExecutionUnit::input_col_descs, RelAlgExecutionUnit::input_descs, RelAlgExecutionUnit::join_quals, RelAlgExecutionUnit::quals, rewrite_overlaps_conjunction(), RelAlgExecutionUnit::scan_limit, RelAlgExecutionUnit::simple_quals, RelAlgExecutionUnit::sort_info, RelAlgExecutionUnit::target_exprs, JoinCondition::type, and RelAlgExecutionUnit::use_bump_allocator.

Referenced by rewrite().

35  {
37  return ra_exe_unit_in;
38  }
39  if (ra_exe_unit_in.join_quals.empty()) {
40  return ra_exe_unit_in;
41  }
42 
43  std::list<std::shared_ptr<Analyzer::Expr>> quals;
44  quals.insert(quals.end(), ra_exe_unit_in.quals.begin(), ra_exe_unit_in.quals.end());
45 
46  JoinQualsPerNestingLevel join_condition_per_nesting_level;
47  for (const auto& join_condition_in : ra_exe_unit_in.join_quals) {
48  JoinCondition join_condition{{}, join_condition_in.type};
49 
50  for (const auto& join_qual_expr_in : join_condition_in.quals) {
51  auto new_overlaps_quals = rewrite_overlaps_conjunction(join_qual_expr_in);
52  if (new_overlaps_quals) {
53  const auto& overlaps_quals = *new_overlaps_quals;
54 
55  // Add overlaps qual
56  join_condition.quals.insert(join_condition.quals.end(),
57  overlaps_quals.join_quals.begin(),
58  overlaps_quals.join_quals.end());
59 
60  // Add original quals
61  join_condition.quals.insert(join_condition.quals.end(),
62  overlaps_quals.quals.begin(),
63  overlaps_quals.quals.end());
64  } else {
65  join_condition.quals.push_back(join_qual_expr_in);
66  }
67  }
68  join_condition_per_nesting_level.push_back(join_condition);
69  }
70  return {ra_exe_unit_in.input_descs,
71  ra_exe_unit_in.input_col_descs,
72  ra_exe_unit_in.simple_quals,
73  quals,
74  join_condition_per_nesting_level,
75  ra_exe_unit_in.groupby_exprs,
76  ra_exe_unit_in.target_exprs,
77  ra_exe_unit_in.estimator,
78  ra_exe_unit_in.sort_info,
79  ra_exe_unit_in.scan_limit,
80  ra_exe_unit_in.use_bump_allocator};
81 }
std::vector< Analyzer::Expr * > target_exprs
std::vector< InputDescriptor > input_descs
std::vector< JoinCondition > JoinQualsPerNestingLevel
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
bool g_enable_overlaps_hashjoin
Definition: Execute.cpp:91
const SortInfo sort_info
const JoinQualsPerNestingLevel join_quals
boost::optional< OverlapsJoinConjunction > rewrite_overlaps_conjunction(const std::shared_ptr< Analyzer::Expr > expr)
const std::shared_ptr< Analyzer::Estimator > estimator
std::list< std::shared_ptr< Analyzer::Expr > > quals
std::list< std::shared_ptr< const InputColDescriptor > > input_col_descs
std::list< std::shared_ptr< Analyzer::Expr > > simple_quals

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

Executor* QueryRewriter::executor_
private

Definition at line 51 of file QueryRewrite.h.

Referenced by rewriteColumnarUpdate(), and rewriteConstrainedByInImpl().

const std::vector<InputTableInfo>& QueryRewriter::query_infos_
private

Definition at line 50 of file QueryRewrite.h.

Referenced by rewriteConstrainedByInImpl().

std::vector<std::shared_ptr<Analyzer::Expr> > QueryRewriter::target_exprs_owned_
mutableprivate

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