Skip to content

Commit 4a2d7ad

Browse files
committed
pg_size_pretty(numeric)
The output of the new pg_xlog_location_diff function is of type numeric, since it could theoretically overflow an int8 due to signedness; this provides a convenient way to format such values. Fujii Masao, with some beautification by me.
1 parent d4db16d commit 4a2d7ad

File tree

5 files changed

+150
-2
lines changed

5 files changed

+150
-2
lines changed

doc/src/sgml/func.sgml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14981,7 +14981,20 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
1498114981
<literal><function>pg_size_pretty(<type>bigint</type>)</function></literal>
1498214982
</entry>
1498314983
<entry><type>text</type></entry>
14984-
<entry>Converts a size in bytes into a human-readable format with size units</entry>
14984+
<entry>
14985+
Converts a size in bytes expressed as a 64-bit integer into a
14986+
human-readable format with size units
14987+
</entry>
14988+
</row>
14989+
<row>
14990+
<entry>
14991+
<literal><function>pg_size_pretty(<type>numeric</type>)</function></literal>
14992+
</entry>
14993+
<entry><type>text</type></entry>
14994+
<entry>
14995+
Converts a size in bytes expressed as a numeric value into a
14996+
human-readable format with size units
14997+
</entry>
1498514998
</row>
1498614999
<row>
1498715000
<entry>

src/backend/utils/adt/dbsize.c

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "storage/fd.h"
2525
#include "utils/acl.h"
2626
#include "utils/builtins.h"
27+
#include "utils/numeric.h"
2728
#include "utils/rel.h"
2829
#include "utils/relmapper.h"
2930
#include "utils/syscache.h"
@@ -550,6 +551,137 @@ pg_size_pretty(PG_FUNCTION_ARGS)
550551
PG_RETURN_TEXT_P(cstring_to_text(buf));
551552
}
552553

554+
static char *
555+
numeric_to_cstring(Numeric n)
556+
{
557+
Datum d = NumericGetDatum(n);
558+
return DatumGetCString(DirectFunctionCall1(numeric_out, d));
559+
}
560+
561+
static Numeric
562+
int64_to_numeric(int64 v)
563+
{
564+
Datum d = Int64GetDatum(v);
565+
return DatumGetNumeric(DirectFunctionCall1(int8_numeric, d));
566+
}
567+
568+
static bool
569+
numeric_is_less(Numeric a, Numeric b)
570+
{
571+
Datum da = NumericGetDatum(a);
572+
Datum db = NumericGetDatum(b);
573+
574+
return DatumGetBool(DirectFunctionCall2(numeric_lt, da, db));
575+
}
576+
577+
static Numeric
578+
numeric_plus_one_over_two(Numeric n)
579+
{
580+
Datum d = NumericGetDatum(n);
581+
Datum one;
582+
Datum two;
583+
Datum result;
584+
585+
one = DirectFunctionCall1(int8_numeric, Int64GetDatum(1));
586+
two = DirectFunctionCall1(int8_numeric, Int64GetDatum(2));
587+
result = DirectFunctionCall2(numeric_add, d, one);
588+
result = DirectFunctionCall2(numeric_div_trunc, result, two);
589+
return DatumGetNumeric(result);
590+
}
591+
592+
static Numeric
593+
numeric_shift_right(Numeric n, unsigned count)
594+
{
595+
Datum d = NumericGetDatum(n);
596+
Datum divisor_int64;
597+
Datum divisor_numeric;
598+
Datum result;
599+
600+
divisor_int64 = Int64GetDatum((int64) (1 << count));
601+
divisor_numeric = DirectFunctionCall1(int8_numeric, divisor_int64);
602+
result = DirectFunctionCall2(numeric_div_trunc, d, divisor_numeric);
603+
return DatumGetNumeric(result);
604+
}
605+
606+
Datum
607+
pg_size_pretty_numeric(PG_FUNCTION_ARGS)
608+
{
609+
Numeric size = PG_GETARG_NUMERIC(0);
610+
Numeric limit,
611+
limit2;
612+
char *buf,
613+
*result;
614+
615+
limit = int64_to_numeric(10 * 1024);
616+
limit2 = int64_to_numeric(10 * 1024 * 2 - 1);
617+
618+
if (numeric_is_less(size, limit))
619+
{
620+
buf = numeric_to_cstring(size);
621+
result = palloc(strlen(buf) + 7);
622+
strcpy(result, buf);
623+
strcat(result, " bytes");
624+
}
625+
else
626+
{
627+
/* keep one extra bit for rounding */
628+
/* size >>= 9 */
629+
size = numeric_shift_right(size, 9);
630+
631+
if (numeric_is_less(size, limit2))
632+
{
633+
/* size = (size + 1) / 2 */
634+
size = numeric_plus_one_over_two(size);
635+
buf = numeric_to_cstring(size);
636+
result = palloc(strlen(buf) + 4);
637+
strcpy(result, buf);
638+
strcat(result, " kB");
639+
}
640+
else
641+
{
642+
/* size >>= 10 */
643+
size = numeric_shift_right(size, 10);
644+
if (numeric_is_less(size, limit2))
645+
{
646+
/* size = (size + 1) / 2 */
647+
size = numeric_plus_one_over_two(size);
648+
buf = numeric_to_cstring(size);
649+
result = palloc(strlen(buf) + 4);
650+
strcpy(result, buf);
651+
strcat(result, " MB");
652+
}
653+
else
654+
{
655+
/* size >>= 10 */
656+
size = numeric_shift_right(size, 10);
657+
658+
if (numeric_is_less(size, limit2))
659+
{
660+
/* size = (size + 1) / 2 */
661+
size = numeric_plus_one_over_two(size);
662+
buf = numeric_to_cstring(size);
663+
result = palloc(strlen(buf) + 4);
664+
strcpy(result, buf);
665+
strcat(result, " GB");
666+
}
667+
else
668+
{
669+
/* size >>= 10 */
670+
size = numeric_shift_right(size, 10);
671+
/* size = (size + 1) / 2 */
672+
size = numeric_plus_one_over_two(size);
673+
buf = numeric_to_cstring(size);
674+
result = palloc(strlen(buf) + 4);
675+
strcpy(result, buf);
676+
strcat(result, " TB");
677+
}
678+
}
679+
}
680+
}
681+
682+
PG_RETURN_TEXT_P(cstring_to_text(result));
683+
}
684+
553685
/*
554686
* Get the filenode of a relation
555687
*

src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 201204131
56+
#define CATALOG_VERSION_NO 201204141
5757

5858
#endif

src/include/catalog/pg_proc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3410,6 +3410,8 @@ DATA(insert OID = 2286 ( pg_total_relation_size PGNSP PGUID 12 1 0 0 0 f f f f t
34103410
DESCR("total disk space usage for the specified table and associated indexes");
34113411
DATA(insert OID = 2288 ( pg_size_pretty PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 25 "20" _null_ _null_ _null_ _null_ pg_size_pretty _null_ _null_ _null_ ));
34123412
DESCR("convert a long int to a human readable text using size units");
3413+
DATA(insert OID = 3166 ( pg_size_pretty PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 25 "1700" _null_ _null_ _null_ _null_ pg_size_pretty_numeric _null_ _null_ _null_ ));
3414+
DESCR("convert a numeric to a human readable text using size units");
34133415
DATA(insert OID = 2997 ( pg_table_size PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 20 "2205" _null_ _null_ _null_ _null_ pg_table_size _null_ _null_ _null_ ));
34143416
DESCR("disk space usage for the specified table, including TOAST, free space and visibility map");
34153417
DATA(insert OID = 2998 ( pg_indexes_size PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 20 "2205" _null_ _null_ _null_ _null_ pg_indexes_size _null_ _null_ _null_ ));

src/include/utils/builtins.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,7 @@ extern Datum pg_database_size_name(PG_FUNCTION_ARGS);
453453
extern Datum pg_relation_size(PG_FUNCTION_ARGS);
454454
extern Datum pg_total_relation_size(PG_FUNCTION_ARGS);
455455
extern Datum pg_size_pretty(PG_FUNCTION_ARGS);
456+
extern Datum pg_size_pretty_numeric(PG_FUNCTION_ARGS);
456457
extern Datum pg_table_size(PG_FUNCTION_ARGS);
457458
extern Datum pg_indexes_size(PG_FUNCTION_ARGS);
458459
extern Datum pg_relation_filenode(PG_FUNCTION_ARGS);

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