Commit 706a3088 authored by Heikki Linnakangas's avatar Heikki Linnakangas

Add relation fork support to pg_relation_size() function. You can now pass

name of a fork ('main' or 'fsm', at the moment) to pg_relation_size() to
get the size of a specific fork. Defaults to 'main', if none given.

While we're at it, modify pg_relation_size to take a regclass as argument,
instead of separate variants taking oid and name. This change is
transparent to typical use where the table name is passed as a string
literal, like pg_relation_size('table'), but will break queries like
pg_relation_size(namecol), where namecol is of type name. text-type input
still works, and using a non-schema-qualified table name is not very
reliable anyway, so this is unlikely to break anyone's queries in practice.
parent 2cc1633a
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.447 2008/09/11 17:32:33 tgl Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.448 2008/10/03 07:33:08 heikki Exp $ -->
<chapter id="functions"> <chapter id="functions">
<title>Functions and Operators</title> <title>Functions and Operators</title>
...@@ -12417,7 +12417,7 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup()); ...@@ -12417,7 +12417,7 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup());
<tbody> <tbody>
<row> <row>
<entry><function>pg_column_size</function>(<type>any</type>)</entry> <entry><literal><function>pg_column_size</function>(<type>any</type>)</literal></entry>
<entry><type>int</type></entry> <entry><type>int</type></entry>
<entry>Number of bytes used to store a particular value (possibly compressed)</entry> <entry>Number of bytes used to store a particular value (possibly compressed)</entry>
</row> </row>
...@@ -12437,19 +12437,22 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup()); ...@@ -12437,19 +12437,22 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup());
</row> </row>
<row> <row>
<entry> <entry>
<literal><function>pg_relation_size</function>(<type>oid</type>)</literal> <literal><function>pg_relation_size</function>(<parameter>relation</parameter> <type>regclass</type>, <parameter>fork</parameter> <type>text</type>)</literal>
</entry> </entry>
<entry><type>bigint</type></entry> <entry><type>bigint</type></entry>
<entry>Disk space used by the table or index with the specified OID</entry> <entry>
Disk space used by the specified fork, <literal>'main'</literal> or
<literal>'fsm'</literal>, of a table or index with the specified OID
or name. The table name can be qualified with a schema name
</entry>
</row> </row>
<row> <row>
<entry> <entry>
<literal><function>pg_relation_size</function>(<type>text</type>)</literal> <literal><function>pg_relation_size</function>(<parameter>relation</parameter> <type>regclass</type>)</literal>
</entry> </entry>
<entry><type>bigint</type></entry> <entry><type>bigint</type></entry>
<entry> <entry>
Disk space used by the table or index with the specified name. Shorthand for <literal>pg_relation_size(..., 'main')</literal>
The table name can be qualified with a schema name
</entry> </entry>
</row> </row>
<row> <row>
...@@ -12475,21 +12478,11 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup()); ...@@ -12475,21 +12478,11 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup());
</row> </row>
<row> <row>
<entry> <entry>
<literal><function>pg_total_relation_size</function>(<type>oid</type>)</literal> <literal><function>pg_total_relation_size</function>(<type>regclass</type>)</literal>
</entry>
<entry><type>bigint</type></entry>
<entry>
Total disk space used by the table with the specified OID,
including indexes and toasted data
</entry>
</row>
<row>
<entry>
<literal><function>pg_total_relation_size</function>(<type>text</type>)</literal>
</entry> </entry>
<entry><type>bigint</type></entry> <entry><type>bigint</type></entry>
<entry> <entry>
Total disk space used by the table with the specified name, Total disk space used by the table with the specified OID or name,
including indexes and toasted data. The table name can be including indexes and toasted data. The table name can be
qualified with a schema name qualified with a schema name
</entry> </entry>
...@@ -12511,7 +12504,12 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup()); ...@@ -12511,7 +12504,12 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup());
<para> <para>
<function>pg_relation_size</> accepts the OID or name of a table, index or <function>pg_relation_size</> accepts the OID or name of a table, index or
toast table, and returns the size in bytes. toast table, and returns the size in bytes. Specifying
<literal>'main'</literal> or leaving out the second argument returns the
size of the main data fork of the relation. Specifying
<literal>'fsm'</literal> returns the size of the
Free Space Map (see <xref linkend="storage-fsm">) associated with the
relation.
</para> </para>
<para> <para>
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Copyright (c) 2002-2008, PostgreSQL Global Development Group * Copyright (c) 2002-2008, PostgreSQL Global Development Group
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.20 2008/08/11 11:05:11 heikki Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.21 2008/10/03 07:33:09 heikki Exp $
* *
*/ */
...@@ -248,15 +248,14 @@ pg_tablespace_size_name(PG_FUNCTION_ARGS) ...@@ -248,15 +248,14 @@ pg_tablespace_size_name(PG_FUNCTION_ARGS)
* calculate size of a relation * calculate size of a relation
*/ */
static int64 static int64
calculate_relation_size(RelFileNode *rfn) calculate_relation_size(RelFileNode *rfn, ForkNumber forknum)
{ {
int64 totalsize = 0; int64 totalsize = 0;
char *relationpath; char *relationpath;
char pathname[MAXPGPATH]; char pathname[MAXPGPATH];
unsigned int segcount = 0; unsigned int segcount = 0;
/* XXX: This ignores the other forks. */ relationpath = relpath(*rfn, forknum);
relationpath = relpath(*rfn, MAIN_FORKNUM);
for (segcount = 0;; segcount++) for (segcount = 0;; segcount++)
{ {
...@@ -284,34 +283,47 @@ calculate_relation_size(RelFileNode *rfn) ...@@ -284,34 +283,47 @@ calculate_relation_size(RelFileNode *rfn)
return totalsize; return totalsize;
} }
Datum
pg_relation_size_oid(PG_FUNCTION_ARGS)
{
Oid relOid = PG_GETARG_OID(0);
Relation rel;
int64 size;
rel = relation_open(relOid, AccessShareLock); /*
* XXX: Consider making this global and moving elsewhere. But currently
* there's no other users for this.
*
* Remember to also update the errhint below if you add entries, and the
* documentation for pg_relation_size().
*/
static char *forkNames[] = {
"main", /* MAIN_FORKNUM */
"fsm" /* FSM_FORKNUM */
};
size = calculate_relation_size(&(rel->rd_node)); static ForkNumber
forkname_to_number(char *forkName)
{
ForkNumber forkNum;
relation_close(rel, AccessShareLock); for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
if (strcmp(forkNames[forkNum], forkName) == 0)
return forkNum;
PG_RETURN_INT64(size); ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid fork name"),
errhint("Valid fork names are 'main' and 'fsm'")));
return InvalidForkNumber; /* keep compiler quiet */
} }
Datum Datum
pg_relation_size_name(PG_FUNCTION_ARGS) pg_relation_size(PG_FUNCTION_ARGS)
{ {
text *relname = PG_GETARG_TEXT_P(0); Oid relOid = PG_GETARG_OID(0);
RangeVar *relrv; text *forkName = PG_GETARG_TEXT_P(1);
Relation rel; Relation rel;
int64 size; int64 size;
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); rel = relation_open(relOid, AccessShareLock);
rel = relation_openrv(relrv, AccessShareLock);
size = calculate_relation_size(&(rel->rd_node)); size = calculate_relation_size(&(rel->rd_node),
forkname_to_number(text_to_cstring(forkName)));
relation_close(rel, AccessShareLock); relation_close(rel, AccessShareLock);
...@@ -330,12 +342,15 @@ calculate_total_relation_size(Oid Relid) ...@@ -330,12 +342,15 @@ calculate_total_relation_size(Oid Relid)
Oid toastOid; Oid toastOid;
int64 size; int64 size;
ListCell *cell; ListCell *cell;
ForkNumber forkNum;
heapRel = relation_open(Relid, AccessShareLock); heapRel = relation_open(Relid, AccessShareLock);
toastOid = heapRel->rd_rel->reltoastrelid; toastOid = heapRel->rd_rel->reltoastrelid;
/* Get the heap size */ /* Get the heap size */
size = calculate_relation_size(&(heapRel->rd_node)); size = 0;
for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
size += calculate_relation_size(&(heapRel->rd_node), forkNum);
/* Include any dependent indexes */ /* Include any dependent indexes */
if (heapRel->rd_rel->relhasindex) if (heapRel->rd_rel->relhasindex)
...@@ -349,7 +364,8 @@ calculate_total_relation_size(Oid Relid) ...@@ -349,7 +364,8 @@ calculate_total_relation_size(Oid Relid)
iRel = relation_open(idxOid, AccessShareLock); iRel = relation_open(idxOid, AccessShareLock);
size += calculate_relation_size(&(iRel->rd_node)); for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
size += calculate_relation_size(&(iRel->rd_node), forkNum);
relation_close(iRel, AccessShareLock); relation_close(iRel, AccessShareLock);
} }
...@@ -367,26 +383,13 @@ calculate_total_relation_size(Oid Relid) ...@@ -367,26 +383,13 @@ calculate_total_relation_size(Oid Relid)
} }
Datum Datum
pg_total_relation_size_oid(PG_FUNCTION_ARGS) pg_total_relation_size(PG_FUNCTION_ARGS)
{ {
Oid relid = PG_GETARG_OID(0); Oid relid = PG_GETARG_OID(0);
PG_RETURN_INT64(calculate_total_relation_size(relid)); PG_RETURN_INT64(calculate_total_relation_size(relid));
} }
Datum
pg_total_relation_size_name(PG_FUNCTION_ARGS)
{
text *relname = PG_GETARG_TEXT_P(0);
RangeVar *relrv;
Oid relid;
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
relid = RangeVarGetRelid(relrv, false);
PG_RETURN_INT64(calculate_total_relation_size(relid));
}
/* /*
* formatting with size units * formatting with size units
*/ */
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.490 2008/09/30 11:11:28 heikki Exp $ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.491 2008/10/03 07:33:09 heikki Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200809301 #define CATALOG_VERSION_NO 200810031
#endif #endif
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.515 2008/09/19 19:03:40 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.516 2008/10/03 07:33:09 heikki Exp $
* *
* NOTES * NOTES
* The script catalog/genbki.sh reads this file and generates .bki * The script catalog/genbki.sh reads this file and generates .bki
...@@ -3591,13 +3591,11 @@ DATA(insert OID = 2324 ( pg_database_size PGNSP PGUID 12 1 0 0 f f t f v 1 20 " ...@@ -3591,13 +3591,11 @@ DATA(insert OID = 2324 ( pg_database_size PGNSP PGUID 12 1 0 0 f f t f v 1 20 "
DESCR("total disk space usage for the specified database"); DESCR("total disk space usage for the specified database");
DATA(insert OID = 2168 ( pg_database_size PGNSP PGUID 12 1 0 0 f f t f v 1 20 "19" _null_ _null_ _null_ pg_database_size_name _null_ _null_ _null_ )); DATA(insert OID = 2168 ( pg_database_size PGNSP PGUID 12 1 0 0 f f t f v 1 20 "19" _null_ _null_ _null_ pg_database_size_name _null_ _null_ _null_ ));
DESCR("total disk space usage for the specified database"); DESCR("total disk space usage for the specified database");
DATA(insert OID = 2325 ( pg_relation_size PGNSP PGUID 12 1 0 0 f f t f v 1 20 "26" _null_ _null_ _null_ pg_relation_size_oid _null_ _null_ _null_ )); DATA(insert OID = 2325 ( pg_relation_size PGNSP PGUID 14 1 0 0 f f t f v 1 20 "2205" _null_ _null_ _null_ "select pg_catalog.pg_relation_size($1, ''main'')" _null_ _null_ _null_ ));
DESCR("disk space usage for the specified table or index"); DESCR("disk space usage for the specified table or index");
DATA(insert OID = 2289 ( pg_relation_size PGNSP PGUID 12 1 0 0 f f t f v 1 20 "25" _null_ _null_ _null_ pg_relation_size_name _null_ _null_ _null_ )); DATA(insert OID = 2332 ( pg_relation_size PGNSP PGUID 12 1 0 0 f f t f v 2 20 "2205 25" _null_ _null_ _null_ pg_relation_size _null_ _null_ _null_ ));
DESCR("disk space usage for the specified table or index"); DESCR("disk space usage for the specified fork of a table or index");
DATA(insert OID = 2286 ( pg_total_relation_size PGNSP PGUID 12 1 0 0 f f t f v 1 20 "26" _null_ _null_ _null_ pg_total_relation_size_oid _null_ _null_ _null_ )); DATA(insert OID = 2286 ( pg_total_relation_size PGNSP PGUID 12 1 0 0 f f t f v 1 20 "2205" _null_ _null_ _null_ pg_total_relation_size _null_ _null_ _null_ ));
DESCR("total disk space usage for the specified table and associated indexes and toast tables");
DATA(insert OID = 2287 ( pg_total_relation_size PGNSP PGUID 12 1 0 0 f f t f v 1 20 "25" _null_ _null_ _null_ pg_total_relation_size_name _null_ _null_ _null_ ));
DESCR("total disk space usage for the specified table and associated indexes and toast tables"); DESCR("total disk space usage for the specified table and associated indexes and toast tables");
DATA(insert OID = 2288 ( pg_size_pretty PGNSP PGUID 12 1 0 0 f f t f v 1 25 "20" _null_ _null_ _null_ pg_size_pretty _null_ _null_ _null_ )); DATA(insert OID = 2288 ( pg_size_pretty PGNSP PGUID 12 1 0 0 f f t f v 1 25 "20" _null_ _null_ _null_ pg_size_pretty _null_ _null_ _null_ ));
DESCR("convert a long int to a human readable text using size units"); DESCR("convert a long int to a human readable text using size units");
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/storage/relfilenode.h,v 1.17 2008/09/30 10:52:14 heikki Exp $ * $PostgreSQL: pgsql/src/include/storage/relfilenode.h,v 1.18 2008/10/03 07:33:10 heikki Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -25,7 +25,10 @@ typedef enum ForkNumber ...@@ -25,7 +25,10 @@ typedef enum ForkNumber
InvalidForkNumber = -1, InvalidForkNumber = -1,
MAIN_FORKNUM = 0, MAIN_FORKNUM = 0,
FSM_FORKNUM FSM_FORKNUM
/* NOTE: change MAX_FORKNUM below when you add new forks */ /*
* NOTE: if you add a new fork, change MAX_FORKNUM below and update the
* name to number mapping in utils/adt/dbsize.c
*/
} ForkNumber; } ForkNumber;
#define MAX_FORKNUM FSM_FORKNUM #define MAX_FORKNUM FSM_FORKNUM
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.320 2008/09/06 00:01:25 tgl Exp $ * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.321 2008/10/03 07:33:10 heikki Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -389,10 +389,8 @@ extern Datum pg_tablespace_size_oid(PG_FUNCTION_ARGS); ...@@ -389,10 +389,8 @@ extern Datum pg_tablespace_size_oid(PG_FUNCTION_ARGS);
extern Datum pg_tablespace_size_name(PG_FUNCTION_ARGS); extern Datum pg_tablespace_size_name(PG_FUNCTION_ARGS);
extern Datum pg_database_size_oid(PG_FUNCTION_ARGS); extern Datum pg_database_size_oid(PG_FUNCTION_ARGS);
extern Datum pg_database_size_name(PG_FUNCTION_ARGS); extern Datum pg_database_size_name(PG_FUNCTION_ARGS);
extern Datum pg_relation_size_oid(PG_FUNCTION_ARGS); extern Datum pg_relation_size(PG_FUNCTION_ARGS);
extern Datum pg_relation_size_name(PG_FUNCTION_ARGS); extern Datum pg_total_relation_size(PG_FUNCTION_ARGS);
extern Datum pg_total_relation_size_oid(PG_FUNCTION_ARGS);
extern Datum pg_total_relation_size_name(PG_FUNCTION_ARGS);
extern Datum pg_size_pretty(PG_FUNCTION_ARGS); extern Datum pg_size_pretty(PG_FUNCTION_ARGS);
/* genfile.c */ /* genfile.c */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment