I'm trying to figure out why a rule gives me a uniqueness violation when I try to do an update.
I have a table, "my_data", defined as: create table my_data ( id INT8 not null default nextval('person_seq'), effective_date_and_time TIMESTAMP WITH TIME ZONE not null default CURRENT_TIMESTAMP, expiration_date_and_time TIMESTAMP WITH TIME ZONE null default 'infinity', user_name VARCHAR(255)null, constraint PK_MY_DATA primary key (effective_date_and_time, id) ); I have a view, my_data_now, defined as: SELECT my_data.id, my_data.user_name, my_data.effective_date_and_time, my_data.expiration_date_and_time FROM my_data WHERE my_data.effective_date_and_time <= 'now'::text::timestamp(6) with time zone AND my_data.expiration_date_and_time >= 'now'::text::timestamp(6) with time zone; And I have this rule (among others): CREATE OR REPLACE RULE upd_my_data_now AS ON UPDATE TO my_data_now DO INSTEAD ( /* Update current record, and make it effective now. */ UPDATE my_data SET id = NEW.id, user_name = NEW.user_name, effective_date_and_time = ('now'::text)::timestamp(6) with time zone WHERE effective_date_and_time = OLD.effective_date_and_time AND id = OLD.id; /* Insert a record containing the old values, and expire it as of now. */ INSERT INTO my_data ( effective_date_and_time, expiration_date_and_time, id, user_name) VALUES ( OLD.effective_date_and_time, ('now'::text)::timestamp(6) with time zone, OLD.id, OLD.user_name) ) ; This rule is supposed to (1) cause an update directed to the view "my_data_now" to be made to the underlying table "my_data", (2) reset the "effective_date_and_time" of that row to 'now', (3) insert a record containing the old values into "my_data", and (4) expire that "old" record by setting its "expiration_date_and_time" to 'now'. But when I try to do an update against the view "my_data_now" with a query such as: update my_data_now set user_name = 'Suzy' where id = 1; I get: ERROR: duplicate key violates unique constraint "pk_my_data" Presumably this happens when the rule tries to insert the new row. The new row does indeed contain the "old" id and effective_date_and_time. However, the rule is structured so that the current row's "effective_date_and_time" gets updated to 'now' *before* the new row is inserted, making its value different from the old "effective_date_and_time". So the uniqueness conflict shouldn't occur. I figure either there's some bug in my code that I can't see, or else the PostgreSQL rule processor works in some way that I don't understand. In either case, help! ~ TIA ~ Ken ---------------------------(end of broadcast)--------------------------- TIP 4: Have you searched our list archives? http://archives.postgresql.org