Skip to content

Commit ce1215d

Browse files
committed
Add support for unit "B" to pg_size_bytes()
This makes it consistent with the units support in GUC. Reviewed-by: David Rowley <[email protected]> Reviewed-by: Dean Rasheed <[email protected]> Discussion: https://www.postgresql.org/message-id/flat/0106914a-9eb5-22be-40d8-652cc88c827d%40enterprisedb.com
1 parent af4d571 commit ce1215d

File tree

4 files changed

+42
-13
lines changed

4 files changed

+42
-13
lines changed

doc/src/sgml/func.sgml

+4-1
Original file line numberDiff line numberDiff line change
@@ -27167,7 +27167,10 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
2716727167
</para>
2716827168
<para>
2716927169
Converts a size in human-readable format (as returned
27170-
by <function>pg_size_pretty</function>) into bytes.
27170+
by <function>pg_size_pretty</function>) into bytes. Valid units are
27171+
<literal>bytes</literal>, <literal>B</literal>, <literal>kB</literal>,
27172+
<literal>MB</literal>, <literal>GB</literal>, <literal>TB</literal>,
27173+
and <literal>PB</literal>.
2717127174
</para></entry>
2717227175
</row>
2717327176

src/backend/utils/adt/dbsize.c

+29-4
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ struct size_pretty_unit
4646
* unit */
4747
};
4848

49-
/* When adding units here also update the error message in pg_size_bytes */
49+
/* When adding units here also update the docs and the error message in pg_size_bytes */
5050
static const struct size_pretty_unit size_pretty_units[] = {
5151
{"bytes", 10 * 1024, false, 0},
5252
{"kB", 20 * 1024 - 1, true, 10},
@@ -57,6 +57,19 @@ static const struct size_pretty_unit size_pretty_units[] = {
5757
{NULL, 0, false, 0}
5858
};
5959

60+
/* Additional unit aliases accepted by pg_size_bytes */
61+
struct size_bytes_unit_alias
62+
{
63+
const char *alias;
64+
int unit_index; /* corresponding size_pretty_units element */
65+
};
66+
67+
/* When adding units here also update the docs and the error message in pg_size_bytes */
68+
static const struct size_bytes_unit_alias size_bytes_aliases[] = {
69+
{"B", 0},
70+
{NULL}
71+
};
72+
6073
/* Return physical size of directory contents, or 0 if dir doesn't exist */
6174
static int64
6275
db_dir_size(const char *path)
@@ -801,9 +814,19 @@ pg_size_bytes(PG_FUNCTION_ARGS)
801814
{
802815
/* Parse the unit case-insensitively */
803816
if (pg_strcasecmp(strptr, unit->name) == 0)
804-
{
805-
multiplier = ((int64) 1) << unit->unitbits;
806817
break;
818+
}
819+
820+
/* If not found, look in table of aliases */
821+
if (unit->name == NULL)
822+
{
823+
for (const struct size_bytes_unit_alias *a = size_bytes_aliases; a->alias != NULL; a++)
824+
{
825+
if (pg_strcasecmp(strptr, a->alias) == 0)
826+
{
827+
unit = &size_pretty_units[a->unit_index];
828+
break;
829+
}
807830
}
808831
}
809832

@@ -813,7 +836,9 @@ pg_size_bytes(PG_FUNCTION_ARGS)
813836
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
814837
errmsg("invalid size: \"%s\"", text_to_cstring(arg)),
815838
errdetail("Invalid size unit: \"%s\".", strptr),
816-
errhint("Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", \"TB\", and \"PB\".")));
839+
errhint("Valid units are \"bytes\", \"B\", \"kB\", \"MB\", \"GB\", \"TB\", and \"PB\".")));
840+
841+
multiplier = ((int64) 1) << unit->unitbits;
817842

818843
if (multiplier > 1)
819844
{

src/test/regress/expected/dbsize.out

+8-7
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,13 @@ SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM
8181

8282
-- pg_size_bytes() tests
8383
SELECT size, pg_size_bytes(size) FROM
84-
(VALUES ('1'), ('123bytes'), ('1kB'), ('1MB'), (' 1 GB'), ('1.5 GB '),
84+
(VALUES ('1'), ('123bytes'), ('256 B'), ('1kB'), ('1MB'), (' 1 GB'), ('1.5 GB '),
8585
('1TB'), ('3000 TB'), ('1e6 MB'), ('99 PB')) x(size);
8686
size | pg_size_bytes
8787
----------+--------------------
8888
1 | 1
8989
123bytes | 123
90+
256 B | 256
9091
1kB | 1024
9192
1MB | 1048576
9293
1 GB | 1073741824
@@ -95,7 +96,7 @@ SELECT size, pg_size_bytes(size) FROM
9596
3000 TB | 3298534883328000
9697
1e6 MB | 1048576000000
9798
99 PB | 111464090777419776
98-
(10 rows)
99+
(11 rows)
99100

100101
-- case-insensitive units are supported
101102
SELECT size, pg_size_bytes(size) FROM
@@ -153,15 +154,15 @@ SELECT size, pg_size_bytes(size) FROM
153154
SELECT pg_size_bytes('1 AB');
154155
ERROR: invalid size: "1 AB"
155156
DETAIL: Invalid size unit: "AB".
156-
HINT: Valid units are "bytes", "kB", "MB", "GB", "TB", and "PB".
157+
HINT: Valid units are "bytes", "B", "kB", "MB", "GB", "TB", and "PB".
157158
SELECT pg_size_bytes('1 AB A');
158159
ERROR: invalid size: "1 AB A"
159160
DETAIL: Invalid size unit: "AB A".
160-
HINT: Valid units are "bytes", "kB", "MB", "GB", "TB", and "PB".
161+
HINT: Valid units are "bytes", "B", "kB", "MB", "GB", "TB", and "PB".
161162
SELECT pg_size_bytes('1 AB A ');
162163
ERROR: invalid size: "1 AB A "
163164
DETAIL: Invalid size unit: "AB A".
164-
HINT: Valid units are "bytes", "kB", "MB", "GB", "TB", and "PB".
165+
HINT: Valid units are "bytes", "B", "kB", "MB", "GB", "TB", and "PB".
165166
SELECT pg_size_bytes('9223372036854775807.9');
166167
ERROR: bigint out of range
167168
SELECT pg_size_bytes('1e100');
@@ -171,7 +172,7 @@ ERROR: value overflows numeric format
171172
SELECT pg_size_bytes('1 byte'); -- the singular "byte" is not supported
172173
ERROR: invalid size: "1 byte"
173174
DETAIL: Invalid size unit: "byte".
174-
HINT: Valid units are "bytes", "kB", "MB", "GB", "TB", and "PB".
175+
HINT: Valid units are "bytes", "B", "kB", "MB", "GB", "TB", and "PB".
175176
SELECT pg_size_bytes('');
176177
ERROR: invalid size: ""
177178
SELECT pg_size_bytes('kb');
@@ -189,6 +190,6 @@ ERROR: invalid size: ".+912"
189190
SELECT pg_size_bytes('+912+ kB');
190191
ERROR: invalid size: "+912+ kB"
191192
DETAIL: Invalid size unit: "+ kB".
192-
HINT: Valid units are "bytes", "kB", "MB", "GB", "TB", and "PB".
193+
HINT: Valid units are "bytes", "B", "kB", "MB", "GB", "TB", and "PB".
193194
SELECT pg_size_bytes('++123 kB');
194195
ERROR: invalid size: "++123 kB"

src/test/regress/sql/dbsize.sql

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM
2929

3030
-- pg_size_bytes() tests
3131
SELECT size, pg_size_bytes(size) FROM
32-
(VALUES ('1'), ('123bytes'), ('1kB'), ('1MB'), (' 1 GB'), ('1.5 GB '),
32+
(VALUES ('1'), ('123bytes'), ('256 B'), ('1kB'), ('1MB'), (' 1 GB'), ('1.5 GB '),
3333
('1TB'), ('3000 TB'), ('1e6 MB'), ('99 PB')) x(size);
3434

3535
-- case-insensitive units are supported

0 commit comments

Comments
 (0)