How foreign key info is stored

Started by Ken Williamsalmost 23 years ago4 messagesgeneral
Jump to latest
#1Ken Williams
ken@mathforum.org

Hi,

I'm wondering some things about how foreign key info is stored.

1) In postgres 7.1.3, how can I access the foreign key relationships
among tables? The pg_constraint table from version 7.3 doesn't seem to
exist, and I couldn't find an equivalent in the documentation for 7.1.

2) Is foreign key definition working properly via 'ALTER TABLE <table>
ADD ...' in 7.3.2? I did the following in a test database (extra
spaces added for clarity):

========================================================================
===
| test=> create table foo (
| test(> id int primary key not null,
| test(> foo_value varchar(30) );
| NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index
'foo_pkey'
| for table 'foo'
| CREATE TABLE
|
| test=> create table foo_people (
| test(> person_id integer primary key,
| test(> name varchar(30) );
| NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index
| 'foo_people_pkey' for table 'foo_people'
| CREATE TABLE
|
| test=> alter table foo add foo_person integer references
foo_people(person_id);
| NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY
check(s)
| ALTER TABLE
|
| test=> \d foo
| Table "public.foo"
| Column | Type | Modifiers
| ------------+-----------------------+-----------
| id | integer | not null
| foo_value | character varying(30) |
| foo_person | integer |
| Indexes: foo_pkey primary key btree (id)
========================================================================
===

This indicates to me that the "references foo_people(person_id)" had no
effect. To confirm this, I tried a bogus INSERT:

========================================================================
===
| test=> insert into foo_people (person_id, name) values (1, 'Bozo');
| INSERT 16985 1
|
| test=> insert into foo (id, foo_value, foo_person) values (1, 'foo!',
5);
| INSERT 16986 1
========================================================================
===

That second INSERT should have failed because there's nothing in
foo_people with an id of 5.

Next I tried specifying the constraint a different way. Note that the
first ALTER TABLE command fails because integrity isn't satisfied.
When I delete data from foo I can create the constraint:

========================================================================
===
| test=> alter table foo add foreign key (foo_person) references
foo_people (person_id);
| NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY
check(s)
| NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY
check(s)
| ERROR: $1 referential integrity violation - key referenced from foo
| not found in foo_people
| ERROR: $1 referential integrity violation - key referenced from foo
| not found in foo_people
|
| test=> delete from foo;
| DELETE 1
|
| test=> alter table foo add foreign key (foo_person) references
foo_people (person_id);
| NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY
check(s)
| NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY
check(s)
| ALTER TABLE
|
| test=> \d foo
| Table "public.foo"
| Column | Type | Modifiers
| ------------+-----------------------+-----------
| id | integer | not null
| foo_value | character varying(30) |
| foo_person | integer |
| Indexes: foo_pkey primary key btree (id)
| Foreign Key constraints: $1 FOREIGN KEY (foo_person) REFERENCES
| foo_people(person_id) ON UPDATE NO ACTION ON DELETE NO ACTION
========================================================================
===

And now, notice the foreign key info shows up in "\d foo".

-Ken

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Ken Williams (#1)
Re: How foreign key info is stored

Ken Williams <ken@mathforum.org> writes:

1) In postgres 7.1.3, how can I access the foreign key relationships
among tables?

The only way is to reverse-engineer it from the contents of pg_trigger.
7.3's contrib/adddepend will help you with this.

2) Is foreign key definition working properly via 'ALTER TABLE <table>
ADD ...' in 7.3.2?

No, there's a bug there --- ALTER ADD COLUMN neglects to process any
foreign-key clauses you might have written. This is fixed for 7.3.3.

regards, tom lane

#3Ken Williams
ken@mathforum.org
In reply to: Tom Lane (#2)
Re: How foreign key info is stored

On Thursday, April 17, 2003, at 02:41 PM, Tom Lane wrote:

Ken Williams <ken@mathforum.org> writes:

1) In postgres 7.1.3, how can I access the foreign key relationships
among tables?

The only way is to reverse-engineer it from the contents of pg_trigger.
7.3's contrib/adddepend will help you with this.

Okay, thanks. Is there any documentation for the pg_trigger table? It
seems to be missing from

http://www.postgresql.org/docs/
view.php?version=7.1&idoc=1&file=catalogs.html

If there are no docs, I can probably reverse-engineer the
reverse-engineering from findForeignKeys() in the adddepend script.

2) Is foreign key definition working properly via 'ALTER TABLE <table>
ADD ...' in 7.3.2?

No, there's a bug there --- ALTER ADD COLUMN neglects to process any
foreign-key clauses you might have written. This is fixed for 7.3.3.

Thanks.

-Ken

#4Tom Lane
tgl@sss.pgh.pa.us
In reply to: Ken Williams (#3)
Re: How foreign key info is stored

Ken Williams <ken@mathforum.org> writes:

Okay, thanks. Is there any documentation for the pg_trigger table? It
seems to be missing from
http://www.postgresql.org/docs/
view.php?version=7.1&idoc=1&file=catalogs.html

I think it's still the same now, so you could consult the more recent
docs which include it.

regards, tom lane