Re: rule on insert with default values for new instance

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Janning Vygen <vygen(at)planwerk6(dot)de>
Cc: "PostgreSQL-General" <pgsql-general(at)postgresql(dot)org>
Subject: Re: rule on insert with default values for new instance
Date: 2001-06-19 14:03:31
Message-ID: 22577.992959411@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Janning Vygen <vygen(at)planwerk6(dot)de> writes:
> CREATE TABLE user (id SERIAL, name text);

> CREATE RULE startaccount AS ON INSERT
> TO user
> DO INSERT INTO account (name) VALUES
> (new.id, new.name);

> i get problems because it seems to me that new.id is not defined at the
> moment i do the insert.

The problem here is that NEW is basically a macro, not a variable.
When you say
INSERT INTO user(name) VALUES ('Joe');
the default expression for id gets inserted:
INSERT INTO user(id,name) VALUES (nextval('user_id_seq'), 'Joe');
and then the rule gets expanded to:
INSERT INTO account VALUES (nextval('user_id_seq'), 'Joe');

See the problem? nextval() gets evaluated twice, so a different ID gets
inserted into account.

AFAIK you can't work around this with a rule. You need to use a trigger
instead. The trigger is passed the already-formed tuple proposed for
insertion into "user", so it can extract the correct value to insert
into "account".

The rule stuff is pretty powerful, but more often than not it's the
wrong tool when you just want to examine single tuples being
inserted/updated/deleted.

regards, tom lane

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Tom Lane 2001-06-19 14:20:18 Re: [PATCHES] [PATCH] Contrib C source for casting MONEY to INT[248] and FLOAT[48]
Previous Message Tom Lane 2001-06-19 13:55:15 Re: Update and cursor