45 const int precision) {
57 std::shared_ptr<Analyzer::Expr> rhs;
59 const auto rex_operator =
dynamic_cast<const RexOperator*
>(rex_scalar);
61 return std::make_pair(rhs, sql_qual);
64 const auto qual_str = rex_function ? rex_function->
getName() :
"";
65 if (qual_str ==
"PG_ANY"sv || qual_str ==
"PG_ALL"sv) {
66 CHECK_EQ(
size_t(1), rex_function->size());
68 sql_qual = (qual_str ==
"PG_ANY"sv) ?
kANY :
kALL;
70 if (!rhs && rex_operator->getOperator() ==
kCAST) {
71 CHECK_EQ(
size_t(1), rex_operator->size());
74 return std::make_pair(rhs, sql_qual);
80 bool is_null_const{
false};
81 switch (ti.get_type()) {
83 const auto ival = boost::get<int64_t>(scalar_tv);
93 const auto ival = boost::get<int64_t>(scalar_tv);
103 const auto ival = boost::get<int64_t>(scalar_tv);
106 is_null_const =
true;
108 d.smallintval = *ival;
113 const auto ival = boost::get<int64_t>(scalar_tv);
116 is_null_const =
true;
128 const auto ival = boost::get<int64_t>(scalar_tv);
131 is_null_const =
true;
138 const auto dval = boost::get<double>(scalar_tv);
141 is_null_const =
true;
148 const auto fval = boost::get<float>(scalar_tv);
151 is_null_const =
true;
160 auto nullable_sptr = boost::get<NullableString>(scalar_tv);
161 CHECK(nullable_sptr);
162 if (boost::get<void*>(nullable_sptr)) {
163 is_null_const =
true;
165 auto sptr = boost::get<std::string>(nullable_sptr);
166 d.stringval =
new std::string(*sptr);
171 CHECK(
false) <<
"Unhandled type: " << ti.get_type_name();
173 return {d, is_null_const};
180 const auto rex_input =
dynamic_cast<const RexInput*
>(rex);
184 const auto rex_literal =
dynamic_cast<const RexLiteral*
>(rex);
189 if (rex_window_function) {
196 const auto rex_operator =
dynamic_cast<const RexOperator*
>(rex);
200 const auto rex_case =
dynamic_cast<const RexCase*
>(rex);
204 const auto rex_subquery =
dynamic_cast<const RexSubQuery*
>(rex);
215 if ((agg_kind ==
kMIN || agg_kind ==
kMAX || agg_kind ==
kSUM || agg_kind ==
kAVG) &&
227 const std::vector<std::shared_ptr<Analyzer::Expr>>& scalar_sources) {
228 const auto agg_kind = rex->
getKind();
231 std::shared_ptr<Analyzer::Expr> arg_expr;
232 std::shared_ptr<Analyzer::Constant> err_rate;
235 CHECK_LT(operand, scalar_sources.size());
237 arg_expr = scalar_sources[operand];
241 if (!err_rate || err_rate->get_type_info().get_type() !=
kINT ||
242 err_rate->get_constval().intval < 1 || err_rate->get_constval().intval > 100) {
243 throw std::runtime_error(
244 "APPROX_COUNT_DISTINCT's second parameter should be SMALLINT literal between "
248 const auto& arg_ti = arg_expr->get_type_info();
250 throw std::runtime_error(
"Aggregate on " + arg_ti.get_type_name() +
251 " is not supported yet.");
254 const auto agg_ti =
get_agg_type(agg_kind, arg_expr.get());
255 return makeExpr<Analyzer::AggExpr>(agg_ti, agg_kind, arg_expr,
is_distinct, err_rate);
259 const RexLiteral* rex_literal) {
261 rex_literal->getType(), rex_literal->getScale(), rex_literal->getPrecision());
263 rex_literal->getTypeScale(),
264 rex_literal->getTypePrecision());
265 switch (rex_literal->getType()) {
269 d.
bigintval = rex_literal->getVal<int64_t>();
270 return makeExpr<Analyzer::Constant>(rex_literal->getType(),
false, d);
273 const auto val = rex_literal->getVal<int64_t>();
274 const int precision = rex_literal->getPrecision();
275 const int scale = rex_literal->getScale();
276 if (target_ti.is_fp() && !scale) {
281 return lit_ti != target_ti ? lit_expr->add_cast(target_ti) : lit_expr;
288 d.
boolval = rex_literal->getVal<
bool>();
289 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
293 d.
doubleval = rex_literal->getVal<
double>();
294 auto lit_expr = makeExpr<Analyzer::Constant>(
kDOUBLE,
false, d);
295 return lit_ti != target_ti ? lit_expr->add_cast(target_ti) : lit_expr;
300 d.
bigintval = rex_literal->getVal<int64_t>();
301 return makeExpr<Analyzer::Constant>(rex_literal->getType(),
false, d);
307 rex_literal->getType() ==
kTIMESTAMP && rex_literal->getPrecision() > 0
308 ? rex_literal->getVal<int64_t>()
309 : rex_literal->getVal<int64_t>() / 1000;
310 return makeExpr<Analyzer::Constant>(
311 SQLTypeInfo(rex_literal->getType(), rex_literal->getPrecision(), 0,
false),
317 d.
bigintval = rex_literal->getVal<int64_t>() * 24 * 3600;
318 return makeExpr<Analyzer::Constant>(rex_literal->getType(),
false, d);
321 if (target_ti.is_array()) {
325 return makeExpr<Analyzer::ArrayExpr>(target_ti,
args,
true);
327 return makeExpr<Analyzer::Constant>(rex_literal->getTargetType(),
true,
Datum{0});
330 LOG(
FATAL) <<
"Unexpected literal type " << lit_ti.get_type_name();
337 const RexSubQuery* rex_subquery)
const {
339 throw std::runtime_error(
"EXPLAIN is not supported with sub-queries");
342 auto result = rex_subquery->getExecutionResult();
343 auto row_set =
result->getRows();
344 const size_t row_count = row_set->rowCount();
345 if (row_count >
size_t(1)) {
346 throw std::runtime_error(
"Scalar sub-query returned multiple rows");
348 if (row_count ==
size_t(0)) {
349 if (row_set->isValidationOnlyRes()) {
351 return makeExpr<Analyzer::Constant>(rex_subquery->getType(),
false, d);
353 throw std::runtime_error(
"Scalar sub-query returned no results");
356 row_set->moveToBegin();
357 auto first_row = row_set->getNextRow(
false,
false);
358 CHECK_EQ(first_row.size(), size_t(1));
359 auto scalar_tv = boost::get<ScalarTargetValue>(&first_row[0]);
360 auto ti = rex_subquery->getType();
361 if (ti.is_string()) {
362 throw std::runtime_error(
"Scalar sub-queries which return strings not supported");
365 bool is_null_const{
false};
367 return makeExpr<Analyzer::Constant>(ti, is_null_const, d);
375 <<
"Not found in input_to_nest_level_, source=" << source->toString();
376 const int rte_idx = it_rte_idx->second;
377 const auto scan_source =
dynamic_cast<const RelScan*
>(source);
382 CHECK(in_metainfo.empty());
383 const auto table_desc = scan_source->getTableDescriptor();
387 auto col_ti = cd->columnType;
388 if (col_ti.is_string()) {
389 col_ti.set_type(
kTEXT);
391 if (cd->isVirtualCol) {
399 col_ti.set_notnull(
false);
401 return std::make_shared<Analyzer::ColumnVar>(
402 col_ti, table_desc->tableId, cd->columnId, rte_idx);
404 CHECK(!in_metainfo.empty()) <<
"for " << source->toString();
406 const size_t col_id = rex_input->
getIndex();
407 CHECK_LT(col_id, in_metainfo.size());
408 auto col_ti = in_metainfo[col_id].get_type_info();
413 col_ti.set_notnull(
false);
417 return std::make_shared<Analyzer::ColumnVar>(col_ti, -source->getId(), col_id, rte_idx);
427 const auto& target_ti = rex_operator->
getType();
429 const auto& operand_ti = operand_expr->get_type_info();
430 if (operand_ti.is_string() && target_ti.is_string()) {
433 if (target_ti.is_time() ||
437 return target_ti.is_date_in_days()
439 : operand_expr->add_cast(target_ti);
441 if (!operand_ti.is_string() && target_ti.is_string()) {
442 return operand_expr->add_cast(target_ti);
445 return std::make_shared<Analyzer::UOper>(target_ti,
false, sql_op, operand_expr);
449 return std::make_shared<Analyzer::UOper>(
kBOOLEAN, sql_op, operand_expr);
456 const auto& ti = operand_expr->get_type_info();
457 return std::make_shared<Analyzer::UOper>(ti,
false,
kUMINUS, operand_expr);
460 const auto& ti = operand_expr->get_type_info();
461 CHECK(ti.is_array());
462 return makeExpr<Analyzer::UOper>(ti.get_elem_type(),
false,
kUNNEST, operand_expr);
473 const ResultSet& val_set) {
478 throw std::runtime_error(
479 "Unable to handle 'expr IN (subquery)', subquery returned 5M+ rows.");
481 std::list<std::shared_ptr<Analyzer::Expr>> value_exprs;
483 std::vector<std::list<std::shared_ptr<Analyzer::Expr>>> expr_set(
484 fetcher_count, std::list<std::shared_ptr<Analyzer::Expr>>());
485 std::vector<std::future<void>> fetcher_threads;
486 const auto& ti = arg->get_type_info();
487 const auto entry_count = val_set.entryCount();
490 stride = (entry_count + fetcher_count - 1) / fetcher_count;
491 i < fetcher_count && start_entry < entry_count;
492 ++
i, start_entry += stride) {
493 const auto end_entry = std::min(start_entry + stride, entry_count);
494 fetcher_threads.push_back(std::async(
496 [&](std::list<std::shared_ptr<Analyzer::Expr>>& in_vals,
499 for (
auto index = start; index < end; ++index) {
500 auto row = val_set.getRowAt(index);
504 auto scalar_tv = boost::get<ScalarTargetValue>(&row[0]);
506 bool is_null_const{
false};
509 auto ti_none_encoded = ti;
511 auto none_encoded_string =
512 makeExpr<Analyzer::Constant>(ti, is_null_const, d);
513 auto dict_encoded_string = std::make_shared<Analyzer::UOper>(
514 ti,
false,
kCAST, none_encoded_string);
515 in_vals.push_back(dict_encoded_string);
517 in_vals.push_back(makeExpr<Analyzer::Constant>(ti, is_null_const, d));
521 std::ref(expr_set[
i]),
525 for (
auto& child : fetcher_threads) {
529 val_set.moveToBegin();
530 for (
auto& exprs : expr_set) {
531 value_exprs.splice(value_exprs.end(), exprs);
533 return makeExpr<Analyzer::InValues>(arg, value_exprs);
546 throw std::runtime_error(
"EXPLAIN is not supported with sub-queries");
551 const auto rex_subquery =
dynamic_cast<const RexSubQuery*
>(rhs);
553 auto ti = lhs->get_type_info();
554 auto result = rex_subquery->getExecutionResult();
556 auto& row_set =
result->getRows();
557 CHECK_EQ(
size_t(1), row_set->colCount());
558 const auto& rhs_ti = row_set->getColType(0);
559 if (rhs_ti.get_type() != ti.get_type()) {
560 throw std::runtime_error(
561 "The two sides of the IN operator must have the same type; found " +
562 ti.get_type_name() +
" and " + rhs_ti.get_type_name());
564 row_set->moveToBegin();
565 if (row_set->entryCount() > 10000) {
566 std::shared_ptr<Analyzer::Expr> expr;
567 if ((ti.is_integer() || (ti.is_string() && ti.get_compression() ==
kENCODING_DICT)) &&
568 !row_set->getQueryMemDesc().didOutputColumnar()) {
573 if (expr && std::static_pointer_cast<Analyzer::InIntegerSet>(expr)
585 std::list<std::shared_ptr<Analyzer::Expr>> value_exprs;
587 auto row = row_set->getNextRow(
true,
false);
592 throw std::runtime_error(
593 "Unable to handle 'expr IN (subquery)', subquery returned 10000+ rows.");
595 auto scalar_tv = boost::get<ScalarTargetValue>(&row[0]);
597 bool is_null_const{
false};
600 auto ti_none_encoded = ti;
602 auto none_encoded_string = makeExpr<Analyzer::Constant>(ti, is_null_const, d);
603 auto dict_encoded_string =
604 std::make_shared<Analyzer::UOper>(ti,
false,
kCAST, none_encoded_string);
605 value_exprs.push_back(dict_encoded_string);
607 value_exprs.push_back(makeExpr<Analyzer::Constant>(ti, is_null_const, d));
610 return makeExpr<Analyzer::InValues>(lhs, value_exprs);
618 std::vector<int64_t>& in_vals,
619 std::atomic<size_t>& total_in_vals_count,
620 const ResultSet* values_rowset,
621 const std::pair<int64_t, int64_t> values_rowset_slice,
624 const int64_t needle_null_val) {
625 CHECK(in_vals.empty());
626 bool dicts_are_equal = source_dict == dest_dict;
627 for (
auto index = values_rowset_slice.first; index < values_rowset_slice.second;
629 const auto row = values_rowset->getOneColRow(index);
633 if (dicts_are_equal) {
634 in_vals.push_back(row.value);
636 const int string_id =
637 row.value == needle_null_val
641 in_vals.push_back(string_id);
646 throw std::runtime_error(
647 "Unable to handle 'expr IN (subquery)', subquery returned 30M+ rows.");
653 std::atomic<size_t>& total_in_vals_count,
654 const ResultSet* values_rowset,
655 const std::pair<int64_t, int64_t> values_rowset_slice) {
656 CHECK(in_vals.empty());
657 for (
auto index = values_rowset_slice.first; index < values_rowset_slice.second;
659 const auto row = values_rowset->getOneColRow(index);
661 in_vals.push_back(row.value);
664 throw std::runtime_error(
665 "Unable to handle 'expr IN (subquery)', subquery returned 30M+ rows.");
679 std::vector<int64_t>& in_vals,
680 std::atomic<size_t>& total_in_vals_count,
681 const ResultSet* values_rowset,
682 const std::pair<int64_t, int64_t> values_rowset_slice,
683 const std::vector<LeafHostInfo>& leaf_hosts,
686 const int32_t dest_generation,
687 const int64_t needle_null_val) {
688 CHECK(in_vals.empty());
689 std::vector<int32_t> source_ids;
690 source_ids.reserve(values_rowset->entryCount());
691 bool has_nulls =
false;
692 if (source_dict_ref == dest_dict_ref) {
693 in_vals.reserve(values_rowset_slice.second - values_rowset_slice.first +
695 for (
auto index = values_rowset_slice.first; index < values_rowset_slice.second;
697 const auto row = values_rowset->getOneColRow(index);
701 if (row.value != needle_null_val) {
702 in_vals.push_back(row.value);
705 throw std::runtime_error(
706 "Unable to handle 'expr IN (subquery)', subquery returned 30M+ rows.");
720 for (
auto index = values_rowset_slice.first; index < values_rowset_slice.second;
722 const auto row = values_rowset->getOneColRow(index);
724 if (row.value != needle_null_val) {
725 source_ids.push_back(row.value);
731 std::vector<int32_t> dest_ids;
738 CHECK_EQ(dest_ids.size(), source_ids.size());
739 in_vals.reserve(dest_ids.size() + (has_nulls ? 1 : 0));
741 in_vals.push_back(needle_null_val);
743 for (
const int32_t dest_id : dest_ids) {
745 in_vals.push_back(dest_id);
748 throw std::runtime_error(
749 "Unable to handle 'expr IN (subquery)', subquery returned 30M+ rows.");
764 std::shared_ptr<Analyzer::Expr> arg,
765 const ResultSet& val_set)
const {
769 std::vector<int64_t> value_exprs;
771 std::vector<std::vector<int64_t>> expr_set(fetcher_count);
772 std::vector<std::future<void>> fetcher_threads;
773 const auto& arg_type = arg->get_type_info();
774 const auto entry_count = val_set.entryCount();
775 CHECK_EQ(
size_t(1), val_set.colCount());
776 const auto& col_type = val_set.getColType(0);
778 (col_type.get_comp_param() <= 0 || arg_type.get_comp_param() <= 0)) {
782 std::atomic<size_t> total_in_vals_count{0};
785 stride = (entry_count + fetcher_count - 1) / fetcher_count;
786 i < fetcher_count && start_entry < entry_count;
787 ++
i, start_entry += stride) {
788 expr_set[
i].reserve(entry_count / fetcher_count);
789 const auto end_entry = std::min(start_entry + stride, entry_count);
790 if (arg_type.is_string()) {
796 const auto dd =
executor_->getStringDictionaryProxy(
797 arg_type.get_comp_param(), val_set.getRowSetMemOwner(),
true);
798 const auto sd =
executor_->getStringDictionaryProxy(
799 col_type.get_comp_param(), val_set.getRowSetMemOwner(),
true);
802 fetcher_threads.push_back(std::async(
806 &total_in_vals_count,
812 std::vector<int64_t>& in_vals,
const size_t start,
const size_t end) {
834 std::ref(expr_set[
i]),
838 CHECK(arg_type.is_integer());
839 fetcher_threads.push_back(std::async(
841 [&val_set, &total_in_vals_count](
842 std::vector<int64_t>& in_vals,
const size_t start,
const size_t end) {
845 std::ref(expr_set[
i]),
850 for (
auto& child : fetcher_threads) {
854 val_set.moveToBegin();
855 value_exprs.reserve(entry_count);
856 for (
auto& exprs : expr_set) {
857 value_exprs.insert(value_exprs.end(), exprs.begin(), exprs.end());
859 return makeExpr<Analyzer::InIntegerSet>(
860 arg, value_exprs, arg_type.get_notnull() && col_type.get_notnull());
866 if (rex_operator->
size() == 1) {
875 if (date_plus_minus) {
876 return date_plus_minus;
888 for (
size_t i = 1;
i < rex_operator->
size(); ++
i) {
889 std::shared_ptr<Analyzer::Expr> rhs;
908 const auto lhs_ti = lhs->get_type_info();
909 if (lhs_ti.is_geometry()) {
912 throw std::runtime_error(
913 "Overlaps equivalence is currently only supported for geospatial types");
918 const RexCase* rex_case)
const {
919 std::shared_ptr<Analyzer::Expr> else_expr;
920 std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
925 expr_list.emplace_back(when_expr, then_expr);
935 CHECK(rex_function->
size() == 2 || rex_function->
size() == 3);
938 if (!std::dynamic_pointer_cast<const Analyzer::Constant>(like)) {
939 throw std::runtime_error(
"The matching pattern must be a literal.");
941 const auto escape = (rex_function->
size() == 3)
944 const bool is_ilike = rex_function->
getName() ==
"PG_ILIKE"sv;
950 CHECK(rex_function->
size() == 2 || rex_function->
size() == 3);
953 if (!std::dynamic_pointer_cast<const Analyzer::Constant>(pattern)) {
954 throw std::runtime_error(
"The matching pattern must be a literal.");
956 const auto escape = (rex_function->
size() == 3)
966 return makeExpr<Analyzer::LikelihoodExpr>(arg, 0.9375);
973 return makeExpr<Analyzer::LikelihoodExpr>(arg, 0.0625);
979 const std::shared_ptr<Analyzer::Constant> literal_expr) {
980 if (!literal_expr || literal_expr->get_is_null()) {
981 throw std::runtime_error(
"The 'DatePart' argument must be a not 'null' literal.");
994 const bool is_date_trunc = rex_function->
getName() ==
"PG_DATE_TRUNC"sv;
1010 datum.tinyintval = val;
1014 datum.smallintval = val;
1022 datum.bigintval = val;
1031 datum.floatval = val;
1035 datum.doubleval = val;
1041 return makeExpr<Analyzer::Constant>(ti,
false, datum);
1053 const auto number_units_const =
1055 if (number_units_const && number_units_const->get_is_null()) {
1056 throw std::runtime_error(
"The 'Interval' argument literal must not be 'null'.");
1060 const auto& datetime_ti = datetime->get_type_info();
1061 if (datetime_ti.get_type() ==
kTIME) {
1062 throw std::runtime_error(
"DateAdd operation not supported for TIME.");
1065 const int dim = datetime_ti.get_dimension();
1066 return makeExpr<Analyzer::DateaddExpr>(
1074 return "DATETIME_PLUS"s;
1081 if (rex_operator->
size() != 2) {
1085 const auto datetime_ti = datetime->get_type_info();
1086 if (!datetime_ti.is_timestamp() && !datetime_ti.is_date()) {
1087 if (datetime_ti.get_type() ==
kTIME) {
1088 throw std::runtime_error(
"DateTime addition/subtraction not supported for TIME.");
1093 const auto rhs_ti = rhs->get_type_info();
1095 if (datetime_ti.is_high_precision_timestamp() ||
1096 rhs_ti.is_high_precision_timestamp()) {
1097 throw std::runtime_error(
1098 "High Precision timestamps are not supported for TIMESTAMPDIFF operation. "
1103 const auto& rex_operator_ti = rex_operator->
getType();
1104 const auto datediff_field =
1107 makeExpr<Analyzer::DatediffExpr>(bigint_ti, datediff_field, rhs, datetime);
1110 return makeExpr<Analyzer::BinOper>(bigint_ti.get_type(),
1121 std::vector<std::shared_ptr<Analyzer::Expr>>
args = {datetime, rhs};
1122 auto dt_plus = makeExpr<Analyzer::FunctionOper>(
1129 const auto interval =
fold_expr(rhs.get());
1130 auto interval_ti = interval->get_type_info();
1134 std::shared_ptr<Analyzer::Expr> interval_sec;
1138 (op ==
kMINUS ? -interval_lit->get_constval().bigintval
1139 : interval_lit->get_constval().bigintval) /
1142 interval_sec = makeExpr<Analyzer::BinOper>(bigint_ti.get_type(),
1149 std::make_shared<Analyzer::UOper>(bigint_ti,
false,
kUMINUS, interval_sec);
1152 return makeExpr<Analyzer::DateaddExpr>(datetime_ti,
daSECOND, interval_sec, datetime);
1155 const auto interval_months = op ==
kMINUS ? std::make_shared<Analyzer::UOper>(
1156 bigint_ti,
false,
kUMINUS, interval)
1158 return makeExpr<Analyzer::DateaddExpr>(datetime_ti,
daMONTH, interval_months, datetime);
1188 return makeExpr<Analyzer::CharLengthExpr>(str_arg->decompress(),
1189 rex_function->
getName() ==
"CHAR_LENGTH"sv);
1197 if (
nullptr == expr || !expr->get_type_info().is_string() ||
1198 expr->get_type_info().is_varlen()) {
1199 throw std::runtime_error(rex_function->
getName() +
1200 " expects a dictionary encoded text column.");
1202 return makeExpr<Analyzer::KeyForStringExpr>(
args[0]);
1209 const auto& arg_ti = arg->get_type_info();
1210 if (arg_ti.get_type() !=
kDOUBLE) {
1212 arg = arg->add_cast(double_ti);
1214 return makeExpr<Analyzer::SampleRatioExpr>(arg);
1219 std::string user{
"SESSIONLESS_USER"};
1221 user =
query_state_->getConstSessionInfo()->get_currentUser().userName;
1232 if (
args[0]->get_type_info().is_dict_encoded_string() ||
1233 dynamic_cast<Analyzer::Constant*>(
args[0].
get())) {
1234 return makeExpr<Analyzer::LowerExpr>(
args[0]);
1237 throw std::runtime_error(rex_function->
getName() +
1238 " expects a dictionary encoded text column or a literal.");
1243 const auto ret_ti = rex_function->
getType();
1245 const auto arg_ti = arg->get_type_info();
1246 if (!arg_ti.is_array()) {
1247 throw std::runtime_error(rex_function->
getName() +
" expects an array expression.");
1249 if (arg_ti.get_subtype() ==
kARRAY) {
1250 throw std::runtime_error(rex_function->
getName() +
1251 " expects one-dimension array expression.");
1253 const auto array_size = arg_ti.get_size();
1254 const auto array_elem_size = arg_ti.get_elem_type().get_array_context_logical_size();
1256 if (array_size > 0) {
1257 if (array_elem_size <= 0) {
1258 throw std::runtime_error(rex_function->
getName() +
1259 ": unexpected array element type.");
1265 return makeExpr<Analyzer::CardinalityExpr>(arg);
1273 return makeExpr<Analyzer::BinOper>(
1274 base->get_type_info().get_elem_type(),
false,
kARRAY_AT,
kONE, base, index);
1286 const std::string datetime_err{R
"(Only DATETIME('NOW') supported for now.)"};
1287 if (!arg_lit || arg_lit->get_is_null()) {
1288 throw std::runtime_error(datetime_err);
1290 CHECK(arg_lit->get_type_info().is_string());
1291 if (*arg_lit->get_constval().stringval !=
"NOW"sv) {
1292 throw std::runtime_error(datetime_err);
1299 std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
1303 const auto& operand_ti = operand->get_type_info();
1304 CHECK(operand_ti.is_number());
1306 const auto lt_zero = makeExpr<Analyzer::BinOper>(
kBOOLEAN,
kLT,
kONE, operand, zero);
1307 const auto uminus_operand =
1308 makeExpr<Analyzer::UOper>(operand_ti.get_type(),
kUMINUS, operand);
1309 expr_list.emplace_back(lt_zero, uminus_operand);
1310 return makeExpr<Analyzer::CaseExpr>(operand_ti,
false, expr_list, operand);
1315 std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
1319 const auto& operand_ti = operand->get_type_info();
1320 CHECK(operand_ti.is_number());
1322 const auto lt_zero = makeExpr<Analyzer::BinOper>(
kBOOLEAN,
kLT,
kONE, operand, zero);
1324 const auto eq_zero = makeExpr<Analyzer::BinOper>(
kBOOLEAN,
kEQ,
kONE, operand, zero);
1326 const auto gt_zero = makeExpr<Analyzer::BinOper>(
kBOOLEAN,
kGT,
kONE, operand, zero);
1328 return makeExpr<Analyzer::CaseExpr>(
1332 makeExpr<Analyzer::Constant>(operand_ti,
true,
Datum{0}));
1336 return makeExpr<Analyzer::OffsetInFragment>();
1342 auto sql_type = rex_function->
getType();
1347 if (translated_function_args.size() > 0) {
1348 const auto first_element_logical_type =
1351 auto diff_elem_itr =
1352 std::find_if(translated_function_args.begin(),
1353 translated_function_args.end(),
1354 [first_element_logical_type](
const auto expr) {
1355 return first_element_logical_type !=
1358 if (diff_elem_itr != translated_function_args.end()) {
1359 throw std::runtime_error(
1361 std::to_string(diff_elem_itr - translated_function_args.begin()) +
1362 " is not of the same type as other elements of the array. Consider casting "
1363 "to force this condition.\nElement Type: " +
1366 "\nArray type: " + first_element_logical_type.to_string());
1369 if (first_element_logical_type.is_string() &&
1370 !first_element_logical_type.is_dict_encoded_string()) {
1371 sql_type.set_subtype(first_element_logical_type.get_type());
1373 }
else if (first_element_logical_type.is_dict_encoded_string()) {
1374 sql_type.set_subtype(first_element_logical_type.get_type());
1377 sql_type.set_subtype(first_element_logical_type.get_type());
1378 sql_type.set_scale(first_element_logical_type.get_scale());
1379 sql_type.set_precision(first_element_logical_type.get_precision());
1382 return makeExpr<Analyzer::ArrayExpr>(sql_type, translated_function_args);
1386 return makeExpr<Analyzer::ArrayExpr>(sql_type, translated_function_args);
1389 return makeExpr<Analyzer::ArrayExpr>(rex_function->
getType(),
1399 if (rex_function->
getName() ==
"REGEXP_LIKE"sv) {
1402 if (rex_function->
getName() ==
"LIKELY"sv) {
1405 if (rex_function->
getName() ==
"UNLIKELY"sv) {
1411 if (rex_function->
getName() ==
"DATEADD"sv) {
1414 if (rex_function->
getName() ==
"DATEDIFF"sv) {
1417 if (rex_function->
getName() ==
"DATEPART"sv) {
1423 if (rex_function->
getName() ==
"KEY_FOR_STRING"sv) {
1426 if (rex_function->
getName() ==
"SAMPLE_RATIO"sv) {
1429 if (rex_function->
getName() ==
"CURRENT_USER"sv) {
1438 if (rex_function->
getName() ==
"ITEM"sv) {
1441 if (rex_function->
getName() ==
"NOW"sv) {
1444 if (rex_function->
getName() ==
"DATETIME"sv) {
1450 if (rex_function->
getName() ==
"ABS"sv) {
1453 if (rex_function->
getName() ==
"SIGN"sv) {
1457 return makeExpr<Analyzer::FunctionOperWithCustomTypeHandling>(
1461 }
else if (rex_function->
getName() ==
"ROUND"sv) {
1462 std::vector<std::shared_ptr<Analyzer::Expr>>
args =
1465 if (rex_function->
size() == 1) {
1473 args.push_back(makeExpr<Analyzer::Constant>(t,
false, d));
1477 CHECK(args.size() == 2);
1479 if (!args[0]->get_type_info().is_number()) {
1480 throw std::runtime_error(
"Only numeric 1st operands are supported");
1485 if (!args[1]->get_type_info().is_integer()) {
1486 throw std::runtime_error(
"Only integer 2nd operands are supported");
1493 ? args[0]->get_type_info()
1496 return makeExpr<Analyzer::FunctionOperWithCustomTypeHandling>(
1499 if (rex_function->
getName() ==
"DATETIME_PLUS"sv) {
1500 auto dt_plus = makeExpr<Analyzer::FunctionOper>(rex_function->
getType(),
1509 if (rex_function->
getName() ==
"/INT"sv) {
1516 if (rex_function->
getName() ==
"Reinterpret"sv) {
1533 "MapD_GeoPolyBoundsPtr"sv ,
1534 "MapD_GeoPolyBoundsPtr"sv ,
1535 "OmniSci_Geo_PolyBoundsPtr"sv,
1536 "OmniSci_Geo_PolyRenderGroup"sv)) {
1541 "convert_meters_to_pixel_width"sv,
1542 "convert_meters_to_pixel_height"sv,
1543 "is_point_in_view"sv,
1544 "is_point_size_in_view"sv)) {
1554 "ST_Approx_Overlaps"sv,
1563 if (rex_function->
getName() ==
"OFFSET_IN_FRAGMENT"sv) {
1567 if (rex_function->
getName() ==
"ARRAY"sv) {
1572 "ST_GeomFromText"sv,
1573 "ST_GeogFromText"sv,
1581 "ST_Intersection"sv,
1594 if (rex_function->
getName() == std::string(
"||") ||
1595 rex_function->
getName() == std::string(
"SUBSTRING")) {
1597 return makeExpr<Analyzer::FunctionOper>(
1598 ret_ti, rex_function->
getName(), arg_expr_list);
1609 auto ext_func_args = ext_func_sig.getArgs();
1610 CHECK_EQ(arg_expr_list.size(), ext_func_args.size());
1611 for (
size_t i = 0;
i < arg_expr_list.size();
i++) {
1614 std::dynamic_pointer_cast<Analyzer::Constant>(arg_expr_list[
i])) {
1616 if (ext_func_arg_ti != arg_expr_list[i]->get_type_info()) {
1617 arg_expr_list[
i] = constant->add_cast(ext_func_arg_ti);
1624 LOG(
WARNING) <<
"RelAlgTranslator::translateFunction: " << e.what();
1630 bool arguments_not_null =
true;
1631 for (
const auto& arg_expr : arg_expr_list) {
1632 if (!arg_expr->get_type_info().get_notnull()) {
1633 arguments_not_null =
false;
1639 return makeExpr<Analyzer::FunctionOper>(ret_ti, rex_function->
getName(), arg_expr_list);
1645 const std::vector<SortField>& sort_fields) {
1646 std::vector<Analyzer::OrderEntry> collation;
1647 for (
size_t i = 0;
i < sort_fields.size(); ++
i) {
1648 const auto& sort_field = sort_fields[
i];
1649 collation.emplace_back(
i,
1664 const auto& window_bound = rex_window_function->
getUpperBound();
1665 const bool to_current_row = !window_bound.
unbounded && !window_bound.preceding &&
1666 !window_bound.following && window_bound.is_current_row &&
1667 !window_bound.offset && window_bound.order_key == 1;
1668 switch (rex_window_function->
getKind()) {
1673 return to_current_row;
1677 ? (window_bound.unbounded && !window_bound.preceding &&
1678 window_bound.following && !window_bound.is_current_row &&
1679 !window_bound.offset && window_bound.order_key == 2)
1692 rex_window_function->
isRows())) {
1693 throw std::runtime_error(
"Frame specification not supported");
1695 std::vector<std::shared_ptr<Analyzer::Expr>>
args;
1696 for (
size_t i = 0;
i < rex_window_function->
size(); ++
i) {
1699 std::vector<std::shared_ptr<Analyzer::Expr>> partition_keys;
1700 for (
const auto& partition_key : rex_window_function->
getPartitionKeys()) {
1703 std::vector<std::shared_ptr<Analyzer::Expr>> order_keys;
1704 for (
const auto& order_key : rex_window_function->
getOrderKeys()) {
1707 auto ti = rex_window_function->
getType();
1710 ti = args.front()->get_type_info();
1712 return makeExpr<Analyzer::WindowFunction>(
1714 rex_window_function->
getKind(),
1723 std::vector<std::shared_ptr<Analyzer::Expr>>
args;
1724 for (
size_t i = 0;
i < rex_function->
size(); ++
i) {
1731 const std::shared_ptr<Analyzer::Expr> qual_expr) {
1735 const auto rewritten_qual_expr =
rewrite_expr(qual_expr.get());
1736 return {{}, {rewritten_qual_expr ? rewritten_qual_expr : qual_expr}};
1739 if (bin_oper->get_optype() ==
kAND) {
1743 simple_quals.insert(
1744 simple_quals.end(), rhs_cf.simple_quals.begin(), rhs_cf.simple_quals.end());
1745 auto quals = lhs_cf.quals;
1746 quals.insert(quals.end(), rhs_cf.quals.begin(), rhs_cf.quals.end());
1747 return {simple_quals, quals};
1750 const auto simple_qual = bin_oper->normalize_simple_predicate(rte_idx);
1756 const std::shared_ptr<Analyzer::Expr>& qual_expr) {
1758 const auto bin_oper = std::dynamic_pointer_cast<
const Analyzer::BinOper>(qual_expr);
1760 const auto rewritten_qual_expr =
rewrite_expr(qual_expr.get());
1761 return {rewritten_qual_expr ? rewritten_qual_expr : qual_expr};
1763 if (bin_oper->get_optype() ==
kOR) {
1766 auto quals = lhs_df;
1767 quals.insert(quals.end(), rhs_df.begin(), rhs_df.end());
1783 const auto& operand_ti = operand->get_type_info();
1784 const auto& target_ti = rex_function->
getType();
1785 if (!operand_ti.is_string()) {
1786 throw std::runtime_error(
1787 "High precision timestamp cast argument must be a string. Input type is: " +
1788 operand_ti.get_type_name());
1789 }
else if (!target_ti.is_high_precision_timestamp()) {
1790 throw std::runtime_error(
1791 "Cast target type should be high precision timestamp. Input type is: " +
1792 target_ti.get_type_name());
1793 }
else if (target_ti.get_dimension() != 6 && target_ti.get_dimension() != 9) {
1794 throw std::runtime_error(
1795 "Cast target type should be TIMESTAMP(6|9). Input type is: TIMESTAMP(" +
1798 return operand->add_cast(target_ti);
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
std::shared_ptr< Analyzer::Expr > translateOffsetInFragment() const
static std::shared_ptr< Analyzer::Expr > get(const std::string &)
std::shared_ptr< Analyzer::Expr > translateRegexp(const RexFunctionOperator *) const
bool supported_lower_bound(const RexWindowFunctionOperator::RexWindowBound &window_bound)
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
static std::shared_ptr< Analyzer::Expr > analyzeValue(const int64_t intval)
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 std::vector< SortField > & getCollation() const
std::shared_ptr< Analyzer::Expr > translateDateadd(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateNow() 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
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)
HOST DEVICE SQLTypes get_type() const
QualsConjunctiveForm qual_to_conjunctive_form(const std::shared_ptr< Analyzer::Expr > qual_expr)
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
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 >)
std::shared_ptr< Analyzer::Expr > translateGeoOverlapsOper(const RexOperator *) const
std::shared_ptr< Analyzer::Expr > translateLower(const RexFunctionOperator *) const
ExtractField to_datepart_field(const std::string &field)
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
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)
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)
std::shared_ptr< const RexScalar > offset
std::vector< Analyzer::OrderEntry > translate_collation(const std::vector< SortField > &sort_fields)
size_t branchCount() const
int getDatabaseId() const
SQLTypeInfo build_type_info(const SQLTypes sql_type, const int scale, const int precision)
static std::shared_ptr< Analyzer::Expr > analyzeValue(const std::string &)
DatetruncField to_datediff_field(const std::string &field)
void translate_string_ids(std::vector< int32_t > &dest_ids, const LeafHostInfo &dict_server_host, const DictRef dest_dict_ref, const std::vector< int32_t > &source_ids, const DictRef source_dict_ref, const int32_t dest_generation)
const std::vector< LeafHostInfo > & getStringDictionaryHosts() const
const ColumnDescriptor * getMetadataForColumnBySpi(const int tableId, const size_t spi) const
const std::unordered_map< const RelAlgNode *, int > input_to_nest_level_
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)
std::pair< std::shared_ptr< Analyzer::Expr >, SQLQualifier > get_quantified_rhs(const RexScalar *rex_scalar, const RelAlgTranslator &translator)
Analyzer::ExpressionPtrVector translateFunctionArgs(const RexFunctionOperator *) const
const ConstRexScalarPtrVector & getPartitionKeys() const
#define TRANSIENT_DICT_ID
const RexWindowBound & getLowerBound() const
std::shared_ptr< Analyzer::Expr > translateOverlapsOper(const RexOperator *) 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::shared_ptr< Analyzer::Expr > translateCurrentUser(const RexFunctionOperator *) const
bool g_enable_experimental_string_functions
std::shared_ptr< Analyzer::Expr > translateSampleRatio(const RexFunctionOperator *) const
SqlWindowFunctionKind getKind() const
std::shared_ptr< Analyzer::Expr > translateLike(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateGeoBinaryConstructor(const RexFunctionOperator *, SQLTypeInfo &, const bool with_bounds) const
bool supported_upper_bound(const RexWindowFunctionOperator *rex_window_function)
bool takes_arg(const TargetInfo &target_info)
T bind_function(std::string name, Analyzer::ExpressionPtrVector func_args, const std::vector< T > &ext_funcs, const std::string processor)
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
const RexWindowBound & getUpperBound() 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 > 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
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::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 > 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)
const Catalog_Namespace::Catalog & cat_
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
std::shared_ptr< Analyzer::Expr > translateGeoPredicate(const RexFunctionOperator *, SQLTypeInfo &, const bool with_bounds) 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