Question

Is it possible to use a schema name as foreign key of a table in PostgreSQL? Something like:

create table account(
    id varchar(30) references information_schema.schemata(schema_name)
);

Runnig the SQL above, i get the following error:

SQL Error:

ERROR:  referenced relation "schemata" is not a table

In block:

create table account(
    id varchar(30) references information_schema.schemata(schema_name)
);

The idea is to check if account's schema exists before create the account.

Was it helpful?

Solution

You can only create FK references to concrete tables - not views, like information_schema.schemata:

regress=> \dv information_schema.schemata
                List of relations
       Schema       |   Name   | Type |  Owner   
--------------------+----------+------+----------
 information_schema | schemata | view | postgres
(1 row)

The underlying pg_catalog.pg_namespace table that backs the view:

regress=> select pg_get_viewdef('information_schema.schemata');
                                           pg_get_viewdef                                            
-----------------------------------------------------------------------------------------------------
  SELECT (current_database())::information_schema.sql_identifier AS catalog_name,                   +
     (n.nspname)::information_schema.sql_identifier AS schema_name,                                 +
     (u.rolname)::information_schema.sql_identifier AS schema_owner,                                +
     (NULL::character varying)::information_schema.sql_identifier AS default_character_set_catalog, +
     (NULL::character varying)::information_schema.sql_identifier AS default_character_set_schema,  +
     (NULL::character varying)::information_schema.sql_identifier AS default_character_set_name,    +
     (NULL::character varying)::information_schema.character_data AS sql_path                       +
    FROM pg_namespace n,                                                                            +
     pg_authid u                                                                                    +
   WHERE ((n.nspowner = u.oid) AND pg_has_role(n.nspowner, 'USAGE'::text));
(1 row)

regress=> \dt pg_catalog.pg_namespace
              List of relations
   Schema   |     Name     | Type  |  Owner   
------------+--------------+-------+----------
 pg_catalog | pg_namespace | table | postgres
(1 row)

... is also not a legal target for a foreign key, because PostgreSQL doesn't support foreign key references to system tables:

regress=> CREATE TABLE blah (x text references pg_catalog.pg_namespace(nspname));
ERROR:  permission denied: "pg_namespace" is a system catalog

So... you can't.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top