From fd2e2d09aa1d5ba198e09e6d936ff1bba7f62895 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Fri, 29 Apr 2011 01:44:50 -0400
Subject: [PATCH] Rewrite pg_size_pretty() to avoid compiler bug.

Convert it to use successive shifts right instead of increasing a divisor.
This is probably a tad more efficient than the original coding, and it's
nicer-looking than the previous patch because we don't need a special case
to avoid overflow in the last branch.  But the real reason to do it is to
avoid a Solaris compiler bug, as per results from buildfarm member moa.
---
 src/backend/utils/adt/dbsize.c | 32 +++++++++++++-------------------
 1 file changed, 13 insertions(+), 19 deletions(-)

diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index aa4066f9f05..2ee59668cd7 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -466,39 +466,33 @@ pg_size_pretty(PG_FUNCTION_ARGS)
 	int64		size = PG_GETARG_INT64(0);
 	char		buf[64];
 	int64		limit = 10 * 1024;
-	int64		mult = 1;
+	int64		limit2 = limit * 2 - 1;
 
-	if (size < limit * mult)
+	if (size < limit)
 		snprintf(buf, sizeof(buf), INT64_FORMAT " bytes", size);
 	else
 	{
-		mult *= 1024;
-		if (size < limit * mult)
+		size >>= 9;				/* keep one extra bit for rounding */
+		if (size < limit2)
 			snprintf(buf, sizeof(buf), INT64_FORMAT " kB",
-					 (size + mult / 2) / mult);
+					 (size + 1) / 2);
 		else
 		{
-			mult *= 1024;
-			if (size < limit * mult)
+			size >>= 10;
+			if (size < limit2)
 				snprintf(buf, sizeof(buf), INT64_FORMAT " MB",
-						 (size + mult / 2) / mult);
+						 (size + 1) / 2);
 			else
 			{
-				mult *= 1024;
-				if (size < limit * mult)
+				size >>= 10;
+				if (size < limit2)
 					snprintf(buf, sizeof(buf), INT64_FORMAT " GB",
-							 (size + mult / 2) / mult);
+							 (size + 1) / 2);
 				else
 				{
-					/* Here we have to worry about avoiding overflow */
-					int64	val;
-
-					mult *= 1024;
-					val = size / mult;
-					if ((size % mult) >= (mult / 2))
-						val++;
+					size >>= 10;
 					snprintf(buf, sizeof(buf), INT64_FORMAT " TB",
-							 val);
+							 (size + 1) / 2);
 				}
 			}
 		}
-- 
GitLab