Search code examples
postgresqlrenametable-rename

How to rename a PostgreSQL table by prefixing an underscore?


I have a database which relies on a PostgreSQL system and I am maintaining it so I want to change tables and overall scheme. For this I thought of renaming the older tables so they have an underscore as a prefix. But this is not working:

DROP TABLE IF EXISTS _my_table; -- table does not exists, this does nothing

ALTER TABLE my_table
  RENAME TO _my_table;

The result of the query is the following:

NOTICE: table "_my_table" does not exist, skipping ERROR:
type "_my_table" already exists
********** Error **********

ERROR: type "_my_table" already exists SQL state: 42710

The '_my_table' table is a fake name, but this error is reproduced by actually creating a '_my_table' table and running the same script above.

I am using pgAdmin III to access the database tables and making use of it's 'rename' operation results in the same error. The postgresql documentation for the alter table method does not tell me explicitly about this particular problem: http://www.postgresql.org/docs/9.3/static/sql-altertable.html

Do I really need to use a prefix like 'backup' instead of '_' ? Or would it be possible to rename it, my only interest is to maintain the information in the table whilst having the minimal changes to the table name.


Solution

  • You cannot simply put an underscore in front of the existing table name because every table has an associated type that is... a leading underscore before the table name. You can verify this in the pg_catalog.pg_type table. Having a table name start with an underscore is not the problem, but the internal procedure is that a new table is created physically from the old table and only when the old table is no longer in use by other processes will the old table, and its associated type, be deleted. Hence the error referencing the type (and not the relation).

    So if you really want to keep the old name with an underscore, you should first ALTER TABLE to some temp name and then ALTER TABLE to the underscore + original name. Or simply use another prefix...