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
This commit is contained in:
parent
dde5f09fad
commit
8a1fab36ab
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
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
|
|||
# ----------
|
||||
# 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
|
||||
test: rules
|
||||
|
|
|
@ -117,6 +117,7 @@ test: alter_operator
|
|||
test: misc
|
||||
test: psql
|
||||
test: async
|
||||
test: dbsize
|
||||
test: rules
|
||||
test: select_views
|
||||
test: portals_p2
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
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);
|
Loading…
Reference in New Issue