From d7c19d68550eb6018e8581a73a351905f4cc435c Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Wed, 1 Jul 2015 18:07:48 -0400
Subject: [PATCH] Make sampler_random_fract() actually obey its API contract.

This function is documented to return a value in the range (0,1),
which is what its predecessor anl_random_fract() did.  However, the
new version depends on pg_erand48() which returns a value in [0,1).
The possibility of returning zero creates hazards of division by zero
or trying to compute log(0) at some call sites, and it might well
break third-party modules using anl_random_fract() too.  So let's
change it to never return zero.  Spotted by Coverity.

Michael Paquier, cosmetically adjusted by me
---
 src/backend/utils/misc/sampling.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/backend/utils/misc/sampling.c b/src/backend/utils/misc/sampling.c
index aaf1d6c4108..6191f797344 100644
--- a/src/backend/utils/misc/sampling.c
+++ b/src/backend/utils/misc/sampling.c
@@ -237,7 +237,14 @@ sampler_random_init_state(long seed, SamplerRandomState randstate)
 double
 sampler_random_fract(SamplerRandomState randstate)
 {
-	return pg_erand48(randstate);
+	double		res;
+
+	/* pg_erand48 returns a value in [0.0 - 1.0), so we must reject 0 */
+	do
+	{
+		res = pg_erand48(randstate);
+	} while (res == 0.0);
+	return res;
 }
 
 
-- 
GitLab