Commit 8a1fab36 authored by Robert Haas's avatar Robert Haas

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
parent dde5f09f
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#include "utils/relmapper.h" #include "utils/relmapper.h"
#include "utils/syscache.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 */ /* Return physical size of directory contents, or 0 if dir doesn't exist */
static int64 static int64
...@@ -534,31 +536,31 @@ pg_size_pretty(PG_FUNCTION_ARGS) ...@@ -534,31 +536,31 @@ pg_size_pretty(PG_FUNCTION_ARGS)
int64 limit = 10 * 1024; int64 limit = 10 * 1024;
int64 limit2 = limit * 2 - 1; int64 limit2 = limit * 2 - 1;
if (size < limit) if (Abs(size) < limit)
snprintf(buf, sizeof(buf), INT64_FORMAT " bytes", size); snprintf(buf, sizeof(buf), INT64_FORMAT " bytes", size);
else else
{ {
size >>= 9; /* keep one extra bit for rounding */ size >>= 9; /* keep one extra bit for rounding */
if (size < limit2) if (Abs(size) < limit2)
snprintf(buf, sizeof(buf), INT64_FORMAT " kB", snprintf(buf, sizeof(buf), INT64_FORMAT " kB",
(size + 1) / 2); half_rounded(size));
else else
{ {
size >>= 10; size >>= 10;
if (size < limit2) if (Abs(size) < limit2)
snprintf(buf, sizeof(buf), INT64_FORMAT " MB", snprintf(buf, sizeof(buf), INT64_FORMAT " MB",
(size + 1) / 2); half_rounded(size));
else else
{ {
size >>= 10; size >>= 10;
if (size < limit2) if (Abs(size) < limit2)
snprintf(buf, sizeof(buf), INT64_FORMAT " GB", snprintf(buf, sizeof(buf), INT64_FORMAT " GB",
(size + 1) / 2); half_rounded(size));
else else
{ {
size >>= 10; size >>= 10;
snprintf(buf, sizeof(buf), INT64_FORMAT " TB", snprintf(buf, sizeof(buf), INT64_FORMAT " TB",
(size + 1) / 2); half_rounded(size));
} }
} }
} }
...@@ -593,17 +595,34 @@ numeric_is_less(Numeric a, Numeric b) ...@@ -593,17 +595,34 @@ numeric_is_less(Numeric a, Numeric b)
} }
static Numeric static Numeric
numeric_plus_one_over_two(Numeric n) numeric_absolute(Numeric n)
{ {
Datum d = NumericGetDatum(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 one;
Datum two; Datum two;
Datum result; Datum result;
zero = DirectFunctionCall1(int8_numeric, Int64GetDatum(0));
one = DirectFunctionCall1(int8_numeric, Int64GetDatum(1)); one = DirectFunctionCall1(int8_numeric, Int64GetDatum(1));
two = DirectFunctionCall1(int8_numeric, Int64GetDatum(2)); 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); return DatumGetNumeric(result);
} }
...@@ -632,7 +651,7 @@ pg_size_pretty_numeric(PG_FUNCTION_ARGS) ...@@ -632,7 +651,7 @@ pg_size_pretty_numeric(PG_FUNCTION_ARGS)
limit = int64_to_numeric(10 * 1024); limit = int64_to_numeric(10 * 1024);
limit2 = int64_to_numeric(10 * 1024 * 2 - 1); 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)); result = psprintf("%s bytes", numeric_to_cstring(size));
} }
...@@ -642,20 +661,18 @@ pg_size_pretty_numeric(PG_FUNCTION_ARGS) ...@@ -642,20 +661,18 @@ pg_size_pretty_numeric(PG_FUNCTION_ARGS)
/* size >>= 9 */ /* size >>= 9 */
size = numeric_shift_right(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_half_rounded(size);
size = numeric_plus_one_over_two(size);
result = psprintf("%s kB", numeric_to_cstring(size)); result = psprintf("%s kB", numeric_to_cstring(size));
} }
else else
{ {
/* size >>= 10 */ /* size >>= 10 */
size = numeric_shift_right(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_half_rounded(size);
size = numeric_plus_one_over_two(size);
result = psprintf("%s MB", numeric_to_cstring(size)); result = psprintf("%s MB", numeric_to_cstring(size));
} }
else else
...@@ -663,18 +680,16 @@ pg_size_pretty_numeric(PG_FUNCTION_ARGS) ...@@ -663,18 +680,16 @@ pg_size_pretty_numeric(PG_FUNCTION_ARGS)
/* size >>= 10 */ /* size >>= 10 */
size = numeric_shift_right(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_half_rounded(size);
size = numeric_plus_one_over_two(size);
result = psprintf("%s GB", numeric_to_cstring(size)); result = psprintf("%s GB", numeric_to_cstring(size));
} }
else else
{ {
/* size >>= 10 */ /* size >>= 10 */
size = numeric_shift_right(size, 10); size = numeric_shift_right(size, 10);
/* size = (size + 1) / 2 */ size = numeric_half_rounded(size);
size = numeric_plus_one_over_two(size);
result = psprintf("%s TB", numeric_to_cstring(size)); result = psprintf("%s TB", numeric_to_cstring(size));
} }
} }
......
SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM
(VALUES (10::bigint), (1000::bigint), (1000000::bigint),
(1000000000::bigint), (1000000000000::bigint),
(1000000000000000::bigint)) x(size);
size | pg_size_pretty | pg_size_pretty
------------------+----------------+----------------
10 | 10 bytes | -10 bytes
1000 | 1000 bytes | -1000 bytes
1000000 | 977 kB | -977 kB
1000000000 | 954 MB | -954 MB
1000000000000 | 931 GB | -931 GB
1000000000000000 | 909 TB | -909 TB
(6 rows)
SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM
(VALUES (10::numeric), (1000::numeric), (1000000::numeric),
(1000000000::numeric), (1000000000000::numeric),
(1000000000000000::numeric),
(10.5::numeric), (1000.5::numeric), (1000000.5::numeric),
(1000000000.5::numeric), (1000000000000.5::numeric),
(1000000000000000.5::numeric)) x(size);
size | pg_size_pretty | pg_size_pretty
--------------------+----------------+----------------
10 | 10 bytes | -10 bytes
1000 | 1000 bytes | -1000 bytes
1000000 | 977 kB | -977 kB
1000000000 | 954 MB | -954 MB
1000000000000 | 931 GB | -931 GB
1000000000000000 | 909 TB | -909 TB
10.5 | 10.5 bytes | -10.5 bytes
1000.5 | 1000.5 bytes | -1000.5 bytes
1000000.5 | 977 kB | -977 kB
1000000000.5 | 954 MB | -954 MB
1000000000000.5 | 931 GB | -931 GB
1000000000000000.5 | 909 TB | -909 TB
(12 rows)
...@@ -89,7 +89,7 @@ test: brin gin gist spgist privileges security_label collate matview lock replic ...@@ -89,7 +89,7 @@ test: brin gin gist spgist privileges security_label collate matview lock replic
# ---------- # ----------
# Another group of parallel tests # Another group of parallel tests
# ---------- # ----------
test: alter_generic alter_operator misc psql async test: alter_generic alter_operator misc psql async dbsize
# rules cannot run concurrently with any test that creates a view # rules cannot run concurrently with any test that creates a view
test: rules test: rules
......
...@@ -117,6 +117,7 @@ test: alter_operator ...@@ -117,6 +117,7 @@ test: alter_operator
test: misc test: misc
test: psql test: psql
test: async test: async
test: dbsize
test: rules test: rules
test: select_views test: select_views
test: portals_p2 test: portals_p2
......
SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM
(VALUES (10::bigint), (1000::bigint), (1000000::bigint),
(1000000000::bigint), (1000000000000::bigint),
(1000000000000000::bigint)) x(size);
SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM
(VALUES (10::numeric), (1000::numeric), (1000000::numeric),
(1000000000::numeric), (1000000000000::numeric),
(1000000000000000::numeric),
(10.5::numeric), (1000.5::numeric), (1000000.5::numeric),
(1000000000.5::numeric), (1000000000000.5::numeric),
(1000000000000000.5::numeric)) x(size);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment