519 const auto cast_ti =
casts_[bin_oper];
522 if ((cast_ti.is_integer() || cast_ti.is_fp()) && lhs_ti.is_integer() &&
523 cast_ti.get_size() > lhs_ti.get_size() &&
527 left_operand = left_operand->deep_copy()->add_cast(cast_ti);
528 right_operand = right_operand->deep_copy()->add_cast(cast_ti);
533 const auto lhs =
visit(left_operand.get());
534 const auto rhs =
visit(right_operand.get());
539 const auto& rhs_ti = rhs->get_type_info();
543 if (const_lhs && const_rhs && lhs_type == rhs_type) {
544 auto lhs_datum = const_lhs->get_constval();
545 auto rhs_datum = const_rhs->get_constval();
546 Datum result_datum = {};
548 if (
foldOper(optype, lhs_type, lhs_datum, rhs_datum, result_datum, result_type)) {
551 return makeExpr<Analyzer::Constant>(result_type,
false, result_datum);
556 return makeExpr<Analyzer::Constant>(ti,
false, result_datum);
561 if (optype ==
kAND && lhs_type == rhs_type && lhs_type ==
kBOOLEAN) {
562 if (const_rhs && !const_rhs->get_is_null()) {
563 auto rhs_datum = const_rhs->get_constval();
564 if (rhs_datum.boolval ==
false) {
568 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
573 if (const_lhs && !const_lhs->get_is_null()) {
574 auto lhs_datum = const_lhs->get_constval();
575 if (lhs_datum.boolval ==
false) {
579 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
585 if (optype ==
kOR && lhs_type == rhs_type && lhs_type ==
kBOOLEAN) {
586 if (const_rhs && !const_rhs->get_is_null()) {
587 auto rhs_datum = const_rhs->get_constval();
588 if (rhs_datum.boolval ==
true) {
592 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
597 if (const_lhs && !const_lhs->get_is_null()) {
598 auto lhs_datum = const_lhs->get_constval();
599 if (lhs_datum.boolval ==
true) {
603 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
610 if (!lhs_ti.get_notnull()) {
611 CHECK(!rhs_ti.get_notnull());
618 return makeExpr<Analyzer::BinOper>(ti,
625 CHECK(rhs_ti.get_notnull());
627 if (optype ==
kEQ || optype ==
kLE || optype ==
kGE) {
630 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
633 if (optype ==
kNE || optype ==
kLT || optype ==
kGT) {
636 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
641 return makeExpr<Analyzer::Constant>(lhs_type,
false, d);
645 if (optype ==
kDIVIDE && const_rhs && rhs_ti.is_fp()) {
646 auto rhs_datum = const_rhs->get_constval();
647 std::shared_ptr<Analyzer::Expr> recip_rhs =
nullptr;
648 if (rhs_ti.get_type() ==
kFLOAT) {
649 if (rhs_datum.floatval == 1.0) {
652 auto f = std::fabs(rhs_datum.floatval);
653 if (
f > 1.0 || (
f != 0.0 && 1.0 <
f * std::numeric_limits<float>::max())) {
654 rhs_datum.floatval = 1.0 / rhs_datum.floatval;
655 recip_rhs = makeExpr<Analyzer::Constant>(rhs_type,
false, rhs_datum);
657 }
else if (rhs_ti.get_type() ==
kDOUBLE) {
658 if (rhs_datum.doubleval == 1.0) {
661 auto d = std::fabs(rhs_datum.doubleval);
662 if (d > 1.0 || (d != 0.0 && 1.0 < d * std::numeric_limits<double>::max())) {
663 rhs_datum.doubleval = 1.0 / rhs_datum.doubleval;
664 recip_rhs = makeExpr<Analyzer::Constant>(rhs_type,
false, rhs_datum);
668 return makeExpr<Analyzer::BinOper>(ti,
677 return makeExpr<Analyzer::BinOper>(ti,
bool get_contains_agg() const
std::shared_ptr< Analyzer::Expr > visit(const Analyzer::Expr *expr) const
SQLOps get_optype() const
bool foldOper(SQLOps optype, SQLTypes type, Datum lhs, Datum rhs, Datum &result, SQLTypes &result_type) const
const SQLTypeInfo & get_type_info() const
SQLTypes decimal_to_int_type(const SQLTypeInfo &ti)
std::unordered_map< const Analyzer::Expr *, const SQLTypeInfo > casts_
const Expr * get_left_operand() const
const std::shared_ptr< Analyzer::Expr > get_own_right_operand() const
const std::shared_ptr< Analyzer::Expr > get_own_left_operand() const
SQLQualifier get_qualifier() const