From 103bf705197419ea5a820c42909fc7590d7e8161 Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Fri, 2 Jan 2026 16:14:28 +0800
Subject: [PATCH v19 19/23] 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 d2e989960a5..8723b4c00b0 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

