Add support for unit "B" to pg_size_bytes()
authorPeter Eisentraut <peter@eisentraut.org>
Tue, 7 Mar 2023 19:26:29 +0000 (20:26 +0100)
committerPeter Eisentraut <peter@eisentraut.org>
Tue, 7 Mar 2023 19:31:16 +0000 (20:31 +0100)
This makes it consistent with the units support in GUC.

Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/0106914a-9eb5-22be-40d8-652cc88c827d%40enterprisedb.com

doc/src/sgml/func.sgml
src/backend/utils/adt/dbsize.c
src/test/regress/expected/dbsize.out
src/test/regress/sql/dbsize.sql

index 7c6dc6383d0f1f1bf2e195bc72896d675ed70827..9c6107f96043b284d37d2cee9a4e5fcbd6ca50ff 100644 (file)
@@ -27167,7 +27167,10 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
        </para>
        <para>
         Converts a size in human-readable format (as returned
-        by <function>pg_size_pretty</function>) into bytes.
+        by <function>pg_size_pretty</function>) into bytes.  Valid units are
+        <literal>bytes</literal>, <literal>B</literal>, <literal>kB</literal>,
+        <literal>MB</literal>, <literal>GB</literal>, <literal>TB</literal>,
+        and <literal>PB</literal>.
        </para></entry>
       </row>
 
index dbd404101f84615c2e18d5926347d0d4d05e071d..e5c0f1c45b67c040b262a57656d627f8c29c4e32 100644 (file)
@@ -46,7 +46,7 @@ struct size_pretty_unit
                                                                 * unit */
 };
 
-/* When adding units here also update the error message in pg_size_bytes */
+/* When adding units here also update the docs and the error message in pg_size_bytes */
 static const struct size_pretty_unit size_pretty_units[] = {
        {"bytes", 10 * 1024, false, 0},
        {"kB", 20 * 1024 - 1, true, 10},
@@ -57,6 +57,19 @@ static const struct size_pretty_unit size_pretty_units[] = {
        {NULL, 0, false, 0}
 };
 
+/* Additional unit aliases accepted by pg_size_bytes */
+struct size_bytes_unit_alias
+{
+       const char *alias;
+       int                     unit_index;             /* corresponding size_pretty_units element */
+};
+
+/* When adding units here also update the docs and the error message in pg_size_bytes */
+static const struct size_bytes_unit_alias size_bytes_aliases[] = {
+       {"B", 0},
+       {NULL}
+};
+
 /* Return physical size of directory contents, or 0 if dir doesn't exist */
 static int64
 db_dir_size(const char *path)
@@ -801,9 +814,19 @@ pg_size_bytes(PG_FUNCTION_ARGS)
                {
                        /* Parse the unit case-insensitively */
                        if (pg_strcasecmp(strptr, unit->name) == 0)
-                       {
-                               multiplier = ((int64) 1) << unit->unitbits;
                                break;
+               }
+
+               /* If not found, look in table of aliases */
+               if (unit->name == NULL)
+               {
+                       for (const struct size_bytes_unit_alias *a = size_bytes_aliases; a->alias != NULL; a++)
+                       {
+                               if (pg_strcasecmp(strptr, a->alias) == 0)
+                               {
+                                       unit = &size_pretty_units[a->unit_index];
+                                       break;
+                               }
                        }
                }
 
@@ -813,7 +836,9 @@ pg_size_bytes(PG_FUNCTION_ARGS)
                                        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                         errmsg("invalid size: \"%s\"", text_to_cstring(arg)),
                                         errdetail("Invalid size unit: \"%s\".", strptr),
-                                        errhint("Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", \"TB\", and \"PB\".")));
+                                        errhint("Valid units are \"bytes\", \"B\", \"kB\", \"MB\", \"GB\", \"TB\", and \"PB\".")));
+
+               multiplier = ((int64) 1) << unit->unitbits;
 
                if (multiplier > 1)
                {
index d8d6686b5f4be23193d6f1c6902ee49c33cd4bd7..f1121a87aa340d5a1eaca47487f2b554a3a29fe0 100644 (file)
@@ -81,12 +81,13 @@ SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM
 
 -- pg_size_bytes() tests
 SELECT size, pg_size_bytes(size) FROM
-    (VALUES ('1'), ('123bytes'), ('1kB'), ('1MB'), (' 1 GB'), ('1.5 GB '),
+    (VALUES ('1'), ('123bytes'), ('256 B'), ('1kB'), ('1MB'), (' 1 GB'), ('1.5 GB '),
             ('1TB'), ('3000 TB'), ('1e6 MB'), ('99 PB')) x(size);
    size   |   pg_size_bytes    
 ----------+--------------------
  1        |                  1
  123bytes |                123
+ 256 B    |                256
  1kB      |               1024
  1MB      |            1048576
   1 GB    |         1073741824
@@ -95,7 +96,7 @@ SELECT size, pg_size_bytes(size) FROM
  3000 TB  |   3298534883328000
  1e6 MB   |      1048576000000
  99 PB    | 111464090777419776
-(10 rows)
+(11 rows)
 
 -- case-insensitive units are supported
 SELECT size, pg_size_bytes(size) FROM
@@ -153,15 +154,15 @@ SELECT size, pg_size_bytes(size) FROM
 SELECT pg_size_bytes('1 AB');
 ERROR:  invalid size: "1 AB"
 DETAIL:  Invalid size unit: "AB".
-HINT:  Valid units are "bytes", "kB", "MB", "GB", "TB", and "PB".
+HINT:  Valid units are "bytes", "B", "kB", "MB", "GB", "TB", and "PB".
 SELECT pg_size_bytes('1 AB A');
 ERROR:  invalid size: "1 AB A"
 DETAIL:  Invalid size unit: "AB A".
-HINT:  Valid units are "bytes", "kB", "MB", "GB", "TB", and "PB".
+HINT:  Valid units are "bytes", "B", "kB", "MB", "GB", "TB", and "PB".
 SELECT pg_size_bytes('1 AB A    ');
 ERROR:  invalid size: "1 AB A    "
 DETAIL:  Invalid size unit: "AB A".
-HINT:  Valid units are "bytes", "kB", "MB", "GB", "TB", and "PB".
+HINT:  Valid units are "bytes", "B", "kB", "MB", "GB", "TB", and "PB".
 SELECT pg_size_bytes('9223372036854775807.9');
 ERROR:  bigint out of range
 SELECT pg_size_bytes('1e100');
@@ -171,7 +172,7 @@ ERROR:  value overflows numeric format
 SELECT pg_size_bytes('1 byte');  -- the singular "byte" is not supported
 ERROR:  invalid size: "1 byte"
 DETAIL:  Invalid size unit: "byte".
-HINT:  Valid units are "bytes", "kB", "MB", "GB", "TB", and "PB".
+HINT:  Valid units are "bytes", "B", "kB", "MB", "GB", "TB", and "PB".
 SELECT pg_size_bytes('');
 ERROR:  invalid size: ""
 SELECT pg_size_bytes('kb');
@@ -189,6 +190,6 @@ ERROR:  invalid size: ".+912"
 SELECT pg_size_bytes('+912+ kB');
 ERROR:  invalid size: "+912+ kB"
 DETAIL:  Invalid size unit: "+ kB".
-HINT:  Valid units are "bytes", "kB", "MB", "GB", "TB", and "PB".
+HINT:  Valid units are "bytes", "B", "kB", "MB", "GB", "TB", and "PB".
 SELECT pg_size_bytes('++123 kB');
 ERROR:  invalid size: "++123 kB"
index 7df865271b681d424d991c7c14650e2c33a31dd2..b34cf33385ebda61a4fdf4b6fee4b285f241eb31 100644 (file)
@@ -29,7 +29,7 @@ SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM
 
 -- pg_size_bytes() tests
 SELECT size, pg_size_bytes(size) FROM
-    (VALUES ('1'), ('123bytes'), ('1kB'), ('1MB'), (' 1 GB'), ('1.5 GB '),
+    (VALUES ('1'), ('123bytes'), ('256 B'), ('1kB'), ('1MB'), (' 1 GB'), ('1.5 GB '),
             ('1TB'), ('3000 TB'), ('1e6 MB'), ('99 PB')) x(size);
 
 -- case-insensitive units are supported