aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/dbsize.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2015-11-06 11:03:02 -0500
committerRobert Haas <rhaas@postgresql.org>2015-11-06 11:03:02 -0500
commit8a1fab36aba7506fcf4559c4ef95fcacdd0b439a (patch)
tree05a33bd92f6f820c0f775a24b005ce89a651b39b /src/backend/utils/adt/dbsize.c
parentdde5f09fad3ac188a155e21667f76825f43a28c8 (diff)
downloadpostgresql-8a1fab36aba7506fcf4559c4ef95fcacdd0b439a.tar.gz
postgresql-8a1fab36aba7506fcf4559c4ef95fcacdd0b439a.zip
pg_size_pretty: Format negative values similar to positive ones.
Previously, negative values were always displayed in bytes, regardless of how large they were. Adrian Vondendriesch, reviewed by Julien Rouhaud and myself
Diffstat (limited to 'src/backend/utils/adt/dbsize.c')
-rw-r--r--src/backend/utils/adt/dbsize.c61
1 files changed, 38 insertions, 23 deletions
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index 82311b4ca95..5ee59d0a2e2 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -31,6 +31,8 @@
#include "utils/relmapper.h"
#include "utils/syscache.h"
+/* Divide by two and round towards positive infinity. */
+#define half_rounded(x) (((x) + ((x) < 0 ? 0 : 1)) / 2)
/* Return physical size of directory contents, or 0 if dir doesn't exist */
static int64
@@ -534,31 +536,31 @@ pg_size_pretty(PG_FUNCTION_ARGS)
int64 limit = 10 * 1024;
int64 limit2 = limit * 2 - 1;
- if (size < limit)
+ if (Abs(size) < limit)
snprintf(buf, sizeof(buf), INT64_FORMAT " bytes", size);
else
{
size >>= 9; /* keep one extra bit for rounding */
- if (size < limit2)
+ if (Abs(size) < limit2)
snprintf(buf, sizeof(buf), INT64_FORMAT " kB",
- (size + 1) / 2);
+ half_rounded(size));
else
{
size >>= 10;
- if (size < limit2)
+ if (Abs(size) < limit2)
snprintf(buf, sizeof(buf), INT64_FORMAT " MB",
- (size + 1) / 2);
+ half_rounded(size));
else
{
size >>= 10;
- if (size < limit2)
+ if (Abs(size) < limit2)
snprintf(buf, sizeof(buf), INT64_FORMAT " GB",
- (size + 1) / 2);
+ half_rounded(size));
else
{
size >>= 10;
snprintf(buf, sizeof(buf), INT64_FORMAT " TB",
- (size + 1) / 2);
+ half_rounded(size));
}
}
}
@@ -593,17 +595,34 @@ numeric_is_less(Numeric a, Numeric b)
}
static Numeric
-numeric_plus_one_over_two(Numeric n)
+numeric_absolute(Numeric n)
{
Datum d = NumericGetDatum(n);
+ Datum result;
+
+ result = DirectFunctionCall1(numeric_abs, d);
+ return DatumGetNumeric(result);
+}
+
+static Numeric
+numeric_half_rounded(Numeric n)
+{
+ Datum d = NumericGetDatum(n);
+ Datum zero;
Datum one;
Datum two;
Datum result;
+ zero = DirectFunctionCall1(int8_numeric, Int64GetDatum(0));
one = DirectFunctionCall1(int8_numeric, Int64GetDatum(1));
two = DirectFunctionCall1(int8_numeric, Int64GetDatum(2));
- result = DirectFunctionCall2(numeric_add, d, one);
- result = DirectFunctionCall2(numeric_div_trunc, result, two);
+
+ if (DatumGetBool(DirectFunctionCall2(numeric_ge, d, zero)))
+ d = DirectFunctionCall2(numeric_add, d, one);
+ else
+ d = DirectFunctionCall2(numeric_sub, d, one);
+
+ result = DirectFunctionCall2(numeric_div_trunc, d, two);
return DatumGetNumeric(result);
}
@@ -632,7 +651,7 @@ pg_size_pretty_numeric(PG_FUNCTION_ARGS)
limit = int64_to_numeric(10 * 1024);
limit2 = int64_to_numeric(10 * 1024 * 2 - 1);
- if (numeric_is_less(size, limit))
+ if (numeric_is_less(numeric_absolute(size), limit))
{
result = psprintf("%s bytes", numeric_to_cstring(size));
}
@@ -642,20 +661,18 @@ pg_size_pretty_numeric(PG_FUNCTION_ARGS)
/* size >>= 9 */
size = numeric_shift_right(size, 9);
- if (numeric_is_less(size, limit2))
+ if (numeric_is_less(numeric_absolute(size), limit2))
{
- /* size = (size + 1) / 2 */
- size = numeric_plus_one_over_two(size);
+ size = numeric_half_rounded(size);
result = psprintf("%s kB", numeric_to_cstring(size));
}
else
{
/* size >>= 10 */
size = numeric_shift_right(size, 10);
- if (numeric_is_less(size, limit2))
+ if (numeric_is_less(numeric_absolute(size), limit2))
{
- /* size = (size + 1) / 2 */
- size = numeric_plus_one_over_two(size);
+ size = numeric_half_rounded(size);
result = psprintf("%s MB", numeric_to_cstring(size));
}
else
@@ -663,18 +680,16 @@ pg_size_pretty_numeric(PG_FUNCTION_ARGS)
/* size >>= 10 */
size = numeric_shift_right(size, 10);
- if (numeric_is_less(size, limit2))
+ if (numeric_is_less(numeric_absolute(size), limit2))
{
- /* size = (size + 1) / 2 */
- size = numeric_plus_one_over_two(size);
+ size = numeric_half_rounded(size);
result = psprintf("%s GB", numeric_to_cstring(size));
}
else
{
/* size >>= 10 */
size = numeric_shift_right(size, 10);
- /* size = (size + 1) / 2 */
- size = numeric_plus_one_over_two(size);
+ size = numeric_half_rounded(size);
result = psprintf("%s TB", numeric_to_cstring(size));
}
}