From 6ba9a93498de3f73c14706463c6ed2c47577f223 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Sun, 2 Nov 2025 21:12:53 +0100
Subject: [PATCH 1/4] Replace internal C function pg_hypot() by standard
 hypot()

The code comment said, "It is expected that this routine will
eventually be replaced with the C99 hypot() function.", so let's do
that now.
---
 src/backend/access/spgist/spgproc.c |  2 +-
 src/backend/utils/adt/geo_ops.c     | 76 ++---------------------------
 src/backend/utils/adt/geo_spgist.c  |  2 +-
 src/include/utils/geo_decls.h       |  8 ---
 4 files changed, 6 insertions(+), 82 deletions(-)

diff --git a/src/backend/access/spgist/spgproc.c b/src/backend/access/spgist/spgproc.c
index 660009291da..722c17ce2e5 100644
--- a/src/backend/access/spgist/spgproc.c
+++ b/src/backend/access/spgist/spgproc.c
@@ -51,7 +51,7 @@ point_box_distance(Point *point, BOX *box)
 	else
 		dy = 0.0;
 
-	return HYPOT(dx, dy);
+	return hypot(dx, dy);
 }
 
 /*
diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c
index 377a1b3f3ad..9101a720744 100644
--- a/src/backend/utils/adt/geo_ops.c
+++ b/src/backend/utils/adt/geo_ops.c
@@ -1276,7 +1276,7 @@ line_distance(PG_FUNCTION_ARGS)
 
 	PG_RETURN_FLOAT8(float8_div(fabs(float8_mi(l1->C,
 											   float8_mul(ratio, l2->C))),
-								HYPOT(l1->A, l1->B)));
+								hypot(l1->A, l1->B)));
 }
 
 /* line_interpt()
@@ -2001,7 +2001,7 @@ point_distance(PG_FUNCTION_ARGS)
 static inline float8
 point_dt(Point *pt1, Point *pt2)
 {
-	return HYPOT(float8_mi(pt1->x, pt2->x), float8_mi(pt1->y, pt2->y));
+	return hypot(float8_mi(pt1->x, pt2->x), float8_mi(pt1->y, pt2->y));
 }
 
 Datum
@@ -5005,7 +5005,7 @@ circle_mul_pt(PG_FUNCTION_ARGS)
 	result = (CIRCLE *) palloc(sizeof(CIRCLE));
 
 	point_mul_point(&result->center, &circle->center, point);
-	result->radius = float8_mul(circle->radius, HYPOT(point->x, point->y));
+	result->radius = float8_mul(circle->radius, hypot(point->x, point->y));
 
 	PG_RETURN_CIRCLE_P(result);
 }
@@ -5020,7 +5020,7 @@ circle_div_pt(PG_FUNCTION_ARGS)
 	result = (CIRCLE *) palloc(sizeof(CIRCLE));
 
 	point_div_point(&result->center, &circle->center, point);
-	result->radius = float8_div(circle->radius, HYPOT(point->x, point->y));
+	result->radius = float8_div(circle->radius, hypot(point->x, point->y));
 
 	PG_RETURN_CIRCLE_P(result);
 }
@@ -5492,71 +5492,3 @@ plist_same(int npts, Point *p1, Point *p2)
 
 	return false;
 }
-
-
-/*-------------------------------------------------------------------------
- * Determine the hypotenuse.
- *
- * If required, x and y are swapped to make x the larger number. The
- * traditional formula of x^2+y^2 is rearranged to factor x outside the
- * sqrt. This allows computation of the hypotenuse for significantly
- * larger values, and with a higher precision than when using the naive
- * formula.  In particular, this cannot overflow unless the final result
- * would be out-of-range.
- *
- * sqrt( x^2 + y^2 ) = sqrt( x^2( 1 + y^2/x^2) )
- *					 = x * sqrt( 1 + y^2/x^2 )
- *					 = x * sqrt( 1 + y/x * y/x )
- *
- * It is expected that this routine will eventually be replaced with the
- * C99 hypot() function.
- *
- * This implementation conforms to IEEE Std 1003.1 and GLIBC, in that the
- * case of hypot(inf,nan) results in INF, and not NAN.
- *-----------------------------------------------------------------------
- */
-float8
-pg_hypot(float8 x, float8 y)
-{
-	float8		yx,
-				result;
-
-	/* Handle INF and NaN properly */
-	if (isinf(x) || isinf(y))
-		return get_float8_infinity();
-
-	if (isnan(x) || isnan(y))
-		return get_float8_nan();
-
-	/* Else, drop any minus signs */
-	x = fabs(x);
-	y = fabs(y);
-
-	/* Swap x and y if needed to make x the larger one */
-	if (x < y)
-	{
-		float8		temp = x;
-
-		x = y;
-		y = temp;
-	}
-
-	/*
-	 * If y is zero, the hypotenuse is x.  This test saves a few cycles in
-	 * such cases, but more importantly it also protects against
-	 * divide-by-zero errors, since now x >= y.
-	 */
-	if (y == 0.0)
-		return x;
-
-	/* Determine the hypotenuse */
-	yx = y / x;
-	result = x * sqrt(1.0 + (yx * yx));
-
-	if (unlikely(isinf(result)))
-		float_overflow_error();
-	if (unlikely(result == 0.0))
-		float_underflow_error();
-
-	return result;
-}
diff --git a/src/backend/utils/adt/geo_spgist.c b/src/backend/utils/adt/geo_spgist.c
index fec33e95372..4308a3065cd 100644
--- a/src/backend/utils/adt/geo_spgist.c
+++ b/src/backend/utils/adt/geo_spgist.c
@@ -390,7 +390,7 @@ pointToRectBoxDistance(Point *point, RectBox *rect_box)
 	else
 		dy = 0;
 
-	return HYPOT(dx, dy);
+	return hypot(dx, dy);
 }
 
 
diff --git a/src/include/utils/geo_decls.h b/src/include/utils/geo_decls.h
index 8a9df75c93c..d4f7ea31f62 100644
--- a/src/include/utils/geo_decls.h
+++ b/src/include/utils/geo_decls.h
@@ -88,7 +88,6 @@ FPge(double A, double B)
 #define FPge(A,B)				((A) >= (B))
 #endif
 
-#define HYPOT(A, B)				pg_hypot(A, B)
 
 /*---------------------------------------------------------------------
  * Point - (x,y)
@@ -275,11 +274,4 @@ CirclePGetDatum(const CIRCLE *X)
 #define PG_GETARG_CIRCLE_P(n) DatumGetCircleP(PG_GETARG_DATUM(n))
 #define PG_RETURN_CIRCLE_P(x) return CirclePGetDatum(x)
 
-
-/*
- * in geo_ops.c
- */
-
-extern float8 pg_hypot(float8 x, float8 y);
-
 #endif							/* GEO_DECLS_H */
-- 
2.51.0

