32 auto rewritten_exe_unit_for_agg_on_gby_col =
40 return ra_exe_unit_in;
43 return ra_exe_unit_in;
46 std::list<std::shared_ptr<Analyzer::Expr>> quals;
47 quals.insert(quals.end(), ra_exe_unit_in.
quals.begin(), ra_exe_unit_in.
quals.end());
50 for (
const auto& join_condition_in : ra_exe_unit_in.
join_quals) {
53 for (
const auto& join_qual_expr_in : join_condition_in.quals) {
54 bool try_to_rewrite_expr_to_overlaps_join =
false;
58 const auto func_name = func_oper->
getName();
60 try_to_rewrite_expr_to_overlaps_join =
true;
65 if (bin_oper && (bin_oper->get_optype() ==
kLE || bin_oper->get_optype() ==
kLT)) {
70 try_to_rewrite_expr_to_overlaps_join =
true;
74 boost::optional<OverlapsJoinConjunction> new_overlaps_quals = boost::none;
75 if (try_to_rewrite_expr_to_overlaps_join) {
79 if (new_overlaps_quals) {
80 const auto& overlaps_quals = *new_overlaps_quals;
82 join_condition.quals.insert(join_condition.quals.end(),
83 overlaps_quals.join_quals.begin(),
84 overlaps_quals.join_quals.end());
86 join_condition.quals.insert(join_condition.quals.end(),
87 overlaps_quals.quals.begin(),
88 overlaps_quals.quals.end());
90 join_condition.quals.push_back(join_qual_expr_in);
93 join_condition_per_nesting_level.push_back(join_condition);
99 join_condition_per_nesting_level,
116 return ra_exe_unit_in;
119 return ra_exe_unit_in;
122 return ra_exe_unit_in;
124 if (ra_exe_unit_in.
quals.size() != 1) {
125 return ra_exe_unit_in;
133 if (!in_vals || in_vals->get_value_list().empty()) {
134 return ra_exe_unit_in;
136 for (
const auto& in_val : in_vals->get_value_list()) {
137 if (!std::dynamic_pointer_cast<Analyzer::Constant>(in_val)) {
141 if (dynamic_cast<const Analyzer::CaseExpr*>(in_vals->get_arg())) {
142 return ra_exe_unit_in;
146 auto it = std::find_if(
149 [&in_val_cv](std::shared_ptr<Analyzer::Expr> groupby_expr) {
150 if (
auto groupby_cv =
151 std::dynamic_pointer_cast<Analyzer::ColumnVar>(groupby_expr)) {
152 return *in_val_cv == *groupby_cv.get();
159 return ra_exe_unit_in;
168 const std::shared_ptr<Analyzer::CaseExpr> case_expr,
170 std::list<std::shared_ptr<Analyzer::Expr>> new_groupby_list;
171 std::vector<Analyzer::Expr*> new_target_exprs;
173 size_t groupby_idx{0};
175 for (
const auto& group_expr : ra_exe_unit_in.
groupby_exprs) {
178 if (*group_expr == *in_vals->
get_arg()) {
184 const size_t range_sz = expr_range.
getIntMax() - expr_range.getIntMin() + 1;
189 new_groupby_list.push_back(case_expr);
190 for (
size_t i = 0; i < ra_exe_unit_in.
target_exprs.size(); ++i) {
192 if (*target == *in_vals->
get_arg()) {
193 auto var_case_expr = makeExpr<Analyzer::Var>(
196 new_target_exprs.push_back(var_case_expr.get());
198 new_target_exprs.push_back(target);
203 new_groupby_list.push_back(group_expr);
208 return ra_exe_unit_in;
213 ra_exe_unit_in.
quals,
229 std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
233 auto case_cond = makeExpr<Analyzer::BinOper>(
235 auto in_val_copy = in_val->deep_copy();
236 auto ti = in_val_copy->get_type_info();
238 ti.set_comp_param(0);
240 in_val_copy->set_type_info(ti);
241 case_expr_list.emplace_back(case_cond, in_val_copy);
245 auto else_expr = case_expr_list.front().second;
246 return makeExpr<Analyzer::CaseExpr>(
247 case_expr_list.front().second->get_type_info(),
false, case_expr_list, else_expr);
250 std::shared_ptr<Analyzer::CaseExpr>
252 std::shared_ptr<Analyzer::Expr> expr)
const {
253 std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
259 const auto then_constant = makeExpr<Analyzer::Constant>(
kBIGINT,
false, then_d);
260 case_expr_list.emplace_back(is_not_null, then_constant);
263 const auto else_constant = makeExpr<Analyzer::Constant>(
kBIGINT,
false, else_d);
264 auto case_expr = makeExpr<Analyzer::CaseExpr>(
265 then_constant->get_type_info(),
false, case_expr_list, else_constant);
275 return string_id > max_valid_int_value<int8_t>();
277 return string_id > max_valid_int_value<int16_t>();
279 return string_id > max_valid_int_value<int32_t>();
295 std::shared_ptr<Analyzer::ColumnVar> column_to_update)
const {
301 throw std::runtime_error(
"Update via join not yet supported for temporary tables.");
304 auto new_column_value = ra_exe_unit_in.
target_exprs.front()->deep_copy();
305 const auto& new_column_ti = new_column_value->get_type_info();
306 if (column_to_update->get_type_info().is_dict_encoded_string()) {
307 CHECK(new_column_ti.is_dict_encoded_string());
308 if (new_column_ti.getStringDictKey().dict_id > 0 &&
309 new_column_ti.getStringDictKey() !=
310 column_to_update->get_type_info().getStringDictKey()) {
311 throw std::runtime_error(
312 "Updating a dictionary encoded string using another dictionary encoded string "
313 "column is not yet supported, unless both columns share dictionaries.");
315 if (
auto uoper = dynamic_cast<Analyzer::UOper*>(new_column_value.get())) {
316 if (uoper->get_optype() ==
kCAST &&
318 const auto original_constant_expr =
320 CHECK(original_constant_expr);
321 CHECK(original_constant_expr->get_type_info().is_string());
325 CHECK(column_to_update->get_type_info().is_dict_encoded_string());
326 const auto& dict_key = column_to_update->get_type_info().getStringDictKey();
327 std::map<int, StringDictionary*> string_dicts;
331 const auto dd = catalog->getMetadataForDict(dict_key.dict_id,
true);
333 auto string_dict = dd->stringDict;
337 string_dict->getOrAdd(*original_constant_expr->get_constval().stringval);
339 throw std::runtime_error(
340 "Ran out of space in dictionary, cannot update column with dictionary "
341 "encoded string value. Dictionary ID: " +
344 if (string_id == inline_int_null_value<int32_t>()) {
353 new std::string(*original_constant_expr->get_constval().stringval);
354 Datum new_string_datum{datum};
357 makeExpr<Analyzer::Constant>(column_to_update->get_type_info(),
358 original_constant_expr->get_is_null(),
362 auto row_set_mem_owner =
executor_->getRowSetMemoryOwner();
363 CHECK(row_set_mem_owner);
364 auto& str_dict_generations = row_set_mem_owner->getStringDictionaryGenerations();
365 if (str_dict_generations.getGeneration(dict_key) > -1) {
366 str_dict_generations.updateGeneration(dict_key,
367 string_dict->storageEntryCount());
371 str_dict_generations.setGeneration(dict_key, string_dict->storageEntryCount());
379 std::shared_ptr<Analyzer::Expr> filter;
380 std::vector<std::shared_ptr<Analyzer::Expr>> filter_exprs;
381 filter_exprs.insert(filter_exprs.end(),
385 filter_exprs.end(), ra_exe_unit_in.
quals.begin(), ra_exe_unit_in.
quals.end());
387 if (filter_exprs.size() > 0) {
388 std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
390 if (filter_exprs.size() == 1) {
391 filter = filter_exprs.front();
394 std::next(filter_exprs.begin()),
396 filter_exprs.front(),
397 [](
const std::shared_ptr<Analyzer::Expr>
a,
398 const std::shared_ptr<Analyzer::Expr> b) {
399 CHECK_EQ(a->get_type_info().get_type(), b->get_type_info().get_type());
400 return makeExpr<Analyzer::BinOper>(a->get_type_info().get_type(),
407 auto when_expr = filter;
408 case_expr_list.emplace_back(std::make_pair(when_expr, new_column_value));
411 auto col_to_update_var =
413 CHECK(col_to_update_var);
414 const auto& column_key = col_to_update_var->getColumnKey();
415 auto col_to_update_desc =
416 std::make_shared<const InputColDescriptor>(column_key.column_id,
419 col_to_update_var->get_rte_idx());
420 auto existing_col_desc_it = std::find_if(
421 input_col_descs.begin(),
422 input_col_descs.end(),
423 [&col_to_update_desc](
const std::shared_ptr<const InputColDescriptor>& in) {
424 return *in == *col_to_update_desc;
426 if (existing_col_desc_it == input_col_descs.end()) {
427 input_col_descs.push_back(col_to_update_desc);
435 std::vector<Analyzer::Expr*> target_exprs;
457 return rewritten_exe_unit;
466 std::shared_ptr<Analyzer::ColumnVar> delete_column)
const {
473 throw std::runtime_error(
"Delete via join not yet supported for temporary tables.");
478 const auto deleted_constant =
479 makeExpr<Analyzer::Constant>(delete_column->get_type_info(),
false, true_datum);
483 std::shared_ptr<Analyzer::Expr> filter;
484 std::vector<std::shared_ptr<Analyzer::Expr>> filter_exprs;
485 filter_exprs.insert(filter_exprs.end(),
489 filter_exprs.end(), ra_exe_unit_in.
quals.begin(), ra_exe_unit_in.
quals.end());
491 if (filter_exprs.size() > 0) {
492 std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
494 if (filter_exprs.size() == 1) {
495 filter = filter_exprs.front();
498 std::next(filter_exprs.begin()),
500 filter_exprs.front(),
501 [](
const std::shared_ptr<Analyzer::Expr>
a,
502 const std::shared_ptr<Analyzer::Expr> b) {
503 CHECK_EQ(a->get_type_info().get_type(), b->get_type_info().get_type());
504 return makeExpr<Analyzer::BinOper>(a->get_type_info().get_type(),
511 std::shared_ptr<Analyzer::Expr> column_to_update{
nullptr};
512 auto when_expr = filter;
513 case_expr_list.emplace_back(std::make_pair(when_expr, deleted_constant));
517 auto delete_col_desc_it = std::find_if(
518 input_col_descs.begin(),
519 input_col_descs.end(),
520 [&delete_column](
const std::shared_ptr<const InputColDescriptor>& in) {
521 return in->getColId() == delete_column->getColumnKey().column_id;
523 CHECK(delete_col_desc_it == input_col_descs.end());
524 const auto& column_key = delete_column->getColumnKey();
525 auto delete_col_desc =
526 std::make_shared<const InputColDescriptor>(column_key.column_id,
529 delete_column->get_rte_idx());
530 input_col_descs.push_back(delete_col_desc);
534 const auto& column_key = delete_column->getColumnKey();
535 auto delete_col_desc =
536 std::make_shared<const InputColDescriptor>(column_key.column_id,
539 delete_column->get_rte_idx());
540 input_col_descs.push_back(delete_col_desc);
544 std::vector<Analyzer::Expr*> target_exprs;
566 return rewritten_exe_unit;
570 const std::list<std::shared_ptr<Analyzer::Expr>>& groupby_exprs)
const {
571 std::set<size_t> gby_col_exprs_hash;
572 for (
auto gby_expr : groupby_exprs) {
573 if (
auto gby_col_var = std::dynamic_pointer_cast<Analyzer::ColumnVar>(gby_expr)) {
574 gby_col_exprs_hash.insert(boost::hash_value(gby_col_var->toString()));
579 return {
true, gby_col_exprs_hash};
587 if (agg_expr->get_arg()) {
589 auto agg_expr_hash = boost::hash_value(agg_expr->get_arg()->toString());
592 if (check_precond.second.count(agg_expr_hash)) {
598 if (!check_precond.first) {
602 return ra_exe_unit_in;
605 std::vector<Analyzer::Expr*> new_target_exprs;
607 bool rewritten =
false;
608 if (
auto agg_expr = dynamic_cast<Analyzer::AggExpr*>(expr)) {
609 if (is_expr_on_gby_col(agg_expr)) {
610 auto target_expr = agg_expr->get_arg();
613 if (target_expr && target_expr->get_type_info().get_type() !=
SQLTypes::kFLOAT) {
614 switch (agg_expr->get_aggtype()) {
619 !agg_expr->get_is_distinct()) {
624 new_target_exprs.push_back(case_expr.get());
636 auto agg_expr_ti = agg_expr->get_type_info();
637 auto target_expr = agg_expr->get_own_arg();
638 if (agg_expr_ti != target_expr->get_type_info()) {
639 target_expr = target_expr->add_cast(agg_expr_ti);
641 new_target_exprs.push_back(target_expr.get());
653 new_target_exprs.push_back(expr);
660 ra_exe_unit_in.
quals,
675 return rewritten_exe_unit;
std::vector< Analyzer::Expr * > target_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 >, const Executor *executor=nullptr)
HOST DEVICE int get_size() const
size_t g_constrained_by_in_threshold
boost::optional< OverlapsJoinConjunction > rewrite_overlaps_conjunction(const std::shared_ptr< Analyzer::Expr > expr, const std::vector< InputDescriptor > &input_table_info, const OverlapsJoinRewriteType rewrite_type, const Executor *executor)
QueryPlanHash query_plan_dag_hash
static bool is_overlaps_supported_func(std::string_view target_func_name)
const std::optional< bool > union_all
RelAlgExecutionUnit rewriteColumnarUpdate(const RelAlgExecutionUnit &ra_exe_unit_in, std::shared_ptr< Analyzer::ColumnVar > column_to_update) const
std::vector< InputDescriptor > input_descs
Constants for Builtin SQL Types supported by HEAVY.AI.
std::vector< JoinCondition > JoinQualsPerNestingLevel
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
Analyzer::ExpressionPtr rewrite_expr(const Analyzer::Expr *expr)
bool g_enable_overlaps_hashjoin
static SysCatalog & instance()
CONSTEXPR DEVICE bool is_null(const T &value)
Classes representing a parse tree.
RelAlgExecutionUnit rewrite(const RelAlgExecutionUnit &ra_exe_unit_in) const
const JoinQualsPerNestingLevel join_quals
std::pair< bool, std::set< size_t > > is_all_groupby_exprs_are_col_var(const std::list< std::shared_ptr< Analyzer::Expr >> &groupby_exprs) const
TableIdToNodeMap table_id_to_node_map
RelAlgExecutionUnit rewriteOverlapsJoin(const RelAlgExecutionUnit &ra_exe_unit_in) const
bool g_enable_distance_rangejoin
DEVICE auto accumulate(ARGS &&...args)
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::shared_ptr< Analyzer::Estimator > estimator
std::shared_ptr< Catalog > getCatalog(const std::string &dbName)
bool check_string_id_overflow(const int32_t string_id, const SQLTypeInfo &ti)
std::unordered_map< size_t, SQLTypeInfo > target_exprs_original_type_infos
const std::list< std::shared_ptr< Analyzer::Expr > > & get_value_list() const
virtual std::shared_ptr< Analyzer::Expr > deep_copy() const =0
const std::vector< InputTableInfo > & query_infos_
std::list< std::shared_ptr< Analyzer::Expr > > quals
int64_t getIntMax() const
RegisteredQueryHint query_hint
int64_t inline_fixed_encoding_null_val(const SQL_TYPE_INFO &ti)
std::shared_ptr< Analyzer::CaseExpr > generateCaseExprForCountDistinctOnGroupByCol(std::shared_ptr< Analyzer::Expr > expr) const
std::shared_ptr< const query_state::QueryState > query_state
std::list< std::shared_ptr< const InputColDescriptor > > input_col_descs
std::string getName() const
RelAlgExecutionUnit rewriteColumnarDelete(const RelAlgExecutionUnit &ra_exe_unit_in, std::shared_ptr< Analyzer::ColumnVar > delete_column) const
static std::shared_ptr< Analyzer::CaseExpr > generateCaseForDomainValues(const Analyzer::InValues *)
RelAlgExecutionUnit rewriteConstrainedByIn(const RelAlgExecutionUnit &ra_exe_unit_in) const
RelAlgExecutionUnit rewriteAggregateOnGroupByColumn(const RelAlgExecutionUnit &ra_exe_unit_in) const
const Expr * get_arg() const
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
std::vector< std::shared_ptr< Analyzer::Expr > > target_exprs_owned_
HashTableBuildDagMap hash_table_build_plan_dag