create sequence seq_foo_id; create table foo_table ( id int8 default nextval('seq_foo_id') ); create table bar_table ( id int8 default nextval('seq_foo_id'), -- yes, foo_id title text ); create table dog_table ( id int8 default nextval('seq_foo_id'), -- yes, foo_id title text, name varchar(255) ); create table cat_table ( id int8 default nextval('seq_foo_id'), -- yes, foo_id position text ); create view foo as select * from foo_table; create view bar as select * from bar_table; create view dog as select * from dog_table; create view cat as select * from cat_table; create rule foo_rule_insert as on insert to foo do instead ( insert into foo_table (id) values (case when NEW.id is null then nextval('seq_foo_id') else NEW.id end); ); create rule bar_rule_insert as on insert to bar do instead ( insert into bar_table (id, title) values (case when NEW.id is null then nextval('seq_foo_id') else NEW.id end, NEW.title); insert into foo_table (id) select id from bar_table where id = currval('seq_foo_id'); ); create rule dog_rule_insert as on insert to dog do instead ( insert into dog_table (id, title, name) values (case when NEW.id is null then nextval('seq_foo_id') else NEW.id end, NEW.title, NEW.name); insert into bar_table (id, title) select id, title from dog_table where id = currval('seq_foo_id'); insert into foo_table (id) select id from dog_table where id = currval('seq_foo_id'); ); create rule cat_rule_isnert as on insert to cat do instead ( insert into cat_table (id, position) values (case when NEW.id is null then nextval('seq_foo_id') else NEW.id end, NEW.position); insert into foo_table (id) select id from cat_table where id = currval('seq_foo_id'); ); create or replace function fn_dog_after_insert () returns OPAQUE as ' BEGIN -- -- THIS IS WHAT CAUSES THINGS TO FAIL IN 7.3.2 -- -- Some experimentation has shown that I can insert -- into other *tables*, but trying to insert into views (w/ rules) -- causes things to break -- insert into cat (position) values (''position''); RETURN NEW; END; ' language 'plpgsql'; create trigger tr_dog_after_insert after insert on dog_table for each row execute procedure fn_dog_after_insert(); -- -- this will cause the after insert trigger to insert -- a record into "cat", which then causes postgres to log: -- -- FATAL: SPI: improper call to spi_dest_setup -- insert into dog (title, name) values ('my title', 'my name'); select * from foo; select * from bar; select * from dog; select * from cat;