diff options
author | Robert Haas <rhaas@postgresql.org> | 2015-11-06 11:03:02 -0500 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2015-11-06 11:03:02 -0500 |
commit | 8a1fab36aba7506fcf4559c4ef95fcacdd0b439a (patch) | |
tree | 05a33bd92f6f820c0f775a24b005ce89a651b39b /src/backend/utils/adt/dbsize.c | |
parent | dde5f09fad3ac188a155e21667f76825f43a28c8 (diff) | |
download | postgresql-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.c | 61 |
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)); } } |