46 const int precision) {
59 std::shared_ptr<Analyzer::Expr> rhs;
61 const auto rex_operator =
dynamic_cast<const RexOperator*
>(rex_scalar);
63 return std::make_pair(rhs, sql_qual);
66 const auto qual_str = rex_function ? rex_function->
getName() :
"";
67 if (qual_str ==
"PG_ANY"sv || qual_str ==
"PG_ALL"sv) {
68 CHECK_EQ(
size_t(1), rex_function->size());
70 sql_qual = (qual_str ==
"PG_ANY"sv) ?
kANY :
kALL;
72 if (!rhs && rex_operator->getOperator() ==
kCAST) {
73 CHECK_EQ(
size_t(1), rex_operator->size());
76 return std::make_pair(rhs, sql_qual);
84 bool is_null_const{
false};
85 switch (ti.get_type()) {
87 const auto ival = boost::get<int64_t>(scalar_tv);
97 const auto ival = boost::get<int64_t>(scalar_tv);
100 is_null_const =
true;
102 d.tinyintval = *ival;
107 const auto ival = boost::get<int64_t>(scalar_tv);
110 is_null_const =
true;
112 d.smallintval = *ival;
117 const auto ival = boost::get<int64_t>(scalar_tv);
120 is_null_const =
true;
132 const auto ival = boost::get<int64_t>(scalar_tv);
135 is_null_const =
true;
142 const auto dval = boost::get<double>(scalar_tv);
145 is_null_const =
true;
152 const auto fval = boost::get<float>(scalar_tv);
155 is_null_const =
true;
164 auto nullable_sptr = boost::get<NullableString>(scalar_tv);
165 CHECK(nullable_sptr);
166 if (boost::get<void*>(nullable_sptr)) {
167 is_null_const =
true;
169 auto sptr = boost::get<std::string>(nullable_sptr);
170 d.stringval =
new std::string(*sptr);
175 CHECK(
false) <<
"Unhandled type: " << ti.get_type_name();
177 return {d, is_null_const};
184 template <
typename... Ts>
186 return {IndexedHandler{std::type_index(
typeid(Ts)),
187 &RelAlgTranslator::translateRexScalar<Ts>}...};
193 : type_index_(std::type_index(type_info)) {}
194 bool operator()(IndexedHandler
const& pair)
const {
return pair.first == type_index_; }
200 std::shared_ptr<Analyzer::Expr> RelAlgTranslator::translateRexScalar<RexInput>(
202 return translateInput(static_cast<RexInput const*>(rex));
205 std::shared_ptr<Analyzer::Expr> RelAlgTranslator::translateRexScalar<RexLiteral>(
207 return translateLiteral(static_cast<RexLiteral const*>(rex));
210 std::shared_ptr<Analyzer::Expr>
211 RelAlgTranslator::translateRexScalar<RexWindowFunctionOperator>(
213 return translateWindowFunction(static_cast<RexWindowFunctionOperator const*>(rex));
216 std::shared_ptr<Analyzer::Expr> RelAlgTranslator::translateRexScalar<RexFunctionOperator>(
218 return translateFunction(static_cast<RexFunctionOperator const*>(rex));
221 std::shared_ptr<Analyzer::Expr> RelAlgTranslator::translateRexScalar<RexOperator>(
223 return translateOper(static_cast<RexOperator const*>(rex));
226 std::shared_ptr<Analyzer::Expr> RelAlgTranslator::translateRexScalar<RexCase>(
228 return translateCase(static_cast<RexCase const*>(rex));
231 std::shared_ptr<Analyzer::Expr> RelAlgTranslator::translateRexScalar<RexSubQuery>(
233 return translateScalarSubquery(static_cast<RexSubQuery const*>(rex));
238 auto cache_itr =
cache_.find(rex);
239 if (cache_itr ==
cache_.end()) {
248 static_assert(std::is_trivially_destructible_v<decltype(handlers)>);
249 auto it = std::find_if(handlers.cbegin(), handlers.cend(), ByTypeIndex{
typeid(*rex)});
250 CHECK(it != handlers.cend()) <<
"Unhandled type: " <<
typeid(*rex).name();
252 auto cached =
cache_.emplace(rex, (this->*it->second)(rex));
253 CHECK(cached.second) <<
"Failed to emplace rex of type " <<
typeid(*rex).name();
254 cache_itr = cached.first;
256 return cache_itr->second;
267 if ((agg_kind ==
kMIN || agg_kind ==
kMAX || agg_kind ==
kSUM || agg_kind ==
kAVG) &&
279 const std::vector<std::shared_ptr<Analyzer::Expr>>& scalar_sources) {
283 std::shared_ptr<Analyzer::Expr> arg_expr;
284 std::shared_ptr<Analyzer::Expr> arg1;
287 CHECK_LT(operand, scalar_sources.size());
289 arg_expr = scalar_sources[operand];
292 if (rex->
size() == 2) {
295 if (!const_arg1 || const_arg1->get_type_info().get_type() !=
kINT ||
296 const_arg1->get_constval().intval < 1 ||
297 const_arg1->get_constval().intval > 100) {
298 throw std::runtime_error(
299 "APPROX_COUNT_DISTINCT's second parameter should be SMALLINT literal "
308 throw std::runtime_error(
309 "APPROX_PERCENTILE/MEDIAN is not supported in distributed mode at this "
313 if (rex->
size() == 2) {
325 arg1 = std::make_shared<Analyzer::Constant>(
kDOUBLE,
false, median);
330 throw std::runtime_error(
331 "MODE is not supported in distributed mode at this time.");
336 throw std::runtime_error(
337 "Currently, COUNT_IF function does not support DISTINCT qualifier.");
342 if (arg1->get_type_info().get_type() !=
kBOOLEAN) {
343 throw std::runtime_error(
"Conditional argument must be a boolean expression.");
349 const auto& arg_ti = arg_expr->get_type_info();
351 throw std::runtime_error(
"Aggregate on " + arg_ti.get_type_name() +
352 " is not supported yet.");
355 const auto agg_ti =
get_agg_type(agg_kind, arg_expr.get());
356 return makeExpr<Analyzer::AggExpr>(agg_ti, agg_kind, arg_expr,
is_distinct, arg1);
360 const RexLiteral* rex_literal) {
362 rex_literal->getType(), rex_literal->getScale(), rex_literal->getPrecision());
364 rex_literal->getTargetScale(),
365 rex_literal->getTargetPrecision());
366 switch (rex_literal->getType()) {
370 d.
bigintval = rex_literal->getVal<int64_t>();
371 return makeExpr<Analyzer::Constant>(rex_literal->getType(),
false, d);
374 const auto val = rex_literal->getVal<int64_t>();
375 const int precision = rex_literal->getPrecision();
376 const int scale = rex_literal->getScale();
377 if (target_ti.is_fp() && !scale) {
382 return lit_ti != target_ti ? lit_expr->add_cast(target_ti) : lit_expr;
390 d.
boolval = rex_literal->getVal<
bool>();
391 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
395 d.
doubleval = rex_literal->getVal<
double>();
397 makeExpr<Analyzer::Constant>(
SQLTypeInfo(rex_literal->getType(),
398 rex_literal->getPrecision(),
399 rex_literal->getScale(),
403 return lit_ti != target_ti ? lit_expr->add_cast(target_ti) : lit_expr;
408 d.
bigintval = rex_literal->getVal<int64_t>();
409 return makeExpr<Analyzer::Constant>(rex_literal->getType(),
false, d);
415 rex_literal->getType() ==
kTIMESTAMP && rex_literal->getPrecision() > 0
416 ? rex_literal->getVal<int64_t>()
417 : rex_literal->getVal<int64_t>() / 1000;
418 return makeExpr<Analyzer::Constant>(
419 SQLTypeInfo(rex_literal->getType(), rex_literal->getPrecision(), 0,
false),
425 d.
bigintval = rex_literal->getVal<int64_t>() * 24 * 3600;
426 return makeExpr<Analyzer::Constant>(rex_literal->getType(),
false, d);
429 if (target_ti.is_array()) {
433 return makeExpr<Analyzer::ArrayExpr>(target_ti,
args,
true);
435 return makeExpr<Analyzer::Constant>(rex_literal->getTargetType(),
true,
Datum{0});
438 LOG(
FATAL) <<
"Unexpected literal type " << lit_ti.get_type_name();
445 const RexSubQuery* rex_subquery)
const {
447 throw std::runtime_error(
"EXPLAIN is not supported with sub-queries");
450 auto result = rex_subquery->getExecutionResult();
451 auto row_set =
result->getRows();
452 const size_t row_count = row_set->rowCount();
453 if (row_count >
size_t(1)) {
454 throw std::runtime_error(
"Scalar sub-query returned multiple rows");
456 if (row_count ==
size_t(0)) {
457 if (row_set->isValidationOnlyRes()) {
459 return makeExpr<Analyzer::Constant>(rex_subquery->getType(),
false, d);
461 throw std::runtime_error(
"Scalar sub-query returned no results");
464 row_set->moveToBegin();
465 auto first_row = row_set->getNextRow(
false,
false);
466 CHECK_EQ(first_row.size(), size_t(1));
467 auto scalar_tv = boost::get<ScalarTargetValue>(&first_row[0]);
468 auto ti = rex_subquery->getType();
469 if (ti.is_string()) {
470 throw std::runtime_error(
"Scalar sub-queries which return strings not supported");
473 bool is_null_const{
false};
475 return makeExpr<Analyzer::Constant>(ti, is_null_const, d);
483 <<
"Not found in input_to_nest_level_, source="
485 const int rte_idx = it_rte_idx->second;
486 const auto scan_source =
dynamic_cast<const RelScan*
>(source);
491 CHECK(in_metainfo.empty());
492 const auto table_desc = scan_source->getTableDescriptor();
493 const auto& catalog = scan_source->getCatalog();
495 catalog.getMetadataForColumnBySpi(table_desc->tableId, rex_input->
getIndex() + 1);
497 auto col_ti = cd->columnType;
498 if (col_ti.is_string()) {
499 col_ti.set_type(
kTEXT);
501 if (cd->isVirtualCol) {
509 col_ti.set_notnull(
false);
511 return std::make_shared<Analyzer::ColumnVar>(
516 CHECK(!in_metainfo.empty()) <<
"for "
519 const int32_t col_id = rex_input->
getIndex();
520 CHECK_LT(col_id, in_metainfo.size());
521 auto col_ti = in_metainfo[col_id].get_type_info();
526 col_ti.set_notnull(
false);
530 return std::make_shared<Analyzer::ColumnVar>(
541 const auto& target_ti = rex_operator->
getType();
543 const auto& operand_ti = operand_expr->get_type_info();
544 if (operand_ti.is_string() && target_ti.is_string()) {
547 if (target_ti.is_time() ||
551 return target_ti.is_date_in_days()
553 : operand_expr->add_cast(target_ti);
555 if (!operand_ti.is_string() && target_ti.is_string()) {
556 return operand_expr->add_cast(target_ti);
558 return std::make_shared<Analyzer::UOper>(target_ti,
false, sql_op, operand_expr);
561 const auto& target_ti = rex_operator->
getType();
563 const auto& operand_ti = operand_expr->get_type_info();
564 CHECK(operand_ti.is_string());
565 if (operand_ti.is_dict_encoded_string()) {
569 if (operand_expr->get_num_column_vars(
true) == 0UL) {
573 throw std::runtime_error(
574 "ENCODE_TEXT is not currently supported in distributed mode at this time.");
581 return makeExpr<Analyzer::UOper>(
582 casted_target_ti, operand_expr->get_contains_agg(),
kCAST, operand_expr);
586 return std::make_shared<Analyzer::UOper>(
kBOOLEAN, sql_op, operand_expr);
593 const auto& ti = operand_expr->get_type_info();
594 return std::make_shared<Analyzer::UOper>(ti,
false,
kUMINUS, operand_expr);
597 const auto& ti = operand_expr->get_type_info();
598 CHECK(ti.is_array());
599 return makeExpr<Analyzer::UOper>(ti.get_elem_type(),
false,
kUNNEST, operand_expr);
610 const ResultSet& val_set) {
615 throw std::runtime_error(
616 "Unable to handle 'expr IN (subquery)', subquery returned 5M+ rows.");
618 std::list<std::shared_ptr<Analyzer::Expr>> value_exprs;
620 std::vector<std::list<std::shared_ptr<Analyzer::Expr>>> expr_set(
621 fetcher_count, std::list<std::shared_ptr<Analyzer::Expr>>());
622 std::vector<std::future<void>> fetcher_threads;
623 const auto& ti = arg->get_type_info();
624 const auto entry_count = val_set.entryCount();
627 stride = (entry_count + fetcher_count - 1) / fetcher_count;
628 i < fetcher_count && start_entry < entry_count;
629 ++i, start_entry += stride) {
630 const auto end_entry = std::min(start_entry + stride, entry_count);
633 [&](std::list<std::shared_ptr<Analyzer::Expr>>& in_vals,
636 for (
auto index = start; index < end; ++index) {
637 auto row = val_set.getRowAt(index);
641 auto scalar_tv = boost::get<ScalarTargetValue>(&row[0]);
643 bool is_null_const{
false};
646 auto ti_none_encoded = ti;
648 auto none_encoded_string =
649 makeExpr<Analyzer::Constant>(ti, is_null_const, d);
650 auto dict_encoded_string = std::make_shared<Analyzer::UOper>(
651 ti,
false,
kCAST, none_encoded_string);
652 in_vals.push_back(dict_encoded_string);
654 in_vals.push_back(makeExpr<Analyzer::Constant>(ti, is_null_const, d));
658 std::ref(expr_set[i]),
662 for (
auto& child : fetcher_threads) {
666 val_set.moveToBegin();
667 for (
auto& exprs : expr_set) {
668 value_exprs.splice(value_exprs.end(), exprs);
670 return makeExpr<Analyzer::InValues>(arg, value_exprs);
683 throw std::runtime_error(
"EXPLAIN is not supported with sub-queries");
688 const auto rex_subquery =
dynamic_cast<const RexSubQuery*
>(rhs);
690 auto ti = lhs->get_type_info();
691 auto result = rex_subquery->getExecutionResult();
693 auto& row_set =
result->getRows();
694 CHECK_EQ(
size_t(1), row_set->colCount());
695 const auto& rhs_ti = row_set->getColType(0);
696 if (rhs_ti.get_type() != ti.get_type()) {
697 throw std::runtime_error(
698 "The two sides of the IN operator must have the same type; found " +
699 ti.get_type_name() +
" and " + rhs_ti.get_type_name());
701 row_set->moveToBegin();
702 if (row_set->entryCount() > 10000) {
703 std::shared_ptr<Analyzer::Expr> expr;
704 if ((ti.is_integer() || (ti.is_string() && ti.get_compression() ==
kENCODING_DICT)) &&
705 !row_set->getQueryMemDesc().didOutputColumnar()) {
710 if (expr && std::static_pointer_cast<Analyzer::InIntegerSet>(expr)
722 std::list<std::shared_ptr<Analyzer::Expr>> value_exprs;
724 auto row = row_set->getNextRow(
true,
false);
729 throw std::runtime_error(
730 "Unable to handle 'expr IN (subquery)', subquery returned 10000+ rows.");
732 auto scalar_tv = boost::get<ScalarTargetValue>(&row[0]);
734 bool is_null_const{
false};
737 auto ti_none_encoded = ti;
739 auto none_encoded_string = makeExpr<Analyzer::Constant>(ti, is_null_const, d);
740 auto dict_encoded_string =
741 std::make_shared<Analyzer::UOper>(ti,
false,
kCAST, none_encoded_string);
742 value_exprs.push_back(dict_encoded_string);
744 value_exprs.push_back(makeExpr<Analyzer::Constant>(ti, is_null_const, d));
747 return makeExpr<Analyzer::InValues>(lhs, value_exprs);
755 std::vector<int64_t>& in_vals,
756 std::atomic<size_t>& total_in_vals_count,
757 const ResultSet* values_rowset,
758 const std::pair<int64_t, int64_t> values_rowset_slice,
761 const int64_t needle_null_val) {
762 CHECK(in_vals.empty());
763 bool dicts_are_equal = source_dict == dest_dict;
764 for (
auto index = values_rowset_slice.first; index < values_rowset_slice.second;
766 const auto row = values_rowset->getOneColRow(index);
770 if (dicts_are_equal) {
771 in_vals.push_back(row.value);
773 const int string_id =
774 row.value == needle_null_val
778 in_vals.push_back(string_id);
783 throw std::runtime_error(
784 "Unable to handle 'expr IN (subquery)', subquery returned 30M+ rows.");
790 std::atomic<size_t>& total_in_vals_count,
791 const ResultSet* values_rowset,
792 const std::pair<int64_t, int64_t> values_rowset_slice) {
793 CHECK(in_vals.empty());
794 for (
auto index = values_rowset_slice.first; index < values_rowset_slice.second;
796 const auto row = values_rowset->getOneColRow(index);
798 in_vals.push_back(row.value);
801 throw std::runtime_error(
802 "Unable to handle 'expr IN (subquery)', subquery returned 30M+ rows.");
816 std::vector<int64_t>& in_vals,
817 std::atomic<size_t>& total_in_vals_count,
818 const ResultSet* values_rowset,
819 const std::pair<int64_t, int64_t> values_rowset_slice,
820 const std::vector<LeafHostInfo>& leaf_hosts,
823 const int32_t dest_generation,
824 const int64_t needle_null_val) {
825 CHECK(in_vals.empty());
826 std::vector<int32_t> source_ids;
827 source_ids.reserve(values_rowset->entryCount());
828 bool has_nulls =
false;
829 if (source_dict_ref == dest_dict_ref) {
830 in_vals.reserve(values_rowset_slice.second - values_rowset_slice.first +
832 for (
auto index = values_rowset_slice.first; index < values_rowset_slice.second;
834 const auto row = values_rowset->getOneColRow(index);
838 if (row.value != needle_null_val) {
839 in_vals.push_back(row.value);
842 throw std::runtime_error(
843 "Unable to handle 'expr IN (subquery)', subquery returned 30M+ rows.");
857 for (
auto index = values_rowset_slice.first; index < values_rowset_slice.second;
859 const auto row = values_rowset->getOneColRow(index);
861 if (row.value != needle_null_val) {
862 source_ids.push_back(row.value);
868 std::vector<int32_t> dest_ids;
875 CHECK_EQ(dest_ids.size(), source_ids.size());
876 in_vals.reserve(dest_ids.size() + (has_nulls ? 1 : 0));
878 in_vals.push_back(needle_null_val);
880 for (
const int32_t dest_id : dest_ids) {
882 in_vals.push_back(dest_id);
885 throw std::runtime_error(
886 "Unable to handle 'expr IN (subquery)', subquery returned 30M+ rows.");
901 std::shared_ptr<Analyzer::Expr> arg,
902 const ResultSet& val_set)
const {
906 std::vector<int64_t> value_exprs;
908 std::vector<std::vector<int64_t>> expr_set(fetcher_count);
909 std::vector<std::future<void>> fetcher_threads;
910 const auto& arg_type = arg->get_type_info();
911 const auto entry_count = val_set.entryCount();
912 CHECK_EQ(
size_t(1), val_set.colCount());
913 const auto& col_type = val_set.getColType(0);
915 (col_type.get_comp_param() <= 0 || arg_type.get_comp_param() <= 0)) {
919 std::atomic<size_t> total_in_vals_count{0};
922 stride = (entry_count + fetcher_count - 1) / fetcher_count;
923 i < fetcher_count && start_entry < entry_count;
924 ++i, start_entry += stride) {
925 expr_set[i].reserve(entry_count / fetcher_count);
926 const auto end_entry = std::min(start_entry + stride, entry_count);
927 if (arg_type.is_string()) {
931 const auto& dest_dict_key = arg_type.getStringDictKey();
932 const auto& source_dict_key = col_type.getStringDictKey();
933 const auto dd =
executor_->getStringDictionaryProxy(
934 arg_type.getStringDictKey(), val_set.getRowSetMemOwner(),
true);
935 const auto sd =
executor_->getStringDictionaryProxy(
936 col_type.getStringDictKey(), val_set.getRowSetMemOwner(),
true);
940 col_expr->getColumnKey().db_id);
946 &total_in_vals_count,
952 catalog](std::vector<int64_t>& in_vals,
const size_t start,
const size_t end) {
960 catalog->getStringDictionaryHosts(),
961 {source_dict_key.db_id, source_dict_key.dict_id},
962 {dest_dict_key.db_id, dest_dict_key.dict_id},
975 std::ref(expr_set[i]),
979 CHECK(arg_type.is_integer());
982 [&val_set, &total_in_vals_count](
983 std::vector<int64_t>& in_vals,
const size_t start,
const size_t end) {
986 std::ref(expr_set[i]),
991 for (
auto& child : fetcher_threads) {
995 val_set.moveToBegin();
996 value_exprs.reserve(entry_count);
997 for (
auto& exprs : expr_set) {
998 value_exprs.insert(value_exprs.end(), exprs.begin(), exprs.end());
1000 return makeExpr<Analyzer::InIntegerSet>(
1001 arg, value_exprs, arg_type.get_notnull() && col_type.get_notnull());
1007 if (rex_operator->
size() == 1) {
1011 if (sql_op ==
kIN) {
1016 if (date_plus_minus) {
1017 return date_plus_minus;
1029 for (
size_t i = 1; i < rex_operator->
size(); ++i) {
1030 std::shared_ptr<Analyzer::Expr> rhs;
1032 const auto rhs_op = rex_operator->
getOperand(i);
1052 const auto lhs_ti = lhs->get_type_info();
1053 if (lhs_ti.is_geometry()) {
1056 throw std::runtime_error(
1057 "Overlaps equivalence is currently only supported for geospatial types");
1062 const RexCase* rex_case)
const {
1063 std::shared_ptr<Analyzer::Expr> else_expr;
1064 std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
1066 for (
size_t i = 0; i < rex_case->
branchCount(); ++i) {
1069 expr_list.emplace_back(when_expr, then_expr);
1084 if (!partition_count->get_type_info().is_integer()) {
1085 throw std::runtime_error(
1086 "PARTITION_COUNT expression of width_bucket function expects an integer type.");
1088 auto check_numeric_type =
1089 [](
const std::string& col_name,
const Analyzer::Expr* expr,
bool allow_null_type) {
1090 if (expr->get_type_info().get_type() ==
kNULLT) {
1091 if (!allow_null_type) {
1092 throw std::runtime_error(
1093 col_name +
" expression of width_bucket function expects non-null type.");
1097 if (!expr->get_type_info().is_number()) {
1098 throw std::runtime_error(
1099 col_name +
" expression of width_bucket function expects a numeric type.");
1103 check_numeric_type(
"TARGET_VALUE", target_value.get(),
true);
1104 check_numeric_type(
"LOWER_BOUND", lower_bound.get(),
false);
1105 check_numeric_type(
"UPPER_BOUND", upper_bound.get(),
false);
1107 auto cast_to_double_if_necessary = [](std::shared_ptr<Analyzer::Expr> arg) {
1108 const auto& arg_ti = arg->get_type_info();
1109 if (arg_ti.get_type() !=
kDOUBLE) {
1111 return arg->add_cast(double_ti);
1115 target_value = cast_to_double_if_necessary(target_value);
1116 lower_bound = cast_to_double_if_necessary(lower_bound);
1117 upper_bound = cast_to_double_if_necessary(upper_bound);
1118 return makeExpr<Analyzer::WidthBucketExpr>(
1124 CHECK(rex_function->
size() == 2 || rex_function->
size() == 3);
1127 if (!std::dynamic_pointer_cast<const Analyzer::Constant>(like)) {
1128 throw std::runtime_error(
"The matching pattern must be a literal.");
1130 const auto escape = (rex_function->
size() == 3)
1133 const bool is_ilike = rex_function->
getName() ==
"PG_ILIKE"sv;
1139 CHECK(rex_function->
size() == 2 || rex_function->
size() == 3);
1142 if (!std::dynamic_pointer_cast<const Analyzer::Constant>(pattern)) {
1143 throw std::runtime_error(
"The matching pattern must be a literal.");
1145 const auto escape = (rex_function->
size() == 3)
1155 return makeExpr<Analyzer::LikelihoodExpr>(arg, 0.9375);
1162 return makeExpr<Analyzer::LikelihoodExpr>(arg, 0.0625);
1168 const std::shared_ptr<Analyzer::Constant> literal_expr) {
1169 if (!literal_expr || literal_expr->get_is_null()) {
1170 throw std::runtime_error(
"The 'DatePart' argument must be a not 'null' literal.");
1183 const bool is_date_trunc = rex_function->
getName() ==
"PG_DATE_TRUNC"sv;
1184 if (is_date_trunc) {
1199 datum.tinyintval = val;
1203 datum.smallintval = val;
1211 datum.bigintval = val;
1220 datum.floatval = val;
1224 datum.doubleval = val;
1230 return makeExpr<Analyzer::Constant>(ti,
false, datum);
1242 const auto number_units_const =
1244 if (number_units_const && number_units_const->get_is_null()) {
1245 throw std::runtime_error(
"The 'Interval' argument literal must not be 'null'.");
1249 const auto& datetime_ti = datetime->get_type_info();
1250 if (datetime_ti.get_type() ==
kTIME) {
1251 throw std::runtime_error(
"DateAdd operation not supported for TIME.");
1254 const int dim = datetime_ti.get_dimension();
1255 return makeExpr<Analyzer::DateaddExpr>(
1263 return "DATETIME_PLUS"s;
1270 if (rex_operator->
size() != 2) {
1274 const auto datetime_ti = datetime->get_type_info();
1275 if (!datetime_ti.is_timestamp() && !datetime_ti.is_date()) {
1276 if (datetime_ti.get_type() ==
kTIME) {
1277 throw std::runtime_error(
"DateTime addition/subtraction not supported for TIME.");
1282 const auto rhs_ti = rhs->get_type_info();
1284 if (datetime_ti.is_high_precision_timestamp() ||
1285 rhs_ti.is_high_precision_timestamp()) {
1286 throw std::runtime_error(
1287 "High Precision timestamps are not supported for TIMESTAMPDIFF operation. "
1292 const auto& rex_operator_ti = rex_operator->
getType();
1293 const auto datediff_field =
1296 makeExpr<Analyzer::DatediffExpr>(bigint_ti, datediff_field, rhs, datetime);
1299 return makeExpr<Analyzer::BinOper>(bigint_ti.get_type(),
1310 std::vector<std::shared_ptr<Analyzer::Expr>>
args = {datetime, rhs};
1311 auto dt_plus = makeExpr<Analyzer::FunctionOper>(
1318 const auto interval =
fold_expr(rhs.get());
1319 auto interval_ti = interval->get_type_info();
1323 std::shared_ptr<Analyzer::Expr> interval_sec;
1327 (op ==
kMINUS ? -interval_lit->get_constval().bigintval
1328 : interval_lit->get_constval().bigintval) /
1331 interval_sec = makeExpr<Analyzer::BinOper>(bigint_ti.get_type(),
1338 std::make_shared<Analyzer::UOper>(bigint_ti,
false,
kUMINUS, interval_sec);
1341 return makeExpr<Analyzer::DateaddExpr>(datetime_ti,
daSECOND, interval_sec, datetime);
1344 const auto interval_months = op ==
kMINUS ? std::make_shared<Analyzer::UOper>(
1345 bigint_ti,
false,
kUMINUS, interval)
1347 return makeExpr<Analyzer::DateaddExpr>(datetime_ti,
daMONTH, interval_months, datetime);
1377 return makeExpr<Analyzer::CharLengthExpr>(str_arg->decompress(),
1378 rex_function->
getName() ==
"CHAR_LENGTH"sv);
1386 if (
nullptr == expr || !expr->get_type_info().is_string() ||
1387 expr->get_type_info().is_varlen()) {
1388 throw std::runtime_error(rex_function->
getName() +
1389 " expects a dictionary encoded text column.");
1393 throw std::runtime_error(
1395 " does not support unnest operator as its input expression.");
1397 return makeExpr<Analyzer::KeyForStringExpr>(
args[0]);
1404 const auto& arg_ti = arg->get_type_info();
1405 if (arg_ti.get_type() !=
kDOUBLE) {
1407 arg = arg->add_cast(double_ti);
1409 return makeExpr<Analyzer::SampleRatioExpr>(arg);
1414 std::string user{
"SESSIONLESS_USER"};
1416 user =
query_state_->getConstSessionInfo()->get_currentUser().userName;
1423 const auto func_name = rex_function->
getName();
1425 std::ostringstream oss;
1426 oss <<
"Function " << func_name <<
" not supported.";
1427 throw std::runtime_error(oss.str());
1432 switch (string_op_kind) {
1434 return makeExpr<Analyzer::LowerStringOper>(
args);
1436 return makeExpr<Analyzer::UpperStringOper>(
args);
1438 return makeExpr<Analyzer::InitCapStringOper>(
args);
1440 return makeExpr<Analyzer::ReverseStringOper>(
args);
1442 return makeExpr<Analyzer::RepeatStringOper>(
args);
1444 return makeExpr<Analyzer::ConcatStringOper>(
args);
1447 return makeExpr<Analyzer::PadStringOper>(string_op_kind,
args);
1452 return makeExpr<Analyzer::TrimStringOper>(string_op_kind,
args);
1455 return makeExpr<Analyzer::SubstringStringOper>(
args);
1457 return makeExpr<Analyzer::OverlayStringOper>(
args);
1459 return makeExpr<Analyzer::ReplaceStringOper>(
args);
1461 return makeExpr<Analyzer::SplitPartStringOper>(
args);
1463 return makeExpr<Analyzer::RegexpReplaceStringOper>(
args);
1465 return makeExpr<Analyzer::RegexpSubstrStringOper>(
args);
1467 return makeExpr<Analyzer::JsonValueStringOper>(
args);
1469 return makeExpr<Analyzer::Base64EncodeStringOper>(
args);
1471 return makeExpr<Analyzer::Base64DecodeStringOper>(
args);
1473 return makeExpr<Analyzer::TryStringCastOper>(rex_function->
getType(),
args);
1475 return makeExpr<Analyzer::PositionStringOper>(
args);
1477 throw std::runtime_error(
"Unsupported string function.");
1484 const auto ret_ti = rex_function->
getType();
1486 const auto arg_ti = arg->get_type_info();
1487 if (!arg_ti.is_array()) {
1488 throw std::runtime_error(rex_function->
getName() +
" expects an array expression.");
1490 if (arg_ti.get_subtype() ==
kARRAY) {
1491 throw std::runtime_error(rex_function->
getName() +
1492 " expects one-dimension array expression.");
1494 const auto array_size = arg_ti.get_size();
1495 const auto array_elem_size = arg_ti.get_elem_type().get_array_context_logical_size();
1497 if (array_size > 0) {
1498 if (array_elem_size <= 0) {
1499 throw std::runtime_error(rex_function->
getName() +
1500 ": unexpected array element type.");
1506 return makeExpr<Analyzer::CardinalityExpr>(arg);
1514 return makeExpr<Analyzer::BinOper>(
1515 base->get_type_info().get_elem_type(),
false,
kARRAY_AT,
kONE, base, index);
1519 constexpr
bool is_null =
false;
1522 return makeExpr<Analyzer::Constant>(
kDATE,
is_null, datum);
1526 constexpr
bool is_null =
false;
1529 return makeExpr<Analyzer::Constant>(
kTIME,
is_null, datum);
1541 const std::string datetime_err{R
"(Only DATETIME('NOW') supported for now.)"};
1542 if (!arg_lit || arg_lit->get_is_null()) {
1543 throw std::runtime_error(datetime_err);
1545 CHECK(arg_lit->get_type_info().is_string());
1546 if (*arg_lit->get_constval().stringval !=
"NOW"sv) {
1547 throw std::runtime_error(datetime_err);
1554 std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
1558 const auto& operand_ti = operand->get_type_info();
1559 CHECK(operand_ti.is_number());
1561 const auto lt_zero = makeExpr<Analyzer::BinOper>(
kBOOLEAN,
kLT,
kONE, operand, zero);
1562 const auto uminus_operand =
1563 makeExpr<Analyzer::UOper>(operand_ti.get_type(),
kUMINUS, operand);
1564 expr_list.emplace_back(lt_zero, uminus_operand);
1565 return makeExpr<Analyzer::CaseExpr>(operand_ti,
false, expr_list, operand);
1570 std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
1574 const auto& operand_ti = operand->get_type_info();
1575 CHECK(operand_ti.is_number());
1577 const auto lt_zero = makeExpr<Analyzer::BinOper>(
kBOOLEAN,
kLT,
kONE, operand, zero);
1579 const auto eq_zero = makeExpr<Analyzer::BinOper>(
kBOOLEAN,
kEQ,
kONE, operand, zero);
1581 const auto gt_zero = makeExpr<Analyzer::BinOper>(
kBOOLEAN,
kGT,
kONE, operand, zero);
1583 return makeExpr<Analyzer::CaseExpr>(
1587 makeExpr<Analyzer::Constant>(operand_ti,
true,
Datum{0}));
1591 return makeExpr<Analyzer::OffsetInFragment>();
1597 auto sql_type = rex_function->
getType();
1602 if (translated_function_args.size() > 0) {
1603 const auto first_element_logical_type =
1606 auto diff_elem_itr =
1607 std::find_if(translated_function_args.begin(),
1608 translated_function_args.end(),
1609 [first_element_logical_type](
const auto expr) {
1610 const auto element_logical_type =
1612 if (first_element_logical_type != element_logical_type) {
1613 if (first_element_logical_type.is_none_encoded_string() &&
1614 element_logical_type.is_none_encoded_string()) {
1621 if (diff_elem_itr != translated_function_args.end()) {
1622 throw std::runtime_error(
1624 std::to_string(diff_elem_itr - translated_function_args.begin()) +
1625 " is not of the same type as other elements of the array. Consider casting "
1626 "to force this condition.\nElement Type: " +
1629 "\nArray type: " + first_element_logical_type.to_string());
1632 if (first_element_logical_type.is_string()) {
1633 sql_type.set_subtype(
kTEXT);
1635 if (first_element_logical_type.is_none_encoded_string()) {
1639 CHECK(first_element_logical_type.is_dict_encoded_string());
1640 sql_type.set_comp_param(first_element_logical_type.get_comp_param());
1641 sql_type.setStringDictKey(first_element_logical_type.getStringDictKey());
1643 }
else if (first_element_logical_type.is_dict_encoded_string()) {
1644 sql_type.set_subtype(
kTEXT);
1646 sql_type.set_comp_param(first_element_logical_type.get_comp_param());
1647 sql_type.setStringDictKey(first_element_logical_type.getStringDictKey());
1649 sql_type.set_subtype(first_element_logical_type.get_type());
1650 sql_type.set_scale(first_element_logical_type.get_scale());
1651 sql_type.set_precision(first_element_logical_type.get_precision());
1654 return makeExpr<Analyzer::ArrayExpr>(sql_type, translated_function_args);
1658 return makeExpr<Analyzer::ArrayExpr>(sql_type, translated_function_args);
1661 return makeExpr<Analyzer::ArrayExpr>(rex_function->
getType(),
1671 if (rex_function->
getName() ==
"REGEXP_LIKE"sv) {
1674 if (rex_function->
getName() ==
"LIKELY"sv) {
1677 if (rex_function->
getName() ==
"UNLIKELY"sv) {
1683 if (rex_function->
getName() ==
"DATEADD"sv) {
1686 if (rex_function->
getName() ==
"DATEDIFF"sv) {
1689 if (rex_function->
getName() ==
"DATEPART"sv) {
1695 if (rex_function->
getName() ==
"KEY_FOR_STRING"sv) {
1698 if (rex_function->
getName() ==
"WIDTH_BUCKET"sv) {
1701 if (rex_function->
getName() ==
"SAMPLE_RATIO"sv) {
1704 if (rex_function->
getName() ==
"CURRENT_USER"sv) {
1736 if (rex_function->
getName() ==
"ITEM"sv) {
1739 if (rex_function->
getName() ==
"CURRENT_DATE"sv) {
1742 if (rex_function->
getName() ==
"CURRENT_TIME"sv) {
1745 if (rex_function->
getName() ==
"CURRENT_TIMESTAMP"sv) {
1748 if (rex_function->
getName() ==
"NOW"sv) {
1751 if (rex_function->
getName() ==
"DATETIME"sv) {
1757 if (rex_function->
getName() ==
"ABS"sv) {
1760 if (rex_function->
getName() ==
"SIGN"sv) {
1764 return makeExpr<Analyzer::FunctionOperWithCustomTypeHandling>(
1768 }
else if (rex_function->
getName() ==
"ROUND"sv) {
1769 std::vector<std::shared_ptr<Analyzer::Expr>>
args =
1772 if (rex_function->
size() == 1) {
1780 args.push_back(makeExpr<Analyzer::Constant>(t,
false, d));
1784 CHECK(args.size() == 2);
1786 if (!args[0]->get_type_info().is_number()) {
1787 throw std::runtime_error(
"Only numeric 1st operands are supported");
1792 if (!args[1]->get_type_info().is_integer()) {
1793 throw std::runtime_error(
"Only integer 2nd operands are supported");
1800 ? args[0]->get_type_info()
1803 return makeExpr<Analyzer::FunctionOperWithCustomTypeHandling>(
1806 if (rex_function->
getName() ==
"DATETIME_PLUS"sv) {
1807 auto dt_plus = makeExpr<Analyzer::FunctionOper>(rex_function->
getType(),
1816 if (rex_function->
getName() ==
"/INT"sv) {
1823 if (rex_function->
getName() ==
"Reinterpret"sv) {
1835 "ST_NumGeometries"sv,
1841 "HeavyDB_Geo_PolyBoundsPtr"sv,
1842 "HeavyDB_Geo_PolyRenderGroup"sv,
1843 "HeavyDB_Geo_PolyCoordsArray"sv,
1844 "HeavyDB_Geo_PolyRingSizesArray"sv,
1845 "HeavyDB_Geo_PolyPolyRingsArray"sv)) {
1855 "convert_meters_to_pixel_width"sv,
1856 "convert_meters_to_pixel_height"sv,
1857 "is_point_in_view"sv,
1858 "is_point_size_in_view"sv)) {
1868 "ST_Approx_Overlaps"sv,
1877 if (rex_function->
getName() ==
"OFFSET_IN_FRAGMENT"sv) {
1881 if (rex_function->
getName() ==
"ARRAY"sv) {
1886 "ST_GeomFromText"sv,
1887 "ST_GeogFromText"sv,
1894 "ST_Transform"sv)) {
1899 "ST_Intersection"sv,
1903 "ST_ConcaveHull"sv)) {
1917 return distance_check;
1924 if (rex_function->
getName() == std::string(
"||") ||
1925 rex_function->
getName() == std::string(
"SUBSTRING")) {
1927 return makeExpr<Analyzer::FunctionOper>(
1928 ret_ti, rex_function->
getName(), arg_expr_list);
1939 auto ext_func_args = ext_func_sig.getInputArgs();
1940 CHECK_LE(arg_expr_list.size(), ext_func_args.size());
1941 for (
size_t i = 0, di = 0; i < arg_expr_list.size(); i++) {
1942 CHECK_LT(i + di, ext_func_args.size());
1943 auto ext_func_arg = ext_func_args[i + di];
1957 std::dynamic_pointer_cast<Analyzer::Constant>(arg_expr_list[i])) {
1959 if (ext_func_arg_ti != arg_expr_list[i]->get_type_info()) {
1960 arg_expr_list[i] = constant->add_cast(ext_func_arg_ti);
1967 LOG(
WARNING) <<
"RelAlgTranslator::translateFunction: " << e.what();
1973 bool arguments_not_null =
true;
1974 for (
const auto& arg_expr : arg_expr_list) {
1975 if (!arg_expr->get_type_info().get_notnull()) {
1976 arguments_not_null =
false;
1982 return makeExpr<Analyzer::FunctionOper>(ret_ti, rex_function->
getName(), arg_expr_list);
1988 const std::vector<SortField>& sort_fields) {
1989 std::vector<Analyzer::OrderEntry> collation;
1990 for (
size_t i = 0; i < sort_fields.size(); ++i) {
1991 const auto& sort_field = sort_fields[i];
1992 collation.emplace_back(i,
2030 if (time_unit_val == 1) {
2032 }
else if (time_unit_val == 12) {
2043 std::vector<std::shared_ptr<Analyzer::Expr>>
args;
2044 for (
size_t i = 0; i < rex_window_function->
size(); ++i) {
2047 std::vector<std::shared_ptr<Analyzer::Expr>> partition_keys;
2048 for (
const auto& partition_key : rex_window_function->
getPartitionKeys()) {
2051 std::vector<std::shared_ptr<Analyzer::Expr>> order_keys;
2052 for (
const auto& order_key : rex_window_function->
getOrderKeys()) {
2055 auto ti = rex_window_function->
getType();
2056 auto window_func_kind = rex_window_function->
getKind();
2059 ti = args.front()->get_type_info();
2061 switch (window_func_kind) {
2066 CHECK(ti.is_boolean());
2073 auto determine_frame_bound_type =
2075 if (bound.unbounded) {
2076 CHECK(!bound.bound_expr && !bound.is_current_row);
2077 if (bound.following) {
2079 }
else if (bound.preceding) {
2083 if (bound.is_current_row) {
2084 CHECK(!bound.unbounded && !bound.bound_expr);
2087 CHECK(!bound.unbounded && bound.bound_expr);
2088 if (bound.following) {
2090 }
else if (bound.preceding) {
2097 auto is_negative_framing_bound =
2098 [](
const SQLTypes t,
const Datum& d,
bool is_time_unit =
false) {
2101 return d.tinyintval < 0;
2103 return d.smallintval < 0;
2105 return d.intval < 0;
2110 CHECK(is_time_unit);
2111 return d.doubleval < 0;
2116 return d.bigintval < 0;
2118 throw std::runtime_error(
2119 "We currently only support integer-type literal expression as a window "
2120 "frame bound expression");
2125 bool negative_constant =
false;
2126 bool detect_invalid_frame_start_bound_expr =
false;
2127 bool detect_invalid_frame_end_bound_expr =
false;
2130 bool has_end_bound_frame_expr =
false;
2131 std::shared_ptr<Analyzer::Expr> frame_start_bound_expr;
2133 determine_frame_bound_type(frame_start_bound);
2134 std::shared_ptr<Analyzer::Expr> frame_end_bound_expr;
2136 determine_frame_bound_type(frame_end_bound);
2137 bool has_framing_clause =
2139 auto frame_mode = rex_window_function->
isRows()
2142 if (order_keys.empty()) {
2149 has_framing_clause =
false;
2157 has_framing_clause =
false;
2159 auto translate_frame_bound_expr = [&](
const RexScalar* bound_expr) {
2160 std::shared_ptr<Analyzer::Expr> translated_expr;
2161 const auto rex_oper =
dynamic_cast<const RexOperator*
>(bound_expr);
2162 if (rex_oper && rex_oper->getType().is_timeinterval()) {
2164 const auto bin_oper =
2166 auto time_literal_expr =
2168 CHECK(time_literal_expr);
2170 is_negative_framing_bound(time_literal_expr->get_type_info().get_type(),
2171 time_literal_expr->get_constval(),
2173 return std::make_pair(
false, translated_expr);
2175 if (dynamic_cast<const RexLiteral*>(bound_expr)) {
2177 if (
auto literal_expr =
2178 dynamic_cast<const Analyzer::Constant*>(translated_expr.get())) {
2179 negative_constant = is_negative_framing_bound(
2180 literal_expr->get_type_info().get_type(), literal_expr->get_constval());
2181 return std::make_pair(
false, translated_expr);
2184 return std::make_pair(
true, translated_expr);
2187 if (frame_start_bound.bound_expr) {
2188 std::tie(detect_invalid_frame_start_bound_expr, frame_start_bound_expr) =
2189 translate_frame_bound_expr(frame_start_bound.bound_expr.get());
2192 if (frame_end_bound.bound_expr) {
2193 std::tie(detect_invalid_frame_end_bound_expr, frame_end_bound_expr) =
2194 translate_frame_bound_expr(frame_end_bound.bound_expr.get());
2198 if (detect_invalid_frame_start_bound_expr || detect_invalid_frame_end_bound_expr) {
2199 throw std::runtime_error(
2200 "We currently only support literal expression as a window frame bound "
2206 if (negative_constant) {
2207 throw std::runtime_error(
2208 "A constant expression for window framing should have nonnegative value.");
2211 auto handle_time_interval_expr_if_necessary = [&](
const Analyzer::Expr* bound_expr,
2213 bool for_start_bound) {
2221 if (for_start_bound) {
2222 frame_start_bound_expr = translated_expr;
2224 frame_end_bound_expr = translated_expr;
2228 handle_time_interval_expr_if_necessary(
2229 frame_start_bound_expr.get(), frame_start_bound_type,
true);
2230 handle_time_interval_expr_if_necessary(
2231 frame_end_bound_expr.get(), frame_end_bound_type,
false);
2234 if (frame_start_bound.following) {
2235 if (frame_end_bound.is_current_row) {
2236 throw std::runtime_error(
2237 "Window framing starting from following row cannot end with current row.");
2238 }
else if (has_end_bound_frame_expr && frame_end_bound.preceding) {
2239 throw std::runtime_error(
2240 "Window framing starting from following row cannot have preceding rows.");
2243 if (frame_start_bound.is_current_row && frame_end_bound.preceding &&
2244 !frame_end_bound.unbounded && has_end_bound_frame_expr) {
2245 throw std::runtime_error(
2246 "Window framing starting from current row cannot have preceding rows.");
2248 if (has_framing_clause) {
2250 if (order_keys.size() != 1) {
2251 throw std::runtime_error(
2252 "Window framing with range mode requires a single order-by column");
2254 if (!frame_start_bound_expr &&
2256 !frame_end_bound_expr &&
2258 has_framing_clause =
false;
2259 VLOG(1) <<
"Ignore range framing mode with a frame bound between "
2260 "UNBOUNDED_PRECEDING and CURRENT_ROW";
2263 bool (*)(
const Analyzer::ColumnVar*,
const Analyzer::ColumnVar*)>
2266 for (
auto cv : colvar_set) {
2267 if (!(cv->get_type_info().is_integer() || cv->get_type_info().is_fp() ||
2268 cv->get_type_info().is_time())) {
2269 has_framing_clause =
false;
2270 VLOG(1) <<
"Range framing mode with non-number type ordering column is not "
2271 "supported yet, skip window framing";
2276 switch (window_func_kind) {
2279 if (order_keys.empty()) {
2280 throw std::runtime_error(::
toString(window_func_kind) +
2281 " requires an ORDER BY clause");
2283 if (!has_framing_clause) {
2284 throw std::runtime_error(::
toString(window_func_kind) +
2285 " requires window frame definition");
2287 const auto num_args = args.size();
2288 const auto func_name =
::toString(window_func_kind);
2289 if (num_args == 1) {
2292 args.push_back(makeExpr<Analyzer::Constant>(
kINT,
false, d));
2293 }
else if (num_args < 1 || num_args > 2) {
2294 throw std::runtime_error(func_name +
" has an invalid number of input arguments");
2296 const auto target_expr_cv =
2298 if (!target_expr_cv) {
2299 throw std::runtime_error(
"Currently, " + func_name +
2300 " only allows a column reference as its first argument");
2302 const auto target_ti = target_expr_cv->get_type_info();
2303 if (target_ti.is_dict_encoded_string()) {
2307 ti.set_comp_param(target_expr_cv->get_type_info().get_comp_param());
2308 ti.setStringDictKey(target_expr_cv->get_type_info().getStringDictKey());
2309 ti.set_fixed_size();
2311 const auto target_offset_cv =
2313 if (!target_expr_cv ||
2314 is_negative_framing_bound(target_offset_cv->get_type_info().get_type(),
2315 target_offset_cv->get_constval())) {
2316 throw std::runtime_error(
2317 "Currently, " + func_name +
2318 " only allows non-negative constant as its second argument");
2328 ti.set_notnull(
false);
2330 throw std::runtime_error(
2331 "NTH_VALUE window function must have a positional argument expression.");
2334 if (order_keys.empty()) {
2335 throw std::runtime_error(::
toString(window_func_kind) +
2336 " requires an ORDER BY clause");
2338 if (!has_framing_clause) {
2339 throw std::runtime_error(::
toString(window_func_kind) +
2340 " requires window frame definition");
2343 if (args[1]->get_type_info().is_integer()) {
2344 if (
auto* n_value_ptr = dynamic_cast<Analyzer::Constant*>(args[1].
get())) {
2345 if (0 < n_value_ptr->get_constval().intval) {
2348 auto d = n_value_ptr->get_constval();
2350 n_value_ptr->set_constval(d);
2355 throw std::runtime_error(
2356 "The positional argument of the NTH_VALUE window function must be a positive "
2357 "integer constant.");
2361 if (!has_framing_clause) {
2364 frame_start_bound_expr =
nullptr;
2365 frame_end_bound_expr =
nullptr;
2371 return makeExpr<Analyzer::WindowFunction>(
2373 rex_window_function->
getKind(),
2378 makeExpr<Analyzer::WindowFrame>(frame_start_bound_type, frame_start_bound_expr),
2379 makeExpr<Analyzer::WindowFrame>(frame_end_bound_type, frame_end_bound_expr),
2384 std::shared_ptr<Analyzer::Expr> order_key,
2385 bool for_preceding_bound,
2390 const auto order_key_ti = order_key->get_type_info();
2391 const auto frame_bound_ti = frame_bound_expr->
get_type_info();
2392 const auto time_val_expr =
2394 const auto time_unit_val_expr =
2398 bool invalid_time_unit_type =
false;
2399 bool invalid_frame_bound_expr_type =
false;
2401 auto prepare_time_value_datum = [&d,
2402 &invalid_frame_bound_expr_type,
2404 &for_preceding_bound](
bool is_timestamp_second) {
2411 switch (time_val_expr->get_type_info().get_type()) {
2413 d.
bigintval = time_val_expr->get_constval().tinyintval;
2417 d.
bigintval = time_val_expr->get_constval().smallintval;
2421 d.
bigintval = time_val_expr->get_constval().intval;
2425 d.
bigintval = time_val_expr->get_constval().bigintval;
2430 if (!is_timestamp_second) {
2432 invalid_frame_bound_expr_type =
true;
2435 d.
bigintval = time_val_expr->get_constval().bigintval;
2439 if (!is_timestamp_second) {
2441 invalid_frame_bound_expr_type =
true;
2444 d.
bigintval = time_val_expr->get_constval().doubleval *
2445 pow(10, time_val_expr->get_type_info().get_scale());
2449 invalid_frame_bound_expr_type =
true;
2453 if (for_preceding_bound) {
2458 switch (order_key_ti.get_type()) {
2460 if (time_val_expr->get_type_info().is_integer()) {
2463 frame_bound_ti.get_type(), time_unit_val_expr);
2464 switch (time_val_expr->get_type_info().get_type()) {
2466 d.
bigintval = time_val_expr->get_constval().tinyintval * time_multiplier;
2470 d.
bigintval = time_val_expr->get_constval().smallintval * time_multiplier;
2474 d.
bigintval = time_val_expr->get_constval().intval * time_multiplier;
2478 d.
bigintval = time_val_expr->get_constval().bigintval * time_multiplier;
2487 invalid_frame_bound_expr_type =
true;
2490 invalid_time_unit_type =
true;
2492 if (invalid_frame_bound_expr_type) {
2493 throw std::runtime_error(
2494 "Invalid time unit is used to define window frame bound expression for " +
2495 order_key_ti.get_type_name() +
" type");
2496 }
else if (invalid_time_unit_type) {
2497 throw std::runtime_error(
2498 "Window frame bound expression has an invalid type for " +
2499 order_key_ti.get_type_name() +
" type");
2501 return std::make_shared<Analyzer::Constant>(
kBIGINT,
false, d);
2505 if (time_val_expr->get_type_info().is_integer()) {
2506 switch (time_unit) {
2520 invalid_frame_bound_expr_type =
true;
2525 invalid_time_unit_type =
true;
2527 if (invalid_frame_bound_expr_type) {
2528 throw std::runtime_error(
2529 "Invalid time unit is used to define window frame bound expression for " +
2530 order_key_ti.get_type_name() +
" type");
2531 }
else if (invalid_time_unit_type) {
2532 throw std::runtime_error(
2533 "Window frame bound expression has an invalid type for " +
2534 order_key_ti.get_type_name() +
" type");
2537 prepare_time_value_datum(
false);
2538 const auto cast_number_units = makeExpr<Analyzer::Constant>(
kBIGINT,
false, d);
2539 const int dim = order_key_ti.get_dimension();
2540 return makeExpr<Analyzer::DateaddExpr>(
2545 switch (time_unit) {
2547 switch (time_val_expr->get_type_info().get_scale()) {
2568 prepare_time_value_datum(
true);
2573 prepare_time_value_datum(
false);
2578 prepare_time_value_datum(
false);
2583 prepare_time_value_datum(
false);
2588 prepare_time_value_datum(
false);
2593 prepare_time_value_datum(
false);
2597 invalid_time_unit_type =
true;
2601 if (!invalid_time_unit_type) {
2603 const auto cast_number_units = makeExpr<Analyzer::Constant>(
kBIGINT,
false, d);
2604 const int dim = order_key_ti.get_dimension();
2617 if (invalid_frame_bound_expr_type) {
2618 throw std::runtime_error(
2619 "Invalid time unit is used to define window frame bound expression for " +
2620 order_key_ti.get_type_name() +
" type");
2621 }
else if (invalid_time_unit_type) {
2622 throw std::runtime_error(
"Window frame bound expression has an invalid type for " +
2623 order_key_ti.get_type_name() +
" type");
2630 std::vector<std::shared_ptr<Analyzer::Expr>>
args;
2631 for (
size_t i = 0; i < rex_function->
size(); ++i) {
2638 const std::shared_ptr<Analyzer::Expr> qual_expr) {
2642 const auto rewritten_qual_expr =
rewrite_expr(qual_expr.get());
2643 return {{}, {rewritten_qual_expr ? rewritten_qual_expr : qual_expr}};
2646 if (bin_oper->get_optype() ==
kAND) {
2650 simple_quals.insert(
2651 simple_quals.end(), rhs_cf.simple_quals.begin(), rhs_cf.simple_quals.end());
2652 auto quals = lhs_cf.quals;
2653 quals.insert(quals.end(), rhs_cf.quals.begin(), rhs_cf.quals.end());
2654 return {simple_quals, quals};
2657 const auto simple_qual = bin_oper->normalize_simple_predicate(rte_idx);
2663 const std::shared_ptr<Analyzer::Expr>& qual_expr) {
2665 const auto bin_oper = std::dynamic_pointer_cast<
const Analyzer::BinOper>(qual_expr);
2667 const auto rewritten_qual_expr =
rewrite_expr(qual_expr.get());
2668 return {rewritten_qual_expr ? rewritten_qual_expr : qual_expr};
2670 if (bin_oper->get_optype() ==
kOR) {
2673 auto quals = lhs_df;
2674 quals.insert(quals.end(), rhs_df.begin(), rhs_df.end());
2690 const auto& operand_ti = operand->get_type_info();
2691 const auto& target_ti = rex_function->
getType();
2692 if (!operand_ti.is_string()) {
2693 throw std::runtime_error(
2694 "High precision timestamp cast argument must be a string. Input type is: " +
2695 operand_ti.get_type_name());
2696 }
else if (!target_ti.is_high_precision_timestamp()) {
2697 throw std::runtime_error(
2698 "Cast target type should be high precision timestamp. Input type is: " +
2699 target_ti.get_type_name());
2700 }
else if (target_ti.get_dimension() != 6 && target_ti.get_dimension() != 9) {
2701 throw std::runtime_error(
2702 "Cast target type should be TIMESTAMP(6|9). Input type is: TIMESTAMP(" +
2705 return operand->add_cast(target_ti);
DEVICE auto upper_bound(ARGS &&...args)
Defines data structures for the semantic analysis phase of query processing.
const RexScalar * getThen(const size_t idx) const
const std::vector< JoinType > join_types_
HOST DEVICE SQLTypes get_subtype() const
void set_compression(EncodingType c)
static std::shared_ptr< Analyzer::Expr > normalize(const std::list< std::pair< std::shared_ptr< Analyzer::Expr >, std::shared_ptr< Analyzer::Expr >>> &, const std::shared_ptr< Analyzer::Expr >, const Executor *executor=nullptr)
std::shared_ptr< Analyzer::Expr > translateOffsetInFragment() const
SqlStringOpKind name_to_string_op_kind(const std::string &func_name)
static std::shared_ptr< Analyzer::Expr > get(const std::string &)
std::shared_ptr< Analyzer::Expr > translateCurrentTimestamp() const
std::shared_ptr< Analyzer::Expr > translateBinaryGeoPredicate(const RexFunctionOperator *, SQLTypeInfo &, const bool with_bounds) const
std::shared_ptr< Analyzer::Expr > translateRegexp(const RexFunctionOperator *) const
static bool colvar_comp(const ColumnVar *l, const ColumnVar *r)
const size_t g_max_integer_set_size
size_t getOperand(size_t idx) const
const Executor * executor_
std::shared_ptr< Analyzer::Expr > translateUnlikely(const RexFunctionOperator *) const
const RexScalar * getElse() const
void collect_column_var(std::set< const ColumnVar *, bool(*)(const ColumnVar *, const ColumnVar *)> &colvar_set, bool include_agg) const override
std::shared_ptr< Analyzer::Expr >(RelAlgTranslator::*)(RexScalar const *) const Handler
static std::shared_ptr< Analyzer::Expr > analyzeValue(const int64_t intval)
bool window_function_conditional_aggregate(const SqlWindowFunctionKind kind)
std::shared_ptr< Analyzer::Expr > translateFunction(const RexFunctionOperator *) const
SQLTypeInfo get_nullable_logical_type_info(const SQLTypeInfo &type_info)
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
const SQLTypeInfo & getType() const
const RexScalar * getOperand(const size_t idx) const
std::shared_ptr< Analyzer::Expr > translateUoper(const RexOperator *) const
HOST DEVICE int get_scale() const
const Expr * get_right_operand() const
const std::vector< SortField > & getCollation() const
std::shared_ptr< Analyzer::Expr > translateDateadd(const RexFunctionOperator *) const
static bool isFramingAvailableWindowFunc(SqlWindowFunctionKind kind)
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 Executor *executor=nullptr)
std::shared_ptr< Analyzer::Expr > translateIntervalExprForWindowFraming(std::shared_ptr< Analyzer::Expr > order_key, bool for_preceding_bound, const Analyzer::BinOper *frame_bound_expr) const
std::shared_ptr< Analyzer::Expr > translateAbs(const RexFunctionOperator *) const
const RexScalar * getWhen(const size_t idx) const
std::shared_ptr< Analyzer::Expr > ExpressionPtr
std::string getString(int32_t string_id) const
#define TRANSIENT_DICT_DB_ID
std::shared_ptr< Analyzer::Expr > getInIntegerSetExpr(std::shared_ptr< Analyzer::Expr > arg, const ResultSet &val_set) const
SQLTypeInfo get_agg_type(const SQLAgg agg_kind, const Analyzer::Expr *arg_expr)
std::shared_ptr< Analyzer::Expr > translateItem(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Constant > makeNumericConstant(const SQLTypeInfo &ti, const long val)
Analyzer::ExpressionPtr rewrite_expr(const Analyzer::Expr *expr)
std::type_index const type_index_
HOST DEVICE SQLTypes get_type() const
bool operator()(IndexedHandler const &pair) const
QualsConjunctiveForm qual_to_conjunctive_form(const std::shared_ptr< Analyzer::Expr > qual_expr)
#define TRANSIENT_DICT_ID
bool is_agg_supported_for_type(const SQLAgg &agg_kind, const SQLTypeInfo &arg_ti)
std::shared_ptr< Analyzer::Expr > translateGeoProjection(const RexFunctionOperator *, SQLTypeInfo &, const bool with_bounds) const
double inline_fp_null_val(const SQL_TYPE_INFO &ti)
std::shared_ptr< Analyzer::Expr > translateOper(const RexOperator *) const
std::shared_ptr< Analyzer::Expr > translateDatediff(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateInput(const RexInput *) const
std::shared_ptr< Analyzer::Expr > translateSign(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateUnaryGeoFunction(const RexFunctionOperator *) const
bool g_enable_string_functions
std::shared_ptr< Analyzer::Expr > translateGeoOverlapsOper(const RexOperator *) const
ExtractField to_datepart_field(const std::string &field)
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
robin_hood::unordered_map< RexScalar const *, std::shared_ptr< Analyzer::Expr > > cache_
Supported runtime functions management and retrieval.
future< Result > async(Fn &&fn, Args &&...args)
static SysCatalog & instance()
static std::shared_ptr< Analyzer::Expr > translateLiteral(const RexLiteral *)
SQLOps getOperator() const
bool window_function_is_value(const SqlWindowFunctionKind kind)
static constexpr int32_t INVALID_STR_ID
CONSTEXPR DEVICE bool is_null(const T &value)
Classes representing a parse tree.
std::shared_ptr< Analyzer::Expr > translateDatetime(const RexFunctionOperator *) const
void fill_dictionary_encoded_in_vals(std::vector< int64_t > &in_vals, std::atomic< size_t > &total_in_vals_count, const ResultSet *values_rowset, const std::pair< int64_t, int64_t > values_rowset_slice, const StringDictionaryProxy *source_dict, const StringDictionaryProxy *dest_dict, const int64_t needle_null_val)
std::shared_ptr< Analyzer::Expr > translateStringOper(const RexFunctionOperator *) const
static std::shared_ptr< Analyzer::Expr > get(std::shared_ptr< Analyzer::Expr > arg_expr, std::shared_ptr< Analyzer::Expr > pattern_expr, std::shared_ptr< Analyzer::Expr > escape_expr, const bool is_not)
size_t determineTimeValMultiplierForTimeType(const SQLTypes &window_frame_bound_type, const Analyzer::Constant *const_expr)
bool is_timeinterval() const
std::pair< std::shared_ptr< Analyzer::Expr >, SQLQualifier > getQuantifiedRhs(const RexScalar *) const
std::vector< Analyzer::OrderEntry > translate_collation(const std::vector< SortField > &sort_fields)
size_t branchCount() const
std::shared_ptr< Analyzer::Expr > translateCurrentTime() const
SQLTypeInfo build_type_info(const SQLTypes sql_type, const int scale, const int precision)
DatetruncField to_datediff_field(const std::string &field)
std::string toString(const ExecutorDeviceType &device_type)
std::array< IndexedHandler, sizeof...(Ts)> makeHandlers()
const RexWindowBound & getFrameEndBound() const
std::shared_ptr< Analyzer::Expr > translate(const RexScalar *rex) const
std::tuple< T, std::vector< SQLTypeInfo > > bind_function(std::string name, Analyzer::ExpressionPtrVector func_args, const std::vector< T > &ext_funcs, const std::string processor)
Argument type based extension function binding.
const SQLTypeInfo & get_type_info() const
ByTypeIndex(std::type_info const &type_info)
const std::unordered_map< const RelAlgNode *, int > input_to_nest_level_
void translate_string_ids(std::vector< int32_t > &dest_ids, const LeafHostInfo &dict_server_host, const shared::StringDictKey &dest_dict_key, const std::vector< int32_t > &source_ids, const shared::StringDictKey &source_dict_key, const int32_t dest_generation)
void set_comp_param(int p)
std::shared_ptr< Catalog > getCatalog(const std::string &dbName)
Analyzer::ExpressionPtrVector translateFunctionArgs(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateUnaryGeoPredicate(const RexFunctionOperator *, SQLTypeInfo &, const bool with_bounds) const
const ConstRexScalarPtrVector & getPartitionKeys() const
static std::shared_ptr< Analyzer::Expr > analyzeValue(const std::string &stringval, const bool is_null)
DEVICE auto lower_bound(ARGS &&...args)
const RexWindowBound & getFrameStartBound() const
std::shared_ptr< Analyzer::Expr > translateOverlapsOper(const RexOperator *) const
std::shared_ptr< Analyzer::Expr > translateUnaryGeoConstructor(const RexFunctionOperator *, SQLTypeInfo &, const bool with_bounds) const
std::shared_ptr< Analyzer::Expr > translateArrayFunction(const RexFunctionOperator *) const
static std::shared_ptr< Analyzer::Expr > get(std::shared_ptr< Analyzer::Expr > arg_expr, std::shared_ptr< Analyzer::Expr > like_expr, std::shared_ptr< Analyzer::Expr > escape_expr, const bool is_ilike, const bool is_not)
std::pair< std::type_index, Handler > IndexedHandler
static RelRexToStringConfig defaults()
Datum get_constval() const
std::shared_ptr< Analyzer::Expr > translateCurrentUser(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateSampleRatio(const RexFunctionOperator *) const
SqlWindowFunctionKind getKind() const
std::shared_ptr< Analyzer::Expr > translateLike(const RexFunctionOperator *) const
bool takes_arg(const TargetInfo &target_info)
static std::shared_ptr< Analyzer::Expr > analyzeValue(const int64_t numericval, const int scale, const int precision)
std::shared_ptr< Analyzer::Expr > translateLikely(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > get_in_values_expr(std::shared_ptr< Analyzer::Expr > arg, const ResultSet &val_set)
static std::shared_ptr< Analyzer::Expr > get(const int64_t)
std::shared_ptr< Analyzer::Expr > translateTernaryGeoFunction(const RexFunctionOperator *) const
const ConstRexScalarPtrVector & getOrderKeys() const
std::vector< std::shared_ptr< Analyzer::Expr > > qual_to_disjunctive_form(const std::shared_ptr< Analyzer::Expr > &qual_expr)
std::shared_ptr< Analyzer::Expr > translateBinaryGeoFunction(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Constant > make_fp_constant(const int64_t val, const SQLTypeInfo &ti)
std::pair< Datum, bool > datum_from_scalar_tv(const ScalarTargetValue *scalar_tv, const SQLTypeInfo &ti) noexcept
std::shared_ptr< Analyzer::Expr > translateWidthBucket(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateInOper(const RexOperator *) const
uint64_t exp_to_scale(const unsigned exp)
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
std::vector< ExpressionPtr > ExpressionPtrVector
const Expr * get_left_operand() const
std::shared_ptr< Analyzer::Expr > translateCase(const RexCase *) const
std::shared_ptr< Analyzer::Expr > translateFunctionWithGeoArg(const RexFunctionOperator *) const
std::shared_ptr< const query_state::QueryState > query_state_
const std::string & getName() const
std::shared_ptr< Analyzer::Expr > translateCurrentDate() const
std::string get_datetimeplus_rewrite_funcname(const SQLOps &op)
void validate_datetime_datepart_argument(const std::shared_ptr< Analyzer::Constant > literal_expr)
std::shared_ptr< Analyzer::Expr > translateCardinality(const RexFunctionOperator *) const
const std::vector< TargetMetaInfo > & getOutputMetainfo() const
std::shared_ptr< Analyzer::Expr > translateGeoComparison(const RexOperator *) const
std::shared_ptr< Analyzer::Expr > translateDatePlusMinus(const RexOperator *) const
std::shared_ptr< Analyzer::Expr > translateHPTLiteral(const RexFunctionOperator *) const
bool is_distinct(const size_t input_idx, const RelAlgNode *node)
int32_t getIdOfString(const std::string &str) const
std::shared_ptr< Analyzer::Expr > translateDatepart(const RexFunctionOperator *) const
bool can_use_parallel_algorithms(const ResultSet &rows)
std::shared_ptr< Analyzer::Expr > translateBinaryGeoConstructor(const RexFunctionOperator *, SQLTypeInfo &, const bool with_bounds) const
std::shared_ptr< Analyzer::Expr > rewrite_to_date_trunc(const Analyzer::FunctionOper *dt_plus)
SQLTypeInfo ext_arg_type_to_type_info(const ExtArgumentType ext_arg_type)
DateaddField to_dateadd_field(const std::string &field)
std::shared_ptr< Analyzer::Expr > fold_expr(const Analyzer::Expr *expr)
void set_precision(int d)
void fill_integer_in_vals(std::vector< int64_t > &in_vals, std::atomic< size_t > &total_in_vals_count, const ResultSet *values_rowset, const std::pair< int64_t, int64_t > values_rowset_slice)
std::shared_ptr< Analyzer::Expr > translateKeyForString(const RexFunctionOperator *) const
static std::shared_ptr< Analyzer::Expr > translateAggregateRex(const RexAgg *rex, const std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources)
std::shared_ptr< Analyzer::Expr > translateWindowFunction(const RexWindowFunctionOperator *) const
const std::shared_ptr< Analyzer::Expr > generate() const
std::shared_ptr< Analyzer::Expr > translateScalarSubquery(const RexSubQuery *) const
boost::variant< int64_t, double, float, NullableString > ScalarTargetValue
std::shared_ptr< Analyzer::Expr > translateLength(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateExtract(const RexFunctionOperator *) const
ExtractField determineTimeUnit(const SQLTypes &window_frame_bound_type, const Analyzer::Constant *const_expr)
HOST DEVICE void set_type(SQLTypes t)