20 #include <boost/locale/conversion.hpp>
21 #include <unordered_set>
42 if (!dynamic_cast<const Analyzer::Constant*>(rhs_no_cast)) {
46 const auto& arg_ti = arg->get_type_info();
47 auto rhs = rhs_no_cast->deep_copy()->add_cast(arg_ti);
48 return makeExpr<Analyzer::InValues>(
49 arg, std::list<std::shared_ptr<Analyzer::Expr>>{rhs});
152 const std::shared_ptr<Analyzer::InValues>& lhs,
153 const std::shared_ptr<Analyzer::InValues>& rhs)
const override {
158 if (lhs->get_arg()->get_type_info() == rhs->get_arg()->get_type_info() &&
159 (*lhs->get_arg() == *rhs->get_arg())) {
160 auto union_values = lhs->get_value_list();
161 const auto& rhs_values = rhs->get_value_list();
162 union_values.insert(union_values.end(), rhs_values.begin(), rhs_values.end());
163 return makeExpr<Analyzer::InValues>(lhs->get_own_arg(), union_values);
175 auto rewritten = simple_visitor.
visit(bin_oper);
182 auto rewritten_lhs = visit(lhs.get());
183 auto rewritten_rhs = visit(rhs.get());
184 return makeExpr<Analyzer::BinOper>(bin_oper->
get_type_info(),
188 rewritten_lhs ? rewritten_lhs : lhs,
189 rewritten_rhs ? rewritten_rhs : rhs);
198 std::vector<std::shared_ptr<Analyzer::Expr>> args_copy;
200 auto const element_expr_ptr = visit(array_expr->
getElement(i));
201 auto const& element_expr_type_info = element_expr_ptr->get_type_info();
203 if (!element_expr_type_info.is_string() ||
205 args_copy.push_back(element_expr_ptr);
207 auto transient_dict_type_info = element_expr_type_info;
211 transient_dict_type_info.setStringDictKey(
213 transient_dict_type_info.set_fixed_size();
214 args_copy.push_back(element_expr_ptr->add_cast(transient_dict_type_info));
219 return makeExpr<Analyzer::ArrayExpr>(
225 template <
typename T>
243 throw std::runtime_error(
"Unable to fold");
247 template <
typename T>
259 throw std::runtime_error(
"Unable to fold");
263 template <
typename T>
265 bool t2_is_zero = (t2 == (t2 - t2));
266 bool t2_is_negative = (t2 < (t2 - t2));
271 if ((t2_is_negative && t1 < std::numeric_limits<T>::lowest() - t2) ||
272 (!t2_is_negative && t1 > std::numeric_limits<T>::max() - t2)) {
274 throw std::runtime_error(
"Plus overflow");
278 if ((t2_is_negative && t1 > std::numeric_limits<T>::max() + t2) ||
279 (!t2_is_negative && t1 < std::numeric_limits<T>::lowest() + t2)) {
281 throw std::runtime_error(
"Minus overflow");
291 if (t2_is_negative) {
292 if (t1 == std::numeric_limits<T>::lowest() ||
293 t2 == std::numeric_limits<T>::lowest()) {
296 throw std::runtime_error(
"Mul neg overflow");
302 bool ct2_is_fraction = (ct2 < (ct2 / ct2));
303 if (!ct2_is_fraction) {
304 if (ct1 > std::numeric_limits<T>::max() / ct2 ||
305 ct1 < std::numeric_limits<T>::lowest() / ct2) {
307 throw std::runtime_error(
"Mul overflow");
314 throw std::runtime_error(
"Will not fold division by zero");
320 throw std::runtime_error(
"Unable to fold");
442 const auto unvisited_operand = uoper->
get_operand();
445 if (optype ==
kCAST) {
447 casts_.insert({unvisited_operand, ti});
449 const auto operand = visit(unvisited_operand);
451 const auto& operand_ti = operand->get_type_info();
452 const auto operand_type =
454 const auto const_operand =
458 const auto operand_datum = const_operand->
get_constval();
459 Datum zero_datum = {};
460 Datum result_datum = {};
471 return makeExpr<Analyzer::Constant>(result_type,
false, result_datum);
482 if (!operand_ti.is_decimal()) {
483 return makeExpr<Analyzer::Constant>(result_type,
false, result_datum);
485 return makeExpr<Analyzer::Constant>(ti,
false, result_datum);
491 if (!ti.is_number() || !operand_ti.is_number()) {
499 if (ti.is_decimal() && operand_ti.is_fp()) {
502 auto operand_copy = const_operand->deep_copy();
503 auto cast_operand = operand_copy->add_cast(ti);
504 auto const_cast_operand =
506 if (const_cast_operand) {
507 auto const_cast_datum = const_cast_operand->
get_constval();
508 return makeExpr<Analyzer::Constant>(ti,
false, const_cast_datum);
516 return makeExpr<Analyzer::UOper>(
528 if (casts_.find(bin_oper) != casts_.end()) {
529 const auto cast_ti = casts_[bin_oper];
532 if ((cast_ti.is_integer() || cast_ti.is_fp()) && lhs_ti.is_integer() &&
533 cast_ti.get_size() > lhs_ti.get_size() &&
537 left_operand = left_operand->deep_copy()->add_cast(cast_ti);
538 right_operand = right_operand->deep_copy()->add_cast(cast_ti);
543 const auto lhs = visit(left_operand.get());
544 const auto rhs = visit(right_operand.get());
549 const auto& rhs_ti = rhs->get_type_info();
553 if (const_lhs && const_rhs && lhs_type == rhs_type) {
554 auto lhs_datum = const_lhs->get_constval();
555 auto rhs_datum = const_rhs->get_constval();
556 Datum result_datum = {};
558 if (foldOper(optype, lhs_type, lhs_datum, rhs_datum, result_datum, result_type)) {
561 return makeExpr<Analyzer::Constant>(result_type,
false, result_datum);
566 return makeExpr<Analyzer::Constant>(ti,
false, result_datum);
571 if (optype ==
kAND && lhs_type == rhs_type && lhs_type ==
kBOOLEAN) {
572 if (const_rhs && !const_rhs->get_is_null()) {
573 auto rhs_datum = const_rhs->get_constval();
574 if (rhs_datum.boolval ==
false) {
578 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
583 if (const_lhs && !const_lhs->get_is_null()) {
584 auto lhs_datum = const_lhs->get_constval();
585 if (lhs_datum.boolval ==
false) {
589 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
595 if (optype ==
kOR && lhs_type == rhs_type && lhs_type ==
kBOOLEAN) {
596 if (const_rhs && !const_rhs->get_is_null()) {
597 auto rhs_datum = const_rhs->get_constval();
598 if (rhs_datum.boolval ==
true) {
602 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
607 if (const_lhs && !const_lhs->get_is_null()) {
608 auto lhs_datum = const_lhs->get_constval();
609 if (lhs_datum.boolval ==
true) {
613 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
620 if (!lhs_ti.get_notnull()) {
621 CHECK(!rhs_ti.get_notnull());
628 return makeExpr<Analyzer::BinOper>(ti,
635 CHECK(rhs_ti.get_notnull());
637 if (optype ==
kEQ || optype ==
kLE || optype ==
kGE) {
640 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
643 if (optype ==
kNE || optype ==
kLT || optype ==
kGT) {
646 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
651 return makeExpr<Analyzer::Constant>(lhs_type,
false, d);
655 if (optype ==
kDIVIDE && const_rhs && rhs_ti.is_fp()) {
656 auto rhs_datum = const_rhs->get_constval();
657 std::shared_ptr<Analyzer::Expr> recip_rhs =
nullptr;
658 if (rhs_ti.get_type() ==
kFLOAT) {
659 if (rhs_datum.floatval == 1.0) {
662 auto f = std::fabs(rhs_datum.floatval);
663 if (
f > 1.0 || (
f != 0.0 && 1.0 <
f * std::numeric_limits<float>::max())) {
664 rhs_datum.floatval = 1.0 / rhs_datum.floatval;
665 recip_rhs = makeExpr<Analyzer::Constant>(rhs_type,
false, rhs_datum);
667 }
else if (rhs_ti.get_type() ==
kDOUBLE) {
668 if (rhs_datum.doubleval == 1.0) {
671 auto d = std::fabs(rhs_datum.doubleval);
672 if (d > 1.0 || (d != 0.0 && 1.0 < d * std::numeric_limits<double>::max())) {
673 rhs_datum.doubleval = 1.0 / rhs_datum.doubleval;
674 recip_rhs = makeExpr<Analyzer::Constant>(rhs_type,
false, rhs_datum);
678 return makeExpr<Analyzer::BinOper>(ti,
687 return makeExpr<Analyzer::BinOper>(ti,
702 const auto original_args = string_oper->
getOwnArgs();
703 std::vector<std::shared_ptr<Analyzer::Expr>> rewritten_args;
705 const auto parent_in_string_op_chain = in_string_op_chain_;
706 const auto in_string_op_chain = non_literal_arity <= 1UL;
707 in_string_op_chain_ = in_string_op_chain;
709 size_t rewritten_arg_literal_arity = 0;
710 for (
auto original_arg : original_args) {
711 rewritten_args.emplace_back(visit(original_arg.get()));
712 if (dynamic_cast<const Analyzer::Constant*>(rewritten_args.back().get())) {
713 rewritten_arg_literal_arity++;
716 in_string_op_chain_ = parent_in_string_op_chain;
717 const auto kind = string_oper->
get_kind();
720 if (string_oper->
getArity() == rewritten_arg_literal_arity) {
724 const auto string_op_info =
726 if (return_ti.is_string()) {
727 const auto literal_result =
730 literal_result.second);
732 const auto literal_datum =
734 auto nullable_return_ti = return_ti;
735 nullable_return_ti.set_notnull(
false);
736 return makeExpr<Analyzer::Constant>(nullable_return_ti,
740 chained_string_op_exprs_.emplace_back(
741 makeExpr<Analyzer::StringOper>(kind, return_ti, rewritten_args));
742 if (parent_in_string_op_chain && in_string_op_chain) {
743 CHECK(rewritten_args[0]->get_type_info().is_string());
744 return rewritten_args[0]->deep_copy();
746 auto new_string_oper = makeExpr<Analyzer::StringOper>(
747 kind, return_ti, rewritten_args, chained_string_op_exprs_);
748 chained_string_op_exprs_.clear();
749 return new_string_oper;
754 mutable bool in_string_op_chain_{
false};
756 mutable std::unordered_map<const Analyzer::Expr*, const SQLTypeInfo>
casts_;
767 if (!with_likelihood) {
770 return with_likelihood->get_arg();
776 return ArrayElementStringLiteralEncodingVisitor().visit(expr);
792 RecursiveOrToInVisitor visitor;
793 auto rewritten_expr = visitor.visit(expr_no_likelihood);
794 const auto expr_with_likelihood =
796 if (expr_with_likelihood) {
798 return std::make_shared<Analyzer::LikelihoodExpr>(
799 rewritten_expr, expr_with_likelihood->get_likelihood());
801 return rewritten_expr;
807 std::unordered_map<const RelAlgNode*, int>& input_to_nest_level,
809 int target_nest_lv) {
810 for (
auto& kv : input_to_nest_level) {
816 return key.table_id == column_key.
table_id &&
817 key.db_id == column_key.
db_id;
819 input_to_nest_level[ra] = target_nest_lv;
827 int target_nest_lv) {
828 int num_input_descs =
static_cast<int>(input_descs.size());
829 for (
int i = 0; i < num_input_descs; i++) {
830 auto const tbl_key = input_descs[i].getTableKey();
831 if (tbl_key.db_id == column_key.
db_id && tbl_key.table_id == column_key.
table_id) {
832 input_descs[i] =
InputDescriptor(tbl_key.db_id, tbl_key.table_id, target_nest_lv);
840 std::list<std::shared_ptr<const InputColDescriptor>>& input_col_desc,
842 int target_nest_lv) {
843 for (
auto it = input_col_desc.begin(); it != input_col_desc.end(); it++) {
844 auto const tbl_key = (*it)->getScanDesc().getTableKey();
845 if (tbl_key.db_id == column_key.
db_id && tbl_key.table_id == column_key.
table_id) {
846 (*it) = std::make_shared<InputColDescriptor>(
847 (*it)->getColId(), tbl_key.table_id, tbl_key.db_id, target_nest_lv);
851 return input_col_desc.end();
858 const std::shared_ptr<Analyzer::Expr> expr,
859 std::vector<InputDescriptor>& input_descs,
860 std::unordered_map<const RelAlgNode*, int>& input_to_nest_level,
861 std::vector<size_t>& input_permutation,
862 std::list<std::shared_ptr<const InputColDescriptor>>& input_col_desc,
864 Executor
const* executor) {
865 auto collect_table_cardinality = [&executor](
const Analyzer::Expr* lhs,
869 if (lhs_cv && rhs_cv) {
870 return std::make_pair<int64_t, int64_t>(
875 return std::make_pair<int64_t, int64_t>(-1, -1);
882 std::set<int> lhs_rte_idx;
884 std::set<int> rhs_rte_idx;
885 rhs->collect_rte_idx(rhs_rte_idx);
886 auto has_invalid_num_join_cols = lhs_rte_idx.size() != 1 || rhs_rte_idx.size() != 1;
887 auto has_invalid_rte_idx = lhs_rte_idx > rhs_rte_idx;
888 return std::make_pair(has_invalid_num_join_cols || has_invalid_rte_idx,
889 has_invalid_rte_idx);
891 bool swap_args =
false;
892 auto convert_to_range_join_oper =
893 [&](std::string_view func_name,
894 const std::shared_ptr<Analyzer::Expr> expr,
901 auto l_arg = lhs->getOperand(0);
903 auto r_arg = lhs->getOperand(1);
904 const bool is_geography = l_arg->get_type_info().get_subtype() ==
kGEOGRAPHY ||
905 r_arg->get_type_info().get_subtype() ==
kGEOGRAPHY;
907 VLOG(1) <<
"Range join not yet supported for geodesic distance "
915 auto invalid_range_join_qual =
916 has_invalid_join_col_order(bin_oper_arg, range_join_arg);
917 if (invalid_range_join_qual.first) {
918 LOG(
INFO) <<
"Unable to rewrite " << func_name
919 <<
" to exploit bounding box intersection. Cannot build hash table "
921 "Check join order.\n"
922 << range_join_expr->toString();
932 bool lhs_is_point{l_arg->get_type_info().get_type() ==
kPOINT};
933 bool rhs_is_point{r_arg->get_type_info().get_type() ==
kPOINT};
934 if (!lhs_is_point || !rhs_is_point) {
936 VLOG(1) <<
"Currently, we only support range hash join for Point-to-Point "
937 "distance query: fallback to a loop join";
940 auto const card_info = collect_table_cardinality(range_join_arg, bin_oper_arg);
941 if (invalid_range_join_qual.second && card_info.first > 0 && lhs_is_point) {
943 }
else if (card_info.first >= 0 && card_info.first < card_info.second) {
952 if (r_cv && l_cv && input_descs.size() == 2) {
960 auto const l_col_key = l_cv->getColumnKey();
961 int r_rte_idx = r_cv->get_rte_idx();
962 int l_rte_idx = l_cv->get_rte_idx();
963 r_cv->set_rte_idx(l_rte_idx);
964 l_cv->set_rte_idx(r_rte_idx);
967 auto const r_input_desc_idx =
970 auto const l_input_desc_idx =
973 auto r_input_col_desc_it =
975 CHECK(r_input_col_desc_it != input_col_desc.end());
976 auto l_input_col_desc_it =
978 CHECK(l_input_col_desc_it != input_col_desc.end());
979 if (!input_permutation.empty()) {
981 std::find(input_permutation.begin(), input_permutation.end(), r_rte_idx);
982 CHECK(r_itr != input_permutation.end());
984 std::find(input_permutation.begin(), input_permutation.end(), l_rte_idx);
985 CHECK(l_itr != input_permutation.end());
988 std::swap(input_descs[r_input_desc_idx], input_descs[l_input_desc_idx]);
989 std::swap(r_input_col_desc_it, l_input_col_desc_it);
990 r_arg = lhs->getOperand(0);
991 l_arg = lhs->getOperand(1);
992 VLOG(1) <<
"Swap range join qual's input arguments to exploit hash join "
993 "framework for bounding box intersection";
994 invalid_range_join_qual.first =
false;
997 const bool inclusive = range_join_expr->get_optype() ==
kLE;
998 auto range_expr = makeExpr<Analyzer::RangeOper>(
999 inclusive, inclusive, r_arg->deep_copy(), rhs->deep_copy());
1000 VLOG(1) <<
"Successfully converted to range hash join";
1001 return makeExpr<Analyzer::BinOper>(
1024 std::shared_ptr<Analyzer::BinOper> bbox_intersect_oper{
nullptr};
1025 bool needs_to_return_original_expr =
false;
1026 std::string func_name{
""};
1030 func_name = func_oper->getName();
1033 LOG(
WARNING) <<
"Many-to-many hashjoin support is disabled, unable to rewrite "
1034 << func_oper->toString() <<
" to use accelerated geo join.";
1039 CHECK_GE(func_oper->getArity(), size_t(2));
1049 auto lhs = func_oper->getOwnArg(0);
1050 auto rewritten_lhs = deep_copy_visitor.
visit(lhs.get());
1051 CHECK(rewritten_lhs);
1053 auto rhs = func_oper->getOwnArg(1);
1054 auto rewritten_rhs = deep_copy_visitor.
visit(rhs.get());
1055 CHECK(rewritten_rhs);
1056 bbox_intersect_oper = makeExpr<Analyzer::BinOper>(
1058 }
else if (func_name ==
1060 CHECK_EQ(func_oper->getArity(), size_t(8));
1061 const auto lhs = func_oper->getOwnArg(0);
1062 const auto rhs = func_oper->getOwnArg(1);
1065 const auto distance_const_val =
1067 if (lhs && rhs && distance_const_val) {
1068 std::vector<std::shared_ptr<Analyzer::Expr>>
args{lhs, rhs};
1069 auto range_oper = makeExpr<Analyzer::GeoOperator>(
1074 auto distance_oper = makeExpr<Analyzer::BinOper>(
1076 VLOG(1) <<
"Rewrite " << func_oper->getName() <<
" to ST_Distance_Point_Point";
1077 bbox_intersect_oper = convert_to_range_join_oper(
1080 distance_oper.get(),
1082 distance_const_val);
1083 needs_to_return_original_expr =
true;
1086 is_poly_mpoly_rewrite_target_func(func_name)) {
1093 CHECK_GE(func_oper->getArity(), size_t(4));
1094 auto lhs = func_oper->getOwnArg(1);
1095 auto rewritten_lhs = deep_copy_visitor.
visit(lhs.get());
1096 CHECK(rewritten_lhs);
1097 auto rhs = func_oper->getOwnArg(3);
1098 auto rewritten_rhs = deep_copy_visitor.
visit(rhs.get());
1099 CHECK(rewritten_rhs);
1101 bbox_intersect_oper = makeExpr<Analyzer::BinOper>(
1103 needs_to_return_original_expr =
true;
1105 is_point_poly_rewrite_target_func(func_name)) {
1116 size_t point_arg_idx = 0;
1117 size_t poly_arg_idx = 2;
1118 if (func_oper->getOwnArg(point_arg_idx)->get_type_info().get_type() !=
kPOINT) {
1122 auto point_cv = func_oper->getOwnArg(point_arg_idx);
1123 auto poly_cv = func_oper->getOwnArg(poly_arg_idx);
1126 auto rewritten_lhs = deep_copy_visitor.
visit(point_cv.get());
1127 CHECK(rewritten_lhs);
1128 auto rewritten_rhs = deep_copy_visitor.
visit(poly_cv.get());
1129 CHECK(rewritten_rhs);
1130 VLOG(1) <<
"Rewriting the " << func_name
1131 <<
" to use bounding box intersection with lhs as "
1132 << rewritten_lhs->toString() <<
" and rhs as " << rewritten_rhs->toString();
1133 bbox_intersect_oper = makeExpr<Analyzer::BinOper>(
1135 needs_to_return_original_expr =
true;
1137 is_poly_point_rewrite_target_func(func_name)) {
1141 auto lhs = func_oper->getOwnArg(2);
1142 auto rewritten_lhs = deep_copy_visitor.
visit(lhs.get());
1143 CHECK(rewritten_lhs);
1144 const auto& lhs_ti = rewritten_lhs->get_type_info();
1155 LOG(
INFO) <<
"Unable to rewrite " << func_name
1156 <<
" to bounding box intersection conjunction. LHS input type is "
1157 "neither a geospatial "
1158 "column nor a constructed point"
1159 << func_oper->toString();
1164 auto rhs = func_oper->getOwnArg(1);
1165 auto rewritten_rhs = deep_copy_visitor.
visit(rhs.get());
1166 CHECK(rewritten_rhs);
1168 if (has_invalid_join_col_order(lhs.get(), rhs.get()).first) {
1169 LOG(
INFO) <<
"Unable to rewrite " << func_name
1170 <<
" to bounding box intersection conjunction. Cannot build hash table "
1173 << func_oper->toString();
1177 VLOG(1) <<
"Rewriting " << func_name
1178 <<
" to use bounding box intersection with lhs as "
1179 << rewritten_lhs->toString() <<
" and rhs as " << rewritten_rhs->toString();
1181 bbox_intersect_oper = makeExpr<Analyzer::BinOper>(
1184 ST_APPROX_OVERLAPS_MULTIPOLYGON_POINT_sv) {
1185 needs_to_return_original_expr =
true;
1195 func_name = lhs->getName();
1196 bbox_intersect_oper = convert_to_range_join_oper(func_name, expr, bin_oper, lhs, rhs);
1197 needs_to_return_original_expr =
true;
1199 const auto expr_str = !func_name.empty() ? func_name : expr->toString();
1200 if (bbox_intersect_oper) {
1204 bbox_intersect_join_qual.
join_quals.push_back(bbox_intersect_oper);
1205 if (needs_to_return_original_expr) {
1206 bbox_intersect_join_qual.
quals.push_back(expr);
1209 VLOG(1) <<
"Successfully converted " << expr_str
1210 <<
" to use bounding box intersection";
1213 VLOG(1) <<
"Bounding box intersection not enabled for " << expr_str;
1219 std::vector<InputDescriptor>& input_descs,
1220 std::unordered_map<const RelAlgNode*, int>& input_to_nest_level,
1221 std::vector<size_t>& input_permutation,
1222 std::list<std::shared_ptr<const InputColDescriptor>>& input_col_desc,
1223 Executor
const* executor) {
1225 return {join_quals,
false,
false};
1229 bool is_reordered{
false};
1230 bool has_bbox_intersect{
false};
1231 for (
const auto& join_condition_in : join_quals) {
1234 for (
const auto& join_qual_expr_in : join_condition_in.quals) {
1235 bool try_to_rewrite_expr_to_bbox_intersect =
false;
1240 const auto func_name = func_oper->
getName();
1243 try_to_rewrite_expr_to_bbox_intersect =
true;
1248 if (bin_oper && (bin_oper->get_optype() ==
kLE || bin_oper->get_optype() ==
kLT)) {
1253 try_to_rewrite_expr_to_bbox_intersect =
true;
1258 if (try_to_rewrite_expr_to_bbox_intersect) {
1262 input_to_nest_level,
1269 const auto& bbox_intersect_quals =
1271 has_bbox_intersect =
true;
1273 join_condition.quals.insert(join_condition.quals.end(),
1274 bbox_intersect_quals.join_quals.begin(),
1275 bbox_intersect_quals.join_quals.end());
1277 join_condition.quals.insert(join_condition.quals.end(),
1278 bbox_intersect_quals.quals.begin(),
1279 bbox_intersect_quals.quals.end());
1281 join_condition.quals.push_back(join_qual_expr_in);
1285 join_condition_per_nesting_level.push_back(join_condition);
1287 return {join_condition_per_nesting_level, has_bbox_intersect, is_reordered};
1301 for (
const auto& join_condition : join_quals) {
1302 for (
const auto& qual : join_condition.quals) {
1304 if (qual_bin_oper) {
1306 qual_bin_oper->get_right_operand());
1315 const auto lhs = func_oper->
getArg(2);
1316 const auto rhs = func_oper->
getArg(1);
1318 if (*lhs == *qual_pair.first && *rhs == *qual_pair.second) {
1333 const std::list<std::shared_ptr<Analyzer::Expr>>& quals,
1339 if (join_quals.empty()) {
1343 std::list<std::shared_ptr<Analyzer::Expr>> quals_to_return;
1346 for (
const auto& qual : quals) {
1347 if (!visitor.
visit(qual.get())) {
1349 quals_to_return.push_back(qual);
1353 return quals_to_return;
1361 ConstantFoldingVisitor visitor;
1362 auto rewritten_expr = visitor.visit(expr_no_likelihood);
1363 if (visitor.get_num_overflows() > 0 && rewritten_expr->get_type_info().is_integer() &&
1364 rewritten_expr->get_type_info().get_type() !=
kBIGINT) {
1365 auto rewritten_expr_const =
1367 if (!rewritten_expr_const) {
1371 auto bigint_expr_no_likelihood = expr_no_likelihood->deep_copy()->add_cast(ti);
1372 auto rewritten_expr_take2 = visitor.visit(bigint_expr_no_likelihood.get());
1373 auto rewritten_expr_take2_const =
1375 if (rewritten_expr_take2_const) {
1377 rewritten_expr = rewritten_expr_take2_const;
1382 if (expr_with_likelihood) {
1384 return std::make_shared<Analyzer::LikelihoodExpr>(
1385 rewritten_expr, expr_with_likelihood->get_likelihood());
1387 return rewritten_expr;
1392 const int max_rte_covered) {
1402 std::unordered_map<int, llvm::Value*>& scan_idx_to_hash_pos) {
1403 int ret = INT32_MIN;
1404 for (
auto& kv : scan_idx_to_hash_pos) {
1405 if (kv.first > ret) {
1413 Executor
const* executor) {
1417 CHECK(td->fragmenter);
1418 return td->fragmenter->getNumRows();
1421 return temp_tbl->rowCount();
Analyzer::ExpressionPtr rewrite_array_elements(Analyzer::Expr const *expr)
std::optional< BoundingBoxIntersectJoinConjunction > converted_bbox_intersect_join_info
std::list< std::shared_ptr< Analyzer::Expr > > join_quals
std::shared_ptr< Analyzer::InValues > visitLikeExpr(const Analyzer::LikeExpr *) const override
std::shared_ptr< Analyzer::InValues > visitDateaddExpr(const Analyzer::DateaddExpr *) const override
Datum apply_numeric_op_to_literals(const StringOpInfo &string_op_info)
bool self_join_not_covered_by_left_deep_tree(const Analyzer::ColumnVar *key_side, const Analyzer::ColumnVar *val_side, const int max_rte_covered)
std::shared_ptr< Analyzer::WindowFunction > rewrite_avg_window(const Analyzer::Expr *expr)
bool g_strip_join_covered_quals
std::shared_ptr< Analyzer::InValues > visitKeyForString(const Analyzer::KeyForStringExpr *) const override
std::shared_ptr< Analyzer::WindowFunction > rewrite_sum_window(const Analyzer::Expr *expr)
static constexpr std::string_view ST_DISTANCE_sv
std::shared_ptr< Analyzer::InValues > visitBinOper(const Analyzer::BinOper *bin_oper) const override
const Expr * get_right_operand() const
bool is_constructed_point(const Analyzer::Expr *expr)
size_t get_table_cardinality(shared::TableKey const &table_key, Executor const *executor)
static bool is_range_join_rewrite_target_func(std::string_view target_func_name)
const TableDescriptor * get_metadata_for_table(const ::shared::TableKey &table_key, bool populate_fragmenter)
bool get_contains_agg() const
std::shared_ptr< Analyzer::Expr > ExpressionPtr
const Analyzer::Expr * extract_cast_arg(const Analyzer::Expr *expr)
std::vector< JoinCondition > JoinQualsPerNestingLevel
T visit(const Analyzer::Expr *expr) const
Analyzer::ExpressionPtr rewrite_expr(const Analyzer::Expr *expr)
#define TRANSIENT_DICT_ID
std::shared_ptr< Analyzer::InValues > aggregateResult(const std::shared_ptr< Analyzer::InValues > &lhs, const std::shared_ptr< Analyzer::InValues > &rhs) const override
std::list< std::shared_ptr< Analyzer::Expr > > strip_join_covered_filter_quals(const std::list< std::shared_ptr< Analyzer::Expr >> &quals, const JoinQualsPerNestingLevel &join_quals)
std::shared_ptr< Analyzer::InValues > visitUOper(const Analyzer::UOper *uoper) const override
const int get_max_rte_scan_table(std::unordered_map< int, llvm::Value * > &scan_idx_to_hash_pos)
std::shared_ptr< Analyzer::Expr > visitBinOper(const Analyzer::BinOper *bin_oper) const override
std::shared_ptr< Analyzer::Expr > RetType
static BoundingBoxIntersectJoinTranslationResult createEmptyResult()
std::list< std::shared_ptr< Analyzer::Expr > > quals
std::shared_ptr< Analyzer::InValues > visitCharLength(const Analyzer::CharLengthExpr *) const override
std::shared_ptr< Analyzer::InValues > visitInIntegerSet(const Analyzer::InIntegerSet *) const override
SQLOps get_optype() const
const ResultSetPtr & get_temporary_table(const TemporaryTables *temporary_tables, const int table_id)
std::shared_ptr< Analyzer::Expr > visitUOper(const Analyzer::UOper *uoper) const override
LiteralArgMap getLiteralArgs() const
static constexpr std::string_view ST_INTERSECTSBOX_sv
Classes representing a parse tree.
bool g_enable_hashjoin_many_to_many
std::shared_ptr< Analyzer::InValues > visitRegexpExpr(const Analyzer::RegexpExpr *) const override
BoundingBoxIntersectJoinTranslationResult translate_bounding_box_intersect_with_reordering(const std::shared_ptr< Analyzer::Expr > expr, std::vector< InputDescriptor > &input_descs, std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, std::vector< size_t > &input_permutation, std::list< std::shared_ptr< const InputColDescriptor >> &input_col_desc, const BoundingBoxIntersectJoinRewriteType rewrite_type, Executor const *executor)
bool g_enable_distance_rangejoin
std::shared_ptr< Analyzer::InValues > visitAggExpr(const Analyzer::AggExpr *) const override
bool visitFunctionOper(const Analyzer::FunctionOper *func_oper) const override
bool foldOper(SQLOps optype, SQLTypes type, Datum lhs, Datum rhs, Datum &result, SQLTypes &result_type) const
std::pair< std::string, bool > apply_string_op_to_literals(const StringOpInfo &string_op_info)
bool defaultResult() const override
std::shared_ptr< Analyzer::Expr > visitStringOper(const Analyzer::StringOper *string_oper) const override
RetType visitArrayOper(const Analyzer::ArrayExpr *array_expr) const override
bool IsNullDatum(const Datum datum, const SQLTypeInfo &ti)
BoundingBoxIntersectJoinTranslationInfo convert_bbox_intersect_join(JoinQualsPerNestingLevel const &join_quals, std::vector< InputDescriptor > &input_descs, std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, std::vector< size_t > &input_permutation, std::list< std::shared_ptr< const InputColDescriptor >> &input_col_desc, Executor const *executor)
const SQLTypeInfo & get_type_info() const
std::shared_ptr< Analyzer::Expr > visitBinOper(const Analyzer::BinOper *bin_oper) const override
size_t getElementCount() const
SQLTypes decimal_to_int_type(const SQLTypeInfo &ti)
bool foldLogic(SQLOps optype, T t1, T t2) const
void update_input_to_nest_lv(std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, shared::ColumnKey const &column_key, int target_nest_lv)
static bool is_bbox_intersect_supported_func(std::string_view target_func_name)
std::vector< std::shared_ptr< Analyzer::Expr > > chained_string_op_exprs_
std::vector< std::pair< const Analyzer::Expr *, const Analyzer::Expr * > > join_qual_pairs
Expression class for string functions The "arg" constructor parameter must be an expression that reso...
const shared::ColumnKey & getColumnKey() const
static std::shared_ptr< Analyzer::Expr > analyzeValue(const std::string &stringval, const bool is_null)
bool isLocalAlloc() const
SqlStringOpKind get_kind() const
const Analyzer::Expr * getArg(const size_t i) const
bool g_enable_bbox_intersect_hashjoin
const Expr * get_operand() const
Datum get_constval() const
torch::Tensor f(torch::Tensor x, torch::Tensor W_target, torch::Tensor b_target)
std::unordered_map< const Analyzer::Expr *, const SQLTypeInfo > casts_
std::shared_ptr< Analyzer::InValues > visitDatediffExpr(const Analyzer::DatediffExpr *) const override
static const StringDictKey kTransientDictKey
std::shared_ptr< Analyzer::InValues > visitLikelihood(const Analyzer::LikelihoodExpr *) const override
auto update_input_col_desc(std::list< std::shared_ptr< const InputColDescriptor >> &input_col_desc, shared::ColumnKey const &column_key, int target_nest_lv)
std::shared_ptr< Analyzer::InValues > visitInValues(const Analyzer::InValues *) const override
int update_input_desc(std::vector< InputDescriptor > &input_descs, shared::ColumnKey const &column_key, int target_nest_lv)
static constexpr std::string_view ST_DWITHIN_POINT_POINT_sv
virtual void collect_rte_idx(std::set< int > &rte_idx_set) const
T foldArithmetic(SQLOps optype, T t1, T t2) const
int32_t get_num_overflows()
std::shared_ptr< Analyzer::InValues > visitPCAProject(const Analyzer::PCAProjectExpr *) const override
const Expr * get_left_operand() const
Common Enum definitions for SQL processing.
std::shared_ptr< Analyzer::InValues > visitCaseExpr(const Analyzer::CaseExpr *) const override
bool any_of(std::vector< Analyzer::Expr * > const &target_exprs)
JoinCoveredQualVisitor(const JoinQualsPerNestingLevel &join_quals)
const std::shared_ptr< Analyzer::Expr > get_own_right_operand() const
BoundingBoxIntersectJoinRewriteType
std::string getName() const
int32_t get_rte_idx() const
bool foldComparison(SQLOps optype, T t1, T t2) const
size_t getNonLiteralsArity() const
static bool is_many_to_many_func(std::string_view target_func_name)
std::shared_ptr< Analyzer::InValues > visitDatetruncExpr(const Analyzer::DatetruncExpr *) const override
DEVICE void swap(ARGS &&...args)
std::shared_ptr< Analyzer::InValues > visitMLPredict(const Analyzer::MLPredictExpr *) const override
const std::shared_ptr< Analyzer::Expr > get_own_left_operand() const
std::vector< std::shared_ptr< Analyzer::Expr > > getOwnArgs() const
SQLOps get_optype() const
std::shared_ptr< Analyzer::Expr > fold_expr(const Analyzer::Expr *expr)
shared::TableKey getTableKey() const
std::shared_ptr< Analyzer::InValues > visitExtractExpr(const Analyzer::ExtractExpr *) const override
const Analyzer::Expr * getElement(const size_t i) const
SQLQualifier get_qualifier() const
const Analyzer::Expr * strip_likelihood(const Analyzer::Expr *expr)
std::shared_ptr< Analyzer::InValues > visitSampleRatio(const Analyzer::SampleRatioExpr *) const override
void reset_num_overflows()
std::shared_ptr< Analyzer::InValues > visitCardinality(const Analyzer::CardinalityExpr *) const override