Reguły PostgreSQL i nextval () / problem seryjny (bardzo specyficzny dla PostgreSQL)

Gdy używam reguły przepisywania, która dzieli wstawkę na jedną tabelę na wstawki do dwóch innych tabel, w których jedna z wprowadzonych wartości ma domyślną wartość nextval („niektóre_sekwencje”) z tą samą sekwencją dla obu tabel, wówczas wprowadzone wartości domyślne są różne w dwie tabele. Jest to prawdopodobnie spowodowane prostą wymianą tekstu przez regułę przepisywania. Miałem nadzieję, że zamiast tego domyślna wartość zostanie najpierw rozwiązana, a następnie ta sama wartość zostanie zapisana w obu tabelach.

Oto przykład (jak się pewnie domyślasz, próbuję zaimplementować specjalizację / uogólnienie za pomocą reguł):

-- 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;

Dane specyficzne dla dzieci pierwszego rodzaju są przechowywane w

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)
);

Następnie zdefiniowałem widok Children1, który łączy obie tabele powyżej (przepisałem widok, wyraźnie określając, co robi PostgreSQL, aby zdefiniować widoki zgodnie z dokumentacją)

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;

Wreszcie reguła przepisywania, z którą mam problemy:

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');
  );

Próbuję wstawić dane za pomocą

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

wyświetla komunikat o błędzie

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".

Sposobem na rozwiązanie tego problemu jest zastąpienie drugiej wstawki reguły przepisywania przez

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

ale to zależy od wyjątkowości atrybutu1, którego nie chcę narzucać. Innym rozwiązaniem byłoby wstawienie wartości najpierw do tabeli tymczasowej, a następnie dwukrotne wybranie stamtąd wstawień do dwóch tabel. Ale nie podoba mi się to ze względu na wydajność.

Czy ktoś ma inny pomysł, jak uzyskać te same wartości domyślne w obu tabelach (tylko używając reguł inie wyzwalacze)?

questionAnswers(2)

yourAnswerToTheQuestion