diff --git a/deps/oblib/src/lib/wide_integer/ob_wide_integer_helper.h b/deps/oblib/src/lib/wide_integer/ob_wide_integer_helper.h index d1012eb24..e5b2afd9d 100644 --- a/deps/oblib/src/lib/wide_integer/ob_wide_integer_helper.h +++ b/deps/oblib/src/lib/wide_integer/ob_wide_integer_helper.h @@ -510,31 +510,23 @@ inline bool is_zero(const ObDecimalInt *decint, int32_t int_bytes) } inline int negate(const ObDecimalInt *decint, int32_t int_bytes, ObDecimalInt *&out_decint, - ObIAllocator &allocator) + int32_t out_bytes, ObIAllocator &allocator) { -#define NEG_VAL_CASE(int_type) \ - case sizeof(int_type): { \ - *reinterpret_cast(out_decint) = -(*reinterpret_cast(decint)); \ - } break +#define DO_NEG_VAL(in_type, out_type)\ + *reinterpret_cast(out_decint) = -(*reinterpret_cast(decint)); int ret = OB_SUCCESS; out_decint = nullptr; - if (int_bytes == 0) { + if (out_bytes == 0 || int_bytes == 0) { // do nothing - } else if (OB_ISNULL(out_decint = (ObDecimalInt *)allocator.alloc(int_bytes))) { + } else if (OB_ISNULL(out_decint = (ObDecimalInt *)allocator.alloc(out_bytes))) { ret = OB_ALLOCATE_MEMORY_FAILED; SQL_LOG(WARN, "allocate memory failed", K(ret)); } else { - switch (int_bytes) { - LST_DO_CODE(NEG_VAL_CASE, int32_t, int64_t, int128_t, int256_t, int512_t); - default: { - ret = OB_ERR_UNEXPECTED; - SQL_LOG(WARN, "unexpected int bytes", K(ret), K(int_bytes)); - } - } + DISPATCH_INOUT_WIDTH_TASK(int_bytes, out_bytes, DO_NEG_VAL); } return ret; -#undef NEG_VAL_CASE +#undef DO_NEG_VAL } template diff --git a/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp b/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp index 3222e1f72..ced82f716 100644 --- a/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp @@ -162,14 +162,16 @@ int ObRawExprResolverImpl::try_negate_const(ObRawExpr *&expr, ObObj new_val; if (const_expr->get_value().is_decimal_int()) { ObDecimalInt *neg_dec = nullptr; + int32_t out_prec = + const_expr->get_accuracy().get_precision() + (lib::is_oracle_mode() ? 0 : 1); + int32_t out_bytes = wide::ObDecimalIntConstValue::get_int_bytes_by_precision(out_prec); if (!is_odd) {// do nothing } else if (OB_FAIL(wide::negate(const_expr->get_value().get_decimal_int(), const_expr->get_value().get_int_bytes(), neg_dec, - ctx_.expr_factory_.get_allocator()))) { + out_bytes, ctx_.expr_factory_.get_allocator()))) { LOG_WARN("negate decimal int failed", K(ret)); } else { - new_val.set_decimal_int(const_expr->get_value().get_int_bytes(), - const_expr->get_value().get_scale(), neg_dec); + new_val.set_decimal_int(out_bytes, const_expr->get_value().get_scale(), neg_dec); negated = true; } } else {