5.5. H�ritage

Cr�ons deux tables. La table capitales contient les capitales d'�tat qui sont aussi des villes. Naturellement, la table capitales doit h�riter de villes.

CREATE TABLE villes (
    name            text,
    population      float,
    altitude        int     -- (in ft)
);

CREATE TABLE capitales (
    state           char(2)
) INHERITS (villes);

Dans ce cas une rang�e de capitales h�rite tout les attributs (nom, population, et altitude) de son parent villes. Le type de l'attribut name est text, un type natif de PostgreSQL pour des cha�nes de caract�res de longueur variable. Le type de l'attribut population est float, un type natif de PostgreSQL pour les nombres flottants de pr�cision double. Les capitales d'�tats ont un attribut suppl�mentaire state qui donne leur �tat. Dans PostgreSQL, une table peut h�riter de z�ro tables ou plus et une requ�te peut r�f�rencer toutes les rang�es d'une table ou toutes les rang�es d'une table plus celles de ses descendants.

Note�: La hi�rarchie d'h�ritage est en fait un graphe acyclique dirig�.

Par exemple, la requ�te suivante cherche les noms de toutes les villes, y compris les capitales d'�tat, qui se situent � une altitude de plus de 500 pieds:

SELECT name, altitude
    FROM villes
    WHERE altitude > 500;

qui retourne:

   name    | altitude
-----------+----------
 Las Vegas |     2174
 Mariposa  |     1953
 Madison   |      845

D'un autre c�t�, la requ�te suivante cherche toutes les villes qui ne sont pas des capitales d'�tat et qui sont situ�s � une altitude de plus de 500 pieds:

SELECT name, altitude
    FROM ONLY villes
    WHERE altitude > 500;

   name    | altitude
-----------+----------
 Las Vegas |     2174
 Mariposa  |     1953

Ici, le <<�ONLY�>> avant villes indique que la requ�te ne devrait �tre lanc�e que sur villes et non les tables en dessous de villes dans la hi�rarchie d'h�ritage. Beaucoup des commandes donc nous avons d�j� discut� -- SELECT, UPDATE et DELETE -- g�rent cette syntaxe <<�ONLY�>>.

Dans certain cas, vous souhaiterez savoir dans quel table provient une rang�e donn�e. Il y a une colonne syst�me appel�e TABLEOID dans chaque table qui peut vous donner la table d'origine:

SELECT c.tableoid, c.name, c.altitude
FROM villes c
WHERE c.altitude > 500;

qui renvoie :

 tableoid |   name    | altitude
----------+-----------+----------
   139793 | Las Vegas |     2174
   139793 | Mariposa  |     1953
   139798 | Madison   |      845

(Si vous essayez de reproduire cet exemple, vous obtiendrez probablement des OIDs num�riques diff�rents.) En faisant une jointure avec pg_class, vous pourrez voir les noms de tables actuelles:

SELECT p.relname, c.name, c.altitude
FROM villes c, pg_class p
WHERE c.altitude > 500 and c.tableoid = p.oid;

ce qui retourne:

 relname   |   name    | altitude
-----------+-----------+----------
 villes    | Las Vegas |     2174
 villes    | Mariposa  |     1953
 capitales | Madison   |      845

Obsol�te�: Dans les versions pr�c�dentes de PostgreSQL, le comportement par d�faut �tait de ne pas inclure les tables filles dans les requ�tes. Ceci provoquait des erreurs et �tait aussi en violation du standard SQL99. Sous l'ancienne syntaxe, pour avoir les sous-tables, il fallait ajouter * au nom de la table. Par exemple

SELECT * from villes*;

Vous pouvez toujours pr�ciser explicitement les tables filles en rajoutant * en plus de sp�cifier explicitement de ne pas parcourir les tables filles en �crivant <<�ONLY�>>. Mais, a partir de la version 7.1, le comportement par d�faut pour un nom de table brut est de parcourir aussi ses tables filles bien qu'avant, la norme �tait de ne pas le faire. Pour retrouver l'ancien comportement, mettez l'option de configuration SQL_Inheritance � off, i.e.,

SET SQL_Inheritance TO OFF;

ou ajoutez une ligne dans votre fichier postgresql.conf.

Une limite de la fonctionnalit� d'h�ritage est que les indexes (y compris les contraintes uniques) et les contraintes de cl�s �trang�res ne s'appliquent qu'aux tables seules et non leurs descendants d'h�ritage. Donc, dans l'exemple pr�c�dant, sp�cifier qu'une colonne d'une autre table REFERENCES villes(name) autorisera l'autre table a contenir des noms de villes mais pas de noms de capitales. Cette lacune sera probablement corrig�e dans une future version.