Fixed the problem of stddev rooting negative numbers due to overflow
This commit is contained in:
@ -220,7 +220,16 @@ int calc_sqrt_expr_oracle_number(const ObExpr &expr, ObEvalCtx &ctx,
|
|||||||
number::ObNumber res_nmb;
|
number::ObNumber res_nmb;
|
||||||
ObEvalCtx::TempAllocGuard alloc_guard(ctx);
|
ObEvalCtx::TempAllocGuard alloc_guard(ctx);
|
||||||
if (OB_FAIL(arg_nmb.sqrt(res_nmb, alloc_guard.get_allocator()))) {
|
if (OB_FAIL(arg_nmb.sqrt(res_nmb, alloc_guard.get_allocator()))) {
|
||||||
LOG_WARN("calc sqrt failed", K(ret), K(arg_nmb), K(res_nmb));
|
// The input of the sqrt rewritten by stddev will not be negative. If it is negative, it
|
||||||
|
// means that the parameter has overflowed. Since the precision of ob is very large and the
|
||||||
|
// absolute value of the parameter is very small, the result can be directly corrected to 0
|
||||||
|
if (OB_UNLIKELY(arg_nmb.is_negative() && expr.extra_ == T_FUN_STDDEV)) {
|
||||||
|
res_nmb.set_zero();
|
||||||
|
res_datum.set_number(res_nmb);
|
||||||
|
ret = OB_SUCCESS;
|
||||||
|
} else {
|
||||||
|
LOG_WARN("calc sqrt failed", K(ret), K(arg_nmb), K(res_nmb));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
res_datum.set_number(res_nmb);
|
res_datum.set_number(res_nmb);
|
||||||
}
|
}
|
||||||
@ -251,7 +260,17 @@ int calc_sqrt_expr_oracle_number_in_batch(const ObExpr &expr,
|
|||||||
} else {
|
} else {
|
||||||
arg_nmb = arg_datums.at(i)->get_number();
|
arg_nmb = arg_datums.at(i)->get_number();
|
||||||
if (OB_FAIL(arg_nmb.sqrt(res_nmb, temp_allocator))) {
|
if (OB_FAIL(arg_nmb.sqrt(res_nmb, temp_allocator))) {
|
||||||
LOG_WARN("calc sqrt failed", K(ret), K(arg_nmb), K(res_nmb));
|
// The input of the sqrt rewritten by stddev will not be negative. If it is negative, it
|
||||||
|
// means that the parameter has overflowed. Since the precision of ob is very large and
|
||||||
|
// the absolute value of the parameter is very small, the result can be directly
|
||||||
|
// corrected to 0
|
||||||
|
if (OB_UNLIKELY(arg_nmb.is_negative() && expr.extra_ == T_FUN_STDDEV)) {
|
||||||
|
res_nmb.set_zero();
|
||||||
|
res_datums[i].set_number(res_nmb);
|
||||||
|
ret = OB_SUCCESS;
|
||||||
|
} else {
|
||||||
|
LOG_WARN("calc sqrt failed", K(ret), K(arg_nmb), K(res_nmb));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
res_datums[i].set_number(res_nmb);
|
res_datums[i].set_number(res_nmb);
|
||||||
}
|
}
|
||||||
@ -269,7 +288,7 @@ int ObExprSqrt::cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_expr,
|
|||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
UNUSED(expr_cg_ctx);
|
UNUSED(expr_cg_ctx);
|
||||||
UNUSED(raw_expr);
|
rt_expr.extra_ = raw_expr.get_extra();
|
||||||
if (OB_UNLIKELY(1 != rt_expr.arg_cnt_)) {
|
if (OB_UNLIKELY(1 != rt_expr.arg_cnt_)) {
|
||||||
ret = OB_ERR_UNEXPECTED;
|
ret = OB_ERR_UNEXPECTED;
|
||||||
LOG_WARN("invalid arg_cnt_ of expr", K(ret), K(rt_expr));
|
LOG_WARN("invalid arg_cnt_ of expr", K(ret), K(rt_expr));
|
||||||
|
|||||||
@ -2035,6 +2035,7 @@ int ObExpandAggregateUtils::expand_stddev_expr(ObAggFunRawExpr *aggr_expr,
|
|||||||
} else {
|
} else {
|
||||||
ObString func_name = ObString::make_string("sqrt");
|
ObString func_name = ObString::make_string("sqrt");
|
||||||
sqrt_expr->set_func_name(func_name);
|
sqrt_expr->set_func_name(func_name);
|
||||||
|
sqrt_expr->set_extra(aggr_expr->get_expr_type());
|
||||||
replace_expr = sqrt_expr;
|
replace_expr = sqrt_expr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user