Postgres 8.4 and greater databases contain common tables in public
schema and company specific tables in company
schema.
company
schema names always start with 'company'
and end with the company number.
So there may be schemas like:
public
company1
company2
company3
...
companynn
An application always works with a single company.
The search_path
is specified accordingly in odbc or npgsql connection string, like:
search_path='company3,public'
How would you check if a given table exists in a specified companyn
schema?
eg:
select isSpecific('company3','tablenotincompany3schema')
should return false
, and
select isSpecific('company3','tableincompany3schema')
should return true
.
In any case, the function should check only companyn
schema passed, not other schemas.
If a given table exists in both public
and the passed schema, the function should return true
.
It should work for Postgres 8.4 or later.
It depends on what you want to test exactly.
Information schema?
To find "whether the table exists" (no matter who's asking), querying the information schema (
information_schema.tables
) is incorrect, strictly speaking, because (per documentation):The query provided by @kong can return
FALSE
, but the table can still exist. It answers the question:How to check whether a table (or view) exists, and the current user has access to it?
The information schema is mainly useful to stay portable across major versions and across different RDBMS. But the implementation is slow, because Postgres has to use sophisticated views to comply to the standard (
information_schema.tables
is a rather simple example). And some information (like OIDs) gets lost in translation from the system catalogs - which actually carry all information.System catalogs
Your question was:
How to check whether a table exists?
Use the system catalogs
pg_class
andpg_namespace
directly, which is also considerably faster. However, per documentation onpg_class
:For this particular question you can also use the system view
pg_tables
. A bit simpler and more portable across major Postgres versions (which is hardly of concern for this basic query):Identifiers have to be unique among all objects mentioned above. If you want to ask:
How to check whether a name for a table or similar object in a given schema is taken?
Alternative: cast to
regclass
This raises an exception if the (optionally schema-qualified) table (or other object occupying that name) does not exist.
If you do not schema-qualify the table name, a cast to
regclass
defaults to thesearch_path
and returns the OID for the first table found - or an exception if the table is in none of the listed schemas. Note that the system schemaspg_catalog
andpg_temp
(the schema for temporary objects of the current session) are automatically part of thesearch_path
.You can use that and catch a possible exception in a function. Example:
A query like above avoids possible exceptions and is therefore slightly faster.
Note that the each component of the name is treated as identifier here - as opposed to above queries where names are given as literal strings. Identifiers are cast to lower case unless double-quoted. If you have forced otherwise illegal identifiers with double-quotes, those need to be included. Like:
See:
to_regclass(rel_name)
in Postgres 9.4+Much simpler now:
Same as the cast, but it returns ...