phppostgresqlzend-frameworkzend-dbpgadmin-4

Undefined table: 7 ERROR: relation "V5TableName" does not exist


I am using an MVC framework (Zend) for my application and I want to find the total size of a table in PostgreSQL (including index). The table name is "V5TableName" - quotes included because table name is case sensitive. I have made sure that there is NO typo involved.

My code to get the table size is shown below:

public function getMyTableSize()
{
  $sql = "SELECT pg_size_pretty(pg_total_relation_size( '\"V5TableName\"' ) );";

  /* Custom_Db is a custom library in my application which makes the PostgreSQL connection 
     and queries the database
   */
  $tableSize = Custom_Db::query($sql)->fetchColumn(); 

  return $tableSize;
}

When my application calls this function it returns the following error in my logs :

[22-Apr-2020 09:42:37] PID:30849 ERR: SQLSTATE[42P01]: Undefined table: 7 ERROR:  relation "V5TableName" does not exist
LINE 1: SELECT pg_size_pretty(pg_total_relation_size( '"V5TableName...
                                                      ^
query was: SELECT pg_size_pretty(pg_total_relation_size( '"V5TableName"' ) );

If I run this same query in pgAdmin4 it works perfectly fine returning the table size (for instance: 104Mb).

I have tried:

  1. Removing and adding quotes to the table name in the code.
  2. Appending the schema as prefix to the table name (example: 'public."V5TableName"').

NONE of the above seem to work. I am not sure what is going wrong over here.

I also tried to find the total database size in my application (db name: MyDbName - with mixed case spelling) and my query looked something like below:

$sql = "SELECT pg_size_pretty(pg_database_size('MyDbName'))"; // this DID NOT WORK

So I changed it to the one shown below: (it worked)

$sql = "SELECT pg_size_pretty(pg_database_size( current_database() ))"; // this WORKED

I was wondering if there is something similar that could be done to find the table size.


Solution

  • Your query should work. The use of double-quotes seems correct.

    SELECT pg_size_pretty(pg_total_relation_size('"V5TableName"'));
    

    First make sure you are connecting to the right database cluster (a.k.a. "server"). It's defined by its data directory, or equally unambiguous by hostname and port number. Read the manual here and here.

    Then make sure you are connecting to the right database within that database cluster. A Postgres database cluster consists of 1-n databases. When connecting without specifying the actual database, you end up in the maintenance database named postgres by default. That's the most likely explanation. Check with:

    SELECT current_database();
    

    Then check for the right table and schema name:

    SELECT * FROM pg_tables
    WHERE tablename ~* 'V5TableName';  -- ~* matches case-insensitive
    

    The first riddle should be solved at this point.

    Check your DB spelling and possible near-duplicates with:

    SELECT datname FROM pg_database;
    

    The call is without double-quotes (like you tried correctly), but requires correct capitalization:

    SELECT pg_size_pretty(pg_database_size('MyDbName'));
    

    Note the subtle difference (as documented in the manual):

    pg_database_size() has to differ because there is no dedicated object identifier type for databases (no regdatabase).

    The gist of it: avoid double-quoted identifiers in Postgres if at all possible. It makes your life easier.