OmniSciDB  04ee39c94c
QueryRewriter Class Reference

#include <QueryRewrite.h>

+ Collaboration diagram for QueryRewriter:

Public Member Functions

 QueryRewriter (const std::vector< InputTableInfo > &query_infos, const Executor *executor)
 
RelAlgExecutionUnit rewrite (const RelAlgExecutionUnit &ra_exe_unit_in) 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::CaseExprgenerateCaseForDomainValues (const Analyzer::InValues *)
 

Private Attributes

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

Detailed Description

Definition at line 22 of file QueryRewrite.h.

Constructor & Destructor Documentation

◆ QueryRewriter()

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

Definition at line 24 of file QueryRewrite.h.

References generateCaseForDomainValues(), rewrite(), rewriteConstrainedByIn(), rewriteConstrainedByInImpl(), and rewriteOverlapsJoin().

25  : query_infos_(query_infos), executor_(executor) {}
const std::vector< InputTableInfo > & query_infos_
Definition: QueryRewrite.h:43
const Executor * executor_
Definition: QueryRewrite.h:44
+ Here is the call graph for this function:

Member Function Documentation

◆ generateCaseForDomainValues()

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

Definition at line 165 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 QueryRewriter(), and rewriteConstrainedByIn().

166  {
167  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
168  case_expr_list;
169  auto in_val_arg = in_vals->get_arg()->deep_copy();
170  for (const auto in_val : in_vals->get_value_list()) {
171  auto case_cond = makeExpr<Analyzer::BinOper>(
172  SQLTypeInfo(kBOOLEAN, true), false, kEQ, kONE, in_val_arg, in_val);
173  auto in_val_copy = in_val->deep_copy();
174  auto ti = in_val_copy->get_type_info();
175  if (ti.is_string() && ti.get_compression() == kENCODING_DICT) {
176  ti.set_comp_param(0);
177  }
178  in_val_copy->set_type_info(ti);
179  case_expr_list.emplace_back(case_cond, in_val_copy);
180  }
181  // TODO(alex): refine the expression range for case with empty else expression;
182  // for now, add a dummy else which should never be taken
183  auto else_expr = case_expr_list.front().second;
184  return makeExpr<Analyzer::CaseExpr>(
185  case_expr_list.front().second->get_type_info(), false, case_expr_list, else_expr);
186 }
const Expr * get_arg() const
Definition: Analyzer.h:577
Definition: sqldefs.h:30
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:823
Definition: sqldefs.h:69
virtual std::shared_ptr< Analyzer::Expr > deep_copy() const =0
const std::list< std::shared_ptr< Analyzer::Expr > > & get_value_list() const
Definition: Analyzer.h:579
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ rewrite()

RelAlgExecutionUnit QueryRewriter::rewrite ( const RelAlgExecutionUnit ra_exe_unit_in) const

Definition at line 22 of file QueryRewrite.cpp.

References rewriteConstrainedByIn(), and rewriteOverlapsJoin().

Referenced by QueryRewriter(), and rewriteConstrainedByInImpl().

23  {
24  auto rewritten_exe_unit = rewriteConstrainedByIn(ra_exe_unit_in);
25  return rewriteOverlapsJoin(rewritten_exe_unit);
26 }
RelAlgExecutionUnit rewriteConstrainedByIn(const RelAlgExecutionUnit &ra_exe_unit_in) const
RelAlgExecutionUnit rewriteOverlapsJoin(const RelAlgExecutionUnit &ra_exe_unit_in) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ rewriteConstrainedByIn()

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

Definition at line 74 of file QueryRewrite.cpp.

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

Referenced by QueryRewriter(), and rewrite().

75  {
76  if (ra_exe_unit_in.groupby_exprs.empty()) {
77  return ra_exe_unit_in;
78  }
79  if (ra_exe_unit_in.groupby_exprs.size() == 1 && !ra_exe_unit_in.groupby_exprs.front()) {
80  return ra_exe_unit_in;
81  }
82  if (!ra_exe_unit_in.simple_quals.empty()) {
83  return ra_exe_unit_in;
84  }
85  if (ra_exe_unit_in.quals.size() != 1) {
86  return ra_exe_unit_in;
87  }
88  auto in_vals =
89  std::dynamic_pointer_cast<Analyzer::InValues>(ra_exe_unit_in.quals.front());
90  if (!in_vals) {
91  in_vals = std::dynamic_pointer_cast<Analyzer::InValues>(
92  rewrite_expr(ra_exe_unit_in.quals.front().get()));
93  }
94  if (!in_vals || in_vals->get_value_list().empty()) {
95  return ra_exe_unit_in;
96  }
97  for (const auto in_val : in_vals->get_value_list()) {
98  if (!std::dynamic_pointer_cast<Analyzer::Constant>(in_val)) {
99  break;
100  }
101  }
102  if (dynamic_cast<const Analyzer::CaseExpr*>(in_vals->get_arg())) {
103  return ra_exe_unit_in;
104  }
105  auto case_expr = generateCaseForDomainValues(in_vals.get());
106  return rewriteConstrainedByInImpl(ra_exe_unit_in, case_expr, in_vals.get());
107 }
RelAlgExecutionUnit rewriteConstrainedByInImpl(const RelAlgExecutionUnit &ra_exe_unit_in, const std::shared_ptr< Analyzer::CaseExpr >, const Analyzer::InValues *) const
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
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ rewriteConstrainedByInImpl()

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 109 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 QueryRewriter(), and rewriteConstrainedByIn().

112  {
113  std::list<std::shared_ptr<Analyzer::Expr>> new_groupby_list;
114  std::vector<Analyzer::Expr*> new_target_exprs;
115  bool rewrite{false};
116  size_t groupby_idx{0};
117  auto it = ra_exe_unit_in.groupby_exprs.begin();
118  for (const auto group_expr : ra_exe_unit_in.groupby_exprs) {
119  CHECK(group_expr);
120  ++groupby_idx;
121  if (*group_expr == *in_vals->get_arg()) {
122  const auto expr_range = getExpressionRange(it->get(), query_infos_, executor_);
123  if (expr_range.getType() != ExpressionRangeType::Integer) {
124  ++it;
125  continue;
126  }
127  const size_t range_sz = expr_range.getIntMax() - expr_range.getIntMin() + 1;
128  if (range_sz <= in_vals->get_value_list().size() * g_constrained_by_in_threshold) {
129  ++it;
130  continue;
131  }
132  new_groupby_list.push_back(case_expr);
133  for (size_t i = 0; i < ra_exe_unit_in.target_exprs.size(); ++i) {
134  const auto target = ra_exe_unit_in.target_exprs[i];
135  if (*target == *in_vals->get_arg()) {
136  auto var_case_expr = makeExpr<Analyzer::Var>(
137  case_expr->get_type_info(), Analyzer::Var::kGROUPBY, groupby_idx);
138  target_exprs_owned_.push_back(var_case_expr);
139  new_target_exprs.push_back(var_case_expr.get());
140  } else {
141  new_target_exprs.push_back(target);
142  }
143  }
144  rewrite = true;
145  } else {
146  new_groupby_list.push_back(group_expr);
147  }
148  ++it;
149  }
150  if (!rewrite) {
151  return ra_exe_unit_in;
152  }
153  return {ra_exe_unit_in.input_descs,
154  ra_exe_unit_in.input_col_descs,
155  ra_exe_unit_in.simple_quals,
156  ra_exe_unit_in.quals,
157  ra_exe_unit_in.join_quals,
158  new_groupby_list,
159  new_target_exprs,
160  nullptr,
161  ra_exe_unit_in.sort_info,
162  ra_exe_unit_in.scan_limit};
163 }
std::vector< Analyzer::Expr * > target_exprs
const Expr * get_arg() const
Definition: Analyzer.h:577
size_t g_constrained_by_in_threshold
Definition: Execute.cpp:89
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
RelAlgExecutionUnit rewrite(const RelAlgExecutionUnit &ra_exe_unit_in) const
const std::vector< InputDescriptor > input_descs
int64_t getIntMax() const
const SortInfo sort_info
const JoinQualsPerNestingLevel join_quals
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:43
std::list< std::shared_ptr< Analyzer::Expr > > quals
#define CHECK(condition)
Definition: Logger.h:187
const Executor * executor_
Definition: QueryRewrite.h:44
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:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ rewriteOverlapsJoin()

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

Definition at line 28 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, RelAlgExecutionUnit::query_features, rewrite_overlaps_conjunction(), RelAlgExecutionUnit::scan_limit, RelAlgExecutionUnit::simple_quals, RelAlgExecutionUnit::sort_info, RelAlgExecutionUnit::target_exprs, JoinCondition::type, and RelAlgExecutionUnit::use_bump_allocator.

Referenced by QueryRewriter(), and rewrite().

29  {
31  return ra_exe_unit_in;
32  }
33  if (ra_exe_unit_in.join_quals.empty()) {
34  return ra_exe_unit_in;
35  }
36 
37  std::list<std::shared_ptr<Analyzer::Expr>> quals;
38  quals.insert(quals.end(), ra_exe_unit_in.quals.begin(), ra_exe_unit_in.quals.end());
39 
40  JoinQualsPerNestingLevel join_condition_per_nesting_level;
41  for (const auto& join_condition_in : ra_exe_unit_in.join_quals) {
42  JoinCondition join_condition{{}, join_condition_in.type};
43 
44  for (const auto& join_qual_expr_in : join_condition_in.quals) {
45  auto new_overlaps_quals = rewrite_overlaps_conjunction(join_qual_expr_in);
46  if (new_overlaps_quals) {
47  const auto& overlaps_quals = *new_overlaps_quals;
48  join_condition.quals.insert(join_condition.quals.end(),
49  overlaps_quals.join_quals.begin(),
50  overlaps_quals.join_quals.end());
51 
52  quals.insert(
53  quals.end(), overlaps_quals.quals.begin(), overlaps_quals.quals.end());
54  } else {
55  join_condition.quals.push_back(join_qual_expr_in);
56  }
57  }
58  join_condition_per_nesting_level.push_back(join_condition);
59  }
60  return {ra_exe_unit_in.input_descs,
61  ra_exe_unit_in.input_col_descs,
62  ra_exe_unit_in.simple_quals,
63  quals,
64  join_condition_per_nesting_level,
65  ra_exe_unit_in.groupby_exprs,
66  ra_exe_unit_in.target_exprs,
67  ra_exe_unit_in.estimator,
68  ra_exe_unit_in.sort_info,
69  ra_exe_unit_in.scan_limit,
70  ra_exe_unit_in.query_features,
71  ra_exe_unit_in.use_bump_allocator};
72 }
std::vector< Analyzer::Expr * > target_exprs
std::vector< JoinCondition > JoinQualsPerNestingLevel
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
const std::vector< InputDescriptor > input_descs
bool g_enable_overlaps_hashjoin
Definition: Execute.cpp:85
QueryFeatureDescriptor query_features
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_

const Executor* QueryRewriter::executor_
private

Definition at line 44 of file QueryRewrite.h.

Referenced by rewriteConstrainedByInImpl().

◆ query_infos_

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

Definition at line 43 of file QueryRewrite.h.

Referenced by rewriteConstrainedByInImpl().

◆ target_exprs_owned_

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

Definition at line 45 of file QueryRewrite.h.

Referenced by rewriteConstrainedByInImpl().


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