36 #include "../Parser/ParserNode.h"
37 #include "../Shared/measure.h"
47 const auto compound =
dynamic_cast<const RelCompound*
>(ra);
48 const auto aggregate =
dynamic_cast<const RelAggregate*
>(ra);
49 return ((compound && compound->isAggregate()) || aggregate);
56 std::unordered_set<PhysicalInput> phys_inputs2;
57 for (
auto& phi : phys_inputs) {
79 LOG(
INFO) <<
"Query unable to run in GPU mode, retrying on CPU";
104 std::lock_guard<std::mutex> lock(
executor_->execute_mutex_);
105 int64_t queue_time_ms =
timer_stop(clock_begin);
109 ScopeGuard row_set_holder = [
this, &render_info] {
120 executor_->setupCaching(phys_inputs, phys_table_ids);
139 ed_seq, co, eo, render_info, queue_time_ms);
144 const auto subquery_ra = subquery->getRelAlg();
146 if (subquery_ra->hasContextData()) {
153 subquery->setExecutionResult(std::make_shared<ExecutionResult>(
result));
161 return executor_->computeColRangesCache(phys_inputs);
167 return executor_->computeStringDictionaryGenerations(phys_inputs);
172 return executor_->computeTableGenerations(phys_table_ids);
182 executor_->lit_str_dict_proxy_ =
nullptr;
187 const size_t step_idx,
194 const auto sort =
dynamic_cast<const RelSort*
>(exe_desc_ptr->getBody());
196 size_t shard_count{0};
204 source_work_unit.exe_unit, *
executor_->getCatalog());
207 CHECK_EQ(
size_t(1), sort->inputCount());
208 const auto source = sort->getInput(0);
211 CHECK_EQ(temp_seq.size(), size_t(1));
221 std::make_pair(step_idx, step_idx + 1),
226 merge_type(exe_desc_ptr->getBody()),
227 exe_desc_ptr->getBody()->getId(),
241 executor_->row_set_mem_owner_ = std::make_shared<RowSetMemoryOwner>();
242 executor_->table_generations_ = table_generations;
243 executor_->agg_col_range_cache_ = agg_col_range;
244 executor_->string_dictionary_generations_ = string_dictionary_generations;
251 const int64_t queue_time_ms,
252 const bool with_existing_temp_tables) {
254 if (!with_existing_temp_tables) {
265 for (
size_t i = 0; i < exec_desc_count; i++) {
271 (i == exec_desc_count - 1) ? render_info :
nullptr,
280 const std::pair<size_t, size_t> interval,
284 const int64_t queue_time_ms) {
292 for (
size_t i = interval.first; i < interval.second; i++) {
298 (i == interval.second - 1) ? render_info :
nullptr,
306 const size_t step_idx,
310 const int64_t queue_time_ms) {
314 CHECK(exec_desc_ptr);
315 auto& exec_desc = *exec_desc_ptr;
316 const auto body = exec_desc.getBody();
335 const auto compound =
dynamic_cast<const RelCompound*
>(body);
337 if (compound->isDeleteViaSelect()) {
339 }
else if (compound->isUpdateViaSelect()) {
343 executeCompound(compound, co, eo_work_unit, render_info, queue_time_ms));
344 if (exec_desc.getResult().isFilterPushDownEnabled()) {
351 const auto project =
dynamic_cast<const RelProject*
>(body);
353 if (project->isDeleteViaSelect()) {
355 }
else if (project->isUpdateViaSelect()) {
358 ssize_t prev_count = -1;
363 CHECK(prev_exec_desc);
364 if (dynamic_cast<const RelCompound*>(prev_exec_desc->getBody())) {
365 const auto& prev_exe_result = prev_exec_desc->getResult();
366 const auto prev_result = prev_exe_result.getRows();
368 prev_count =
static_cast<ssize_t
>(prev_result->rowCount());
373 project, co, eo_work_unit, render_info, queue_time_ms, prev_count));
374 if (exec_desc.getResult().isFilterPushDownEnabled()) {
381 const auto aggregate =
dynamic_cast<const RelAggregate*
>(body);
388 const auto filter =
dynamic_cast<const RelFilter*
>(body);
391 executeFilter(filter, co, eo_work_unit, render_info, queue_time_ms));
395 const auto sort =
dynamic_cast<const RelSort*
>(body);
397 exec_desc.setResult(
executeSort(sort, co, eo_work_unit, render_info, queue_time_ms));
398 if (exec_desc.getResult().isFilterPushDownEnabled()) {
405 if (logical_values) {
410 const auto modify =
dynamic_cast<const RelModify*
>(body);
428 CHECK(dynamic_cast<const RelAggregate*>(body));
429 CHECK_EQ(
size_t(1), body->inputCount());
430 const auto input = body->getInput(0);
431 body->setOutputMetainfo(input->getOutputMetainfo());
437 ed.setResult({it->second, input->getOutputMetainfo()});
447 return synthesized_physical_inputs_owned;
451 const RexInput* rex_input)
const override {
454 const auto scan_ra =
dynamic_cast<const RelScan*
>(input_ra);
458 const auto col_id = rex_input->
getIndex();
459 const auto cd = cat_.getMetadataForColumnBySpi(td->tableId, col_id + 1);
460 if (cd && cd->columnType.get_physical_cols() > 0) {
462 std::unordered_set<const RexInput*> synthesized_physical_inputs;
463 for (
auto i = 0; i < cd->columnType.get_physical_cols(); i++) {
464 auto physical_input =
466 synthesized_physical_inputs_owned.emplace_back(physical_input);
467 synthesized_physical_inputs.insert(physical_input);
469 return synthesized_physical_inputs;
478 const std::unordered_set<const RexInput*>& aggregate,
479 const std::unordered_set<const RexInput*>& next_result)
const override {
481 result.insert(next_result.begin(), next_result.end());
491 if (
auto join = dynamic_cast<const RelJoin*>(ra_node)) {
496 auto only_src = ra_node->
getInput(0);
497 const bool is_join =
dynamic_cast<const RelJoin*
>(only_src) ||
498 dynamic_cast<const RelLeftDeepInnerJoin*>(only_src);
499 return is_join ? only_src : ra_node;
502 std::pair<std::unordered_set<const RexInput*>, std::vector<std::shared_ptr<RexInput>>>
506 std::unordered_set<const RexInput*> used_inputs =
507 filter_expr ? visitor.
visit(filter_expr) : std::unordered_set<const RexInput*>{};
509 for (
size_t i = 0; i < sources_size; ++i) {
511 used_inputs.insert(source_inputs.begin(), source_inputs.end());
513 std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.
get_inputs_owned());
514 return std::make_pair(used_inputs, used_inputs_owned);
517 std::pair<std::unordered_set<const RexInput*>, std::vector<std::shared_ptr<RexInput>>>
520 std::unordered_set<const RexInput*> used_inputs;
521 std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
522 const auto source = aggregate->
getInput(0);
525 CHECK_GE(in_metainfo.size(), group_count);
526 for (
size_t i = 0; i < group_count; ++i) {
527 auto synthesized_used_input =
new RexInput(source, i);
528 used_inputs_owned.emplace_back(synthesized_used_input);
529 used_inputs.insert(synthesized_used_input);
531 for (
const auto& agg_expr : aggregate->
getAggExprs()) {
532 for (
size_t i = 0; i < agg_expr->size(); ++i) {
533 const auto operand_idx = agg_expr->getOperand(i);
534 CHECK_GE(in_metainfo.size(),
static_cast<size_t>(operand_idx));
535 auto synthesized_used_input =
new RexInput(source, operand_idx);
536 used_inputs_owned.emplace_back(synthesized_used_input);
537 used_inputs.insert(synthesized_used_input);
540 return std::make_pair(used_inputs, used_inputs_owned);
543 std::pair<std::unordered_set<const RexInput*>, std::vector<std::shared_ptr<RexInput>>>
546 std::unordered_set<const RexInput*> used_inputs;
547 for (
size_t i = 0; i < project->
size(); ++i) {
549 used_inputs.insert(proj_inputs.begin(), proj_inputs.end());
551 std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.
get_inputs_owned());
552 return std::make_pair(used_inputs, used_inputs_owned);
555 std::pair<std::unordered_set<const RexInput*>, std::vector<std::shared_ptr<RexInput>>>
559 std::unordered_set<const RexInput*> used_inputs;
562 used_inputs.insert(table_func_inputs.begin(), table_func_inputs.end());
564 std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.
get_inputs_owned());
565 return std::make_pair(used_inputs, used_inputs_owned);
568 std::pair<std::unordered_set<const RexInput*>, std::vector<std::shared_ptr<RexInput>>>
570 std::unordered_set<const RexInput*> used_inputs;
571 std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
573 for (
size_t nest_level = 0; nest_level < data_sink_node->inputCount(); ++nest_level) {
574 const auto source = data_sink_node->getInput(nest_level);
575 const auto scan_source =
dynamic_cast<const RelScan*
>(source);
577 CHECK(source->getOutputMetainfo().empty());
578 for (
size_t i = 0; i < scan_source->size(); ++i) {
579 auto synthesized_used_input =
new RexInput(scan_source, i);
580 used_inputs_owned.emplace_back(synthesized_used_input);
581 used_inputs.insert(synthesized_used_input);
584 const auto& partial_in_metadata = source->getOutputMetainfo();
585 for (
size_t i = 0; i < partial_in_metadata.size(); ++i) {
586 auto synthesized_used_input =
new RexInput(source, i);
587 used_inputs_owned.emplace_back(synthesized_used_input);
588 used_inputs.insert(synthesized_used_input);
592 return std::make_pair(used_inputs, used_inputs_owned);
596 const auto scan_ra =
dynamic_cast<const RelScan*
>(ra_node);
602 return -ra_node->
getId();
607 const std::vector<size_t>& input_permutation) {
609 std::unordered_map<const RelAlgNode*, int> input_to_nest_level;
610 for (
size_t input_idx = 0; input_idx < data_sink_node->inputCount(); ++input_idx) {
611 const auto input_node_idx =
612 input_permutation.empty() ? input_idx : input_permutation[input_idx];
613 const auto input_ra = data_sink_node->getInput(input_node_idx);
614 const auto it_ok = input_to_nest_level.emplace(input_ra, input_idx);
617 <<
"Assigned input " << input_ra->toString() <<
" to nest level " << input_idx;
619 return input_to_nest_level;
622 std::pair<std::unordered_set<const RexInput*>, std::vector<std::shared_ptr<RexInput>>>
626 if (
auto join = dynamic_cast<const RelJoin*>(data_sink_node)) {
628 const auto condition =
join->getCondition();
630 auto condition_inputs = visitor.
visit(condition);
631 std::vector<std::shared_ptr<RexInput>> condition_inputs_owned(
633 return std::make_pair(condition_inputs, condition_inputs_owned);
636 if (
auto left_deep_join = dynamic_cast<const RelLeftDeepInnerJoin*>(data_sink_node)) {
637 CHECK_GE(left_deep_join->inputCount(), 2u);
638 const auto condition = left_deep_join->getInnerCondition();
641 for (
size_t nesting_level = 1; nesting_level <= left_deep_join->inputCount() - 1;
643 const auto outer_condition = left_deep_join->getOuterCondition(nesting_level);
644 if (outer_condition) {
645 const auto outer_result = visitor.
visit(outer_condition);
646 result.insert(outer_result.begin(), outer_result.end());
649 std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.
get_inputs_owned());
650 return std::make_pair(
result, used_inputs_owned);
654 return std::make_pair(std::unordered_set<const RexInput*>{},
655 std::vector<std::shared_ptr<RexInput>>{});
659 std::vector<const RelAlgNode*> seq;
660 for (
auto join = dynamic_cast<const RelJoin*>(ra);
join;
663 seq.emplace_back(
join->getInput(1));
664 auto lhs =
join->getInput(0);
665 if (!dynamic_cast<const RelJoin*>(lhs)) {
666 seq.emplace_back(lhs);
670 std::reverse(seq.begin(), seq.end());
675 std::vector<InputDescriptor>& input_descs,
677 std::unordered_set<std::shared_ptr<const InputColDescriptor>>& input_col_descs_unique,
679 const std::unordered_set<const RexInput*>& source_used_inputs,
680 const std::unordered_map<const RelAlgNode*, int>& input_to_nest_level) {
681 std::unordered_set<InputDescriptor> input_descs_unique(input_descs.begin(),
684 std::unordered_map<const RelAlgNode*, int> non_join_to_nest_level;
685 for (
const auto node : non_join_src_seq) {
686 non_join_to_nest_level.insert(std::make_pair(node, non_join_to_nest_level.size()));
688 for (
const auto used_input : source_used_inputs) {
689 const auto input_ra = used_input->getSourceNode();
691 const auto col_id = used_input->getIndex();
692 auto it = input_to_nest_level.find(input_ra);
693 if (it == input_to_nest_level.end()) {
694 throw std::runtime_error(
"Bushy joins not supported");
696 const int input_desc = it->second;
697 input_col_descs_unique.insert(std::make_shared<const InputColDescriptor>(
698 dynamic_cast<const RelScan*>(input_ra)
707 std::pair<std::vector<InputDescriptor>,
708 std::list<std::shared_ptr<const InputColDescriptor>>>
710 const std::unordered_set<const RexInput*>& used_inputs,
711 const std::unordered_map<const RelAlgNode*, int>& input_to_nest_level,
712 const std::vector<size_t>& input_permutation,
714 std::vector<InputDescriptor> input_descs;
716 for (
size_t input_idx = 0; input_idx < data_sink_node->inputCount(); ++input_idx) {
717 const auto input_node_idx =
718 input_permutation.empty() ? input_idx : input_permutation[input_idx];
719 const auto input_ra = data_sink_node->getInput(input_node_idx);
721 input_descs.emplace_back(table_id, input_idx);
723 std::sort(input_descs.begin(),
728 std::unordered_set<std::shared_ptr<const InputColDescriptor>> input_col_descs_unique;
731 input_col_descs_unique,
734 input_to_nest_level);
735 std::unordered_set<const RexInput*> join_source_used_inputs;
736 std::vector<std::shared_ptr<RexInput>> join_source_used_inputs_owned;
737 std::tie(join_source_used_inputs, join_source_used_inputs_owned) =
741 input_col_descs_unique,
743 join_source_used_inputs,
744 input_to_nest_level);
745 std::vector<std::shared_ptr<const InputColDescriptor>> input_col_descs(
746 input_col_descs_unique.begin(), input_col_descs_unique.end());
749 input_col_descs.begin(),
750 input_col_descs.end(),
751 [](std::shared_ptr<const InputColDescriptor>
const& lhs,
752 std::shared_ptr<const InputColDescriptor>
const& rhs) {
753 if (lhs->getScanDesc().getNestLevel() == rhs->getScanDesc().getNestLevel()) {
754 return lhs->getColId() < rhs->getColId();
756 return lhs->getScanDesc().getNestLevel() < rhs->getScanDesc().getNestLevel();
759 std::list<std::shared_ptr<const InputColDescriptor>>(input_col_descs.begin(),
760 input_col_descs.end())};
764 std::tuple<std::vector<InputDescriptor>,
765 std::list<std::shared_ptr<const InputColDescriptor>>,
766 std::vector<std::shared_ptr<RexInput>>>
768 const std::unordered_map<const RelAlgNode*, int>& input_to_nest_level,
769 const std::vector<size_t>& input_permutation,
771 std::unordered_set<const RexInput*> used_inputs;
772 std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
773 std::tie(used_inputs, used_inputs_owned) =
get_used_inputs(ra_node, cat);
775 ra_node, used_inputs, input_to_nest_level, input_permutation, cat);
776 return std::make_tuple(
777 input_desc_pair.first, input_desc_pair.second, used_inputs_owned);
785 return project->
size();
805 const std::shared_ptr<Analyzer::Expr> expr) {
806 const auto& ti = expr->get_type_info();
810 auto transient_dict_ti = ti;
813 transient_dict_ti.set_fixed_size();
814 return expr->add_cast(transient_dict_ti);
818 std::vector<std::shared_ptr<Analyzer::Expr>>& scalar_sources,
819 const std::shared_ptr<Analyzer::Expr>& expr) {
823 scalar_sources.push_back(
fold_expr(expr.get()));
831 std::vector<std::shared_ptr<Analyzer::Expr>> scalar_sources;
833 const auto scalar_rex =
scalar_at(i, ra_node);
834 if (dynamic_cast<const RexRef*>(scalar_rex)) {
840 const auto scalar_expr =
842 const auto rewritten_expr =
rewrite_expr(scalar_expr.get());
846 return scalar_sources;
852 const std::string& colName) {
860 if (cast_logical_ti.is_varlen() && cast_logical_ti.is_array()) {
866 if (std::dynamic_pointer_cast<Analyzer::ColumnVar>(expr)) {
871 return expr->add_cast(cast_logical_ti);
881 size_t starting_projection_column_idx) {
882 std::vector<std::shared_ptr<Analyzer::Expr>> scalar_sources;
884 const auto scalar_rex =
scalar_at(i, ra_node);
885 if (dynamic_cast<const RexRef*>(scalar_rex)) {
891 std::shared_ptr<Analyzer::Expr> translated_expr;
896 colNames[i - starting_projection_column_idx]);
901 const auto rewritten_expr =
rewrite_expr(scalar_expr.get());
905 return scalar_sources;
910 const std::vector<std::shared_ptr<Analyzer::Expr>>& scalar_sources) {
914 std::list<std::shared_ptr<Analyzer::Expr>> groupby_exprs;
915 for (
size_t group_idx = 0; group_idx < compound->
getGroupByCount(); ++group_idx) {
918 return groupby_exprs;
923 const std::vector<std::shared_ptr<Analyzer::Expr>>& scalar_sources) {
924 std::list<std::shared_ptr<Analyzer::Expr>> groupby_exprs;
925 for (
size_t group_idx = 0; group_idx < aggregate->
getGroupByCount(); ++group_idx) {
928 return groupby_exprs;
934 const auto filter_expr =
941 std::vector<std::shared_ptr<Analyzer::Expr>>& target_exprs_owned,
942 const std::vector<std::shared_ptr<Analyzer::Expr>>& scalar_sources,
943 const std::list<std::shared_ptr<Analyzer::Expr>>& groupby_exprs,
946 std::vector<Analyzer::Expr*> target_exprs;
947 for (
size_t i = 0; i < compound->
size(); ++i) {
949 const auto target_rex_agg =
dynamic_cast<const RexAgg*
>(target_rex);
950 std::shared_ptr<Analyzer::Expr> target_expr;
951 if (target_rex_agg) {
955 const auto target_rex_scalar =
dynamic_cast<const RexScalar*
>(target_rex);
956 const auto target_rex_ref =
dynamic_cast<const RexRef*
>(target_rex_scalar);
957 if (target_rex_ref) {
958 const auto ref_idx = target_rex_ref->
getIndex();
960 CHECK_LE(ref_idx, groupby_exprs.size());
961 const auto groupby_expr = *std::next(groupby_exprs.begin(), ref_idx - 1);
966 target_expr =
fold_expr(rewritten_expr.get());
975 target_exprs_owned.push_back(target_expr);
976 target_exprs.push_back(target_expr.get());
982 std::vector<std::shared_ptr<Analyzer::Expr>>& target_exprs_owned,
983 const std::vector<std::shared_ptr<Analyzer::Expr>>& scalar_sources,
984 const std::list<std::shared_ptr<Analyzer::Expr>>& groupby_exprs,
987 std::vector<Analyzer::Expr*> target_exprs;
988 size_t group_key_idx = 0;
989 for (
const auto& groupby_expr : groupby_exprs) {
992 target_exprs_owned.push_back(target_expr);
993 target_exprs.push_back(target_expr.get());
996 for (
const auto& target_rex_agg : aggregate->
getAggExprs()) {
1000 target_expr =
fold_expr(target_expr.get());
1001 target_exprs_owned.push_back(target_expr);
1002 target_exprs.push_back(target_expr.get());
1004 return target_exprs;
1008 std::vector<std::shared_ptr<Analyzer::Expr>>& target_exprs_owned,
1009 const std::vector<std::shared_ptr<Analyzer::Expr>>& scalar_sources,
1010 const std::list<std::shared_ptr<Analyzer::Expr>>& groupby_exprs,
1016 size_t starting_projection_column_idx) {
1017 std::vector<Analyzer::Expr*> target_exprs;
1018 for (
size_t i = 0; i < compound->
size(); ++i) {
1020 const auto target_rex_agg =
dynamic_cast<const RexAgg*
>(target_rex);
1021 std::shared_ptr<Analyzer::Expr> target_expr;
1022 if (target_rex_agg) {
1026 const auto target_rex_scalar =
dynamic_cast<const RexScalar*
>(target_rex);
1027 const auto target_rex_ref =
dynamic_cast<const RexRef*
>(target_rex_scalar);
1028 if (target_rex_ref) {
1029 const auto ref_idx = target_rex_ref->
getIndex();
1031 CHECK_LE(ref_idx, groupby_exprs.size());
1032 const auto groupby_expr = *std::next(groupby_exprs.begin(), ref_idx - 1);
1035 if (i >= starting_projection_column_idx &&
1041 colNames[i - starting_projection_column_idx]);
1046 target_expr =
fold_expr(rewritten_expr.get());
1050 target_exprs_owned.push_back(target_expr);
1051 target_exprs.push_back(target_expr.get());
1053 return target_exprs;
1063 if (agg_expr && agg_expr->get_contains_agg()) {
1075 const std::vector<Analyzer::Expr*>& target_exprs) {
1076 std::vector<TargetMetaInfo> targets_meta;
1079 CHECK(target_exprs[i]);
1084 : target_exprs[i]->get_type_info());
1087 return targets_meta;
1093 }
else if (
is_agg(&expr)) {
1102 const std::vector<Analyzer::Expr*>& target_exprs) {
1103 std::vector<TargetMetaInfo> targets_meta;
1104 for (
size_t i = 0; i < ra_node->size(); ++i) {
1105 CHECK(target_exprs[i]);
1107 targets_meta.emplace_back(ra_node->getFieldName(i),
1109 target_exprs[i]->get_type_info());
1111 return targets_meta;
1120 const int64_t queue_time_ms) {
1123 throw std::runtime_error(
1124 "Unsupported update operation encountered. (None-encoded string column updates "
1125 "are not supported.)");
1142 executor_->executeUpdate(work_unit.exe_unit,
1150 update_params.finalizeTransaction();
1152 LOG(
INFO) <<
"Update operation failed.";
1161 const int64_t queue_time_ms) {
1164 throw std::runtime_error(
1165 "Unsupported update operation encountered. (None-encoded string column updates "
1166 "are not supported.)");
1177 const auto input_ra = project->
getInput(0);
1178 if (dynamic_cast<const RelSort*>(input_ra)) {
1179 const auto& input_table =
1182 work_unit.exe_unit.scan_limit = input_table->rowCount();
1194 executor_->executeUpdate(work_unit.exe_unit,
1201 update_params.finalizeTransaction();
1203 LOG(
INFO) <<
"Update operation failed.";
1212 const int64_t queue_time_ms) {
1214 if (!table_descriptor->hasDeletedCol) {
1215 throw std::runtime_error(
1216 "DELETE only supported on tables with the vacuum attribute set to 'delayed'");
1228 DeleteTransactionParameters delete_params;
1231 executor_->executeUpdate(work_unit.exe_unit,
1238 delete_params.finalizeTransaction();
1240 LOG(
INFO) <<
"Delete operation failed.";
1249 const int64_t queue_time_ms) {
1251 if (!table_descriptor->hasDeletedCol) {
1252 throw std::runtime_error(
1253 "DELETE only supported on tables with the vacuum attribute set to 'delayed'");
1264 const auto input_ra = project->
getInput(0);
1265 if (dynamic_cast<const RelSort*>(input_ra)) {
1266 const auto& input_table =
1269 work_unit.exe_unit.scan_limit = input_table->rowCount();
1276 DeleteTransactionParameters delete_params;
1279 executor_->executeUpdate(work_unit.exe_unit,
1286 delete_params.finalizeTransaction();
1288 LOG(
INFO) <<
"Delete operation failed.";
1297 const int64_t queue_time_ms) {
1314 const int64_t queue_time_ms) {
1343 const int64_t queue_time_ms,
1344 const ssize_t previous_count) {
1350 const auto input_ra = project->
getInput(0);
1351 if (dynamic_cast<const RelSort*>(input_ra)) {
1353 const auto& input_table =
1356 work_unit.exe_unit.scan_limit =
1357 std::min(input_table->getLimit(), input_table->rowCount());
1373 const int64_t queue_time_ms) {
1379 throw std::runtime_error(
"Table functions not supported in distributed mode yet");
1382 throw std::runtime_error(
"Table function support is disabled");
1386 const auto body = table_func_work_unit.body;
1389 const auto table_infos =
1401 table_func_work_unit.exe_unit, table_infos, co, eo,
cat_),
1402 body->getOutputMetainfo()};
1406 throw std::runtime_error(
"Table function ran out of memory during execution");
1408 result.setQueueTime(queue_time_ms);
1421 std::vector<std::shared_ptr<Analyzer::Expr>> transformed_tuple;
1422 for (
const auto& element : tuple->getTuple()) {
1425 return makeExpr<Analyzer::ExpressionTuple>(transformed_tuple);
1429 throw std::runtime_error(
"Only columns supported in the window partition for now");
1431 return makeExpr<Analyzer::ColumnVar>(
1432 col->get_type_info(), col->get_table_id(), col->get_column_id(), 1);
1441 const int64_t queue_time_ms) {
1443 CHECK_EQ(query_infos.size(), size_t(1));
1444 if (query_infos.front().info.fragments.size() != 1) {
1445 throw std::runtime_error(
1446 "Only single fragment tables supported for window functions for now");
1448 query_infos.push_back(query_infos.front());
1450 for (
size_t target_index = 0; target_index < ra_exe_unit.
target_exprs.size();
1452 const auto& target_expr = ra_exe_unit.
target_exprs[target_index];
1459 std::shared_ptr<Analyzer::Expr> partition_key_tuple;
1460 if (partition_keys.size() > 1) {
1461 partition_key_tuple = makeExpr<Analyzer::ExpressionTuple>(partition_keys);
1463 if (partition_keys.empty()) {
1464 throw std::runtime_error(
1465 "Empty window function partitions are not supported yet");
1467 CHECK_EQ(partition_keys.size(), size_t(1));
1468 partition_key_tuple = partition_keys.front();
1471 const auto partition_key_cond =
1472 makeExpr<Analyzer::BinOper>(
kBOOLEAN,
1475 partition_key_tuple,
1478 window_func, partition_key_cond, ra_exe_unit, query_infos, co, column_cache_map);
1480 window_project_node_context->addWindowFunctionContext(std::move(context),
1487 const std::shared_ptr<Analyzer::BinOper>& partition_key_cond,
1489 const std::vector<InputTableInfo>& query_infos,
1495 const auto join_table_or_err =
1496 executor_->buildHashTableForQualifier(partition_key_cond,
1501 if (!join_table_or_err.fail_reason.empty()) {
1502 throw std::runtime_error(join_table_or_err.fail_reason);
1504 CHECK(join_table_or_err.hash_table->getHashType() ==
1507 std::vector<std::shared_ptr<Chunk_NS::Chunk>> chunks_owner;
1508 const size_t elem_count = query_infos.front().info.fragments.front().getNumTuples();
1509 auto context = std::make_unique<WindowFunctionContext>(
1510 window_func, join_table_or_err.hash_table, elem_count, co.
device_type_);
1511 for (
const auto& order_key : order_keys) {
1512 const auto order_col =
1515 throw std::runtime_error(
"Only order by columns supported for now");
1517 const int8_t* column;
1518 size_t join_col_elem_count;
1519 std::tie(column, join_col_elem_count) =
1522 query_infos.front().info.fragments.front(),
1527 CHECK_EQ(join_col_elem_count, elem_count);
1528 context->addOrderColumn(column, order_col.get(), chunks_owner);
1537 const int64_t queue_time_ms) {
1538 const auto work_unit =
1541 work_unit, filter->
getOutputMetainfo(),
false, co, eo, render_info, queue_time_ms);
1547 throw std::runtime_error(
"EXPLAIN not supported for ModifyTable");
1556 std::vector<TargetMetaInfo> empty_targets;
1557 return {rs, empty_targets};
1564 throw std::runtime_error(
"EXPLAIN not supported for LogicalValues");
1571 const auto& tuple_type = logical_values->
getTupleType();
1572 for (
size_t i = 0; i < tuple_type.size(); ++i) {
1576 std::vector<std::unique_ptr<Analyzer::ColumnVar>> owned_column_expressions;
1577 std::vector<Analyzer::Expr*> target_expressions;
1578 for (
const auto& tuple_component : tuple_type) {
1579 const auto column_var =
1581 target_expressions.push_back(column_var);
1582 owned_column_expressions.emplace_back(column_var);
1584 std::vector<TargetInfo> target_infos;
1585 for (
const auto& tuple_type_component : tuple_type) {
1588 tuple_type_component.get_type_info(),
1593 auto rs = std::make_shared<ResultSet>(target_infos,
1598 return {rs, tuple_type};
1606 std::list<Analyzer::OrderEntry>
result;
1609 result.emplace_back(sort_field.getField() + 1,
1617 const auto aggregate =
dynamic_cast<const RelAggregate*
>(ra);
1621 const auto compound =
dynamic_cast<const RelCompound*
>(ra);
1622 return (compound && compound->isAggregate()) ? 0 : limit;
1626 return !order_entries.empty() && order_entries.front().is_desc;
1635 const int64_t queue_time_ms) {
1637 const auto source = sort->
getInput(0);
1638 if (dynamic_cast<const RelSort*>(source)) {
1639 throw std::runtime_error(
"Sort node not supported as input to another sort");
1650 auto& aggregated_result = it->second;
1651 auto& result_rows = aggregated_result.rs;
1652 const size_t limit = sort->
getLimit();
1653 const size_t offset = sort->
getOffset();
1655 if (limit || offset) {
1656 if (!order_entries.empty()) {
1657 result_rows->sort(order_entries, limit + offset);
1659 result_rows->dropFirstN(offset);
1661 result_rows->keepFirstN(limit);
1670 std::list<std::shared_ptr<Analyzer::Expr>> groupby_exprs;
1671 bool is_desc{
false};
1674 is_desc =
first_oe_is_desc(source_work_unit.exe_unit.sort_info.order_entries);
1690 groupby_exprs = source_work_unit.exe_unit.groupby_exprs;
1692 source->getOutputMetainfo(),
1698 if (render_info && render_info->isPotentialInSituRender()) {
1699 return source_result;
1701 if (source_result.isFilterPushDownEnabled()) {
1702 return source_result;
1704 auto rows_to_sort = source_result.
getRows();
1706 return {rows_to_sort, {}};
1708 const size_t limit = sort->
getLimit();
1709 const size_t offset = sort->
getOffset();
1710 if (sort->
collationCount() != 0 && !rows_to_sort->definitelyHasNoRows() &&
1712 rows_to_sort->getQueryMemDesc())) {
1713 rows_to_sort->sort(source_work_unit.exe_unit.sort_info.order_entries,
1716 if (limit || offset) {
1718 if (offset >= rows_to_sort->rowCount()) {
1719 rows_to_sort->dropFirstN(offset);
1721 rows_to_sort->keepFirstN(limit + offset);
1724 rows_to_sort->dropFirstN(offset);
1726 rows_to_sort->keepFirstN(limit);
1730 return {rows_to_sort, source_result.getTargetsMeta()};
1732 CHECK_EQ(
size_t(1), groupby_exprs.size());
1737 return {std::make_shared<ResultSet>(std::vector<TargetInfo>{},
1747 const bool just_explain) {
1748 const auto source = sort->
getInput(0);
1749 const size_t limit = sort->
getLimit();
1750 const size_t offset = sort->
getOffset();
1752 const size_t scan_total_limit =
1754 size_t max_groups_buffer_entry_guess{
1758 SortInfo sort_info{order_entries, sort_algorithm, limit, offset};
1759 auto source_work_unit =
createWorkUnit(source, sort_info, just_explain);
1760 const auto& source_exe_unit = source_work_unit.exe_unit;
1761 if (source_exe_unit.groupby_exprs.size() == 1) {
1762 if (!source_exe_unit.groupby_exprs.front()) {
1775 return {{source_exe_unit.input_descs,
1776 std::move(source_exe_unit.input_col_descs),
1777 source_exe_unit.simple_quals,
1778 source_exe_unit.quals,
1779 source_exe_unit.join_quals,
1780 source_exe_unit.groupby_exprs,
1781 source_exe_unit.target_exprs,
1783 {sort_info.order_entries, sort_algorithm, limit, offset},
1785 source_exe_unit.query_features},
1787 max_groups_buffer_entry_guess,
1788 std::move(source_work_unit.query_rewriter),
1789 source_work_unit.input_permutation,
1790 source_work_unit.left_deep_join_input_sizes};
1802 CHECK(!table_infos.empty());
1803 const auto& first_table = table_infos.front();
1804 size_t max_num_groups = first_table.info.getNumTuplesUpperBound();
1805 for (
const auto& table_info : table_infos) {
1806 if (table_info.info.getNumTuplesUpperBound() > max_num_groups) {
1807 max_num_groups = table_info.info.getNumTuplesUpperBound();
1810 return std::max(max_num_groups,
size_t(1));
1820 for (
const auto target_expr : ra_exe_unit.
target_exprs) {
1821 if (dynamic_cast<const Analyzer::AggExpr*>(target_expr)) {
1833 return !(ra_exe_unit.
quals.empty() && ra_exe_unit.
join_quals.empty() &&
1839 const std::vector<InputTableInfo>& table_infos,
1840 const Executor* executor,
1842 std::vector<std::shared_ptr<Analyzer::Expr>>& target_exprs_owned) {
1844 for (
size_t i = 0; i < ra_exe_unit.
target_exprs.size(); ++i) {
1850 CHECK(dynamic_cast<const Analyzer::AggExpr*>(target_expr));
1853 const auto& arg_ti = arg->get_type_info();
1859 if (!(arg_ti.is_number() || arg_ti.is_boolean() || arg_ti.is_time() ||
1860 (arg_ti.is_string() && arg_ti.get_compression() ==
kENCODING_DICT))) {
1871 const auto bitmap_sz_bits = arg_range.getIntMax() - arg_range.getIntMin() + 1;
1872 const auto sub_bitmap_count =
1874 int64_t approx_bitmap_sz_bits{0};
1875 const auto error_rate =
1878 CHECK(error_rate->get_type_info().get_type() ==
kINT);
1879 CHECK_GE(error_rate->get_constval().intval, 1);
1885 arg_range.getIntMin(),
1886 approx_bitmap_sz_bits,
1891 arg_range.getIntMin(),
1896 if (approx_count_distinct_desc.bitmapPaddedSizeBytes() >=
1897 precise_count_distinct_desc.bitmapPaddedSizeBytes()) {
1898 auto precise_count_distinct = makeExpr<Analyzer::AggExpr>(
1900 target_exprs_owned.push_back(precise_count_distinct);
1901 ra_exe_unit.
target_exprs[i] = precise_count_distinct.get();
1908 const std::vector<Analyzer::Expr*>& work_unit_target_exprs,
1909 const std::vector<TargetMetaInfo>& targets_meta) {
1910 CHECK_EQ(work_unit_target_exprs.size(), targets_meta.size());
1912 for (
size_t i = 0; i < targets_meta.size(); ++i) {
1913 render_info.
targets.emplace_back(std::make_shared<Analyzer::TargetEntry>(
1914 targets_meta[i].get_resname(),
1915 work_unit_target_exprs[i]->get_shared_ptr(),
1931 const std::vector<TargetMetaInfo>& targets_meta,
1936 const int64_t queue_time_ms,
1937 const ssize_t previous_count) {
1945 throw std::runtime_error(
1946 "Window functions support not supported in distributed mode");
1949 throw std::runtime_error(
"Window functions support is disabled");
1961 const auto body = work_unit.
body;
1967 auto& aggregated_result = it->second;
1968 auto& result_rows = aggregated_result.rs;
1970 body->setOutputMetainfo(aggregated_result.targets_meta);
1982 CHECK_EQ(table_infos.size(), size_t(1));
1983 CHECK_EQ(table_infos.front().info.fragments.size(), size_t(1));
1984 max_groups_buffer_entry_guess =
1985 table_infos.front().info.fragments.front().getNumTuples();
1986 ra_exe_unit.scan_limit = max_groups_buffer_entry_guess;
1989 ra_exe_unit.scan_limit =
static_cast<size_t>(previous_count);
1993 ra_exe_unit.scan_limit = 0;
1994 ra_exe_unit.use_bump_allocator =
true;
1997 if (filter_count_all >= 0) {
1998 ra_exe_unit.scan_limit = std::max(filter_count_all, ssize_t(1));
2011 auto execute_and_handle_errors =
2012 [&](
const auto max_groups_buffer_entry_guess_in,
2017 auto local_groups_buffer_entry_guess = max_groups_buffer_entry_guess_in;
2019 return {
executor_->executeWorkUnit(local_groups_buffer_entry_guess,
2028 has_cardinality_estimation,
2034 {ra_exe_unit, work_unit.
body, local_groups_buffer_entry_guess},
2046 result = execute_and_handle_errors(
2047 max_groups_buffer_entry_guess,
2050 const auto estimated_groups_buffer_entry_guess =
2053 CHECK_GT(estimated_groups_buffer_entry_guess,
size_t(0));
2054 result = execute_and_handle_errors(estimated_groups_buffer_entry_guess,
true);
2057 result.setQueueTime(queue_time_ms);
2063 std::make_shared<ResultSet>(queue_time_ms, 0,
executor_->row_set_mem_owner_),
2080 const auto count_all_exe_unit =
2098 }
catch (
const std::exception& e) {
2099 LOG(
WARNING) <<
"Failed to run pre-flight filtered count with error " << e.what();
2102 const auto count_row = count_all_result->getNextRow(
false,
false);
2103 CHECK_EQ(
size_t(1), count_row.size());
2104 const auto& count_tv = count_row.front();
2105 const auto count_scalar_tv = boost::get<ScalarTargetValue>(&count_tv);
2106 CHECK(count_scalar_tv);
2107 const auto count_ptr = boost::get<int64_t>(count_scalar_tv);
2110 auto count_upper_bound =
static_cast<size_t>(*count_ptr);
2111 return std::max(count_upper_bound,
size_t(1));
2115 const auto& ra_exe_unit = work_unit.
exe_unit;
2116 if (ra_exe_unit.input_descs.size() != 1) {
2119 const auto& table_desc = ra_exe_unit.
input_descs.front();
2123 const int table_id = table_desc.getTableId();
2124 for (
const auto simple_qual : ra_exe_unit.simple_quals) {
2125 const auto comp_expr =
2127 if (!comp_expr || comp_expr->get_optype() !=
kEQ) {
2132 if (!lhs_col || !lhs_col->get_table_id() || lhs_col->get_rte_idx()) {
2135 const auto rhs = comp_expr->get_right_operand();
2141 if (cd->isVirtualCol) {
2151 const std::vector<TargetMetaInfo>& targets_meta,
2156 const bool was_multifrag_kernel_launch,
2157 const int64_t queue_time_ms) {
2162 auto ra_exe_unit_in = work_unit.
exe_unit;
2187 if (was_multifrag_kernel_launch) {
2191 LOG(
WARNING) <<
"Multifrag query ran out of memory, retrying with multifragment "
2192 "kernels disabled.";
2208 result.setQueueTime(queue_time_ms);
2211 LOG(
WARNING) <<
"Kernel per fragment query ran out of memory, retrying on CPU.";
2229 VLOG(1) <<
"Resetting max groups buffer entry guess.";
2230 max_groups_buffer_entry_guess = 0;
2232 int iteration_ctr = -1;
2257 CHECK(max_groups_buffer_entry_guess);
2261 throw std::runtime_error(
"Query ran out of output slots in the result");
2263 max_groups_buffer_entry_guess *= 2;
2264 LOG(
WARNING) <<
"Query ran out of slots in the output buffer, retrying with max "
2265 "groups buffer entry "
2267 << max_groups_buffer_entry_guess;
2273 result.setQueueTime(queue_time_ms);
2280 LOG(
ERROR) <<
"Query execution failed with error "
2289 LOG(
INFO) <<
"Query ran out of GPU memory, attempting punt to CPU";
2291 throw std::runtime_error(
2292 "Query ran out of GPU memory, unable to automatically retry on CPU");
2300 if (error_code < 0) {
2301 return "Ran out of slots in the query output buffer";
2303 switch (error_code) {
2305 return "Division by zero";
2307 return "Query couldn't keep the entire working set of columns in GPU memory";
2309 return "Self joins not supported yet";
2311 return "Not enough host memory to execute the query";
2313 return "Overflow or underflow";
2315 return "Query execution has exceeded the time limit";
2317 return "Query execution has been interrupted";
2319 return "Columnar conversion not supported for variable length types";
2321 return "Too many literals in the query";
2323 return "NONE ENCODED String types are not supported as input result set.";
2325 return "Not enough OpenGL memory to render the query results";
2327 return "Streaming-Top-N not supported in Render Query";
2334 const bool just_explain) {
2335 const auto compound =
dynamic_cast<const RelCompound*
>(node);
2339 const auto project =
dynamic_cast<const RelProject*
>(node);
2343 const auto aggregate =
dynamic_cast<const RelAggregate*
>(node);
2347 const auto filter =
dynamic_cast<const RelFilter*
>(node);
2356 if (
auto join = dynamic_cast<const RelJoin*>(sink)) {
2357 return join->getJoinType();
2359 if (dynamic_cast<const RelLeftDeepInnerJoin*>(sink)) {
2367 const auto condition =
dynamic_cast<const RexOperator*
>(scalar);
2368 if (!condition || condition->getOperator() !=
kOR || condition->size() != 2) {
2371 const auto equi_join_condition =
2372 dynamic_cast<const RexOperator*
>(condition->getOperand(0));
2373 if (!equi_join_condition || equi_join_condition->getOperator() !=
kEQ) {
2376 const auto both_are_null_condition =
2377 dynamic_cast<const RexOperator*
>(condition->getOperand(1));
2378 if (!both_are_null_condition || both_are_null_condition->getOperator() !=
kAND ||
2379 both_are_null_condition->size() != 2) {
2382 const auto lhs_is_null =
2383 dynamic_cast<const RexOperator*
>(both_are_null_condition->getOperand(0));
2384 const auto rhs_is_null =
2385 dynamic_cast<const RexOperator*
>(both_are_null_condition->getOperand(1));
2386 if (!lhs_is_null || !rhs_is_null || lhs_is_null->getOperator() !=
kISNULL ||
2387 rhs_is_null->getOperator() !=
kISNULL) {
2390 CHECK_EQ(
size_t(1), lhs_is_null->size());
2391 CHECK_EQ(
size_t(1), rhs_is_null->size());
2392 CHECK_EQ(
size_t(2), equi_join_condition->size());
2393 const auto eq_lhs =
dynamic_cast<const RexInput*
>(equi_join_condition->getOperand(0));
2394 const auto eq_rhs =
dynamic_cast<const RexInput*
>(equi_join_condition->getOperand(1));
2395 const auto is_null_lhs =
dynamic_cast<const RexInput*
>(lhs_is_null->getOperand(0));
2396 const auto is_null_rhs =
dynamic_cast<const RexInput*
>(rhs_is_null->getOperand(0));
2397 if (!eq_lhs || !eq_rhs || !is_null_lhs || !is_null_rhs) {
2400 std::vector<std::unique_ptr<const RexScalar>> eq_operands;
2401 if (*eq_lhs == *is_null_lhs && *eq_rhs == *is_null_rhs) {
2403 auto lhs_op_copy = deep_copy_visitor.
visit(equi_join_condition->getOperand(0));
2404 auto rhs_op_copy = deep_copy_visitor.
visit(equi_join_condition->getOperand(1));
2405 eq_operands.emplace_back(lhs_op_copy.release());
2406 eq_operands.emplace_back(rhs_op_copy.release());
2407 return boost::make_unique<const RexOperator>(
2408 kBW_EQ, eq_operands, equi_join_condition->getType());
2415 const auto condition =
dynamic_cast<const RexOperator*
>(scalar);
2416 if (condition && condition->getOperator() ==
kAND) {
2417 CHECK_GE(condition->size(), size_t(2));
2422 for (
size_t i = 1; i < condition->size(); ++i) {
2423 std::vector<std::unique_ptr<const RexScalar>> and_operands;
2424 and_operands.emplace_back(std::move(acc));
2427 boost::make_unique<const RexOperator>(
kAND, and_operands, condition->getType());
2437 for (
size_t nesting_level = 1; nesting_level <= left_deep_join->
inputCount() - 1;
2448 std::vector<InputDescriptor>& input_descs,
2449 std::list<std::shared_ptr<const InputColDescriptor>>& input_col_descs,
2451 std::unordered_map<const RelAlgNode*, int>& input_to_nest_level,
2453 const std::vector<InputTableInfo>& query_infos,
2454 const Executor* executor) {
2460 const auto& cat = *executor->getCatalog();
2461 for (
const auto& table_info : query_infos) {
2462 if (table_info.table_id < 0) {
2465 const auto td = cat.getMetadataForTable(table_info.table_id);
2471 const auto input_permutation =
2474 std::tie(input_descs, input_col_descs, std::ignore) =
2475 get_input_desc(node, input_to_nest_level, input_permutation, cat);
2476 return input_permutation;
2481 std::vector<size_t> input_sizes;
2482 for (
size_t i = 0; i < left_deep_join->
inputCount(); ++i) {
2484 input_sizes.push_back(inputs.size());
2490 const std::list<std::shared_ptr<Analyzer::Expr>>& quals) {
2491 std::list<std::shared_ptr<Analyzer::Expr>> rewritten_quals;
2492 for (
const auto& qual : quals) {
2494 rewritten_quals.push_back(rewritten_qual ? rewritten_qual : qual);
2496 return rewritten_quals;
2504 const bool just_explain) {
2505 std::vector<InputDescriptor> input_descs;
2506 std::list<std::shared_ptr<const InputColDescriptor>> input_col_descs;
2508 std::tie(input_descs, input_col_descs, std::ignore) =
2512 const auto left_deep_join =
2517 if (left_deep_join) {
2519 left_deep_join, input_descs, input_to_nest_level, just_explain);
2524 input_to_nest_level,
2529 size_t starting_projection_column_idx =
2531 CHECK_GT(starting_projection_column_idx, 0u);
2532 const auto scalar_sources =
2538 starting_projection_column_idx);
2550 starting_projection_column_idx);
2556 const auto update_expr_iter =
2557 std::next(target_exprs.cbegin(), starting_projection_column_idx);
2558 decltype(target_exprs) filtered_target_exprs(update_expr_iter, target_exprs.end());
2561 std::unordered_set<int> id_accumulator;
2563 for (
auto const& expr :
2564 boost::make_iterator_range(update_expr_iter, target_exprs.end())) {
2565 auto used_column_ids = used_columns_visitor.
visit(expr);
2566 id_accumulator.insert(used_column_ids.begin(), used_column_ids.end());
2568 for (
auto const& expr : quals_cf.simple_quals) {
2569 auto simple_quals_used_column_ids = used_columns_visitor.visit(expr.get());
2570 id_accumulator.insert(simple_quals_used_column_ids.begin(),
2571 simple_quals_used_column_ids.end());
2573 for (
auto const& expr : quals_cf.quals) {
2574 auto quals_used_column_ids = used_columns_visitor.visit(expr.get());
2575 id_accumulator.insert(quals_used_column_ids.begin(), quals_used_column_ids.end());
2578 decltype(input_col_descs) filtered_input_col_descs;
2579 for (
auto col_desc : input_col_descs) {
2580 if (id_accumulator.find(col_desc->getColId()) != id_accumulator.end()) {
2581 filtered_input_col_descs.push_back(col_desc);
2586 filtered_input_col_descs,
2589 left_deep_join_quals,
2591 filtered_target_exprs,
2597 auto query_rewriter = std::make_unique<QueryRewriter>(query_infos,
executor_);
2598 const auto rewritten_exe_unit = query_rewriter->rewrite(exe_unit);
2599 const auto targets_meta =
2602 return {rewritten_exe_unit,
2605 std::move(query_rewriter)};
2611 const bool just_explain) {
2612 std::vector<InputDescriptor> input_descs;
2613 std::list<std::shared_ptr<const InputColDescriptor>> input_col_descs;
2615 std::tie(input_descs, input_col_descs, std::ignore) =
2619 const auto left_deep_join =
2624 std::vector<size_t> input_permutation;
2625 std::vector<size_t> left_deep_join_input_sizes;
2626 if (left_deep_join) {
2629 left_deep_join, input_descs, input_to_nest_level, just_explain);
2631 std::find(join_types.begin(), join_types.end(),
JoinType::LEFT) ==
2635 left_deep_join_quals,
2636 input_to_nest_level,
2641 std::tie(input_descs, input_col_descs, std::ignore) =
2644 left_deep_join, input_descs, input_to_nest_level, just_explain);
2650 input_to_nest_level,
2665 left_deep_join_quals,
2673 auto query_rewriter = std::make_unique<QueryRewriter>(query_infos,
executor_);
2674 const auto rewritten_exe_unit = query_rewriter->rewrite(exe_unit);
2675 const auto targets_meta =
get_targets_meta(compound, rewritten_exe_unit.target_exprs);
2677 return {rewritten_exe_unit,
2680 std::move(query_rewriter),
2682 left_deep_join_input_sizes};
2689 const auto bin_oper =
dynamic_cast<const RexOperator*
>(qual_expr);
2690 if (!bin_oper || bin_oper->getOperator() !=
kAND) {
2693 CHECK_GE(bin_oper->size(), size_t(2));
2695 for (
size_t i = 1; i < bin_oper->size(); ++i) {
2697 lhs_cf.insert(lhs_cf.end(), rhs_cf.begin(), rhs_cf.end());
2703 const std::vector<std::shared_ptr<Analyzer::Expr>>& factors,
2705 CHECK(!factors.empty());
2706 auto acc = factors.front();
2707 for (
size_t i = 1; i < factors.size(); ++i) {
2713 template <
class QualsList>
2715 const std::shared_ptr<Analyzer::Expr>& needle) {
2716 for (
const auto& qual : haystack) {
2717 if (*qual == *needle) {
2728 const std::shared_ptr<Analyzer::Expr>& expr) {
2730 CHECK_GE(expr_terms.size(), size_t(1));
2731 const auto& first_term = expr_terms.front();
2733 std::vector<std::shared_ptr<Analyzer::Expr>> common_factors;
2736 for (
const auto& first_term_factor : first_term_factors.quals) {
2738 expr_terms.size() > 1;
2739 for (
size_t i = 1; i < expr_terms.size(); ++i) {
2747 common_factors.push_back(first_term_factor);
2750 if (common_factors.empty()) {
2754 std::vector<std::shared_ptr<Analyzer::Expr>> remaining_terms;
2755 for (
const auto& term : expr_terms) {
2757 std::vector<std::shared_ptr<Analyzer::Expr>> remaining_quals(
2758 term_cf.simple_quals.begin(), term_cf.simple_quals.end());
2759 for (
const auto& qual : term_cf.quals) {
2761 remaining_quals.push_back(qual);
2764 if (!remaining_quals.empty()) {
2770 if (remaining_terms.empty()) {
2781 const std::vector<JoinType>& join_types,
2782 const std::unordered_map<const RelAlgNode*, int>& input_to_nest_level,
2783 const bool just_explain)
const {
2787 input_to_nest_level,
2793 std::list<std::shared_ptr<Analyzer::Expr>> join_condition_quals;
2794 for (
const auto rex_condition_component : rex_condition_cf) {
2796 const auto join_condition =
2798 bw_equals ? bw_equals.get() : rex_condition_component));
2800 join_condition_quals.insert(join_condition_quals.end(),
2801 join_condition_cf.quals.begin(),
2802 join_condition_cf.quals.end());
2803 join_condition_quals.insert(join_condition_quals.end(),
2804 join_condition_cf.simple_quals.begin(),
2805 join_condition_cf.simple_quals.end());
2815 const std::vector<InputDescriptor>& input_descs,
2816 const std::unordered_map<const RelAlgNode*, int>& input_to_nest_level,
2817 const bool just_explain) {
2823 std::unordered_set<std::shared_ptr<Analyzer::Expr>> visited_quals;
2824 for (
size_t rte_idx = 1; rte_idx < input_descs.size(); ++rte_idx) {
2826 if (outer_condition) {
2827 result[rte_idx - 1].quals =
2828 makeJoinQuals(outer_condition, join_types, input_to_nest_level, just_explain);
2829 CHECK_LE(rte_idx, join_types.size());
2834 for (
const auto qual : join_condition_quals) {
2835 if (visited_quals.count(qual)) {
2838 const auto qual_rte_idx = rte_idx_visitor.visit(qual.get());
2839 if (static_cast<size_t>(qual_rte_idx) <= rte_idx) {
2840 const auto it_ok = visited_quals.emplace(qual);
2841 CHECK(it_ok.second);
2842 result[rte_idx - 1].quals.push_back(qual);
2845 CHECK_LE(rte_idx, join_types.size());
2856 const size_t nest_level,
2857 const std::vector<TargetMetaInfo>& in_metainfo,
2858 const std::unordered_map<const RelAlgNode*, int>& input_to_nest_level) {
2861 const auto input = ra_node->
getInput(nest_level);
2862 const auto it_rte_idx = input_to_nest_level.find(input);
2863 CHECK(it_rte_idx != input_to_nest_level.end());
2864 const int rte_idx = it_rte_idx->second;
2866 std::vector<std::shared_ptr<Analyzer::Expr>> inputs;
2867 const auto scan_ra =
dynamic_cast<const RelScan*
>(input);
2869 for (
const auto& input_meta : in_metainfo) {
2871 std::make_shared<Analyzer::ColumnVar>(input_meta.get_type_info(),
2873 scan_ra ? input_idx + 1 : input_idx,
2885 const bool just_explain) {
2886 std::vector<InputDescriptor> input_descs;
2887 std::list<std::shared_ptr<const InputColDescriptor>> input_col_descs;
2888 std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
2890 std::tie(input_descs, input_col_descs, used_inputs_owned) =
2896 input_to_nest_level,
2902 const auto source = aggregate->
getInput(0);
2904 const auto scalar_sources =
2911 return {{input_descs,
2931 const bool just_explain) {
2932 std::vector<InputDescriptor> input_descs;
2933 std::list<std::shared_ptr<const InputColDescriptor>> input_col_descs;
2935 std::tie(input_descs, input_col_descs, std::ignore) =
2937 const auto left_deep_join =
2942 if (left_deep_join) {
2944 left_deep_join, input_descs, input_to_nest_level, just_explain);
2949 input_to_nest_level,
2954 size_t starting_projection_column_idx =
2956 CHECK_GT(starting_projection_column_idx, 0u);
2957 auto target_exprs_owned =
2963 starting_projection_column_idx);
2969 const auto update_expr_iter =
2970 std::next(target_exprs.cbegin(), starting_projection_column_idx);
2971 decltype(target_exprs) filtered_target_exprs(update_expr_iter, target_exprs.end());
2974 std::unordered_set<int> id_accumulator;
2976 for (
auto const& expr :
2977 boost::make_iterator_range(update_expr_iter, target_exprs.end())) {
2978 auto used_column_ids = used_columns_visitor.
visit(expr);
2979 id_accumulator.insert(used_column_ids.begin(), used_column_ids.end());
2982 decltype(input_col_descs) filtered_input_col_descs;
2983 for (
auto col_desc : input_col_descs) {
2984 if (id_accumulator.find(col_desc->getColId()) != id_accumulator.end()) {
2985 filtered_input_col_descs.push_back(col_desc);
2989 const auto targets_meta =
2992 return {{input_descs,
2993 filtered_input_col_descs,
2996 left_deep_join_quals,
2998 filtered_target_exprs,
3011 const bool just_explain) {
3012 std::vector<InputDescriptor> input_descs;
3013 std::list<std::shared_ptr<const InputColDescriptor>> input_col_descs;
3015 std::tie(input_descs, input_col_descs, std::ignore) =
3019 const auto left_deep_join =
3024 std::vector<size_t> input_permutation;
3025 std::vector<size_t> left_deep_join_input_sizes;
3026 if (left_deep_join) {
3030 left_deep_join, input_descs, input_to_nest_level, just_explain);
3034 left_deep_join_quals,
3035 input_to_nest_level,
3040 std::tie(input_descs, input_col_descs, std::ignore) =
3043 left_deep_join, input_descs, input_to_nest_level, just_explain);
3050 input_to_nest_level,
3063 left_deep_join_quals,
3071 auto query_rewriter = std::make_unique<QueryRewriter>(query_infos,
executor_);
3072 const auto rewritten_exe_unit = query_rewriter->rewrite(exe_unit);
3073 const auto targets_meta =
get_targets_meta(project, rewritten_exe_unit.target_exprs);
3075 return {rewritten_exe_unit,
3078 std::move(query_rewriter),
3080 left_deep_join_input_sizes};
3085 const bool just_explain) {
3086 std::vector<InputDescriptor> input_descs;
3087 std::list<std::shared_ptr<const InputColDescriptor>> input_col_descs;
3089 std::tie(input_descs, input_col_descs, std::ignore) =
3102 std::vector<Analyzer::ColumnVar*> input_col_exprs;
3103 for (
auto input_expr : input_exprs) {
3104 if (
auto col_var = dynamic_cast<Analyzer::ColumnVar*>(input_expr)) {
3105 input_col_exprs.push_back(col_var);
3110 const auto& table_function_impl =
3113 std::vector<Analyzer::Expr*> table_func_outputs;
3114 for (
size_t i = 0; i < table_function_impl.getOutputsSize(); i++) {
3120 std::optional<size_t> output_row_multiplier;
3121 if (table_function_impl.hasUserSpecifiedOutputMultiplier()) {
3122 const auto parameter_index = table_function_impl.getOutputRowParameter();
3123 CHECK_GT(parameter_index,
size_t(0));
3125 const auto parameter_expr_literal =
dynamic_cast<const RexLiteral*
>(parameter_expr);
3126 if (!parameter_expr_literal) {
3127 throw std::runtime_error(
3128 "Provided output buffer multiplier parameter is not a literal. Only literal "
3129 "values are supported with output buffer multiplier configured table "
3132 int64_t literal_val = parameter_expr_literal->getVal<int64_t>();
3133 if (literal_val < 0) {
3134 throw std::runtime_error(
"Provided output row multiplier " +
3136 " is not valid for table functions.");
3138 output_row_multiplier =
static_cast<size_t>(literal_val);
3147 output_row_multiplier,
3151 return {exe_unit, table_func};
3156 std::pair<std::vector<TargetMetaInfo>, std::vector<std::shared_ptr<Analyzer::Expr>>>
3159 const std::vector<std::shared_ptr<RexInput>>& inputs_owned,
3160 const std::unordered_map<const RelAlgNode*, int>& input_to_nest_level) {
3161 std::vector<TargetMetaInfo> in_metainfo;
3162 std::vector<std::shared_ptr<Analyzer::Expr>> exprs_owned;
3164 auto input_it = inputs_owned.begin();
3165 for (
size_t nest_level = 0; nest_level < data_sink_node->inputCount(); ++nest_level) {
3166 const auto source = data_sink_node->getInput(nest_level);
3167 const auto scan_source =
dynamic_cast<const RelScan*
>(source);
3169 CHECK(source->getOutputMetainfo().empty());
3170 std::vector<std::shared_ptr<Analyzer::Expr>> scalar_sources_owned;
3171 for (
size_t i = 0; i < scan_source->size(); ++i, ++input_it) {
3174 const auto source_metadata =
3177 in_metainfo.end(), source_metadata.begin(), source_metadata.end());
3179 exprs_owned.end(), scalar_sources_owned.begin(), scalar_sources_owned.end());
3181 const auto& source_metadata = source->getOutputMetainfo();
3182 input_it += source_metadata.size();
3184 in_metainfo.end(), source_metadata.begin(), source_metadata.end());
3186 data_sink_node, nest_level, source_metadata, input_to_nest_level);
3188 exprs_owned.end(), scalar_sources_owned.begin(), scalar_sources_owned.end());
3191 return std::make_pair(in_metainfo, exprs_owned);
3198 const bool just_explain) {
3200 std::vector<InputDescriptor> input_descs;
3201 std::list<std::shared_ptr<const InputColDescriptor>> input_col_descs;
3202 std::vector<TargetMetaInfo> in_metainfo;
3203 std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
3204 std::vector<std::shared_ptr<Analyzer::Expr>> target_exprs_owned;
3207 std::tie(input_descs, input_col_descs, used_inputs_owned) =
3213 input_to_nest_level,
3218 std::tie(in_metainfo, target_exprs_owned) =
3219 get_inputs_meta(filter, translator, used_inputs_owned, input_to_nest_level);
3220 const auto filter_expr = translator.translateScalarRex(filter->
getCondition());
3221 const auto qual =
fold_expr(filter_expr.get());
3227 return {{input_descs,
3230 {rewritten_qual ? rewritten_qual : qual},
const size_t getGroupByCount() const
SQLTypeInfo getOutputSQLType(const size_t idx) const
bool is_agg(const Analyzer::Expr *expr)
Analyzer::ExpressionPtr rewrite_array_elements(Analyzer::Expr const *expr)
std::vector< Analyzer::Expr * > target_exprs
SortField getCollation(const size_t i) const
ExecutionResult executeRelAlgQueryNoRetry(const std::string &query_ra, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info)
void collect_used_input_desc(std::vector< InputDescriptor > &input_descs, const Catalog_Namespace::Catalog &cat, std::unordered_set< std::shared_ptr< const InputColDescriptor >> &input_col_descs_unique, const RelAlgNode *ra_node, const std::unordered_set< const RexInput * > &source_used_inputs, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level)
ExecutionResult executeAggregate(const RelAggregate *aggregate, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms)
RaExecutionDesc * getDescriptor(size_t idx) const
ExecutionResult executeProject(const RelProject *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms, const ssize_t previous_count)
std::unordered_map< const RelAlgNode *, int > get_input_nest_levels(const RelAlgNode *ra_node, const std::vector< size_t > &input_permutation)
std::vector< JoinType > left_deep_join_types(const RelLeftDeepInnerJoin *left_deep_join)
const RenderQueryOptions * getRenderQueryOptsPtr() const
int32_t getErrorCode() const
TableFunctionWorkUnit createTableFunctionWorkUnit(const RelTableFunction *table_func, const bool just_explain)
bool can_use_bump_allocator(const RelAlgExecutionUnit &ra_exe_unit, const CompilationOptions &co, const ExecutionOptions &eo)
bool contains(const std::shared_ptr< Analyzer::Expr > expr, const bool desc) const
const Rex * getTargetExpr(const size_t i) const
static const int32_t ERR_INTERRUPTED
std::vector< size_t > do_table_reordering(std::vector< InputDescriptor > &input_descs, std::list< std::shared_ptr< const InputColDescriptor >> &input_col_descs, const JoinQualsPerNestingLevel &left_deep_join_quals, std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, const RA *node, const std::vector< InputTableInfo > &query_infos, const Executor *executor)
class for a per-database catalog. also includes metadata for the current database and the current use...
WorkUnit createProjectWorkUnit(const RelProject *, const SortInfo &, const bool just_explain)
AggregatedColRange computeColRangesCache(const RelAlgNode *ra)
size_t size() const override
int hll_size_for_rate(const int err_percent)
bool g_enable_bump_allocator
ExecutionResult executeRelAlgSeq(const RaExecutionSequence &seq, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms, const bool with_existing_temp_tables=false)
const RexScalar * getFilterExpr() const
std::shared_ptr< Analyzer::Expr > set_transient_dict(const std::shared_ptr< Analyzer::Expr > expr)
std::vector< std::shared_ptr< Analyzer::Expr > > synthesize_inputs(const RelAlgNode *ra_node, const size_t nest_level, const std::vector< TargetMetaInfo > &in_metainfo, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level)
std::shared_ptr< RowSetMemoryOwner > row_set_mem_owner
std::vector< std::shared_ptr< RexSubQuery > > subqueries_
WorkUnit createAggregateWorkUnit(const RelAggregate *, const SortInfo &, const bool just_explain)
WorkUnit createWorkUnit(const RelAlgNode *, const SortInfo &, const bool just_explain)
void setForceNonInSituData()
std::vector< Analyzer::Expr * > translate_targets(std::vector< std::shared_ptr< Analyzer::Expr >> &target_exprs_owned, const std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources, const std::list< std::shared_ptr< Analyzer::Expr >> &groupby_exprs, const RelCompound *compound, const RelAlgTranslator &translator)
#define SPIMAP_GEO_PHYSICAL_INPUT(c, i)
size_t get_scan_limit(const RelAlgNode *ra, const size_t limit)
std::unique_ptr< const RexOperator > get_bitwise_equals_conjunction(const RexScalar *scalar)
const RexScalar * getOuterCondition(const size_t nesting_level) const
SQLTypeInfo get_nullable_logical_type_info(const SQLTypeInfo &type_info)
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
TargetInfo get_target_info(const PointerType target_expr, const bool bigint_count)
size_t size() const override
static std::shared_ptr< Catalog > get(const std::string &dbName)
static SpeculativeTopNBlacklist speculative_topn_blacklist_
size_t get_scalar_sources_size(const RelCompound *compound)
RelAlgExecutionUnit exe_unit
std::pair< std::vector< TargetMetaInfo >, std::vector< std::shared_ptr< Analyzer::Expr > > > get_inputs_meta(const RelFilter *filter, const RelAlgTranslator &translator, const std::vector< std::shared_ptr< RexInput >> &inputs_owned, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level)
std::vector< std::shared_ptr< Analyzer::TargetEntry > > targets
const bool hoist_literals_
TemporaryTables temporary_tables_
static const size_t max_groups_buffer_entry_default_guess
const std::list< Analyzer::OrderEntry > order_entries
TableGenerations computeTableGenerations(const RelAlgNode *ra)
ExecutionResult executeRelAlgQueryWithFilterPushDown(const RaExecutionSequence &seq, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms)
bool setInSituDataIfUnset(const bool is_in_situ_data)
const RexScalar * getCondition() const
const ExecutorOptLevel opt_level_
const std::vector< TargetMetaInfo > getTupleType() const
std::vector< std::shared_ptr< Analyzer::Expr > > translate_scalar_sources_for_update(const RA *ra_node, const RelAlgTranslator &translator, int32_t tableId, const Catalog_Namespace::Catalog &cat, const ColumnNameList &colNames, size_t starting_projection_column_idx)
std::vector< TargetMetaInfo > get_modify_manipulated_targets_meta(ModifyManipulationTarget const *manip_node, const std::vector< Analyzer::Expr * > &target_exprs)
std::shared_ptr< Analyzer::Var > var_ref(const Analyzer::Expr *expr, const Analyzer::Var::WhichRow which_row, const int varno)
bool use_speculative_top_n(const RelAlgExecutionUnit &ra_exe_unit, const QueryMemoryDescriptor &query_mem_desc)
std::vector< PushedDownFilterInfo > selectFiltersToBePushedDown(const RelAlgExecutor::WorkUnit &work_unit, const CompilationOptions &co, const ExecutionOptions &eo)
static const TableFunction & get(const std::string &name)
SQLTypeInfo get_logical_type_info(const SQLTypeInfo &type_info)
TypeR::rep timer_stop(Type clock_begin)
ExecutionResult executeModify(const RelModify *modify, const ExecutionOptions &eo)
void addTemporaryTable(const int table_id, const ResultSetPtr &result)
std::unordered_map< unsigned, AggregatedResult > leaf_results_
SQLTypeInfo get_agg_type(const SQLAgg agg_kind, const Analyzer::Expr *arg_expr)
std::vector< TargetInfo > TargetInfoList
std::vector< JoinCondition > JoinQualsPerNestingLevel
std::shared_ptr< ResultSet > ResultSetPtr
WorkUnit createCompoundWorkUnit(const RelCompound *, const SortInfo &, const bool just_explain)
static const int32_t ERR_TOO_MANY_LITERALS
ExecutionResult executeLogicalValues(const RelLogicalValues *, const ExecutionOptions &)
bool g_enable_dynamic_watchdog
T visit(const Analyzer::Expr *expr) const
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
std::vector< Analyzer::Expr * > get_exprs_not_owned(const std::vector< std::shared_ptr< Analyzer::Expr >> &exprs)
Analyzer::ExpressionPtr rewrite_expr(const Analyzer::Expr *expr)
static void invalidateCaches()
ExecutionResult executeFilter(const RelFilter *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
size_t getNDVEstimation(const WorkUnit &work_unit, const bool is_agg, const CompilationOptions &co, const ExecutionOptions &eo)
QualsConjunctiveForm qual_to_conjunctive_form(const std::shared_ptr< Analyzer::Expr > qual_expr)
const std::vector< InputDescriptor > input_descs
const std::vector< std::shared_ptr< Analyzer::Expr > > & getOrderKeys() const
bool is_window_execution_unit(const RelAlgExecutionUnit &ra_exe_unit)
std::vector< const RexScalar * > rex_to_conjunctive_form(const RexScalar *qual_expr)
bool is_count_distinct(const Analyzer::Expr *expr)
std::shared_ptr< Analyzer::Expr > transform_to_inner(const Analyzer::Expr *expr)
void handleNop(RaExecutionDesc &ed)
int getTargetColumnCount() const
std::shared_ptr< const RelAlgNode > deserialize_ra_dag(const std::string &query_ra, const Catalog_Namespace::Catalog &cat, RelAlgExecutor *ra_executor, const RenderQueryOptions *render_opts)
#define LOG_IF(severity, condition)
void computeWindow(const RelAlgExecutionUnit &ra_exe_unit, const CompilationOptions &co, const ExecutionOptions &eo, ColumnCacheMap &column_cache_map, const int64_t queue_time_ms)
bool disallow_in_situ_only_if_final_ED_is_aggregate
std::vector< node_t > get_node_input_permutation(const JoinQualsPerNestingLevel &left_deep_join_quals, const std::vector< InputTableInfo > &table_infos, const Executor *executor)
static const size_t high_scan_limit
bool list_contains_expression(const QualsList &haystack, const std::shared_ptr< Analyzer::Expr > &needle)
size_t get_count_distinct_sub_bitmap_count(const size_t bitmap_sz_bits, const RelAlgExecutionUnit &ra_exe_unit, const ExecutorDeviceType device_type)
static const int32_t ERR_STRING_CONST_IN_RESULTSET
size_t getColInputsSize() const
virtual T visit(const RexScalar *rex_scalar) const
const size_t getScalarSourcesSize() const
static const int32_t ERR_STREAMING_TOP_N_NOT_SUPPORTED_IN_RENDER_QUERY
static const int32_t ERR_COLUMNAR_CONVERSION_NOT_SUPPORTED
const ResultSetPtr & get_temporary_table(const TemporaryTables *temporary_tables, const int table_id)
RelAlgExecutionUnit create_count_all_execution_unit(const RelAlgExecutionUnit &ra_exe_unit, std::shared_ptr< Analyzer::Expr > replacement_target)
std::vector< std::shared_ptr< Analyzer::Expr > > target_exprs_owned_
static const int32_t ERR_DIV_BY_ZERO
const bool allow_multifrag
std::vector< Analyzer::Expr * > translate_targets_for_update(std::vector< std::shared_ptr< Analyzer::Expr >> &target_exprs_owned, const std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources, const std::list< std::shared_ptr< Analyzer::Expr >> &groupby_exprs, const RelCompound *compound, const RelAlgTranslator &translator, int32_t tableId, const Catalog_Namespace::Catalog &cat, const ColumnNameList &colNames, size_t starting_projection_column_idx)
WorkUnit createModifyProjectWorkUnit(const RelProject *project, const SortInfo &sort_info, const bool just_explain)
const bool find_push_down_candidates
bool g_from_table_reordering
ColumnNameList const & getTargetColumns() const
#define INJECT_TIMER(DESC)
const bool with_dynamic_watchdog
static const int32_t ERR_OUT_OF_RENDER_MEM
std::list< std::shared_ptr< Analyzer::Expr > > translate_groupby_exprs(const RelCompound *compound, const std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources)
const JoinQualsPerNestingLevel join_quals
SQLTypeInfo get_logical_type_for_expr(const Analyzer::Expr &expr)
std::pair< std::vector< InputDescriptor >, std::list< std::shared_ptr< const InputColDescriptor > > > get_input_desc_impl(const RA *ra_node, const std::unordered_set< const RexInput * > &used_inputs, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, const std::vector< size_t > &input_permutation, const Catalog_Namespace::Catalog &cat)
const int8_t const int64_t const uint64_t const int32_t const int64_t int64_t uint32_t const int64_t int32_t * error_code
const double gpu_input_mem_limit_percent
A container for relational algebra descriptors defining the execution order for a relational algebra ...
const Catalog_Namespace::Catalog & cat_
size_t g_big_group_threshold
static const int32_t ERR_OVERFLOW_OR_UNDERFLOW
const std::shared_ptr< ResultSet > & getRows() const
const ColumnDescriptor * getMetadataForColumn(int tableId, const std::string &colName) const
static const int32_t ERR_OUT_OF_TIME
ExecutionResult handleOutOfMemoryRetry(const RelAlgExecutor::WorkUnit &work_unit, const std::vector< TargetMetaInfo > &targets_meta, const bool is_agg, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const bool was_multifrag_kernel_launch, const int64_t queue_time_ms)
size_t groups_approx_upper_bound(const std::vector< InputTableInfo > &table_infos)
const RelAlgNode * getInput(const size_t idx) const
std::shared_ptr< Analyzer::Expr > build_logical_expression(const std::vector< std::shared_ptr< Analyzer::Expr >> &factors, const SQLOps sql_op)
ColumnValidationFunction yieldColumnValidator(TableDescriptorType const *table_descriptor)
const bool register_intel_jit_listener_
static WindowProjectNodeContext * create()
static const int32_t ERR_UNSUPPORTED_SELF_JOIN
ExecutionResult executeRelAlgSubSeq(const RaExecutionSequence &seq, const std::pair< size_t, size_t > interval, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms)
const bool output_columnar_hint
bool get_is_distinct() const
WorkUnit createModifyCompoundWorkUnit(const RelCompound *compound, const SortInfo &sort_info, const bool just_explain)
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)
void build_render_targets(RenderInfo &render_info, const std::vector< Analyzer::Expr * > &work_unit_target_exprs, const std::vector< TargetMetaInfo > &targets_meta)
JoinType get_join_type(const RelAlgNode *ra)
void executeRelAlgStep(const RaExecutionSequence &seq, const size_t step_idx, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
static std::pair< const int8_t *, size_t > getOneColumnFragment(Executor *executor, const Analyzer::ColumnVar &hash_col, const Fragmenter_Namespace::FragmentInfo &fragment, const Data_Namespace::MemoryLevel effective_mem_lvl, const int device_id, std::vector< std::shared_ptr< Chunk_NS::Chunk >> &chunks_owner, ColumnCacheMap &column_cache)
static const int32_t ERR_OUT_OF_GPU_MEM
size_t getTableFuncInputsSize() const
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
std::shared_ptr< Analyzer::Expr > reverse_logical_distribution(const std::shared_ptr< Analyzer::Expr > &expr)
const SQLTypeInfo & get_type_info() const
ExecutorDeviceType device_type_
Executor * getExecutor() const
std::shared_ptr< Analyzer::Expr > cast_to_column_type(std::shared_ptr< Analyzer::Expr > expr, int32_t tableId, const Catalog_Namespace::Catalog &cat, const std::string &colName)
static std::shared_ptr< Analyzer::Expr > normalize(const SQLOps optype, const SQLQualifier qual, std::shared_ptr< Analyzer::Expr > left_expr, std::shared_ptr< Analyzer::Expr > right_expr)
const std::vector< std::unique_ptr< const RexAgg > > & getAggExprs() const
UpdateCallback yieldUpdateCallback(UpdateTransactionParameters &update_parameters)
bool node_is_aggregate(const RelAlgNode *ra)
std::vector< TargetMetaInfo > get_targets_meta(const RA *ra_node, const std::vector< Analyzer::Expr * > &target_exprs)
bool g_enable_window_functions
bool isEmptyResult() const
ExecutionResult executeTableFunction(const RelTableFunction *, const CompilationOptions &, const ExecutionOptions &, const int64_t queue_time_ms)
UpdateCallback yieldDeleteCallback(DeleteTransactionParameters &delete_parameters)
const RexScalar * getProjectAt(const size_t idx) const
const ExecutorExplainType explain_type_
ssize_t getFilteredCountAll(const WorkUnit &work_unit, const bool is_agg, const CompilationOptions &co, const ExecutionOptions &eo)
#define TRANSIENT_DICT_ID
const bool just_calcite_explain
std::vector< std::shared_ptr< Analyzer::Expr > > translate_scalar_sources(const RA *ra_node, const RelAlgTranslator &translator)
std::pair< std::unordered_set< const RexInput * >, std::vector< std::shared_ptr< RexInput > > > get_used_inputs(const RelCompound *compound, const Catalog_Namespace::Catalog &cat)
bool table_is_replicated(const TableDescriptor *td)
std::pair< std::unordered_set< const RexInput * >, std::vector< std::shared_ptr< RexInput > > > get_join_source_used_inputs(const RelAlgNode *ra_node, const Catalog_Namespace::Catalog &cat)
void executeDeleteViaCompound(const RelCompound *compound, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms)
const size_t getGroupByCount() const
size_t collationCount() const
void executeUpdateViaProject(const RelProject *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
ExecutionResult executeSort(const RelSort *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
bool isRowidLookup(const WorkUnit &work_unit)
bool exe_unit_has_quals(const RelAlgExecutionUnit ra_exe_unit)
int table_id_from_ra(const RelAlgNode *ra_node)
bool g_enable_table_functions
static void handlePersistentError(const int32_t error_code)
const RexScalar * getTableFuncInputAt(const size_t idx) const
void executeDeleteViaProject(const RelProject *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
bool compute_output_buffer_size(const RelAlgExecutionUnit &ra_exe_unit)
SQLAgg get_aggtype() const
const size_t max_groups_buffer_entry_guess
std::string getFunctionName() const
std::list< std::shared_ptr< Analyzer::Expr > > quals
const bool allow_loop_joins
bool wasMultifragKernelLaunch() const
bool g_skip_intermediate_count
static const int32_t ERR_SPECULATIVE_TOP_OOM
ExecutionResult executeWorkUnit(const WorkUnit &work_unit, const std::vector< TargetMetaInfo > &targets_meta, const bool is_agg, const CompilationOptions &co_in, const ExecutionOptions &eo, RenderInfo *, const int64_t queue_time_ms, const ssize_t previous_count=-1)
RANodeOutput get_node_output(const RelAlgNode *ra_node)
void executeUpdateViaCompound(const RelCompound *compound, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info, const int64_t queue_time_ms)
const RexScalar * getInnerCondition() const
bool isPotentialInSituRender() const
void addTransientStringLiterals()
#define DEBUG_TIMER(name)
std::vector< std::shared_ptr< Analyzer::Expr > > qual_to_disjunctive_form(const std::shared_ptr< Analyzer::Expr > &qual_expr)
void setOutputMetainfo(const std::vector< TargetMetaInfo > &targets_metainfo) const
ExecutionResult executeCompound(const RelCompound *, const CompilationOptions &, const ExecutionOptions &, RenderInfo *, const int64_t queue_time_ms)
const RelAlgNode * getBody() const
std::list< Analyzer::OrderEntry > get_order_entries(const RelSort *sort)
std::unique_ptr< const RexOperator > get_bitwise_equals(const RexScalar *scalar)
Estimators to be used when precise cardinality isn't useful.
static std::string getErrorMessageFromCode(const int32_t error_code)
std::unordered_map< int, std::unordered_map< int, std::shared_ptr< const ColumnarResults > > > ColumnCacheMap
WorkUnit createSortInputWorkUnit(const RelSort *, const bool just_explain)
QualsConjunctiveForm translate_quals(const RelCompound *compound, const RelAlgTranslator &translator)
void add(const std::shared_ptr< Analyzer::Expr > expr, const bool desc)
const Expr * get_left_operand() const
void cleanupPostExecution()
std::unique_ptr< WindowFunctionContext > createWindowFunctionContext(const Analyzer::WindowFunction *window_func, const std::shared_ptr< Analyzer::BinOper > &partition_key_cond, const RelAlgExecutionUnit &ra_exe_unit, const std::vector< InputTableInfo > &query_infos, const CompilationOptions &co, ColumnCacheMap &column_cache_map)
ExecutionResult executeRelAlgQuery(const std::string &query_ra, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info)
std::list< std::shared_ptr< Analyzer::Expr > > makeJoinQuals(const RexScalar *join_condition, const std::vector< JoinType > &join_types, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, const bool just_explain) const
const RexScalar * scalar_at(const size_t i, const RelCompound *compound)
std::vector< Analyzer::Expr * > target_exprs
std::tuple< std::vector< InputDescriptor >, std::list< std::shared_ptr< const InputColDescriptor > >, std::vector< std::shared_ptr< RexInput > > > get_input_desc(const RA *ra_node, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, const std::vector< size_t > &input_permutation, const Catalog_Namespace::Catalog &cat)
const size_t inputCount() const
void addColSlotInfo(const std::vector< std::tuple< int8_t, int8_t >> &slots_for_col)
auto const isVarlenUpdateRequired() const
const bool with_dynamic_watchdog_
FirstStepExecutionResult executeRelAlgQuerySingleStep(const RaExecutionSequence &seq, const size_t step_idx, const CompilationOptions &co, const ExecutionOptions &eo, RenderInfo *render_info)
RelAlgExecutionUnit decide_approx_count_distinct_implementation(const RelAlgExecutionUnit &ra_exe_unit_in, const std::vector< InputTableInfo > &table_infos, const Executor *executor, const ExecutorDeviceType device_type_in, std::vector< std::shared_ptr< Analyzer::Expr >> &target_exprs_owned)
const std::vector< std::shared_ptr< Analyzer::Expr > > & getPartitionKeys() const
const RelAlgNode * get_data_sink(const RelAlgNode *ra_node)
const unsigned dynamic_watchdog_time_limit
const std::vector< TargetMetaInfo > & getOutputMetainfo() const
static const int32_t ERR_OUT_OF_CPU_MEM
const TableDescriptor * getTableDescriptor() const
std::vector< const RelAlgNode * > get_non_join_sequence(const RelAlgNode *ra)
std::list< std::shared_ptr< Analyzer::Expr > > combine_equi_join_conditions(const std::list< std::shared_ptr< Analyzer::Expr >> &join_quals)
WorkUnit createFilterWorkUnit(const RelFilter *, const SortInfo &, const bool just_explain)
std::list< std::shared_ptr< Analyzer::Expr > > simple_quals
std::shared_ptr< Analyzer::Expr > fold_expr(const Analyzer::Expr *expr)
std::vector< std::string > ColumnNameList
const int getColumnIdBySpi(const int tableId, const size_t spi) const
JoinQualsPerNestingLevel translateLeftDeepJoinFilter(const RelLeftDeepInnerJoin *join, const std::vector< InputDescriptor > &input_descs, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, const bool just_explain)
const ColumnDescriptor * get_column_descriptor(const int col_id, const int table_id, const Catalog_Namespace::Catalog &cat)
TableDescriptor const * getModifiedTableDescriptor() const
static size_t shard_count_for_top_groups(const RelAlgExecutionUnit &ra_exe_unit, const Catalog_Namespace::Catalog &catalog)
static std::shared_ptr< Analyzer::Expr > translateAggregateRex(const RexAgg *rex, const std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources)
bool first_oe_is_desc(const std::list< Analyzer::OrderEntry > &order_entries)
void prepareLeafExecution(const AggregatedColRange &agg_col_range, const StringDictionaryGenerations &string_dictionary_generations, const TableGenerations &table_generations)
const RexScalar * getScalarSource(const size_t i) const
StringDictionaryGenerations computeStringDictionaryGenerations(const RelAlgNode *ra)
std::vector< size_t > get_left_deep_join_input_sizes(const RelLeftDeepInnerJoin *left_deep_join)
bool validateTargetColumns(VALIDATION_FUNCTOR validator) const
void set_transient_dict_maybe(std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources, const std::shared_ptr< Analyzer::Expr > &expr)
std::list< std::shared_ptr< Analyzer::Expr > > rewrite_quals(const std::list< std::shared_ptr< Analyzer::Expr >> &quals)