Règles de PostgreSQL et problème nextval () / serial (très spécifique à PostgreSQL)

Lorsque j'utilise une règle de réécriture qui se fend d'une insertion dans une table en insertions de deux autres tables où l'un de l'insertion des valeurs par défaut nextval('some_sequence') avec le même ordre pour les deux tables, puis l'insertion des valeurs par défaut sont différents dans les deux tables. Ceci est probablement dû à un simple texte de remplacement par la règle de réécriture. J'avais espéré au lieu de la valeur par défaut serait d'abord résolu et puis la même valeur écrite dans les deux tables.

Voici un exemple (comme vous avez pu le deviner, je suis en train de mettre en œuvre de spécialisation/généralisation à l'aide de règles):

-- first and third commands can be skipped if id is defined as serial
create sequence parents_id_seq;
create table Parents(
  id integer default(nextval('parents_id_seq')) primary key,
  type varchar(50) not null check(type in ('Child1', 'Child2')),
  unique (id, type),
  attribute1 varchar(50) not null unique check(length(attribute1) > 0)
);
alter sequence parents_id_seq owned by parents.id;

Les données spécifiques à l'enfant le premier est conservé dans

create table Partial_Children1(
  id integer default(nextval('parents_id_seq')) primary key,
  type varchar(50) not null check(type = 'Child1'),
  foreign key (id, type) references Parents(id, type),
  attribute2 varchar(50) not null check(length(attribute2) > 0)
);

Ensuite, j'ai défini une vue Enfants1 qui joint les deux tableaux ci-dessus (je l'ai réécrit le point de vue en précisant explicitement que PostgreSQL n'a à définir des vues en fonction de la documentation)

create table Children1(
  id int default(nextval('parents_id_seq')),
  type varchar(50) not null check(type in ('Child1')),
  attribute1 varchar(50) not null check(length(attribute1) > 0),
  attribute2 varchar(50) not null check(length(attribute2) > 0)
);
create rule "_RETURN" as on select to Children1 do instead
  select p.*, c.attribute2
  from Parents p
    join Partial_Children1 c
      on p.id = c.id;

Enfin, la règle de réécriture, je vais avoir des problèmes avec:

create rule ct_i_children1 as
  on insert to Children1
  do instead (
    insert into Parents(attribute1, type)
      values(new.attribute1, 'Child1');
    insert into Partial_Children1(attribute2, type)
      values(new.attribute2, 'Child1');
  );

Essayer d'insérer des données avec

insert into Children1 (attribute1, attribute2)
  values ('a1', 'a2'),
         ('b1', 'b2');

donne le message d'erreur

ERROR:  insert or update on table "partial_children1" violates foreign key constraint "partial_children1_id_fkey"
DETAIL:  Key (id,type)=(3,Child1) is not present in table "parents".

Un moyen de résoudre ce problème est le remplacement de la deuxième insertion de la règle de réécriture par

insert into Partial_Children1(id, attribute2, type)
  select p.id, new.attribute2, p.type
    from Parents p
    where p.attribute1 = new.attribute1

mais cela repose sur l'unicité de attribut1, je ne veux pas imposer. Une autre solution serait d'insérer les valeurs dans une table temporaire, et ensuite de sélectionner deux fois pour les insertions dans les deux tables. Mais je ne l'aime pas parce que des raisons de performances.

Quelqu'un a une autre idée de la façon d'obtenir les mêmes valeurs par défaut dans les deux tables (juste à l'aide de règles et pas déclencheurs)?

source d'informationauteur j.p. | 2009-08-24