OSDN Git Service

Add relation fork support to pg_relation_size() function. You can now pass
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 3 Oct 2008 07:33:10 +0000 (07:33 +0000)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 3 Oct 2008 07:33:10 +0000 (07:33 +0000)
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.

doc/src/sgml/func.sgml
src/backend/utils/adt/dbsize.c
src/include/catalog/catversion.h
src/include/catalog/pg_proc.h
src/include/storage/relfilenode.h
src/include/utils/builtins.h

index 05f0aab..31ef6dc 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $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">
   <title>Functions and Operators</title>
@@ -12417,7 +12417,7 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup());
 
      <tbody>
       <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>Number of bytes used to store a particular value (possibly compressed)</entry>
       </row>
@@ -12437,19 +12437,22 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup());
       </row>
       <row>
        <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><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>
        <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><type>bigint</type></entry>
        <entry>
-        Disk space used by the table or index with the specified name.
-        The table name can be qualified with a schema name
+        Shorthand for <literal>pg_relation_size(..., 'main')</literal>
        </entry>
       </row>
       <row>
@@ -12475,21 +12478,11 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup());
       </row>
       <row>
        <entry>
-        <literal><function>pg_total_relation_size</function>(<type>oid</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>
+        <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 name,
+        Total disk space used by the table with the specified OID or name,
         including indexes and toasted data.  The table name can be
         qualified with a schema name
        </entry>
@@ -12511,7 +12504,12 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup());
 
    <para>
     <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>
index e85d11c..d225b3e 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (c) 2002-2008, PostgreSQL Global Development Group
  *
  * 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)
  * calculate size of a relation
  */
 static int64
-calculate_relation_size(RelFileNode *rfn)
+calculate_relation_size(RelFileNode *rfn, ForkNumber forknum)
 {
        int64           totalsize = 0;
        char       *relationpath;
        char            pathname[MAXPGPATH];
        unsigned int segcount = 0;
 
-       /* XXX: This ignores the other forks. */
-       relationpath = relpath(*rfn, MAIN_FORKNUM);
+       relationpath = relpath(*rfn, forknum);
 
        for (segcount = 0;; segcount++)
        {
@@ -284,34 +283,47 @@ calculate_relation_size(RelFileNode *rfn)
        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
-pg_relation_size_name(PG_FUNCTION_ARGS)
+pg_relation_size(PG_FUNCTION_ARGS)
 {
-       text       *relname = PG_GETARG_TEXT_P(0);
-       RangeVar   *relrv;
+       Oid                     relOid = PG_GETARG_OID(0);
+       text       *forkName = PG_GETARG_TEXT_P(1);
        Relation        rel;
        int64           size;
 
-       relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
-       rel = relation_openrv(relrv, AccessShareLock);
+       rel = relation_open(relOid, 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);
 
@@ -330,12 +342,15 @@ calculate_total_relation_size(Oid Relid)
        Oid                     toastOid;
        int64           size;
        ListCell   *cell;
+       ForkNumber      forkNum;
 
        heapRel = relation_open(Relid, AccessShareLock);
        toastOid = heapRel->rd_rel->reltoastrelid;
 
        /* 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 */
        if (heapRel->rd_rel->relhasindex)
@@ -349,7 +364,8 @@ calculate_total_relation_size(Oid Relid)
 
                        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);
                }
@@ -367,26 +383,13 @@ calculate_total_relation_size(Oid Relid)
 }
 
 Datum
-pg_total_relation_size_oid(PG_FUNCTION_ARGS)
+pg_total_relation_size(PG_FUNCTION_ARGS)
 {
        Oid                     relid = PG_GETARG_OID(0);
 
        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
  */
index 99b9062..e333b6d 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * 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 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     200809301
+#define CATALOG_VERSION_NO     200810031
 
 #endif
index 42d8ce7..2b3de5e 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * 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
  *       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 "
 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_ ));
 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");
-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_ ));
-DESCR("disk space usage for the specified 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_ ));
-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_ ));
+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 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 "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 = 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");
index 571f261..128cff9 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * 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
        InvalidForkNumber = -1,
        MAIN_FORKNUM = 0,
        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;
 
 #define MAX_FORKNUM            FSM_FORKNUM
index 09d38e9..58ccb03 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * 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);
 extern Datum pg_tablespace_size_name(PG_FUNCTION_ARGS);
 extern Datum pg_database_size_oid(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_name(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_relation_size(PG_FUNCTION_ARGS);
+extern Datum pg_total_relation_size(PG_FUNCTION_ARGS);
 extern Datum pg_size_pretty(PG_FUNCTION_ARGS);
 
 /* genfile.c */