提交 8aade630 编写于 作者: H hezuojiao 提交者: ob-robot

Fix fixed float column convert range check

上级 4737fc89
......@@ -598,13 +598,11 @@ int real_range_check_only(const ObAccuracy &accuracy, Type value)
if (OB_LIKELY(precision > 0) &&
OB_LIKELY(scale >= 0) &&
OB_LIKELY(precision >= scale)) {
// Because double type represents a larger width, use double type instead of float to check
// result range.
double integer_part = static_cast<double>(pow(10.0, static_cast<double>(precision - scale)));
double decimal_part = static_cast<double>(pow(10.0, static_cast<double>(scale)));
double max_value = integer_part - 1 / decimal_part;
double min_value = -max_value;
if (OB_FAIL(numeric_range_check(static_cast<double>(value), min_value, max_value, value))) {
Type integer_part = static_cast<Type>(pow(10.0, static_cast<double>(precision - scale)));
Type decimal_part = static_cast<Type>(pow(10.0, static_cast<double>(scale)));
Type max_value = integer_part - 1 / decimal_part;
Type min_value = -max_value;
if (OB_FAIL(numeric_range_check(value, min_value, max_value, value))) {
}
}
return ret;
......
......@@ -84,27 +84,6 @@ OB_INLINE int numeric_range_check<double, float>(const double in_val,
return ret;
}
// check range using double type
OB_INLINE int numeric_range_check(const double in_val,
const double min_out_val,
const double max_out_val,
float &out_val)
{
int ret = OB_SUCCESS;
if (isinf(in_val)) {
out_val = static_cast<float>(in_val);
} else {
if (in_val < min_out_val) {
ret = OB_DATA_OUT_OF_RANGE;
out_val = static_cast<float>(min_out_val);
} else if (in_val > max_out_val) {
ret = OB_DATA_OUT_OF_RANGE;
out_val = static_cast<float>(max_out_val);
}
}
return ret;
}
// check if is negative only.
template <typename OutType>
OB_INLINE int numeric_negative_check(OutType &out_val)
......@@ -191,13 +170,11 @@ int real_range_check(const ObAccuracy &accuracy, Type &value)
if (OB_LIKELY(precision > 0) &&
OB_LIKELY(scale >= 0) &&
OB_LIKELY(precision >= scale)) {
// Because double type represents a larger width, use double type instead of float to check
// result range.
double integer_part = static_cast<double>(pow(10.0, static_cast<double>(precision - scale)));
double decimal_part = static_cast<double>(pow(10.0, static_cast<double>(scale)));
double max_value = static_cast<double>(integer_part - 1 / decimal_part);
double min_value = static_cast<double>(-max_value);
if (OB_FAIL(numeric_range_check(static_cast<double>(value), min_value, max_value, value))) {
Type integer_part = static_cast<Type>(pow(10.0, static_cast<double>(precision - scale)));
Type decimal_part = static_cast<Type>(pow(10.0, static_cast<double>(scale)));
Type max_value = static_cast<Type>(integer_part - 1 / decimal_part);
Type min_value = static_cast<Type>(-max_value);
if (OB_FAIL(numeric_range_check(value, min_value, max_value, value))) {
} else {
value = static_cast<Type>(rint((value -
floor(static_cast<double>(value)))* decimal_part) /
......
......@@ -1092,8 +1092,20 @@ static OB_INLINE int common_double_float(const ObExpr &expr,
ObObjType out_type = expr.datum_meta_.type_;
// oracle support float/double infiniy, no need to verify data overflow.
// C language would cast value to infinity, which is correct behavor in oracle mode
if (lib::is_mysql_mode() && CAST_FAIL(real_range_check(out_type, in_val, out_val))) {
LOG_WARN("real_range_check failed", K(ret), K(in_val));
if (lib::is_mysql_mode()) {
double truncated_val = in_val;
if (ob_is_float_tc(out_type) && CM_IS_COLUMN_CONVERT(expr.extra_)) {
// truncate float value if its ps information is fixed.
ObAccuracy accuracy(expr.datum_meta_.precision_, expr.datum_meta_.scale_);
if (CAST_FAIL(real_range_check(accuracy, truncated_val))) {
LOG_WARN("fail to real range check", K(ret));
} else {
out_val = static_cast<float>(truncated_val);
}
}
if (OB_SUCC(ret) && CAST_FAIL(real_range_check(out_type, truncated_val, out_val))) {
LOG_WARN("real_range_check failed", K(ret), K(in_val));
}
}
return ret;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册