11<!--
2- $PostgreSQL: pgsql/doc/src/sgml/advanced.sgml,v 1.43 2004/08/07 19:53:48 tgl Exp $
2+ $PostgreSQL: pgsql/doc/src/sgml/advanced.sgml,v 1.44 2004/08/08 01:51:05 momjian Exp $
33-->
44
55 <chapter id="tutorial-advanced">
@@ -108,7 +108,7 @@ CREATE TABLE cities (
108108);
109109
110110CREATE TABLE weather (
111- city varchar(80) references cities,
111+ city varchar(80) references cities(city) ,
112112 temp_lo int,
113113 temp_hi int,
114114 prcp real,
@@ -327,16 +327,97 @@ COMMIT;
327327 </indexterm>
328328
329329 <para>
330- Inheritance is a concept from object-oriented databases. It opens
331- up interesting new possibilities of database design.
330+ Inheritance is a concept from object-oriented databases. Although
331+ it opens up interesting new possibilities of database design,
332+ this feature is currently unmaintained and known to have serious
333+ gotchas in its foreign key implementation, which you should take
334+ care to avoid. The fixes below are probably version-specific and may
335+ require updates in the future.
336+ </para>
337+ <para>
338+ The example below illustrates the gotcha.
339+ </para>
340+ <para>
341+ <programlisting>
342+ BEGIN;
343+ CREATE TABLE foo (
344+ foo_id SERIAL PRIMARY KEY
345+ );
346+
347+ CREATE TABLE parent (
348+ parent_id SERIAL PRIMARY KEY
349+ , foo_id INTEGER NOT NULL REFERENCES foo(foo_id) ON DELETE CASCADE
350+ , parent_1_text TEXT NOT NULL
351+ );
352+
353+ CREATE TABLE child_1 (
354+ child_1_text TEXT NOT NULL
355+ ) INHERITS(parent);
356+
357+ CREATE TABLE child_2 (
358+ child_2_text TEXT NOT NULL
359+ ) INHERITS(parent);
360+
361+ INSERT INTO foo VALUES(DEFAULT);
362+ INSERT INTO child_1 (foo_id, parent_1_text, child_1_text)
363+ VALUES (currval('public.foo_foo_id_seq'), 'parent text 1', 'child_1 text 1');
364+
365+ INSERT INTO foo VALUES(DEFAULT);
366+ INSERT INTO child_1 (foo_id, parent_1_text, child_1_text)
367+ VALUES (currval('public.foo_foo_id_seq'), 'parent text 2', 'child_1 text 2');
368+
369+ INSERT INTO foo VALUES(DEFAULT);
370+ INSERT INTO child_2 (foo_id, parent_1_text, child_2_text)
371+ VALUES (currval('foo_foo_id_seq'), 'parent text 3', 'child_2 text 1');
372+
373+ DELETE FROM foo WHERE foo_id = 1;
374+
375+ SELECT * FROM parent;
376+ parent_id | foo_id | parent_1_text
377+ -----------+--------+---------------
378+ 1 | 1 | parent text 1
379+ 2 | 2 | parent text 2
380+ 3 | 3 | parent text 3
381+ (3 rows)
382+
383+ SELECT * FROM child_1;
384+ parent_id | foo_id | parent_1_text | child_1_text
385+ -----------+--------+---------------+----------------
386+ 1 | 1 | parent text 1 | child_1 text 1
387+ 2 | 2 | parent text 2 | child_1 text 2
388+ (2 rows)
389+ ROLLBACK;
390+ </programlisting>
391+
392+ </para>
393+ <para>
394+ Oops!! None of parent, child or foo should have any rows with
395+ foo_id = 1 in them. Here is a way to fix the above tables.
396+ </para>
397+
398+ <para>
399+ To fix the gotcha, you must put foreign key constraints on each of
400+ the child tables, as they will not be automatically inherited as
401+ you might expect.
402+ </para>
403+
404+ <para>
405+ <programlisting>
406+ ALTER TABLE child_1 ADD CONSTRAINT cascade_foo
407+ FOREIGN KEY (foo_id) REFERENCES foo(foo_id) ON DELETE CASCADE;
408+
409+ ALTER TABLE child_2 ADD CONSTRAINT cascade_foo
410+ FOREIGN KEY (foo_id) REFERENCES foo(foo_id) ON DELETE CASCADE;
411+ </programlisting>
332412 </para>
333413
334414 <para>
335- Let's create two tables: A table <classname>cities</classname>
336- and a table <classname>capitals</classname>. Naturally, capitals
337- are also cities, so you want some way to show the capitals
338- implicitly when you list all cities. If you're really clever you
339- might invent some scheme like this:
415+ That caveat out of the way, let's create two tables: A table
416+ <classname>cities</classname> and a table
417+ <classname>capitals</classname>. Naturally, capitals are also cities,
418+ so you want some way to show the capitals implicitly when you list all
419+ cities. If you're really clever you might invent some scheme like
420+ this:
340421
341422<programlisting>
342423CREATE TABLE capitals (
@@ -359,7 +440,7 @@ CREATE VIEW cities AS
359440</programlisting>
360441
361442 This works OK as far as querying goes, but it gets ugly when you
362- need to update several rows, to name one thing.
443+ need to update several rows, for one thing.
363444 </para>
364445
365446 <para>
0 commit comments