Las reglas de PostgreSQL y el problema nextval () / serial (muy específico de PostgreSQL)

Cuando utilizo una regla de reescritura que divide una inserción en una tabla en inserciones en otras dos tablas donde uno de los valores insertados tiene el siguiente valor predeterminado ('some_sequence') con la misma secuencia para ambas tablas, entonces los valores predeterminados insertados son diferentes en las dos mesas Esto probablemente se deba a un simple reemplazo de texto por la regla de reescritura. Esperaba que el valor predeterminado se resolviera primero y luego se escribiera el mismo valor en ambas tablas.

Aquí un ejemplo (como probablemente adivines, estoy tratando de implementar la especialización / generalización usando reglas):

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

Los datos específicos de los niños del primer tipo se mantienen en

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

A continuación, definí una vista Children1 que une las dos tablas anteriores (reescribí la vista declarando explícitamente qué hace PostgreSQL para definir las vistas de acuerdo con la documentación)

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;

Finalmente la regla de reescritura estoy teniendo problemas con:

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

Tratando de insertar datos con

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

muestra el mensaje de error

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

Una forma de resolver esto es reemplazar la segunda inserción de la regla de reescritura por

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

pero esto se basa en la singularidad de attribute1, que no quiero imponer. Otra solución sería insertar los valores primero en una tabla temporal, y luego seleccionar dos veces desde allí para las inserciones en las dos tablas. Pero no me gusta por razones de rendimiento.

¿Alguien tiene otra idea de cómo obtener los mismos valores predeterminados en ambas tablas (solo usando reglas yno desencadenantes)?

Respuestas a la pregunta(2)

Su respuesta a la pregunta