Thread: Foreign keys, table inheritance, and TRUNCATE

Foreign keys, table inheritance, and TRUNCATE

From
Florian Weimer
Date:
Here's something I've just noticed:

CREATE TABLE foo (f INTEGER PRIMARY KEY);
INSERT INTO foo VALUES (1);
CREATE TABLE bar (b INTEGER REFERENCES foo);
CREATE TABLE bar1 () INHERITS (bar);
INSERT INTO bar1 VALUES (1);

This is quite correct:

TRUNCATE foo;
ERROR:  cannot truncate a table referenced in a foreign key constraint
DETAIL:  Table "bar" references "foo".
HINT:  Truncate table "bar" at the same time, or use TRUNCATE ... CASCADE.

But:

TRUNCATE foo, bar;
SELECT * FROM bar;
 b
---
 1
(1 row)

SELECT * FROM foo;
 f
---
(0 rows)

Whoops.  The referential constraint has been violated.  Perhaps it's a
good idea to extend TRUNCATE on a parent table to all children?

--
Florian Weimer                <fweimer@bfk.de>
BFK edv-consulting GmbH       http://www.bfk.de/
Kriegsstraße 100              tel: +49-721-96201-1
D-76133 Karlsruhe             fax: +49-721-96201-99

Re: Foreign keys, table inheritance, and TRUNCATE

From
Alvaro Herrera
Date:
Florian Weimer wrote:
> Here's something I've just noticed:
>
> CREATE TABLE foo (f INTEGER PRIMARY KEY);
> INSERT INTO foo VALUES (1);
> CREATE TABLE bar (b INTEGER REFERENCES foo);
> CREATE TABLE bar1 () INHERITS (bar);
> INSERT INTO bar1 VALUES (1);
>
> This is quite correct:

No, it isn't; try leaving the first INSERT out:

alvherre=# CREATE TABLE foo (f INTEGER PRIMARY KEY);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo"
CREATE TABLE
alvherre=# CREATE TABLE bar (b INTEGER REFERENCES foo);
CREATE TABLE
alvherre=# CREATE TABLE bar1 () INHERITS (bar);
CREATE TABLE
alvherre=# INSERT INTO bar1 VALUES (1);
INSERT 0 1
alvherre=# select * from bar;
 b
---
 1
(1 fila)

alvherre=# select * from foo;
 f
---
(0 filas)

There is a bug here, but it's not in TRUNCATE.  FKs don't work with
inheritance.

--
Alvaro Herrera                                http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.