Skip to content

Commit b181062

Browse files
committed
Fix incorrect return value for pg_size_pretty(bigint)
pg_size_pretty(bigint) would return the value in bytes rather than PB for the smallest-most bigint value. This happened due to an incorrect assumption that the absolute value of -9223372036854775808 could be stored inside a signed 64-bit type. Here we fix that by instead storing that value in an unsigned 64-bit type. This bug does exist in versions prior to 15 but the code there is sufficiently different and the bug seems sufficiently non-critical that it does not seem worth risking backpatching further. Author: Joseph Koshakow <koshy44@gmail.com> Discussion: https://postgr.es/m/CAAvxfHdTsMZPWEHUrZ=h3cky9Ccc3Mtx2whUHygY+ABP-mCmUw@mail.gmail.com Backpatch-through: 15
1 parent 1e666fd commit b181062

File tree

3 files changed

+18
-2
lines changed

3 files changed

+18
-2
lines changed

src/backend/utils/adt/dbsize.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -575,9 +575,13 @@ pg_size_pretty(PG_FUNCTION_ARGS)
575575
for (unit = size_pretty_units; unit->name != NULL; unit++)
576576
{
577577
uint8 bits;
578+
uint64 abs_size = size < 0 ? 0 - (uint64) size : (uint64) size;
578579

579-
/* use this unit if there are no more units or we're below the limit */
580-
if (unit[1].name == NULL || i64abs(size) < unit->limit)
580+
/*
581+
* Use this unit if there are no more units or the absolute size is
582+
* below the limit for the current unit.
583+
*/
584+
if (unit[1].name == NULL || abs_size < unit->limit)
581585
{
582586
if (unit->round)
583587
size = half_rounded(size);

src/test/regress/expected/dbsize.out

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM
7979
11528652096115048448 | 10240 PB | -10240 PB
8080
(12 rows)
8181

82+
-- Ensure we get the expected results when passing the extremities of bigint
83+
SELECT pg_size_pretty('-9223372036854775808'::bigint),
84+
pg_size_pretty('9223372036854775807'::bigint);
85+
pg_size_pretty | pg_size_pretty
86+
----------------+----------------
87+
-8192 PB | 8192 PB
88+
(1 row)
89+
8290
-- pg_size_bytes() tests
8391
SELECT size, pg_size_bytes(size) FROM
8492
(VALUES ('1'), ('123bytes'), ('256 B'), ('1kB'), ('1MB'), (' 1 GB'), ('1.5 GB '),

src/test/regress/sql/dbsize.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM
2727
(11258449312612351::numeric), (11258449312612352::numeric),
2828
(11528652096115048447::numeric), (11528652096115048448::numeric)) x(size);
2929

30+
-- Ensure we get the expected results when passing the extremities of bigint
31+
SELECT pg_size_pretty('-9223372036854775808'::bigint),
32+
pg_size_pretty('9223372036854775807'::bigint);
33+
3034
-- pg_size_bytes() tests
3135
SELECT size, pg_size_bytes(size) FROM
3236
(VALUES ('1'), ('123bytes'), ('256 B'), ('1kB'), ('1MB'), (' 1 GB'), ('1.5 GB '),

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy