Values do not converge in a very interesting way, namely the following nextval is used. If the insert id is set explicitly, the rule copies the data normally. Apparently, this is the problem, the second insert receives the default value of the column again.
It seems that the rule system works initially .
Experimenting
create function testnotice() returns bigint as $$ begin raise notice 'executed'; return 1; end $$ language plpgsql; alter table test add column tescolumn bigint default testnotice(); alter table v_test add column tescolumn bigint; CREATE OR REPLACE RULE insert AS ON INSERT TO test DO INSERT INTO v_test (v_id, v_name, tescolumn) VALUES (new.id, new.name, new.tescolumn);
try to write something down:
melkij=# insert into test(name) values ('6'); NOTICE: executed NOTICE: executed INSERT 0 1
So it is, the function for the default field is called twice. serial / bigserial, which are actually macros for default nextval(sequencename) , are therefore also called twice.
As new.* not the values from the result of some query that are substituted, but the declaration of the columns directly: the values specified explicitly in the insert or default query.
Use the after insert trigger instead. It will have the expected behavior and in NEW it will provide the values of the already written string.