Re: Inheritance and constraints duplicate values - Mailing list pgsql-bugs

From Oliver Elphick
Subject Re: Inheritance and constraints duplicate values
Date
Msg-id 1093376045.15248.20.camel@linda
Whole thread Raw
In response to Inheritance and constraints duplicate values  ("Marian Lojka" <911@inmail.sk>)
List pgsql-bugs
On Sat, 2004-08-21 at 12:44, Marian Lojka wrote:
> After doing some research, this is apparently a known long-standing
> issue with inheritance in Postgres. Nobody calls it a "bug" outright,
> though. Just a limitation. It makes me wonder how others have tackled
> problems of a similar nature.

> CREATE TABLE products (
> id serial NOT NULL PRIMARY KEY,
> name varchar(64) NOT NULL,
> price numeric(6,2)
> );
>
> CREATE TABLE pants (
> waist smallint,
> length smallint,
> colour varchar(12)
> ) inherits (products);
>
> CREATE TABLE computers (
> cpu varchar(12),
> mhz smallint,
> ) inherits (products);
>
> INSERT INTO pants (name,price,waist,length,colour)
> VALUES ('Brand-X Cargo Pants', 49.95, 32, 34, 'khaki');
>
> INSERT INTO computers (name,price,cpu,mhz)
> VALUES ('Flower Power iMac', $666.66, 'Motorola 750', 500);

> INSERT INTO computers (id, name,price,cpu,mhz)
> VALUES (1, 'Mac Plus', $5.00, 'Motorola 68000', 8);
>
> SELECT id,name FROM products;
>
> --> 1 Brand-X Cargo Pants
> --> 1 Mac Plus
> --> 2 Flower Power iMac
>
>
> Huh? But products.id is a primary key! The "Mac Plus" screwed it up by
> inserting duplicate values!

Unfortunately it's only a primary key in the parent table; that
constraint is not inherited.

To implement foreign keys on an inheritance hierarchy would require
indexes that could index multiple tables.  As far as I know, that is not
currently possible.

The work-around is to create another table

  CREATE TABLE product_xref (
    id serial PRIMARY KEY
  );

then

  ALTER TABLE products ADD CONSTRAINT FOREIGN KEY (id) references
product_xref(id);

(and id in products should not be a serial field, or the default should
be explicitly set to nextval(product_xref_id_seq))

and the same for each child table

Then create a trigger function to create a record in product_xref on
insertion and delete it on deletion.

--
Oliver Elphick                                          olly@lfix.co.uk
Isle of Wight                              http://www.lfix.co.uk/oliver
GPG: 1024D/A54310EA  92C8 39E7 280E 3631 3F0E  1EC0 5664 7A2F A543 10EA
                 ========================================
     "I saw in the night visions, and, behold, one like the
      Son of man came with the clouds of heaven, and came to
      the Ancient of days, and they brought him near before
      him. And there was given him dominion, and glory, and
      a kingdom, that all people, nations, and languages,
      should serve him; his dominion is an everlasting
      dominion, which shall not pass away, and his kingdom
      that which shall not be destroyed."
                                    Daniel 7:13,14

pgsql-bugs by date:

Previous
From: Reini Urban
Date:
Subject: 8.0.0b1 cygwin problems
Next
From: Tom Lane
Date:
Subject: Re: server crash in very big transaction [postgresql 8.0beta1]