From 72fa0fc1a8a154b68442d2a8731bb82e39eff4fa Mon Sep 17 00:00:00 2001 From: jian he Date: Wed, 10 Dec 2025 11:55:40 +0800 Subject: [PATCH v15 18/22] introduce float8 safe function this patch introduce the following function: float8_pl_safe float8_mi_safe float8_mul_safe float8_div_safe refactoring existing function is be too invasive. thus add these new functions. It's close to existing non-safe version functions. discussion: https://postgr.es/m/CADkLM=fv1JfY4Ufa-jcwwNbjQixNViskQ8jZu3Tz_p656i_4hQ@mail.gmail.com --- src/include/utils/float.h | 79 ++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/src/include/utils/float.h b/src/include/utils/float.h index 1d0cb026d4e..f46861ab5c3 100644 --- a/src/include/utils/float.h +++ b/src/include/utils/float.h @@ -109,16 +109,24 @@ float4_pl(const float4 val1, const float4 val2) return result; } +static inline float8 +float8_pl_safe(const float8 val1, const float8 val2, struct Node *escontext) +{ + float8 result; + + result = val1 + val2; + if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) + { + float_overflow_error(escontext); + return 0.0; + } + return result; +} + static inline float8 float8_pl(const float8 val1, const float8 val2) { - float8 result; - - result = val1 + val2; - if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) - float_overflow_error(NULL); - - return result; + return float8_pl_safe(val1, val2, NULL);; } static inline float4 @@ -133,16 +141,24 @@ float4_mi(const float4 val1, const float4 val2) return result; } +static inline float8 +float8_mi_safe(const float8 val1, const float8 val2, struct Node *escontext) +{ + float8 result; + + result = val1 - val2; + if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) + { + float_overflow_error(escontext); + return 0.0; + } + return result; +} + static inline float8 float8_mi(const float8 val1, const float8 val2) { - float8 result; - - result = val1 - val2; - if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) - float_overflow_error(NULL); - - return result; + return float8_mi_safe(val1, val2, NULL); } static inline float4 @@ -160,19 +176,33 @@ float4_mul(const float4 val1, const float4 val2) } static inline float8 -float8_mul(const float8 val1, const float8 val2) +float8_mul_safe(const float8 val1, const float8 val2, struct Node *escontext) { float8 result; result = val1 * val2; if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) - float_overflow_error(NULL); + { + float_overflow_error(escontext); + return 0.0; + } + if (unlikely(result == 0.0) && val1 != 0.0 && val2 != 0.0) - float_underflow_error(NULL); + { + float_underflow_error(escontext); + return 0.0; + } return result; } +static inline float8 +float8_mul(const float8 val1, const float8 val2) +{ + return float8_mul_safe(val1, val2, NULL); +} + + static inline float4 float4_div(const float4 val1, const float4 val2) { @@ -190,21 +220,28 @@ float4_div(const float4 val1, const float4 val2) } static inline float8 -float8_div(const float8 val1, const float8 val2) +float8_div_safe(const float8 val1, const float8 val2, struct Node *escontext) { float8 result; if (unlikely(val2 == 0.0) && !isnan(val1)) - float_zero_divide_error(NULL); + float_zero_divide_error(escontext); result = val1 / val2; if (unlikely(isinf(result)) && !isinf(val1)) - float_overflow_error(NULL); + float_overflow_error(escontext); if (unlikely(result == 0.0) && val1 != 0.0 && !isinf(val2)) - float_underflow_error(NULL); + float_underflow_error(escontext); return result; } +static inline float8 +float8_div(const float8 val1, const float8 val2) +{ + return float8_div_safe(val1, val2, NULL); +} + + /* * Routines for NaN-aware comparisons * -- 2.34.1