Fixed the problem of stddev rooting negative numbers due to overflow

This commit is contained in:
hwx65
2024-08-05 16:36:21 +00:00
committed by ob-robot
parent dec3c8e2fa
commit d688f4acb9
2 changed files with 23 additions and 3 deletions

View File

@ -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()))) {
// 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)); 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))) {
// 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)); 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));

View File

@ -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;
} }
} }