aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/utils/adt/dbsize.c61
-rw-r--r--src/test/regress/expected/dbsize.out37
-rw-r--r--src/test/regress/parallel_schedule2
-rw-r--r--src/test/regress/serial_schedule1
-rw-r--r--src/test/regress/sql/dbsize.sql12
5 files changed, 89 insertions, 24 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));
}
}
diff --git a/src/test/regress/expected/dbsize.out b/src/test/regress/expected/dbsize.out
new file mode 100644
index 00000000000..aa513e7eff0
--- /dev/null
+++ b/src/test/regress/expected/dbsize.out
@@ -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)
+
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index c63abf4b0ad..3987b4c700f 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -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
diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule
index 88dcd64dfce..379f2729be4 100644
--- a/src/test/regress/serial_schedule
+++ b/src/test/regress/serial_schedule
@@ -117,6 +117,7 @@ test: alter_operator
test: misc
test: psql
test: async
+test: dbsize
test: rules
test: select_views
test: portals_p2
diff --git a/src/test/regress/sql/dbsize.sql b/src/test/regress/sql/dbsize.sql
new file mode 100644
index 00000000000..c118090cc64
--- /dev/null
+++ b/src/test/regress/sql/dbsize.sql
@@ -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);