INFORMATION_SCHEMA and foreign keys - Mailing list pgsql-sql

From Troels Arvin
Subject INFORMATION_SCHEMA and foreign keys
Date
Msg-id pan.2004.09.05.22.56.56.521040@arvin.dk
Whole thread Raw
Responses Re: INFORMATION_SCHEMA and foreign keys  (Stephan Szabo <sszabo@megazone.bigpanda.com>)
List pgsql-sql
Hello,

For a table with a foreign key, I need to find out which columns are being
referred to in the foreing key.

Example setup: Create two ("master") tables, and two ("slave") tables
which refer to a master table:

CREATE TABLE MASTER_A ( fullname VARCHAR(50) NOT NULL, birthday TIMESTAMP NOT NULL, email VARCHAR(50), PRIMARY
KEY(fullname,birthday)
);
CREATE TABLE MASTER_B ( fullname VARCHAR(50) NOT NULL, birthday TIMESTAMP NOT NULL, email VARCHAR(50), PRIMARY
KEY(fullname,birthday)
);

CREATE TABLE SLAVE_A ( fullname VARCHAR(50) NOT NULL, birthday TIMESTAMP NOT NULL, phone VARCHAR(30), FOREIGN
KEY(fullname,birthday)REFERENCES MASTER_A
 
);
CREATE TABLE SLAVE_B ( fullname VARCHAR(50) NOT NULL, birthday TIMESTAMP NOT NULL, phone VARCHAR(30), FOREIGN
KEY(fullname,birthday)REFERENCES MASTER_B
 
);

\d slave_a gives:              Table "public.slave_a" Column  |            Type             | Modifiers
----------+-----------------------------+-----------fullname | character varying(50)       | not null birthday |
timestampwithouttime zone | not null phone    | character varying(30)       |
 
Foreign-key constraints:   "$1" FOREIGN KEY (fullname, birthday) REFERENCES master_a(fullname,   birthday)

\d slave_b gives:              Table "public.slave_b" Column  |            Type             | Modifiers
----------+-----------------------------+-----------fullname | character varying(50)       | not null birthday |
timestampwithouttime zone | not null phone    | character varying(30)       |
 
Foreign-key constraints:   "$1" FOREIGN KEY (fullname, birthday) REFERENCES master_b(fullname,   birthday)

Note that the constraint name for both foreign keys is "$1".

Now, I tried a query like this, which I hoped to use to find out which
columns in the "slave_a" table were part of which foreign key in
"master_a":

SELECT tc.CONSTRAINT_NAME AS consnam, ccu.COLUMN_NAME AS colnam, UNIQUE_CONSTRAINT_NAME AS ucnam, ref_ccu.COLUMN_NAME
ASrefer_to_col
 
FROM   INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc NATURAL JOIN   INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS ccu
INNERJOIN   INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS rc     ON tc.CONSTRAINT_NAME=rc.CONSTRAINT_NAME INNER JOIN
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGEAS ref_ccu     ON UNIQUE_CONSTRAINT_NAME=ref_ccu.CONSTRAINT_NAME
 
WHERE   tc.TABLE_NAME='slave_a' AND   CONSTRAINT_TYPE='FOREIGN KEY';

The result:
consnam |  colnam  |     ucnam     | refer_to_col
---------+----------+---------------+--------------$1      | fullname | master_a_pkey | fullname$1      | birthday |
master_a_pkey| fullname$1      | fullname | master_a_pkey | birthday$1      | birthday | master_a_pkey | birthday$1
| fullname | master_b_pkey | fullname$1      | birthday | master_b_pkey | fullname$1      | fullname | master_b_pkey |
birthday$1     | birthday | master_b_pkey | birthday
 

The query returns double the numer of rows, compared to what I wanted. The
problem seems to stem from PostgreSQL's naming of constraints without
explicit name: They seem to be named $1, $2, etc, and the default names
are reused.

My INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS looks like this:

SELECT CONSTRAINT_NAME,UNIQUE_CONSTRAINT_NAME FROM
INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS;
constraint_name | unique_constraint_name
-----------------+------------------------$1              | master_b_pkey$1              | master_a_pkey

Note, again, that the CONSTRAINT_NAMEs are not unique, although they
affect two different tables. Hence, there doesn't seem to be a way to map
a specifict referential constraint to a specific primary/unique constraint
in the table being referred to.

Is my only way forward to drop using the INFORMATION_SCHEMA and work with
the pg_catalog if I want to determine which columns are being referred to
in a (set of) foreign key column(s)?

(Thanks to readers who got this far.)

-- 
Greetings from Troels Arvin, Copenhagen, Denmark




pgsql-sql by date:

Previous
From: Pierre-Frédéric Caillaud
Date:
Subject: Re: Storing properties in a logical way.
Next
From: Stephan Szabo
Date:
Subject: Re: INFORMATION_SCHEMA and foreign keys