515 const auto cast_ti =
casts_[bin_oper];
518 if ((cast_ti.is_integer() || cast_ti.is_fp()) && lhs_ti.is_integer() &&
519 cast_ti.get_size() > lhs_ti.get_size() &&
523 left_operand = left_operand->deep_copy()->add_cast(cast_ti);
524 right_operand = right_operand->deep_copy()->add_cast(cast_ti);
529 const auto lhs =
visit(left_operand.get());
530 const auto rhs =
visit(right_operand.get());
535 const auto& rhs_ti = rhs->get_type_info();
539 if (const_lhs && const_rhs && lhs_type == rhs_type) {
540 auto lhs_datum = const_lhs->get_constval();
541 auto rhs_datum = const_rhs->get_constval();
542 Datum result_datum = {};
544 if (
foldOper(optype, lhs_type, lhs_datum, rhs_datum, result_datum, result_type)) {
547 return makeExpr<Analyzer::Constant>(result_type,
false, result_datum);
552 return makeExpr<Analyzer::Constant>(ti,
false, result_datum);
557 if (optype ==
kAND && lhs_type == rhs_type && lhs_type ==
kBOOLEAN) {
558 if (const_rhs && !const_rhs->get_is_null()) {
559 auto rhs_datum = const_rhs->get_constval();
560 if (rhs_datum.boolval ==
false) {
564 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
569 if (const_lhs && !const_lhs->get_is_null()) {
570 auto lhs_datum = const_lhs->get_constval();
571 if (lhs_datum.boolval ==
false) {
575 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
581 if (optype ==
kOR && lhs_type == rhs_type && lhs_type ==
kBOOLEAN) {
582 if (const_rhs && !const_rhs->get_is_null()) {
583 auto rhs_datum = const_rhs->get_constval();
584 if (rhs_datum.boolval ==
true) {
588 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
593 if (const_lhs && !const_lhs->get_is_null()) {
594 auto lhs_datum = const_lhs->get_constval();
595 if (lhs_datum.boolval ==
true) {
599 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
607 if (optype ==
kEQ || optype ==
kLE || optype ==
kGE) {
610 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
613 if (optype ==
kNE || optype ==
kLT || optype ==
kGT) {
616 return makeExpr<Analyzer::Constant>(
kBOOLEAN,
false, d);
621 return makeExpr<Analyzer::Constant>(lhs_type,
false, d);
625 if (optype ==
kDIVIDE && const_rhs && rhs_ti.is_fp()) {
626 auto rhs_datum = const_rhs->get_constval();
627 std::shared_ptr<Analyzer::Expr> recip_rhs =
nullptr;
628 if (rhs_ti.get_type() ==
kFLOAT) {
629 if (rhs_datum.floatval == 1.0) {
632 auto f = std::fabs(rhs_datum.floatval);
633 if (f > 1.0 || (f != 0.0 && 1.0 < f * std::numeric_limits<float>::max())) {
634 rhs_datum.floatval = 1.0 / rhs_datum.floatval;
635 recip_rhs = makeExpr<Analyzer::Constant>(rhs_type,
false, rhs_datum);
637 }
else if (rhs_ti.get_type() ==
kDOUBLE) {
638 if (rhs_datum.doubleval == 1.0) {
641 auto d = std::fabs(rhs_datum.doubleval);
642 if (d > 1.0 || (d != 0.0 && 1.0 < d * std::numeric_limits<double>::max())) {
643 rhs_datum.doubleval = 1.0 / rhs_datum.doubleval;
644 recip_rhs = makeExpr<Analyzer::Constant>(rhs_type,
false, rhs_datum);
648 return makeExpr<Analyzer::BinOper>(ti,
657 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