Un-Windows-ify newlines.
authorTom Lane
Tue, 2 Aug 2005 14:07:27 +0000 (14:07 +0000)
committerTom Lane
Tue, 2 Aug 2005 14:07:27 +0000 (14:07 +0000)
src/backend/utils/adt/dbsize.c

index 158d2cf402658a7dfe9dc53bce0106c1a0ad6a0d..57b72fe15cc3be3d23f79d666926c8f6eb4419ca 100644 (file)
-/*\r
- * dbsize.c\r
- * object size functions\r
- *\r
- * Copyright (c) 2002-2005, PostgreSQL Global Development Group\r
- *\r
- * IDENTIFICATION\r
- *   $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.1 2005/07/29 14:46:57 momjian Exp $\r
- *\r
- */\r
-\r
-#include "postgres.h"\r
-\r
-#include \r
-#include \r
-\r
-#include "access/heapam.h"\r
-#include "catalog/namespace.h"\r
-#include "catalog/pg_tablespace.h"\r
-#include "commands/dbcommands.h"\r
-#include "commands/tablespace.h"\r
-#include "miscadmin.h"\r
-#include "storage/fd.h"\r
-#include "utils/builtins.h"\r
-#include "utils/syscache.h"\r
-#include "utils/relcache.h"\r
-\r
-\r
-/* Return physical size of directory contents, or 0 if dir doesn't exist */\r
-static int64\r
-db_dir_size(const char *path)\r
-{\r
-   int64       dirsize = 0;\r
-    struct dirent *direntry;\r
-   DIR         *dirdesc;\r
-   char filename[MAXPGPATH];\r
-\r
-   dirdesc = AllocateDir(path);\r
-\r
-   if (!dirdesc)\r
-       return 0;\r
-\r
-   while ((direntry = readdir(dirdesc)) != NULL)\r
-   {\r
-       struct stat fst;\r
-\r
-       if (strcmp(direntry->d_name, ".") == 0 ||\r
-           strcmp(direntry->d_name, "..") == 0)\r
-           continue;\r
-\r
-       snprintf(filename, MAXPGPATH, "%s/%s", path, direntry->d_name);\r
-\r
-       if (stat(filename, &fst) < 0)\r
-           ereport(ERROR,\r
-                   (errcode_for_file_access(),\r
-                    errmsg("could not stat \"%s\": %m", filename)));\r
-        \r
-        dirsize += fst.st_size;\r
-   }\r
-\r
-   FreeDir(dirdesc);\r
-   return dirsize;\r
-}\r
-\r
-/*\r
- * calculate size of database in all tablespaces\r
- */\r
-static int64\r
-calculate_database_size(Oid dbOid)\r
-{\r
-   int64       totalsize = 0;\r
-   DIR         *dirdesc;\r
-    struct dirent *direntry;\r
-   char pathname[MAXPGPATH];\r
-\r
-   /* Shared storage in pg_global is not counted */\r
-\r
-   /* Include pg_default storage */\r
-   snprintf(pathname, MAXPGPATH, "%s/base/%u", DataDir, dbOid);\r
-   totalsize += db_dir_size(pathname);\r
-\r
-   /* Scan the non-default tablespaces */\r
-   snprintf(pathname, MAXPGPATH, "%s/pg_tblspc", DataDir);\r
-   dirdesc = AllocateDir(pathname);\r
-   if (!dirdesc)\r
-       ereport(ERROR,\r
-               (errcode_for_file_access(),\r
-                errmsg("could not open tablespace directory \"%s\": %m",\r
-                       pathname)));\r
-\r
-   while ((direntry = readdir(dirdesc)) != NULL)\r
-   {\r
-       if (strcmp(direntry->d_name, ".") == 0 ||\r
-           strcmp(direntry->d_name, "..") == 0)\r
-           continue;\r
-\r
-       snprintf(pathname, MAXPGPATH, "%s/pg_tblspc/%s/%u",\r
-                DataDir, direntry->d_name, dbOid);\r
-       totalsize += db_dir_size(pathname);\r
-   }\r
-\r
-   FreeDir(dirdesc);\r
-\r
-   /* Complain if we found no trace of the DB at all */\r
-   if (!totalsize)\r
-       ereport(ERROR,\r
-               (ERRCODE_UNDEFINED_DATABASE,\r
-                errmsg("database with OID %u does not exist", dbOid)));\r
-\r
-   return totalsize;\r
-}\r
-\r
-Datum\r
-pg_database_size_oid(PG_FUNCTION_ARGS)\r
-{\r
-    Oid dbOid = PG_GETARG_OID(0);\r
-\r
-   PG_RETURN_INT64(calculate_database_size(dbOid));\r
-}\r
-\r
-Datum\r
-pg_database_size_name(PG_FUNCTION_ARGS)\r
-{\r
-   Name dbName = PG_GETARG_NAME(0);\r
-   Oid dbOid = get_database_oid(NameStr(*dbName));\r
-\r
-   if (!OidIsValid(dbOid))\r
-       ereport(ERROR,\r
-               (errcode(ERRCODE_UNDEFINED_DATABASE),\r
-                errmsg("database \"%s\" does not exist",\r
-                       NameStr(*dbName))));\r
-\r
-   PG_RETURN_INT64(calculate_database_size(dbOid));\r
-}\r
-\r
-\r
-/*\r
- * calculate total size of tablespace\r
- */\r
-static int64\r
-calculate_tablespace_size(Oid tblspcOid)\r
-{\r
-   char tblspcPath[MAXPGPATH];\r
-   char pathname[MAXPGPATH];\r
-   int64       totalsize=0;\r
-   DIR         *dirdesc;\r
-    struct dirent *direntry;\r
-\r
-   if (tblspcOid == DEFAULTTABLESPACE_OID)\r
-       snprintf(tblspcPath, MAXPGPATH, "%s/base", DataDir);\r
-   else if (tblspcOid == GLOBALTABLESPACE_OID)\r
-       snprintf(tblspcPath, MAXPGPATH, "%s/global", DataDir);\r
-   else\r
-       snprintf(tblspcPath, MAXPGPATH, "%s/pg_tblspc/%u", DataDir, tblspcOid);\r
-\r
-   dirdesc = AllocateDir(tblspcPath);\r
-\r
-   if (!dirdesc)\r
-       ereport(ERROR,\r
-               (errcode_for_file_access(),\r
-                errmsg("could not open tablespace directory \"%s\": %m",\r
-                       tblspcPath)));\r
-\r
-   while ((direntry = readdir(dirdesc)) != NULL)\r
-   {\r
-       struct stat fst;\r
-\r
-       if (strcmp(direntry->d_name, ".") == 0 ||\r
-           strcmp(direntry->d_name, "..") == 0)\r
-           continue;\r
-\r
-       snprintf(pathname, MAXPGPATH, "%s/%s", tblspcPath, direntry->d_name);\r
-\r
-       if (stat(pathname, &fst) < 0)\r
-           ereport(ERROR,\r
-                   (errcode_for_file_access(),\r
-                    errmsg("could not stat \"%s\": %m", pathname)));\r
-\r
-       if (fst.st_mode & S_IFDIR)\r
-           totalsize += db_dir_size(pathname);\r
-        \r
-        totalsize += fst.st_size;\r
-   }\r
-\r
-   FreeDir(dirdesc);\r
-    \r
-   return totalsize;\r
-}\r
-\r
-Datum\r
-pg_tablespace_size_oid(PG_FUNCTION_ARGS)\r
-{\r
-    Oid tblspcOid = PG_GETARG_OID(0);\r
-    \r
-   PG_RETURN_INT64(calculate_tablespace_size(tblspcOid));\r
-}\r
-\r
-Datum\r
-pg_tablespace_size_name(PG_FUNCTION_ARGS)\r
-{\r
-   Name tblspcName = PG_GETARG_NAME(0);\r
-   Oid tblspcOid = get_tablespace_oid(NameStr(*tblspcName));\r
-\r
-   if (!OidIsValid(tblspcOid))\r
-       ereport(ERROR,\r
-               (errcode(ERRCODE_UNDEFINED_OBJECT),\r
-                errmsg("tablespace \"%s\" does not exist",\r
-                       NameStr(*tblspcName))));\r
-\r
-   PG_RETURN_INT64(calculate_tablespace_size(tblspcOid));\r
-}\r
-\r
-\r
-/*\r
- * calculate size of a relation\r
- */\r
-static int64\r
-calculate_relation_size(Oid tblspcOid, Oid relnodeOid)\r
-{\r
-   int64       totalsize=0;\r
-   unsigned int segcount=0;\r
-   char dirpath[MAXPGPATH];\r
-   char pathname[MAXPGPATH];\r
-\r
-   if (!tblspcOid)\r
-       tblspcOid = MyDatabaseTableSpace;\r
-\r
-   if (tblspcOid == DEFAULTTABLESPACE_OID)\r
-       snprintf(dirpath, MAXPGPATH, "%s/base/%u", DataDir, MyDatabaseId);\r
-   else if (tblspcOid == GLOBALTABLESPACE_OID)\r
-       snprintf(dirpath, MAXPGPATH, "%s/global", DataDir);\r
-   else\r
-       snprintf(dirpath, MAXPGPATH, "%s/pg_tblspc/%u/%u",\r
-                DataDir, tblspcOid, MyDatabaseId);\r
-\r
-   for (segcount = 0 ;; segcount++)\r
-   {\r
-       struct stat fst;\r
-\r
-       if (segcount == 0)\r
-           snprintf(pathname, MAXPGPATH, "%s/%u",\r
-                    dirpath, relnodeOid);\r
-       else\r
-           snprintf(pathname, MAXPGPATH, "%s/%u.%u",\r
-                    dirpath, relnodeOid, segcount);\r
-\r
-       if (stat(pathname, &fst) < 0)\r
-       {\r
-           if (errno == ENOENT)\r
-               break;\r
-           else\r
-               ereport(ERROR,\r
-                       (errcode_for_file_access(),\r
-                        errmsg("could not stat \"%s\": %m", pathname)));\r
-       }\r
-       totalsize += fst.st_size;\r
-   }\r
-\r
-   return totalsize;\r
-}\r
-\r
-Datum\r
-pg_relation_size_oid(PG_FUNCTION_ARGS)\r
-{\r
-   Oid         relOid=PG_GETARG_OID(0);\r
-   HeapTuple   tuple;\r
-   Form_pg_class pg_class;\r
-   Oid         relnodeOid;\r
-   Oid         tblspcOid;\r
-\r
-   tuple = SearchSysCache(RELOID,\r
-                          ObjectIdGetDatum(relOid),\r
-                          0, 0, 0);\r
-   if (!HeapTupleIsValid(tuple))\r
-       ereport(ERROR,\r
-               (ERRCODE_UNDEFINED_TABLE,\r
-                errmsg("relation with OID %u does not exist", relOid)));\r
-\r
-   pg_class = (Form_pg_class) GETSTRUCT(tuple);\r
-   relnodeOid = pg_class->relfilenode;\r
-   tblspcOid = pg_class->reltablespace;\r
-\r
-   ReleaseSysCache(tuple);\r
-\r
-   PG_RETURN_INT64(calculate_relation_size(tblspcOid, relnodeOid));\r
-}\r
-\r
-Datum\r
-pg_relation_size_name(PG_FUNCTION_ARGS)\r
-{\r
-   text       *relname = PG_GETARG_TEXT_P(0);\r
-   RangeVar   *relrv;\r
-   Relation    relation;\r
-   Oid         relnodeOid;\r
-   Oid         tblspcOid;\r
-    \r
-   relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));    \r
-   relation = relation_openrv(relrv, AccessShareLock);\r
-    \r
-   tblspcOid  = relation->rd_rel->reltablespace;             \r
-   relnodeOid = relation->rd_rel->relfilenode;\r
-             \r
-   relation_close(relation, AccessShareLock);\r
-\r
-   PG_RETURN_INT64(calculate_relation_size(tblspcOid, relnodeOid));\r
-}\r
-\r
-\r
-/*\r
- *  Compute on-disk size of files for 'relation' according to the stat function, \r
- *  optionally including heap data, index data, and/or toast data.\r
- */\r
-static int64\r
-calculate_complete_relation_size(Oid tblspcOid, Oid relnodeOid)\r
-{\r
-    Relation        heapRelation;\r
-   Relation        idxRelation;\r
-   Relation        toastRelation;\r
-    Oid             idxOid;\r
-    Oid             idxTblspcOid;\r
-   Oid             toastOid;\r
-   Oid             toastTblspcOid;\r
-   bool            hasIndices;\r
-   int64           size = 0;\r
-   List            *indexoidlist;\r
-   ListCell        *idx;\r
-\r
-    heapRelation = relation_open(relnodeOid, AccessShareLock);\r
-   toastOid = heapRelation->rd_rel->reltoastrelid;\r
-   hasIndices = heapRelation->rd_rel->relhasindex;\r
-\r
-    /* Get the heap size */\r
-    size += calculate_relation_size(tblspcOid, relnodeOid);\r
-\r
-    /* Get Index size */\r
-   if ( hasIndices ) {\r
-       /* recursively include any dependent indexes ... */\r
-       indexoidlist = RelationGetIndexList(heapRelation);\r
-             \r
-       foreach(idx, indexoidlist) {\r
-            idxOid = lfirst_oid(idx);\r
-           idxRelation = relation_open(idxOid, AccessShareLock);\r
-            idxTblspcOid = idxRelation->rd_rel->reltablespace;\r
-           size += calculate_relation_size(idxTblspcOid, idxOid);\r
-           relation_close(idxRelation, AccessShareLock);\r
-       }\r
-       list_free(indexoidlist);\r
-   }\r
-    \r
-    /* Close heapReleation now we no longer need it */\r
-    relation_close(heapRelation, AccessShareLock);\r
-\r
-    /* Get toast table size */\r
-   if ( toastOid != 0 ) {\r
-\r
-       /* recursively include any toast relations ... */\r
-       toastRelation = relation_open(toastOid, AccessShareLock);\r
-       toastTblspcOid = toastRelation->rd_rel->reltablespace;\r
-       size += calculate_relation_size(toastTblspcOid, toastOid);\r
-       relation_close(toastRelation, AccessShareLock);\r
-   }\r
-\r
-   return size;\r
-}\r
-\r
-/*\r
- *  Compute on-disk size of files for 'relation' including \r
- *  heap data, index data, and toasted data.\r
- */\r
-Datum\r
-pg_complete_relation_size_oid(PG_FUNCTION_ARGS)\r
-{\r
-   Oid     relOid=PG_GETARG_OID(0);\r
-   HeapTuple   tuple;\r
-   Form_pg_class   pg_class;\r
-   Oid     relnodeOid;\r
-   Oid     tblspcOid;\r
-\r
-   tuple = SearchSysCache(RELOID,\r
-                  ObjectIdGetDatum(relOid),\r
-                  0, 0, 0);\r
-   if (!HeapTupleIsValid(tuple))\r
-       ereport(ERROR,\r
-               (ERRCODE_UNDEFINED_TABLE,\r
-                errmsg("relation with OID %u does not exist", relOid)));\r
-\r
-   pg_class = (Form_pg_class) GETSTRUCT(tuple);\r
-   relnodeOid = pg_class->relfilenode;\r
-   tblspcOid = pg_class->reltablespace;\r
-\r
-   ReleaseSysCache(tuple);\r
-\r
-   PG_RETURN_INT64(calculate_complete_relation_size(tblspcOid, relnodeOid));\r
-}\r
-\r
-Datum\r
-pg_complete_relation_size_name(PG_FUNCTION_ARGS)\r
-{\r
-   text        *relname = PG_GETARG_TEXT_P(0);\r
-   RangeVar    *relrv;\r
-   Relation    relation;\r
-   Oid     relnodeOid;\r
-   Oid     tblspcOid;\r
-    \r
-   relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));    \r
-   relation = relation_openrv(relrv, AccessShareLock);\r
-    \r
-   tblspcOid  = relation->rd_rel->reltablespace;             \r
-   relnodeOid = relation->rd_rel->relfilenode;\r
-             \r
-   relation_close(relation, AccessShareLock);\r
-\r
-   PG_RETURN_INT64(calculate_complete_relation_size(tblspcOid, relnodeOid));\r
-}\r
-\r
-/*\r
- * formatting with size units\r
- */\r
-Datum\r
-pg_size_pretty(PG_FUNCTION_ARGS)\r
-{\r
-   int64 size=PG_GETARG_INT64(0);\r
-   char *result=palloc(50+VARHDRSZ);\r
-   int64 limit = 10*1024;\r
-   int64 mult=1;\r
-\r
-   if (size < limit*mult)\r
-       snprintf(VARDATA(result), 50, INT64_FORMAT" bytes",\r
-                size);\r
-   else\r
-   {\r
-       mult *= 1024;\r
-       if (size < limit*mult)\r
-            snprintf(VARDATA(result), 50, INT64_FORMAT " kB",\r
-                     (size+mult/2) / mult);\r
-       else\r
-       {\r
-           mult *= 1024;\r
-           if (size < limit*mult)\r
-               snprintf(VARDATA(result), 50, INT64_FORMAT " MB",\r
-                        (size+mult/2) / mult);\r
-           else\r
-           {\r
-               mult *= 1024;\r
-               if (size < limit*mult)\r
-                   snprintf(VARDATA(result), 50, INT64_FORMAT " GB",\r
-                            (size+mult/2) / mult);\r
-               else\r
-               {\r
-                   mult *= 1024;\r
-                   snprintf(VARDATA(result), 50, INT64_FORMAT " TB",\r
-                            (size+mult/2) / mult);\r
-               }\r
-           }\r
-       }\r
-   }\r
-\r
-   VARATT_SIZEP(result) = strlen(VARDATA(result)) + VARHDRSZ;\r
-\r
-   PG_RETURN_TEXT_P(result);\r
-}\r
+/*
+ * dbsize.c
+ * object size functions
+ *
+ * Copyright (c) 2002-2005, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.2 2005/08/02 14:07:27 tgl Exp $
+ *
+ */
+
+#include "postgres.h"
+
+#include 
+#include 
+
+#include "access/heapam.h"
+#include "catalog/namespace.h"
+#include "catalog/pg_tablespace.h"
+#include "commands/dbcommands.h"
+#include "commands/tablespace.h"
+#include "miscadmin.h"
+#include "storage/fd.h"
+#include "utils/builtins.h"
+#include "utils/syscache.h"
+#include "utils/relcache.h"
+
+
+/* Return physical size of directory contents, or 0 if dir doesn't exist */
+static int64
+db_dir_size(const char *path)
+{
+   int64       dirsize = 0;
+    struct dirent *direntry;
+   DIR         *dirdesc;
+   char filename[MAXPGPATH];
+
+   dirdesc = AllocateDir(path);
+
+   if (!dirdesc)
+       return 0;
+
+   while ((direntry = readdir(dirdesc)) != NULL)
+   {
+       struct stat fst;
+
+       if (strcmp(direntry->d_name, ".") == 0 ||
+           strcmp(direntry->d_name, "..") == 0)
+           continue;
+
+       snprintf(filename, MAXPGPATH, "%s/%s", path, direntry->d_name);
+
+       if (stat(filename, &fst) < 0)
+           ereport(ERROR,
+                   (errcode_for_file_access(),
+                    errmsg("could not stat \"%s\": %m", filename)));
+        
+        dirsize += fst.st_size;
+   }
+
+   FreeDir(dirdesc);
+   return dirsize;
+}
+
+/*
+ * calculate size of database in all tablespaces
+ */
+static int64
+calculate_database_size(Oid dbOid)
+{
+   int64       totalsize = 0;
+   DIR         *dirdesc;
+    struct dirent *direntry;
+   char pathname[MAXPGPATH];
+
+   /* Shared storage in pg_global is not counted */
+
+   /* Include pg_default storage */
+   snprintf(pathname, MAXPGPATH, "%s/base/%u", DataDir, dbOid);
+   totalsize += db_dir_size(pathname);
+
+   /* Scan the non-default tablespaces */
+   snprintf(pathname, MAXPGPATH, "%s/pg_tblspc", DataDir);
+   dirdesc = AllocateDir(pathname);
+   if (!dirdesc)
+       ereport(ERROR,
+               (errcode_for_file_access(),
+                errmsg("could not open tablespace directory \"%s\": %m",
+                       pathname)));
+
+   while ((direntry = readdir(dirdesc)) != NULL)
+   {
+       if (strcmp(direntry->d_name, ".") == 0 ||
+           strcmp(direntry->d_name, "..") == 0)
+           continue;
+
+       snprintf(pathname, MAXPGPATH, "%s/pg_tblspc/%s/%u",
+                DataDir, direntry->d_name, dbOid);
+       totalsize += db_dir_size(pathname);
+   }
+
+   FreeDir(dirdesc);
+
+   /* Complain if we found no trace of the DB at all */
+   if (!totalsize)
+       ereport(ERROR,
+               (ERRCODE_UNDEFINED_DATABASE,
+                errmsg("database with OID %u does not exist", dbOid)));
+
+   return totalsize;
+}
+
+Datum
+pg_database_size_oid(PG_FUNCTION_ARGS)
+{
+    Oid dbOid = PG_GETARG_OID(0);
+
+   PG_RETURN_INT64(calculate_database_size(dbOid));
+}
+
+Datum
+pg_database_size_name(PG_FUNCTION_ARGS)
+{
+   Name dbName = PG_GETARG_NAME(0);
+   Oid dbOid = get_database_oid(NameStr(*dbName));
+
+   if (!OidIsValid(dbOid))
+       ereport(ERROR,
+               (errcode(ERRCODE_UNDEFINED_DATABASE),
+                errmsg("database \"%s\" does not exist",
+                       NameStr(*dbName))));
+
+   PG_RETURN_INT64(calculate_database_size(dbOid));
+}
+
+
+/*
+ * calculate total size of tablespace
+ */
+static int64
+calculate_tablespace_size(Oid tblspcOid)
+{
+   char tblspcPath[MAXPGPATH];
+   char pathname[MAXPGPATH];
+   int64       totalsize=0;
+   DIR         *dirdesc;
+    struct dirent *direntry;
+
+   if (tblspcOid == DEFAULTTABLESPACE_OID)
+       snprintf(tblspcPath, MAXPGPATH, "%s/base", DataDir);
+   else if (tblspcOid == GLOBALTABLESPACE_OID)
+       snprintf(tblspcPath, MAXPGPATH, "%s/global", DataDir);
+   else
+       snprintf(tblspcPath, MAXPGPATH, "%s/pg_tblspc/%u", DataDir, tblspcOid);
+
+   dirdesc = AllocateDir(tblspcPath);
+
+   if (!dirdesc)
+       ereport(ERROR,
+               (errcode_for_file_access(),
+                errmsg("could not open tablespace directory \"%s\": %m",
+                       tblspcPath)));
+
+   while ((direntry = readdir(dirdesc)) != NULL)
+   {
+       struct stat fst;
+
+       if (strcmp(direntry->d_name, ".") == 0 ||
+           strcmp(direntry->d_name, "..") == 0)
+           continue;
+
+       snprintf(pathname, MAXPGPATH, "%s/%s", tblspcPath, direntry->d_name);
+
+       if (stat(pathname, &fst) < 0)
+           ereport(ERROR,
+                   (errcode_for_file_access(),
+                    errmsg("could not stat \"%s\": %m", pathname)));
+
+       if (fst.st_mode & S_IFDIR)
+           totalsize += db_dir_size(pathname);
+        
+        totalsize += fst.st_size;
+   }
+
+   FreeDir(dirdesc);
+    
+   return totalsize;
+}
+
+Datum
+pg_tablespace_size_oid(PG_FUNCTION_ARGS)
+{
+    Oid tblspcOid = PG_GETARG_OID(0);
+    
+   PG_RETURN_INT64(calculate_tablespace_size(tblspcOid));
+}
+
+Datum
+pg_tablespace_size_name(PG_FUNCTION_ARGS)
+{
+   Name tblspcName = PG_GETARG_NAME(0);
+   Oid tblspcOid = get_tablespace_oid(NameStr(*tblspcName));
+
+   if (!OidIsValid(tblspcOid))
+       ereport(ERROR,
+               (errcode(ERRCODE_UNDEFINED_OBJECT),
+                errmsg("tablespace \"%s\" does not exist",
+                       NameStr(*tblspcName))));
+
+   PG_RETURN_INT64(calculate_tablespace_size(tblspcOid));
+}
+
+
+/*
+ * calculate size of a relation
+ */
+static int64
+calculate_relation_size(Oid tblspcOid, Oid relnodeOid)
+{
+   int64       totalsize=0;
+   unsigned int segcount=0;
+   char dirpath[MAXPGPATH];
+   char pathname[MAXPGPATH];
+
+   if (!tblspcOid)
+       tblspcOid = MyDatabaseTableSpace;
+
+   if (tblspcOid == DEFAULTTABLESPACE_OID)
+       snprintf(dirpath, MAXPGPATH, "%s/base/%u", DataDir, MyDatabaseId);
+   else if (tblspcOid == GLOBALTABLESPACE_OID)
+       snprintf(dirpath, MAXPGPATH, "%s/global", DataDir);
+   else
+       snprintf(dirpath, MAXPGPATH, "%s/pg_tblspc/%u/%u",
+                DataDir, tblspcOid, MyDatabaseId);
+
+   for (segcount = 0 ;; segcount++)
+   {
+       struct stat fst;
+
+       if (segcount == 0)
+           snprintf(pathname, MAXPGPATH, "%s/%u",
+                    dirpath, relnodeOid);
+       else
+           snprintf(pathname, MAXPGPATH, "%s/%u.%u",
+                    dirpath, relnodeOid, segcount);
+
+       if (stat(pathname, &fst) < 0)
+       {
+           if (errno == ENOENT)
+               break;
+           else
+               ereport(ERROR,
+                       (errcode_for_file_access(),
+                        errmsg("could not stat \"%s\": %m", pathname)));
+       }
+       totalsize += fst.st_size;
+   }
+
+   return totalsize;
+}
+
+Datum
+pg_relation_size_oid(PG_FUNCTION_ARGS)
+{
+   Oid         relOid=PG_GETARG_OID(0);
+   HeapTuple   tuple;
+   Form_pg_class pg_class;
+   Oid         relnodeOid;
+   Oid         tblspcOid;
+
+   tuple = SearchSysCache(RELOID,
+                          ObjectIdGetDatum(relOid),
+                          0, 0, 0);
+   if (!HeapTupleIsValid(tuple))
+       ereport(ERROR,
+               (ERRCODE_UNDEFINED_TABLE,
+                errmsg("relation with OID %u does not exist", relOid)));
+
+   pg_class = (Form_pg_class) GETSTRUCT(tuple);
+   relnodeOid = pg_class->relfilenode;
+   tblspcOid = pg_class->reltablespace;
+
+   ReleaseSysCache(tuple);
+
+   PG_RETURN_INT64(calculate_relation_size(tblspcOid, relnodeOid));
+}
+
+Datum
+pg_relation_size_name(PG_FUNCTION_ARGS)
+{
+   text       *relname = PG_GETARG_TEXT_P(0);
+   RangeVar   *relrv;
+   Relation    relation;
+   Oid         relnodeOid;
+   Oid         tblspcOid;
+    
+   relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));    
+   relation = relation_openrv(relrv, AccessShareLock);
+    
+   tblspcOid  = relation->rd_rel->reltablespace;             
+   relnodeOid = relation->rd_rel->relfilenode;
+             
+   relation_close(relation, AccessShareLock);
+
+   PG_RETURN_INT64(calculate_relation_size(tblspcOid, relnodeOid));
+}
+
+
+/*
+ *  Compute on-disk size of files for 'relation' according to the stat function, 
+ *  optionally including heap data, index data, and/or toast data.
+ */
+static int64
+calculate_complete_relation_size(Oid tblspcOid, Oid relnodeOid)
+{
+    Relation        heapRelation;
+   Relation        idxRelation;
+   Relation        toastRelation;
+    Oid             idxOid;
+    Oid             idxTblspcOid;
+   Oid             toastOid;
+   Oid             toastTblspcOid;
+   bool            hasIndices;
+   int64           size = 0;
+   List            *indexoidlist;
+   ListCell        *idx;
+
+    heapRelation = relation_open(relnodeOid, AccessShareLock);
+   toastOid = heapRelation->rd_rel->reltoastrelid;
+   hasIndices = heapRelation->rd_rel->relhasindex;
+
+    /* Get the heap size */
+    size += calculate_relation_size(tblspcOid, relnodeOid);
+
+    /* Get Index size */
+   if ( hasIndices ) {
+       /* recursively include any dependent indexes ... */
+       indexoidlist = RelationGetIndexList(heapRelation);
+             
+       foreach(idx, indexoidlist) {
+            idxOid = lfirst_oid(idx);
+           idxRelation = relation_open(idxOid, AccessShareLock);
+            idxTblspcOid = idxRelation->rd_rel->reltablespace;
+           size += calculate_relation_size(idxTblspcOid, idxOid);
+           relation_close(idxRelation, AccessShareLock);
+       }
+       list_free(indexoidlist);
+   }
+    
+    /* Close heapReleation now we no longer need it */
+    relation_close(heapRelation, AccessShareLock);
+
+    /* Get toast table size */
+   if ( toastOid != 0 ) {
+
+       /* recursively include any toast relations ... */
+       toastRelation = relation_open(toastOid, AccessShareLock);
+       toastTblspcOid = toastRelation->rd_rel->reltablespace;
+       size += calculate_relation_size(toastTblspcOid, toastOid);
+       relation_close(toastRelation, AccessShareLock);
+   }
+
+   return size;
+}
+
+/*
+ *  Compute on-disk size of files for 'relation' including 
+ *  heap data, index data, and toasted data.
+ */
+Datum
+pg_complete_relation_size_oid(PG_FUNCTION_ARGS)
+{
+   Oid     relOid=PG_GETARG_OID(0);
+   HeapTuple   tuple;
+   Form_pg_class   pg_class;
+   Oid     relnodeOid;
+   Oid     tblspcOid;
+
+   tuple = SearchSysCache(RELOID,
+                  ObjectIdGetDatum(relOid),
+                  0, 0, 0);
+   if (!HeapTupleIsValid(tuple))
+       ereport(ERROR,
+               (ERRCODE_UNDEFINED_TABLE,
+                errmsg("relation with OID %u does not exist", relOid)));
+
+   pg_class = (Form_pg_class) GETSTRUCT(tuple);
+   relnodeOid = pg_class->relfilenode;
+   tblspcOid = pg_class->reltablespace;
+
+   ReleaseSysCache(tuple);
+
+   PG_RETURN_INT64(calculate_complete_relation_size(tblspcOid, relnodeOid));
+}
+
+Datum
+pg_complete_relation_size_name(PG_FUNCTION_ARGS)
+{
+   text        *relname = PG_GETARG_TEXT_P(0);
+   RangeVar    *relrv;
+   Relation    relation;
+   Oid     relnodeOid;
+   Oid     tblspcOid;
+    
+   relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));    
+   relation = relation_openrv(relrv, AccessShareLock);
+    
+   tblspcOid  = relation->rd_rel->reltablespace;             
+   relnodeOid = relation->rd_rel->relfilenode;
+             
+   relation_close(relation, AccessShareLock);
+
+   PG_RETURN_INT64(calculate_complete_relation_size(tblspcOid, relnodeOid));
+}
+
+/*
+ * formatting with size units
+ */
+Datum
+pg_size_pretty(PG_FUNCTION_ARGS)
+{
+   int64 size=PG_GETARG_INT64(0);
+   char *result=palloc(50+VARHDRSZ);
+   int64 limit = 10*1024;
+   int64 mult=1;
+
+   if (size < limit*mult)
+       snprintf(VARDATA(result), 50, INT64_FORMAT" bytes",
+                size);
+   else
+   {
+       mult *= 1024;
+       if (size < limit*mult)
+            snprintf(VARDATA(result), 50, INT64_FORMAT " kB",
+                     (size+mult/2) / mult);
+       else
+       {
+           mult *= 1024;
+           if (size < limit*mult)
+               snprintf(VARDATA(result), 50, INT64_FORMAT " MB",
+                        (size+mult/2) / mult);
+           else
+           {
+               mult *= 1024;
+               if (size < limit*mult)
+                   snprintf(VARDATA(result), 50, INT64_FORMAT " GB",
+                            (size+mult/2) / mult);
+               else
+               {
+                   mult *= 1024;
+                   snprintf(VARDATA(result), 50, INT64_FORMAT " TB",
+                            (size+mult/2) / mult);
+               }
+           }
+       }
+   }
+
+   VARATT_SIZEP(result) = strlen(VARDATA(result)) + VARHDRSZ;
+
+   PG_RETURN_TEXT_P(result);
+}