PostgreSQL Source Code  git master
dbsize.c File Reference
#include "postgres.h"
#include <sys/stat.h>
#include "access/heapam.h"
#include "access/htup_details.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_tablespace.h"
#include "commands/dbcommands.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/numeric.h"
#include "utils/rel.h"
#include "utils/relfilenodemap.h"
#include "utils/relmapper.h"
#include "utils/syscache.h"
Include dependency graph for dbsize.c:

Go to the source code of this file.

Macros

#define half_rounded(x)   (((x) + ((x) < 0 ? 0 : 1)) / 2)
 

Functions

static int64 db_dir_size (const char *path)
 
static int64 calculate_database_size (Oid dbOid)
 
Datum pg_database_size_oid (PG_FUNCTION_ARGS)
 
Datum pg_database_size_name (PG_FUNCTION_ARGS)
 
static int64 calculate_tablespace_size (Oid tblspcOid)
 
Datum pg_tablespace_size_oid (PG_FUNCTION_ARGS)
 
Datum pg_tablespace_size_name (PG_FUNCTION_ARGS)
 
static int64 calculate_relation_size (RelFileNode *rfn, BackendId backend, ForkNumber forknum)
 
Datum pg_relation_size (PG_FUNCTION_ARGS)
 
static int64 calculate_toast_table_size (Oid toastrelid)
 
static int64 calculate_table_size (Relation rel)
 
static int64 calculate_indexes_size (Relation rel)
 
Datum pg_table_size (PG_FUNCTION_ARGS)
 
Datum pg_indexes_size (PG_FUNCTION_ARGS)
 
static int64 calculate_total_relation_size (Relation rel)
 
Datum pg_total_relation_size (PG_FUNCTION_ARGS)
 
Datum pg_size_pretty (PG_FUNCTION_ARGS)
 
static char * numeric_to_cstring (Numeric n)
 
static Numeric int64_to_numeric (int64 v)
 
static bool numeric_is_less (Numeric a, Numeric b)
 
static Numeric numeric_absolute (Numeric n)
 
static Numeric numeric_half_rounded (Numeric n)
 
static Numeric numeric_shift_right (Numeric n, unsigned count)
 
Datum pg_size_pretty_numeric (PG_FUNCTION_ARGS)
 
Datum pg_size_bytes (PG_FUNCTION_ARGS)
 
Datum pg_relation_filenode (PG_FUNCTION_ARGS)
 
Datum pg_filenode_relation (PG_FUNCTION_ARGS)
 
Datum pg_relation_filepath (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ half_rounded

#define half_rounded (   x)    (((x) + ((x) < 0 ? 0 : 1)) / 2)

Definition at line 35 of file dbsize.c.

Referenced by pg_size_pretty().

Function Documentation

◆ calculate_database_size()

static int64 calculate_database_size ( Oid  dbOid)
static

Definition at line 83 of file dbsize.c.

References ACL_CONNECT, ACL_KIND_DATABASE, aclcheck_error(), ACLCHECK_OK, AllocateDir(), CHECK_FOR_INTERRUPTS, dirent::d_name, db_dir_size(), DEFAULT_ROLE_READ_ALL_STATS, FreeDir(), get_database_name(), GetUserId(), is_member_of_role(), MAXPGPATH, pg_database_aclcheck(), ReadDir(), snprintf(), TABLESPACE_VERSION_DIRECTORY, and totalsize.

Referenced by pg_database_size_name(), and pg_database_size_oid().

84 {
85  int64 totalsize;
86  DIR *dirdesc;
87  struct dirent *direntry;
88  char dirpath[MAXPGPATH];
89  char pathname[MAXPGPATH + 12 + sizeof(TABLESPACE_VERSION_DIRECTORY)];
90  AclResult aclresult;
91 
92  /*
93  * User must have connect privilege for target database or be a member of
94  * pg_read_all_stats
95  */
96  aclresult = pg_database_aclcheck(dbOid, GetUserId(), ACL_CONNECT);
97  if (aclresult != ACLCHECK_OK &&
99  {
101  get_database_name(dbOid));
102  }
103 
104  /* Shared storage in pg_global is not counted */
105 
106  /* Include pg_default storage */
107  snprintf(pathname, sizeof(pathname), "base/%u", dbOid);
108  totalsize = db_dir_size(pathname);
109 
110  /* Scan the non-default tablespaces */
111  snprintf(dirpath, MAXPGPATH, "pg_tblspc");
112  dirdesc = AllocateDir(dirpath);
113 
114  while ((direntry = ReadDir(dirdesc, dirpath)) != NULL)
115  {
117 
118  if (strcmp(direntry->d_name, ".") == 0 ||
119  strcmp(direntry->d_name, "..") == 0)
120  continue;
121 
122  snprintf(pathname, sizeof(pathname), "pg_tblspc/%s/%s/%u",
123  direntry->d_name, TABLESPACE_VERSION_DIRECTORY, dbOid);
124  totalsize += db_dir_size(pathname);
125  }
126 
127  FreeDir(dirdesc);
128 
129  return totalsize;
130 }
Oid GetUserId(void)
Definition: miscinit.c:284
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3457
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2596
static uint64 totalsize
#define ACL_CONNECT
Definition: parsenodes.h:84
AclResult
Definition: acl.h:178
#define DEFAULT_ROLE_READ_ALL_STATS
Definition: pg_authid.h:108
bool is_member_of_role(Oid member, Oid role)
Definition: acl.c:4857
AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4492
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2662
#define TABLESPACE_VERSION_DIRECTORY
Definition: catalog.h:26
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98
char d_name[MAX_PATH]
Definition: dirent.h:14
int FreeDir(DIR *dir)
Definition: fd.c:2714
static int64 db_dir_size(const char *path)
Definition: dbsize.c:39

◆ calculate_indexes_size()

static int64 calculate_indexes_size ( Relation  rel)
static

Definition at line 416 of file dbsize.c.

References AccessShareLock, calculate_relation_size(), lfirst_oid, list_free(), MAX_FORKNUM, RelationData::rd_backend, RelationData::rd_node, RelationData::rd_rel, relation_close(), relation_open(), and RelationGetIndexList().

Referenced by calculate_total_relation_size(), and pg_indexes_size().

417 {
418  int64 size = 0;
419 
420  /*
421  * Aggregate all indexes on the given relation
422  */
423  if (rel->rd_rel->relhasindex)
424  {
425  List *index_oids = RelationGetIndexList(rel);
426  ListCell *cell;
427 
428  foreach(cell, index_oids)
429  {
430  Oid idxOid = lfirst_oid(cell);
431  Relation idxRel;
432  ForkNumber forkNum;
433 
434  idxRel = relation_open(idxOid, AccessShareLock);
435 
436  for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
437  size += calculate_relation_size(&(idxRel->rd_node),
438  idxRel->rd_backend,
439  forkNum);
440 
442  }
443 
444  list_free(index_oids);
445  }
446 
447  return size;
448 }
static int64 calculate_relation_size(RelFileNode *rfn, BackendId backend, ForkNumber forknum)
Definition: dbsize.c:273
#define AccessShareLock
Definition: lockdefs.h:36
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1266
Form_pg_class rd_rel
Definition: rel.h:114
unsigned int Oid
Definition: postgres_ext.h:31
ForkNumber
Definition: relpath.h:24
RelFileNode rd_node
Definition: rel.h:85
BackendId rd_backend
Definition: rel.h:89
#define MAX_FORKNUM
Definition: relpath.h:39
List * RelationGetIndexList(Relation relation)
Definition: relcache.c:4360
void list_free(List *list)
Definition: list.c:1133
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1120
Definition: pg_list.h:45
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ calculate_relation_size()

static int64 calculate_relation_size ( RelFileNode rfn,
BackendId  backend,
ForkNumber  forknum 
)
static

Definition at line 273 of file dbsize.c.

References CHECK_FOR_INTERRUPTS, ereport, errcode_for_file_access(), errmsg(), ERROR, MAXPGPATH, relpathbackend, snprintf(), stat, and totalsize.

Referenced by calculate_indexes_size(), calculate_table_size(), calculate_toast_table_size(), and pg_relation_size().

274 {
275  int64 totalsize = 0;
276  char *relationpath;
277  char pathname[MAXPGPATH];
278  unsigned int segcount = 0;
279 
280  relationpath = relpathbackend(*rfn, backend, forknum);
281 
282  for (segcount = 0;; segcount++)
283  {
284  struct stat fst;
285 
287 
288  if (segcount == 0)
289  snprintf(pathname, MAXPGPATH, "%s",
290  relationpath);
291  else
292  snprintf(pathname, MAXPGPATH, "%s.%u",
293  relationpath, segcount);
294 
295  if (stat(pathname, &fst) < 0)
296  {
297  if (errno == ENOENT)
298  break;
299  else
300  ereport(ERROR,
302  errmsg("could not stat file \"%s\": %m", pathname)));
303  }
304  totalsize += fst.st_size;
305  }
306 
307  return totalsize;
308 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define ERROR
Definition: elog.h:43
#define MAXPGPATH
int errcode_for_file_access(void)
Definition: elog.c:598
static uint64 totalsize
#define ereport(elevel, rest)
Definition: elog.h:122
#define stat(a, b)
Definition: win32_port.h:266
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98
#define relpathbackend(rnode, backend, forknum)
Definition: relpath.h:62

◆ calculate_table_size()

static int64 calculate_table_size ( Relation  rel)
static

Definition at line 389 of file dbsize.c.

References calculate_relation_size(), calculate_toast_table_size(), MAX_FORKNUM, OidIsValid, RelationData::rd_backend, RelationData::rd_node, and RelationData::rd_rel.

Referenced by calculate_total_relation_size(), and pg_table_size().

390 {
391  int64 size = 0;
392  ForkNumber forkNum;
393 
394  /*
395  * heap size, including FSM and VM
396  */
397  for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
398  size += calculate_relation_size(&(rel->rd_node), rel->rd_backend,
399  forkNum);
400 
401  /*
402  * Size of toast relation
403  */
404  if (OidIsValid(rel->rd_rel->reltoastrelid))
405  size += calculate_toast_table_size(rel->rd_rel->reltoastrelid);
406 
407  return size;
408 }
static int64 calculate_relation_size(RelFileNode *rfn, BackendId backend, ForkNumber forknum)
Definition: dbsize.c:273
Form_pg_class rd_rel
Definition: rel.h:114
#define OidIsValid(objectId)
Definition: c.h:576
ForkNumber
Definition: relpath.h:24
static int64 calculate_toast_table_size(Oid toastrelid)
Definition: dbsize.c:343
RelFileNode rd_node
Definition: rel.h:85
BackendId rd_backend
Definition: rel.h:89
#define MAX_FORKNUM
Definition: relpath.h:39

◆ calculate_tablespace_size()

static int64 calculate_tablespace_size ( Oid  tblspcOid)
static

Definition at line 167 of file dbsize.c.

References ACL_CREATE, ACL_KIND_TABLESPACE, aclcheck_error(), ACLCHECK_OK, AllocateDir(), CHECK_FOR_INTERRUPTS, dirent::d_name, db_dir_size(), DEFAULT_ROLE_READ_ALL_STATS, DEFAULTTABLESPACE_OID, ereport, errcode_for_file_access(), errmsg(), ERROR, FreeDir(), get_tablespace_name(), GetUserId(), GLOBALTABLESPACE_OID, is_member_of_role(), MAXPGPATH, MyDatabaseTableSpace, pg_tablespace_aclcheck(), ReadDir(), S_ISDIR, snprintf(), stat, TABLESPACE_VERSION_DIRECTORY, and totalsize.

Referenced by pg_tablespace_size_name(), and pg_tablespace_size_oid().

168 {
169  char tblspcPath[MAXPGPATH];
170  char pathname[MAXPGPATH * 2];
171  int64 totalsize = 0;
172  DIR *dirdesc;
173  struct dirent *direntry;
174  AclResult aclresult;
175 
176  /*
177  * User must be a member of pg_read_all_stats or have CREATE privilege for
178  * target tablespace, either explicitly granted or implicitly because it
179  * is default for current database.
180  */
181  if (tblspcOid != MyDatabaseTableSpace &&
183  {
184  aclresult = pg_tablespace_aclcheck(tblspcOid, GetUserId(), ACL_CREATE);
185  if (aclresult != ACLCHECK_OK)
187  get_tablespace_name(tblspcOid));
188  }
189 
190  if (tblspcOid == DEFAULTTABLESPACE_OID)
191  snprintf(tblspcPath, MAXPGPATH, "base");
192  else if (tblspcOid == GLOBALTABLESPACE_OID)
193  snprintf(tblspcPath, MAXPGPATH, "global");
194  else
195  snprintf(tblspcPath, MAXPGPATH, "pg_tblspc/%u/%s", tblspcOid,
197 
198  dirdesc = AllocateDir(tblspcPath);
199 
200  if (!dirdesc)
201  return -1;
202 
203  while ((direntry = ReadDir(dirdesc, tblspcPath)) != NULL)
204  {
205  struct stat fst;
206 
208 
209  if (strcmp(direntry->d_name, ".") == 0 ||
210  strcmp(direntry->d_name, "..") == 0)
211  continue;
212 
213  snprintf(pathname, sizeof(pathname), "%s/%s", tblspcPath, direntry->d_name);
214 
215  if (stat(pathname, &fst) < 0)
216  {
217  if (errno == ENOENT)
218  continue;
219  else
220  ereport(ERROR,
222  errmsg("could not stat file \"%s\": %m", pathname)));
223  }
224 
225  if (S_ISDIR(fst.st_mode))
226  totalsize += db_dir_size(pathname);
227 
228  totalsize += fst.st_size;
229  }
230 
231  FreeDir(dirdesc);
232 
233  return totalsize;
234 }
AclResult pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4554
Oid GetUserId(void)
Definition: miscinit.c:284
#define GLOBALTABLESPACE_OID
Definition: pg_tablespace.h:64
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
Definition: dirent.h:9
Oid MyDatabaseTableSpace
Definition: globals.c:79
Definition: dirent.c:25
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:82
#define MAXPGPATH
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3457
#define DEFAULTTABLESPACE_OID
Definition: pg_tablespace.h:63
int errcode_for_file_access(void)
Definition: elog.c:598
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2596
static uint64 totalsize
#define ereport(elevel, rest)
Definition: elog.h:122
#define stat(a, b)
Definition: win32_port.h:266
AclResult
Definition: acl.h:178
#define DEFAULT_ROLE_READ_ALL_STATS
Definition: pg_authid.h:108
bool is_member_of_role(Oid member, Oid role)
Definition: acl.c:4857
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2662
#define TABLESPACE_VERSION_DIRECTORY
Definition: catalog.h:26
#define S_ISDIR(m)
Definition: win32_port.h:307
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * get_tablespace_name(Oid spc_oid)
Definition: tablespace.c:1426
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98
char d_name[MAX_PATH]
Definition: dirent.h:14
int FreeDir(DIR *dir)
Definition: fd.c:2714
static int64 db_dir_size(const char *path)
Definition: dbsize.c:39

◆ calculate_toast_table_size()

static int64 calculate_toast_table_size ( Oid  toastrelid)
static

Definition at line 343 of file dbsize.c.

References AccessShareLock, calculate_relation_size(), lfirst_oid, list_free(), MAX_FORKNUM, RelationData::rd_backend, RelationData::rd_node, relation_close(), relation_open(), and RelationGetIndexList().

Referenced by calculate_table_size().

344 {
345  int64 size = 0;
346  Relation toastRel;
347  ForkNumber forkNum;
348  ListCell *lc;
349  List *indexlist;
350 
351  toastRel = relation_open(toastrelid, AccessShareLock);
352 
353  /* toast heap size, including FSM and VM size */
354  for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
355  size += calculate_relation_size(&(toastRel->rd_node),
356  toastRel->rd_backend, forkNum);
357 
358  /* toast index size, including FSM and VM size */
359  indexlist = RelationGetIndexList(toastRel);
360 
361  /* Size is calculated using all the indexes available */
362  foreach(lc, indexlist)
363  {
364  Relation toastIdxRel;
365 
366  toastIdxRel = relation_open(lfirst_oid(lc),
368  for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
369  size += calculate_relation_size(&(toastIdxRel->rd_node),
370  toastIdxRel->rd_backend, forkNum);
371 
372  relation_close(toastIdxRel, AccessShareLock);
373  }
374  list_free(indexlist);
375  relation_close(toastRel, AccessShareLock);
376 
377  return size;
378 }
static int64 calculate_relation_size(RelFileNode *rfn, BackendId backend, ForkNumber forknum)
Definition: dbsize.c:273
#define AccessShareLock
Definition: lockdefs.h:36
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1266
ForkNumber
Definition: relpath.h:24
RelFileNode rd_node
Definition: rel.h:85
BackendId rd_backend
Definition: rel.h:89
#define MAX_FORKNUM
Definition: relpath.h:39
List * RelationGetIndexList(Relation relation)
Definition: relcache.c:4360
void list_free(List *list)
Definition: list.c:1133
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1120
Definition: pg_list.h:45
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ calculate_total_relation_size()

static int64 calculate_total_relation_size ( Relation  rel)
static

Definition at line 493 of file dbsize.c.

References calculate_indexes_size(), and calculate_table_size().

Referenced by pg_total_relation_size().

494 {
495  int64 size;
496 
497  /*
498  * Aggregate the table size, this includes size of the heap, toast and
499  * toast index with free space and visibility map
500  */
501  size = calculate_table_size(rel);
502 
503  /*
504  * Add size of all attached indexes as well
505  */
506  size += calculate_indexes_size(rel);
507 
508  return size;
509 }
static int64 calculate_table_size(Relation rel)
Definition: dbsize.c:389
static int64 calculate_indexes_size(Relation rel)
Definition: dbsize.c:416

◆ db_dir_size()

static int64 db_dir_size ( const char *  path)
static

Definition at line 39 of file dbsize.c.

References AllocateDir(), CHECK_FOR_INTERRUPTS, dirent::d_name, ereport, errcode_for_file_access(), errmsg(), ERROR, filename, FreeDir(), MAXPGPATH, ReadDir(), snprintf(), and stat.

Referenced by calculate_database_size(), and calculate_tablespace_size().

40 {
41  int64 dirsize = 0;
42  struct dirent *direntry;
43  DIR *dirdesc;
44  char filename[MAXPGPATH * 2];
45 
46  dirdesc = AllocateDir(path);
47 
48  if (!dirdesc)
49  return 0;
50 
51  while ((direntry = ReadDir(dirdesc, path)) != NULL)
52  {
53  struct stat fst;
54 
56 
57  if (strcmp(direntry->d_name, ".") == 0 ||
58  strcmp(direntry->d_name, "..") == 0)
59  continue;
60 
61  snprintf(filename, sizeof(filename), "%s/%s", path, direntry->d_name);
62 
63  if (stat(filename, &fst) < 0)
64  {
65  if (errno == ENOENT)
66  continue;
67  else
68  ereport(ERROR,
70  errmsg("could not stat file \"%s\": %m", filename)));
71  }
72  dirsize += fst.st_size;
73  }
74 
75  FreeDir(dirdesc);
76  return dirsize;
77 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
Definition: dirent.h:9
Definition: dirent.c:25
#define ERROR
Definition: elog.h:43
#define MAXPGPATH
int errcode_for_file_access(void)
Definition: elog.c:598
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2596
#define ereport(elevel, rest)
Definition: elog.h:122
#define stat(a, b)
Definition: win32_port.h:266
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2662
static char * filename
Definition: pg_dumpall.c:90
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98
char d_name[MAX_PATH]
Definition: dirent.h:14
int FreeDir(DIR *dir)
Definition: fd.c:2714

◆ int64_to_numeric()

static Numeric int64_to_numeric ( int64  v)
static

Definition at line 583 of file dbsize.c.

References DatumGetNumeric, DirectFunctionCall1, Int64GetDatum(), and int8_numeric().

Referenced by pg_size_pretty_numeric().

584 {
585  Datum d = Int64GetDatum(v);
586 
588 }
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:585
Datum int8_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:3039
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1786
uintptr_t Datum
Definition: postgres.h:372
#define DatumGetNumeric(X)
Definition: numeric.h:49

◆ numeric_absolute()

static Numeric numeric_absolute ( Numeric  n)
static

Definition at line 600 of file dbsize.c.

References DatumGetNumeric, DirectFunctionCall1, numeric_abs(), and NumericGetDatum.

Referenced by pg_size_pretty_numeric().

601 {
602  Datum d = NumericGetDatum(n);
603  Datum result;
604 
605  result = DirectFunctionCall1(numeric_abs, d);
606  return DatumGetNumeric(result);
607 }
#define NumericGetDatum(X)
Definition: numeric.h:51
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:585
Datum numeric_abs(PG_FUNCTION_ARGS)
Definition: numeric.c:1090
uintptr_t Datum
Definition: postgres.h:372
#define DatumGetNumeric(X)
Definition: numeric.h:49

◆ numeric_half_rounded()

static Numeric numeric_half_rounded ( Numeric  n)
static

Definition at line 610 of file dbsize.c.

References DatumGetBool, DatumGetNumeric, DirectFunctionCall1, DirectFunctionCall2, Int64GetDatum(), int8_numeric(), numeric_add(), numeric_div_trunc(), numeric_ge(), numeric_sub(), and NumericGetDatum.

Referenced by pg_size_pretty_numeric().

611 {
612  Datum d = NumericGetDatum(n);
613  Datum zero;
614  Datum one;
615  Datum two;
616  Datum result;
617 
621 
623  d = DirectFunctionCall2(numeric_add, d, one);
624  else
625  d = DirectFunctionCall2(numeric_sub, d, one);
626 
627  result = DirectFunctionCall2(numeric_div_trunc, d, two);
628  return DatumGetNumeric(result);
629 }
#define NumericGetDatum(X)
Definition: numeric.h:51
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:585
Datum int8_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:3039
Datum numeric_div_trunc(PG_FUNCTION_ARGS)
Definition: numeric.c:2485
#define DatumGetBool(X)
Definition: postgres.h:399
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1786
uintptr_t Datum
Definition: postgres.h:372
Datum numeric_sub(PG_FUNCTION_ARGS)
Definition: numeric.c:2357
#define DatumGetNumeric(X)
Definition: numeric.h:49
Datum numeric_ge(PG_FUNCTION_ARGS)
Definition: numeric.c:2092
Datum numeric_add(PG_FUNCTION_ARGS)
Definition: numeric.c:2319
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:587

◆ numeric_is_less()

static bool numeric_is_less ( Numeric  a,
Numeric  b 
)
static

Definition at line 591 of file dbsize.c.

References DatumGetBool, DirectFunctionCall2, numeric_lt(), and NumericGetDatum.

Referenced by pg_size_pretty_numeric().

592 {
593  Datum da = NumericGetDatum(a);
594  Datum db = NumericGetDatum(b);
595 
597 }
#define NumericGetDatum(X)
Definition: numeric.h:51
#define DatumGetBool(X)
Definition: postgres.h:399
uintptr_t Datum
Definition: postgres.h:372
Datum numeric_lt(PG_FUNCTION_ARGS)
Definition: numeric.c:2107
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:587

◆ numeric_shift_right()

static Numeric numeric_shift_right ( Numeric  n,
unsigned  count 
)
static

Definition at line 632 of file dbsize.c.

References DatumGetNumeric, DirectFunctionCall1, DirectFunctionCall2, Int64GetDatum(), int8_numeric(), numeric_div_trunc(), and NumericGetDatum.

Referenced by pg_size_pretty_numeric().

633 {
634  Datum d = NumericGetDatum(n);
635  Datum divisor_int64;
636  Datum divisor_numeric;
637  Datum result;
638 
639  divisor_int64 = Int64GetDatum((int64) (1 << count));
640  divisor_numeric = DirectFunctionCall1(int8_numeric, divisor_int64);
641  result = DirectFunctionCall2(numeric_div_trunc, d, divisor_numeric);
642  return DatumGetNumeric(result);
643 }
#define NumericGetDatum(X)
Definition: numeric.h:51
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:585
Datum int8_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:3039
Datum numeric_div_trunc(PG_FUNCTION_ARGS)
Definition: numeric.c:2485
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1786
uintptr_t Datum
Definition: postgres.h:372
#define DatumGetNumeric(X)
Definition: numeric.h:49
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:587

◆ numeric_to_cstring()

static char* numeric_to_cstring ( Numeric  n)
static

Definition at line 575 of file dbsize.c.

References DatumGetCString, DirectFunctionCall1, numeric_out(), and NumericGetDatum.

Referenced by pg_size_pretty_numeric().

576 {
577  Datum d = NumericGetDatum(n);
578 
580 }
#define NumericGetDatum(X)
Definition: numeric.h:51
Datum numeric_out(PG_FUNCTION_ARGS)
Definition: numeric.c:652
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:585
#define DatumGetCString(X)
Definition: postgres.h:572
uintptr_t Datum
Definition: postgres.h:372

◆ pg_database_size_name()

Datum pg_database_size_name ( PG_FUNCTION_ARGS  )

Definition at line 147 of file dbsize.c.

References calculate_database_size(), dbName, get_database_oid(), NameStr, PG_GETARG_NAME, PG_RETURN_INT64, and PG_RETURN_NULL.

148 {
150  Oid dbOid = get_database_oid(NameStr(*dbName), false);
151  int64 size;
152 
153  size = calculate_database_size(dbOid);
154 
155  if (size == 0)
156  PG_RETURN_NULL();
157 
158  PG_RETURN_INT64(size);
159 }
#define PG_RETURN_INT64(x)
Definition: fmgr.h:327
unsigned int Oid
Definition: postgres_ext.h:31
Definition: c.h:541
Oid get_database_oid(const char *dbname, bool missing_ok)
Definition: dbcommands.c:2009
static int64 calculate_database_size(Oid dbOid)
Definition: dbsize.c:83
char * dbName
Definition: pgbench.c:180
#define NameStr(name)
Definition: c.h:547
#define PG_RETURN_NULL()
Definition: fmgr.h:305
#define PG_GETARG_NAME(n)
Definition: fmgr.h:243

◆ pg_database_size_oid()

Datum pg_database_size_oid ( PG_FUNCTION_ARGS  )

Definition at line 133 of file dbsize.c.

References calculate_database_size(), PG_GETARG_OID, PG_RETURN_INT64, and PG_RETURN_NULL.

134 {
135  Oid dbOid = PG_GETARG_OID(0);
136  int64 size;
137 
138  size = calculate_database_size(dbOid);
139 
140  if (size == 0)
141  PG_RETURN_NULL();
142 
143  PG_RETURN_INT64(size);
144 }
#define PG_RETURN_INT64(x)
Definition: fmgr.h:327
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
static int64 calculate_database_size(Oid dbOid)
Definition: dbsize.c:83
#define PG_RETURN_NULL()
Definition: fmgr.h:305

◆ pg_filenode_relation()

Datum pg_filenode_relation ( PG_FUNCTION_ARGS  )

Definition at line 920 of file dbsize.c.

References InvalidOid, OidIsValid, PG_GETARG_OID, PG_RETURN_NULL, PG_RETURN_OID, and RelidByRelfilenode().

921 {
922  Oid reltablespace = PG_GETARG_OID(0);
923  Oid relfilenode = PG_GETARG_OID(1);
924  Oid heaprel = InvalidOid;
925 
926  heaprel = RelidByRelfilenode(reltablespace, relfilenode);
927 
928  if (!OidIsValid(heaprel))
929  PG_RETURN_NULL();
930  else
931  PG_RETURN_OID(heaprel);
932 }
Oid RelidByRelfilenode(Oid reltablespace, Oid relfilenode)
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:576
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_RETURN_OID(x)
Definition: fmgr.h:320
#define PG_RETURN_NULL()
Definition: fmgr.h:305

◆ pg_indexes_size()

Datum pg_indexes_size ( PG_FUNCTION_ARGS  )

Definition at line 470 of file dbsize.c.

References AccessShareLock, calculate_indexes_size(), PG_GETARG_OID, PG_RETURN_INT64, PG_RETURN_NULL, relation_close(), and try_relation_open().

471 {
472  Oid relOid = PG_GETARG_OID(0);
473  Relation rel;
474  int64 size;
475 
476  rel = try_relation_open(relOid, AccessShareLock);
477 
478  if (rel == NULL)
479  PG_RETURN_NULL();
480 
481  size = calculate_indexes_size(rel);
482 
484 
485  PG_RETURN_INT64(size);
486 }
Relation try_relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1153
#define PG_RETURN_INT64(x)
Definition: fmgr.h:327
#define AccessShareLock
Definition: lockdefs.h:36
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1266
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_NULL()
Definition: fmgr.h:305
static int64 calculate_indexes_size(Relation rel)
Definition: dbsize.c:416

◆ pg_relation_filenode()

Datum pg_relation_filenode ( PG_FUNCTION_ARGS  )

Definition at line 865 of file dbsize.c.

References GETSTRUCT, HeapTupleIsValid, InvalidOid, ObjectIdGetDatum, OidIsValid, PG_GETARG_OID, PG_RETURN_NULL, PG_RETURN_OID, RelationMapOidToFilenode(), ReleaseSysCache(), RELKIND_INDEX, RELKIND_MATVIEW, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_TOASTVALUE, RELOID, and SearchSysCache1().

866 {
867  Oid relid = PG_GETARG_OID(0);
868  Oid result;
869  HeapTuple tuple;
870  Form_pg_class relform;
871 
872  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
873  if (!HeapTupleIsValid(tuple))
874  PG_RETURN_NULL();
875  relform = (Form_pg_class) GETSTRUCT(tuple);
876 
877  switch (relform->relkind)
878  {
879  case RELKIND_RELATION:
880  case RELKIND_MATVIEW:
881  case RELKIND_INDEX:
882  case RELKIND_SEQUENCE:
883  case RELKIND_TOASTVALUE:
884  /* okay, these have storage */
885  if (relform->relfilenode)
886  result = relform->relfilenode;
887  else /* Consult the relation mapper */
888  result = RelationMapOidToFilenode(relid,
889  relform->relisshared);
890  break;
891 
892  default:
893  /* no storage, return NULL */
894  result = InvalidOid;
895  break;
896  }
897 
898  ReleaseSysCache(tuple);
899 
900  if (!OidIsValid(result))
901  PG_RETURN_NULL();
902 
903  PG_RETURN_OID(result);
904 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define RELKIND_MATVIEW
Definition: pg_class.h:165
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:576
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
#define RELKIND_TOASTVALUE
Definition: pg_class.h:163
Oid RelationMapOidToFilenode(Oid relationId, bool shared)
Definition: relmapper.c:146
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define RELKIND_INDEX
Definition: pg_class.h:161
#define RELKIND_RELATION
Definition: pg_class.h:160
#define RELKIND_SEQUENCE
Definition: pg_class.h:162
#define PG_RETURN_OID(x)
Definition: fmgr.h:320
#define PG_RETURN_NULL()
Definition: fmgr.h:305

◆ pg_relation_filepath()

Datum pg_relation_filepath ( PG_FUNCTION_ARGS  )

Definition at line 940 of file dbsize.c.

References Assert, BackendIdForTempRelations, cstring_to_text(), RelFileNode::dbNode, elog, ERROR, GETSTRUCT, GetTempNamespaceBackendId(), GLOBALTABLESPACE_OID, HeapTupleIsValid, InvalidBackendId, InvalidOid, isTempOrTempToastNamespace(), MAIN_FORKNUM, MyDatabaseId, MyDatabaseTableSpace, ObjectIdGetDatum, OidIsValid, PG_GETARG_OID, PG_RETURN_NULL, PG_RETURN_TEXT_P, RelationMapOidToFilenode(), ReleaseSysCache(), RELKIND_INDEX, RELKIND_MATVIEW, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_TOASTVALUE, RelFileNode::relNode, RELOID, relpathbackend, RELPERSISTENCE_PERMANENT, RELPERSISTENCE_TEMP, RELPERSISTENCE_UNLOGGED, SearchSysCache1(), and RelFileNode::spcNode.

941 {
942  Oid relid = PG_GETARG_OID(0);
943  HeapTuple tuple;
944  Form_pg_class relform;
945  RelFileNode rnode;
946  BackendId backend;
947  char *path;
948 
949  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
950  if (!HeapTupleIsValid(tuple))
951  PG_RETURN_NULL();
952  relform = (Form_pg_class) GETSTRUCT(tuple);
953 
954  switch (relform->relkind)
955  {
956  case RELKIND_RELATION:
957  case RELKIND_MATVIEW:
958  case RELKIND_INDEX:
959  case RELKIND_SEQUENCE:
960  case RELKIND_TOASTVALUE:
961  /* okay, these have storage */
962 
963  /* This logic should match RelationInitPhysicalAddr */
964  if (relform->reltablespace)
965  rnode.spcNode = relform->reltablespace;
966  else
968  if (rnode.spcNode == GLOBALTABLESPACE_OID)
969  rnode.dbNode = InvalidOid;
970  else
971  rnode.dbNode = MyDatabaseId;
972  if (relform->relfilenode)
973  rnode.relNode = relform->relfilenode;
974  else /* Consult the relation mapper */
975  rnode.relNode = RelationMapOidToFilenode(relid,
976  relform->relisshared);
977  break;
978 
979  default:
980  /* no storage, return NULL */
981  rnode.relNode = InvalidOid;
982  /* some compilers generate warnings without these next two lines */
983  rnode.dbNode = InvalidOid;
984  rnode.spcNode = InvalidOid;
985  break;
986  }
987 
988  if (!OidIsValid(rnode.relNode))
989  {
990  ReleaseSysCache(tuple);
991  PG_RETURN_NULL();
992  }
993 
994  /* Determine owning backend. */
995  switch (relform->relpersistence)
996  {
999  backend = InvalidBackendId;
1000  break;
1001  case RELPERSISTENCE_TEMP:
1002  if (isTempOrTempToastNamespace(relform->relnamespace))
1003  backend = BackendIdForTempRelations();
1004  else
1005  {
1006  /* Do it the hard way. */
1007  backend = GetTempNamespaceBackendId(relform->relnamespace);
1008  Assert(backend != InvalidBackendId);
1009  }
1010  break;
1011  default:
1012  elog(ERROR, "invalid relpersistence: %c", relform->relpersistence);
1013  backend = InvalidBackendId; /* placate compiler */
1014  break;
1015  }
1016 
1017  ReleaseSysCache(tuple);
1018 
1019  path = relpathbackend(rnode, backend, MAIN_FORKNUM);
1020 
1022 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define RELPERSISTENCE_UNLOGGED
Definition: pg_class.h:171
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3142
#define RELKIND_MATVIEW
Definition: pg_class.h:165
#define GLOBALTABLESPACE_OID
Definition: pg_tablespace.h:64
int GetTempNamespaceBackendId(Oid namespaceId)
Definition: namespace.c:3195
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:576
Oid MyDatabaseTableSpace
Definition: globals.c:79
#define RELPERSISTENCE_PERMANENT
Definition: pg_class.h:170
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define BackendIdForTempRelations()
Definition: backendid.h:34
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
#define InvalidBackendId
Definition: backendid.h:23
#define RELKIND_TOASTVALUE
Definition: pg_class.h:163
Oid RelationMapOidToFilenode(Oid relationId, bool shared)
Definition: relmapper.c:146
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
int BackendId
Definition: backendid.h:21
Oid MyDatabaseId
Definition: globals.c:77
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
text * cstring_to_text(const char *s)
Definition: varlena.c:150
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:670
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define RELKIND_INDEX
Definition: pg_class.h:161
#define elog
Definition: elog.h:219
#define RELPERSISTENCE_TEMP
Definition: pg_class.h:172
#define RELKIND_RELATION
Definition: pg_class.h:160
#define relpathbackend(rnode, backend, forknum)
Definition: relpath.h:62
#define RELKIND_SEQUENCE
Definition: pg_class.h:162
#define PG_RETURN_NULL()
Definition: fmgr.h:305

◆ pg_relation_size()

Datum pg_relation_size ( PG_FUNCTION_ARGS  )

Definition at line 311 of file dbsize.c.

References AccessShareLock, calculate_relation_size(), forkname_to_number(), PG_GETARG_OID, PG_GETARG_TEXT_PP, PG_RETURN_INT64, PG_RETURN_NULL, RelationData::rd_backend, RelationData::rd_node, relation_close(), text_to_cstring(), and try_relation_open().

312 {
313  Oid relOid = PG_GETARG_OID(0);
314  text *forkName = PG_GETARG_TEXT_PP(1);
315  Relation rel;
316  int64 size;
317 
318  rel = try_relation_open(relOid, AccessShareLock);
319 
320  /*
321  * Before 9.2, we used to throw an error if the relation didn't exist, but
322  * that makes queries like "SELECT pg_relation_size(oid) FROM pg_class"
323  * less robust, because while we scan pg_class with an MVCC snapshot,
324  * someone else might drop the table. It's better to return NULL for
325  * already-dropped tables than throw an error and abort the whole query.
326  */
327  if (rel == NULL)
328  PG_RETURN_NULL();
329 
330  size = calculate_relation_size(&(rel->rd_node), rel->rd_backend,
332 
334 
335  PG_RETURN_INT64(size);
336 }
static int64 calculate_relation_size(RelFileNode *rfn, BackendId backend, ForkNumber forknum)
Definition: dbsize.c:273
Relation try_relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1153
#define PG_RETURN_INT64(x)
Definition: fmgr.h:327
#define AccessShareLock
Definition: lockdefs.h:36
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1266
unsigned int Oid
Definition: postgres_ext.h:31
ForkNumber forkname_to_number(const char *forkName)
Definition: relpath.c:48
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
RelFileNode rd_node
Definition: rel.h:85
BackendId rd_backend
Definition: rel.h:89
char * text_to_cstring(const text *t)
Definition: varlena.c:183
Definition: c.h:487
#define PG_RETURN_NULL()
Definition: fmgr.h:305

◆ pg_size_bytes()

Datum pg_size_bytes ( PG_FUNCTION_ARGS  )

Definition at line 708 of file dbsize.c.

References arg, CStringGetDatum, DatumGetInt64, DatumGetNumeric, DirectFunctionCall1, DirectFunctionCall2, DirectFunctionCall3, ereport, errcode(), errdetail(), errhint(), errmsg(), ERROR, Int32GetDatum, Int64GetDatum(), int8_numeric(), InvalidOid, numeric_in(), numeric_int8(), numeric_mul(), NumericGetDatum, ObjectIdGetDatum, PG_GETARG_TEXT_PP, PG_RETURN_INT64, pg_strcasecmp(), generate_unaccent_rules::str, text_to_cstring(), and VARSIZE_ANY_EXHDR.

709 {
710  text *arg = PG_GETARG_TEXT_PP(0);
711  char *str,
712  *strptr,
713  *endptr;
714  char saved_char;
715  Numeric num;
716  int64 result;
717  bool have_digits = false;
718 
719  str = text_to_cstring(arg);
720 
721  /* Skip leading whitespace */
722  strptr = str;
723  while (isspace((unsigned char) *strptr))
724  strptr++;
725 
726  /* Check that we have a valid number and determine where it ends */
727  endptr = strptr;
728 
729  /* Part (1): sign */
730  if (*endptr == '-' || *endptr == '+')
731  endptr++;
732 
733  /* Part (2): main digit string */
734  if (isdigit((unsigned char) *endptr))
735  {
736  have_digits = true;
737  do
738  endptr++;
739  while (isdigit((unsigned char) *endptr));
740  }
741 
742  /* Part (3): optional decimal point and fractional digits */
743  if (*endptr == '.')
744  {
745  endptr++;
746  if (isdigit((unsigned char) *endptr))
747  {
748  have_digits = true;
749  do
750  endptr++;
751  while (isdigit((unsigned char) *endptr));
752  }
753  }
754 
755  /* Complain if we don't have a valid number at this point */
756  if (!have_digits)
757  ereport(ERROR,
758  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
759  errmsg("invalid size: \"%s\"", str)));
760 
761  /* Part (4): optional exponent */
762  if (*endptr == 'e' || *endptr == 'E')
763  {
764  long exponent;
765  char *cp;
766 
767  /*
768  * Note we might one day support EB units, so if what follows 'E'
769  * isn't a number, just treat it all as a unit to be parsed.
770  */
771  exponent = strtol(endptr + 1, &cp, 10);
772  (void) exponent; /* Silence -Wunused-result warnings */
773  if (cp > endptr + 1)
774  endptr = cp;
775  }
776 
777  /*
778  * Parse the number, saving the next character, which may be the first
779  * character of the unit string.
780  */
781  saved_char = *endptr;
782  *endptr = '\0';
783 
785  CStringGetDatum(strptr),
787  Int32GetDatum(-1)));
788 
789  *endptr = saved_char;
790 
791  /* Skip whitespace between number and unit */
792  strptr = endptr;
793  while (isspace((unsigned char) *strptr))
794  strptr++;
795 
796  /* Handle possible unit */
797  if (*strptr != '\0')
798  {
799  int64 multiplier = 0;
800 
801  /* Trim any trailing whitespace */
802  endptr = str + VARSIZE_ANY_EXHDR(arg) - 1;
803 
804  while (isspace((unsigned char) *endptr))
805  endptr--;
806 
807  endptr++;
808  *endptr = '\0';
809 
810  /* Parse the unit case-insensitively */
811  if (pg_strcasecmp(strptr, "bytes") == 0)
812  multiplier = (int64) 1;
813  else if (pg_strcasecmp(strptr, "kb") == 0)
814  multiplier = (int64) 1024;
815  else if (pg_strcasecmp(strptr, "mb") == 0)
816  multiplier = ((int64) 1024) * 1024;
817 
818  else if (pg_strcasecmp(strptr, "gb") == 0)
819  multiplier = ((int64) 1024) * 1024 * 1024;
820 
821  else if (pg_strcasecmp(strptr, "tb") == 0)
822  multiplier = ((int64) 1024) * 1024 * 1024 * 1024;
823 
824  else
825  ereport(ERROR,
826  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
827  errmsg("invalid size: \"%s\"", text_to_cstring(arg)),
828  errdetail("Invalid size unit: \"%s\".", strptr),
829  errhint("Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\".")));
830 
831  if (multiplier > 1)
832  {
833  Numeric mul_num;
834 
836  Int64GetDatum(multiplier)));
837 
839  NumericGetDatum(mul_num),
840  NumericGetDatum(num)));
841  }
842  }
843 
845  NumericGetDatum(num)));
846 
847  PG_RETURN_INT64(result);
848 }
int errhint(const char *fmt,...)
Definition: elog.c:987
#define PG_RETURN_INT64(x)
Definition: fmgr.h:327
#define NumericGetDatum(X)
Definition: numeric.h:51
Datum numeric_int8(PG_FUNCTION_ARGS)
Definition: numeric.c:3058
int errcode(int sqlerrcode)
Definition: elog.c:575
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:585
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
Datum int8_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:3039
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define DatumGetInt64(X)
Definition: postgres.h:613
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define CStringGetDatum(X)
Definition: postgres.h:584
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:570
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1786
#define ereport(elevel, rest)
Definition: elog.h:122
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:589
Datum numeric_mul(PG_FUNCTION_ARGS)
Definition: numeric.c:2395
#define InvalidOid
Definition: postgres_ext.h:36
#define DatumGetNumeric(X)
Definition: numeric.h:49
char * text_to_cstring(const text *t)
Definition: varlena.c:183
#define Int32GetDatum(X)
Definition: postgres.h:485
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
int errmsg(const char *fmt,...)
Definition: elog.c:797
void * arg
Definition: c.h:487
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:587

◆ pg_size_pretty()

Datum pg_size_pretty ( PG_FUNCTION_ARGS  )

Definition at line 534 of file dbsize.c.

References Abs, buf, cstring_to_text(), half_rounded, INT64_FORMAT, PG_GETARG_INT64, PG_RETURN_TEXT_P, and snprintf().

535 {
536  int64 size = PG_GETARG_INT64(0);
537  char buf[64];
538  int64 limit = 10 * 1024;
539  int64 limit2 = limit * 2 - 1;
540 
541  if (Abs(size) < limit)
542  snprintf(buf, sizeof(buf), INT64_FORMAT " bytes", size);
543  else
544  {
545  size >>= 9; /* keep one extra bit for rounding */
546  if (Abs(size) < limit2)
547  snprintf(buf, sizeof(buf), INT64_FORMAT " kB",
548  half_rounded(size));
549  else
550  {
551  size >>= 10;
552  if (Abs(size) < limit2)
553  snprintf(buf, sizeof(buf), INT64_FORMAT " MB",
554  half_rounded(size));
555  else
556  {
557  size >>= 10;
558  if (Abs(size) < limit2)
559  snprintf(buf, sizeof(buf), INT64_FORMAT " GB",
560  half_rounded(size));
561  else
562  {
563  size >>= 10;
564  snprintf(buf, sizeof(buf), INT64_FORMAT " TB",
565  half_rounded(size));
566  }
567  }
568  }
569  }
570 
572 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define Abs(x)
Definition: c.h:808
#define half_rounded(x)
Definition: dbsize.c:35
static char * buf
Definition: pg_test_fsync.c:67
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
text * cstring_to_text(const char *s)
Definition: varlena.c:150
#define INT64_FORMAT
Definition: c.h:338
#define PG_GETARG_INT64(n)
Definition: fmgr.h:247

◆ pg_size_pretty_numeric()

Datum pg_size_pretty_numeric ( PG_FUNCTION_ARGS  )

Definition at line 646 of file dbsize.c.

References cstring_to_text(), int64_to_numeric(), numeric_absolute(), numeric_half_rounded(), numeric_is_less(), numeric_shift_right(), numeric_to_cstring(), PG_GETARG_NUMERIC, PG_RETURN_TEXT_P, and psprintf().

647 {
648  Numeric size = PG_GETARG_NUMERIC(0);
649  Numeric limit,
650  limit2;
651  char *result;
652 
653  limit = int64_to_numeric(10 * 1024);
654  limit2 = int64_to_numeric(10 * 1024 * 2 - 1);
655 
656  if (numeric_is_less(numeric_absolute(size), limit))
657  {
658  result = psprintf("%s bytes", numeric_to_cstring(size));
659  }
660  else
661  {
662  /* keep one extra bit for rounding */
663  /* size >>= 9 */
664  size = numeric_shift_right(size, 9);
665 
666  if (numeric_is_less(numeric_absolute(size), limit2))
667  {
668  size = numeric_half_rounded(size);
669  result = psprintf("%s kB", numeric_to_cstring(size));
670  }
671  else
672  {
673  /* size >>= 10 */
674  size = numeric_shift_right(size, 10);
675  if (numeric_is_less(numeric_absolute(size), limit2))
676  {
677  size = numeric_half_rounded(size);
678  result = psprintf("%s MB", numeric_to_cstring(size));
679  }
680  else
681  {
682  /* size >>= 10 */
683  size = numeric_shift_right(size, 10);
684 
685  if (numeric_is_less(numeric_absolute(size), limit2))
686  {
687  size = numeric_half_rounded(size);
688  result = psprintf("%s GB", numeric_to_cstring(size));
689  }
690  else
691  {
692  /* size >>= 10 */
693  size = numeric_shift_right(size, 10);
694  size = numeric_half_rounded(size);
695  result = psprintf("%s TB", numeric_to_cstring(size));
696  }
697  }
698  }
699  }
700 
702 }
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
static Numeric numeric_shift_right(Numeric n, unsigned count)
Definition: dbsize.c:632
static char * numeric_to_cstring(Numeric n)
Definition: dbsize.c:575
static Numeric numeric_absolute(Numeric n)
Definition: dbsize.c:600
static Numeric int64_to_numeric(int64 v)
Definition: dbsize.c:583
static Numeric numeric_half_rounded(Numeric n)
Definition: dbsize.c:610
static bool numeric_is_less(Numeric a, Numeric b)
Definition: dbsize.c:591
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
text * cstring_to_text(const char *s)
Definition: varlena.c:150
#define PG_GETARG_NUMERIC(n)
Definition: numeric.h:52

◆ pg_table_size()

Datum pg_table_size ( PG_FUNCTION_ARGS  )

Definition at line 451 of file dbsize.c.

References AccessShareLock, calculate_table_size(), PG_GETARG_OID, PG_RETURN_INT64, PG_RETURN_NULL, relation_close(), and try_relation_open().

452 {
453  Oid relOid = PG_GETARG_OID(0);
454  Relation rel;
455  int64 size;
456 
457  rel = try_relation_open(relOid, AccessShareLock);
458 
459  if (rel == NULL)
460  PG_RETURN_NULL();
461 
462  size = calculate_table_size(rel);
463 
465 
466  PG_RETURN_INT64(size);
467 }
Relation try_relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1153
#define PG_RETURN_INT64(x)
Definition: fmgr.h:327
#define AccessShareLock
Definition: lockdefs.h:36
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1266
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
static int64 calculate_table_size(Relation rel)
Definition: dbsize.c:389
#define PG_RETURN_NULL()
Definition: fmgr.h:305

◆ pg_tablespace_size_name()

Datum pg_tablespace_size_name ( PG_FUNCTION_ARGS  )

Definition at line 251 of file dbsize.c.

References calculate_tablespace_size(), get_tablespace_oid(), NameStr, PG_GETARG_NAME, PG_RETURN_INT64, and PG_RETURN_NULL.

252 {
253  Name tblspcName = PG_GETARG_NAME(0);
254  Oid tblspcOid = get_tablespace_oid(NameStr(*tblspcName), false);
255  int64 size;
256 
257  size = calculate_tablespace_size(tblspcOid);
258 
259  if (size < 0)
260  PG_RETURN_NULL();
261 
262  PG_RETURN_INT64(size);
263 }
Oid get_tablespace_oid(const char *tablespacename, bool missing_ok)
Definition: tablespace.c:1380
#define PG_RETURN_INT64(x)
Definition: fmgr.h:327
unsigned int Oid
Definition: postgres_ext.h:31
Definition: c.h:541
static int64 calculate_tablespace_size(Oid tblspcOid)
Definition: dbsize.c:167
#define NameStr(name)
Definition: c.h:547
#define PG_RETURN_NULL()
Definition: fmgr.h:305
#define PG_GETARG_NAME(n)
Definition: fmgr.h:243

◆ pg_tablespace_size_oid()

Datum pg_tablespace_size_oid ( PG_FUNCTION_ARGS  )

Definition at line 237 of file dbsize.c.

References calculate_tablespace_size(), PG_GETARG_OID, PG_RETURN_INT64, and PG_RETURN_NULL.

238 {
239  Oid tblspcOid = PG_GETARG_OID(0);
240  int64 size;
241 
242  size = calculate_tablespace_size(tblspcOid);
243 
244  if (size < 0)
245  PG_RETURN_NULL();
246 
247  PG_RETURN_INT64(size);
248 }
#define PG_RETURN_INT64(x)
Definition: fmgr.h:327
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
static int64 calculate_tablespace_size(Oid tblspcOid)
Definition: dbsize.c:167
#define PG_RETURN_NULL()
Definition: fmgr.h:305

◆ pg_total_relation_size()

Datum pg_total_relation_size ( PG_FUNCTION_ARGS  )

Definition at line 512 of file dbsize.c.

References AccessShareLock, calculate_total_relation_size(), PG_GETARG_OID, PG_RETURN_INT64, PG_RETURN_NULL, relation_close(), and try_relation_open().

513 {
514  Oid relOid = PG_GETARG_OID(0);
515  Relation rel;
516  int64 size;
517 
518  rel = try_relation_open(relOid, AccessShareLock);
519 
520  if (rel == NULL)
521  PG_RETURN_NULL();
522 
523  size = calculate_total_relation_size(rel);
524 
526 
527  PG_RETURN_INT64(size);
528 }
static int64 calculate_total_relation_size(Relation rel)
Definition: dbsize.c:493
Relation try_relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1153
#define PG_RETURN_INT64(x)
Definition: fmgr.h:327
#define AccessShareLock
Definition: lockdefs.h:36
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1266
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_NULL()
Definition: fmgr.h:305