From e1d250ba19b13fb6858125b68adbbd6a78ed4393 Mon Sep 17 00:00:00 2001 From: David Christensen Date: Fri, 2 Apr 2021 14:35:31 -0500 Subject: [PATCH 1/2] Expand the units that pg_size_pretty(numeric) knows about Rework the logic slightly to allow a lookup table-based approach for displaying units. Add units up to yottabytes, with easy expansion if this ever needs to grow. --- doc/src/sgml/func.sgml | 2 +- src/backend/utils/adt/dbsize.c | 43 ++++++++++-------- src/test/regress/expected/dbsize.out | 67 +++++++++++++++++++--------- src/test/regress/sql/dbsize.sql | 27 ++++++++--- 4 files changed, 94 insertions(+), 45 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 08b07f561e..f6739f150c 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -26371,7 +26371,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); Converts a size in bytes into a more easily human-readable format with - size units (bytes, kB, MB, GB or TB as appropriate). Note that the + size units (bytes, kB, MB, GB, TB, PB, EB, ZB, or YB as appropriate). Note that the units are powers of 2 rather than powers of 10, so 1kB is 1024 bytes, 1MB is 10242 = 1048576 bytes, and so on. diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c index 3c70bb5943..f25ec5c1af 100644 --- a/src/backend/utils/adt/dbsize.c +++ b/src/backend/utils/adt/dbsize.c @@ -638,7 +638,7 @@ pg_size_pretty_numeric(PG_FUNCTION_ARGS) Numeric size = PG_GETARG_NUMERIC(0); Numeric limit, limit2; - char *result; + char *result = NULL; limit = int64_to_numeric(10 * 1024); limit2 = int64_to_numeric(10 * 1024 * 2 - 1); @@ -660,31 +660,36 @@ pg_size_pretty_numeric(PG_FUNCTION_ARGS) } else { - /* size >>= 10 */ - size = numeric_shift_right(size, 10); - if (numeric_is_less(numeric_absolute(size), limit2)) - { - size = numeric_half_rounded(size); - result = psprintf("%s MB", numeric_to_cstring(size)); - } - else - { + int idx, max_iter = 6; /* highest index of table_below */ + char *output_formats[] = { + "%s MB", + "%s GB", + "%s TB", + "%s PB", + "%s EB", + "%s ZB", + "%s YB" + }; + + for (idx = 0; idx < max_iter; idx++) { /* size >>= 10 */ size = numeric_shift_right(size, 10); - if (numeric_is_less(numeric_absolute(size), limit2)) { size = numeric_half_rounded(size); - result = psprintf("%s GB", numeric_to_cstring(size)); - } - else - { - /* size >>= 10 */ - size = numeric_shift_right(size, 10); - size = numeric_half_rounded(size); - result = psprintf("%s TB", numeric_to_cstring(size)); + result = psprintf(output_formats[idx], numeric_to_cstring(size)); + break; } } + + if (!result) { + /* this uses the last format in the table above for anything else */ + + /* size >>= 10 */ + size = numeric_shift_right(size, 10); + size = numeric_half_rounded(size); + result = psprintf(output_formats[max_iter], numeric_to_cstring(size)); + } } } diff --git a/src/test/regress/expected/dbsize.out b/src/test/regress/expected/dbsize.out index e901a2c92a..b93d40fb02 100644 --- a/src/test/regress/expected/dbsize.out +++ b/src/test/regress/expected/dbsize.out @@ -13,27 +13,54 @@ SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM (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), + (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) + (1000000000000000000::numeric), + (1000000000000000000000::numeric), + (1000000000000000000000000::numeric), + (1000000000000000000000000000::numeric), + (1000000000000000000000000000000::numeric), + (10.5::numeric), + (1000.5::numeric), + (1000000.5::numeric), + (1000000000.5::numeric), + (1000000000000.5::numeric), + (1000000000000000.5::numeric), + (1000000000000000000.5::numeric), + (1000000000000000000000.5::numeric), + (1000000000000000000000000.5::numeric), + (1000000000000000000000000000.5::numeric), + (1000000000000000000000000000000.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 + 1000000000000000000 | 888 PB | -888 PB + 1000000000000000000000 | 867 EB | -867 EB + 1000000000000000000000000 | 847 ZB | -847 ZB + 1000000000000000000000000000 | 827 YB | -827 YB + 1000000000000000000000000000000 | 827181 YB | -827181 YB + 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 + 1000000000000000000.5 | 888 PB | -888 PB + 1000000000000000000000.5 | 867 EB | -867 EB + 1000000000000000000000000.5 | 847 ZB | -847 ZB + 1000000000000000000000000000.5 | 827 YB | -827 YB + 1000000000000000000000000000000.5 | 827181 YB | -827181 YB +(22 rows) SELECT size, pg_size_bytes(size) FROM (VALUES ('1'), ('123bytes'), ('1kB'), ('1MB'), (' 1 GB'), ('1.5 GB '), diff --git a/src/test/regress/sql/dbsize.sql b/src/test/regress/sql/dbsize.sql index d10a4d7f68..a97dacbf7b 100644 --- a/src/test/regress/sql/dbsize.sql +++ b/src/test/regress/sql/dbsize.sql @@ -4,12 +4,29 @@ SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM (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), + (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); + (1000000000000000000::numeric), + (1000000000000000000000::numeric), + (1000000000000000000000000::numeric), + (1000000000000000000000000000::numeric), + (1000000000000000000000000000000::numeric), + (10.5::numeric), + (1000.5::numeric), + (1000000.5::numeric), + (1000000000.5::numeric), + (1000000000000.5::numeric), + (1000000000000000.5::numeric), + (1000000000000000000.5::numeric), + (1000000000000000000000.5::numeric), + (1000000000000000000000000.5::numeric), + (1000000000000000000000000000.5::numeric), + (1000000000000000000000000000000.5::numeric) + ) x(size); SELECT size, pg_size_bytes(size) FROM (VALUES ('1'), ('123bytes'), ('1kB'), ('1MB'), (' 1 GB'), ('1.5 GB '), -- 2.30.1 (Apple Git-130)