diff --git a/src/sql/engine/expr/ob_expr_cast.cpp b/src/sql/engine/expr/ob_expr_cast.cpp index 2a301c4648..ff0bbde6c1 100644 --- a/src/sql/engine/expr/ob_expr_cast.cpp +++ b/src/sql/engine/expr/ob_expr_cast.cpp @@ -447,7 +447,11 @@ int ObExprCast::calc_result_type2(ObExprResType &type, // eg: select cast(18446744073709551615 as signed) -> -1 // because exprlicit case need CM_NO_RANGE_CHECK type_ctx.set_cast_mode(explicit_cast_cm & ~CM_EXPLICIT_CAST); - type1.set_calc_accuracy(type.get_accuracy()); + if (lib::is_mysql_mode() && !ob_is_numeric_type(type.get_type()) && type1.is_double()) { + // for double type cast non-numeric type, no need set calc accuracy to dst type. + } else { + type1.set_calc_accuracy(type.get_accuracy()); + } // in engine 3.0, let implicit cast do the real cast bool need_extra_cast_for_src_type = false; diff --git a/src/sql/resolver/expr/ob_raw_expr_deduce_type.cpp b/src/sql/resolver/expr/ob_raw_expr_deduce_type.cpp index 638027cdb6..ac2e1dad99 100644 --- a/src/sql/resolver/expr/ob_raw_expr_deduce_type.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_deduce_type.cpp @@ -381,6 +381,9 @@ int ObRawExprDeduceType::calc_result_type(ObNonTerminalRawExpr &expr, // demands that we set the calculation type here. for (int64_t i = 0; i < types.count(); ++i) { types.at(i).set_calc_meta(types.at(i)); + if (lib::is_mysql_mode() && types.at(i).is_double()) { + types.at(i).set_calc_accuracy(types.at(i).get_accuracy()); + } } if (OB_FAIL(ret)) { } else if (ObExprOperator::NOT_ROW_DIMENSION != row_dimension) { diff --git a/src/sql/resolver/expr/ob_raw_expr_util.cpp b/src/sql/resolver/expr/ob_raw_expr_util.cpp index 5dc4974403..6021bb37d4 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_util.cpp @@ -3441,11 +3441,13 @@ int ObRawExprUtils::try_add_cast_expr_above(ObRawExprFactory *expr_factory, int ret = OB_SUCCESS; new_expr = &expr; bool need_cast = false; + bool is_scale_adjust_cast = false; const ObExprResType &src_type = expr.get_result_type(); CK(OB_NOT_NULL(session) && OB_NOT_NULL(expr_factory)); - OZ(ObRawExprUtils::check_need_cast_expr(src_type, dst_type, need_cast)); + OZ(ObRawExprUtils::check_need_cast_expr(src_type, dst_type, need_cast, is_scale_adjust_cast)); if (OB_SUCC(ret) && need_cast) { - if (T_FUN_SYS_CAST == expr.get_expr_type() && expr.has_flag(IS_OP_OPERAND_IMPLICIT_CAST)) { + if (T_FUN_SYS_CAST == expr.get_expr_type() && expr.has_flag(IS_OP_OPERAND_IMPLICIT_CAST) && + !is_scale_adjust_cast) { ret = OB_ERR_UNEXPECTED; #ifdef DEBUG LOG_ERROR("try to add implicit cast again, check if type deduction is correct", @@ -6594,10 +6596,12 @@ bool ObRawExprUtils::is_sharable_expr(const ObRawExpr &expr) int ObRawExprUtils::check_need_cast_expr(const ObExprResType &src_type, const ObExprResType &dst_type, - bool &need_cast) + bool &need_cast, + bool &is_scale_adjust_cast) { int ret = OB_SUCCESS; need_cast = false; + is_scale_adjust_cast = false; ObObjType in_type = src_type.get_type(); ObObjType out_type = dst_type.get_type(); ObCollationType in_cs_type = src_type.get_collation_type(); @@ -6617,9 +6621,15 @@ int ObRawExprUtils::check_need_cast_expr(const ObExprResType &src_type, src_type.get_scale() != dst_type.get_scale() && src_type.get_precision() != PRECISION_UNKNOWN_YET) { // for the conversion between doubles with increased scale in mysql mode, - // it is necessary to explicitly add the cast expression + // there are tow cases need to explicitly add the cast expression: + // case 1: the scale of dst_type is unknow(-1), the scale represents the largest float/double + // scale in mysql. + // case 2: dst_scale is greater than src_scale, need to be aligned need_cast = (SCALE_UNKNOWN_YET == dst_type.get_scale()) || (src_type.get_scale() < dst_type.get_scale()); + if (need_cast) { + is_scale_adjust_cast = true; + } } } else if (ob_is_enumset_tc(out_type)) { //no need add cast, will add column_conv later diff --git a/src/sql/resolver/expr/ob_raw_expr_util.h b/src/sql/resolver/expr/ob_raw_expr_util.h index 5937486a30..6986faa4ed 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.h +++ b/src/sql/resolver/expr/ob_raw_expr_util.h @@ -842,7 +842,8 @@ public: static int check_need_cast_expr(const ObExprResType &src_res_type, const ObExprResType &dst_res_type, - bool &need_cast); + bool &need_cast, + bool &is_scale_adjust_cast); static int build_add_expr(ObRawExprFactory &expr_factory, ObRawExpr *param_expr1, ObRawExpr *param_expr2,