X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [200.46.204.144]) by svr1.postgresql.org (Postfix) with ESMTP id 04F6A8B9B5E for ; Mon, 7 Feb 2005 10:23:36 +0000 (GMT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 32070-01 for ; Mon, 7 Feb 2005 10:23:26 +0000 (GMT) Received: from fzkmail2.fzk.de (fzkmail2.fzk.de [141.52.27.52]) by svr1.postgresql.org (Postfix) with SMTP id 9D9CD8B9B6B for ; Mon, 7 Feb 2005 10:23:26 +0000 (GMT) Received: FROM resy5.fzk.de BY fzkmail2.fzk.de ; Mon Feb 07 11:23:13 2005 +0100 Received: from rodos.fzk.de (resy6.fzk.de [141.52.68.10]) by resy5.fzk.de (8.12.7/8.12.7/SuSE Linux 0.6) with ESMTP id j17AN8sG027288; Mon, 7 Feb 2005 11:23:12 +0100 Message-ID: <4207418B.E7807E82@rodos.fzk.de> Date: Mon, 07 Feb 2005 11:23:07 +0100 From: Christoph Haller X-Mailer: Mozilla 4.77 [en] (X11; U; HP-UX B.10.20 9000/780) X-Accept-Language: en MIME-Version: 1.0 To: maillist@shauny.de Cc: pgsql-sql@postgresql.org Subject: Re: Rule problem with OLD / NEW record set References: Content-Type: text/plain; charset=iso-8859-2 Content-Transfer-Encoding: 7bit X-Virus-Scanned: by AMaViS - amavis-milter (http://www.amavis.org/) X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, hits=0.039 tagged_above=0 required=5 tests=AWL X-Spam-Level: X-Archive-Number: 200502/99 X-Sequence-Number: 20210 Ralph Graulich wrote: > > Hello everyone, > > given is a table with a version history kind of thing I am currently > working on. Upon this table there is a view and the application interacts > with the view only, updating/inserting/deleting is controlled by rules. It > seems like the record set "OLD" gets changed when it is used in a SQL > expression: > > CREATE TABLE table1 > ( > id INTEGER NOT NULL, > version INTEGER NOT NULL DEFAULT 0, > vnoflag CHAR(1), > content VARCHAR(20) > ); > > INSERT INTO table1 (id, version, vnoflag, content) VALUES (1, 1, 'Y', > 'Test'); > > CREATE VIEW view_table1 AS SELECT * FROM table1; > > -- create a rule for update > CREATE OR REPLACE RULE ru_view_table1_update > AS > ON UPDATE TO view_table1 DO INSTEAD > ( > -- insert a new record with the old id, old version number incremented > -- by one, versionflag set to 'Y' and the new content > INSERT INTO table1 (id, version, vnoflag, content) VALUES (OLD.id, > OLD.version+1, 'Y', NEW.content); > -- update the old version and set its versionflag to 'N' as it is no > -- longer the current record > UPDATE table1 SET vnoflag = 'N' WHERE id = OLD.id AND version = > OLD.version; > ); > > SELECT * FROM view_table1; > id | version | vnoflag | content > ----+---------+---------+--------- > 1 | 1 | Y | Test > (1 row) > > UPDATE view_table1 SET content = 'New Test' WHERE id = 1 AND vnoflag = > 'Y'; > SELECT * FROM view_table1; > id | version | vnoflag | content > ----+---------+---------+---------- > 1 | 1 | N | Test > 1 | 2 | N | New Test > > It seems like the UPDATE statement updates both the old and the new > version. If I correctly go through the statements by hand, they should > read: > > INSERT INTO table1 (id, version, vnoflag, content) VALUES (1, 1+1, 'Y', > 'New Test'); > UPDATE table1 SET vnoflag = 'N' WHERE id = 1 AND version = 1; > > If I change the UPDATE statement to read: > > UPDATE table1 SET vnoflag = 'N' WHERE id = OLD.id AND vno = NEW.vno-1; > > it works like expected: > > id | version | vnoflag | content > ----+---------+---------+---------- > 1 | 2 | Y | New Test > 1 | 1 | N | Test > > Where is my logical error? Shouldn't the first UPDATE statement suffice? > > Best regards > ... Ralph ... > I've read your mail pretty late (meaning today), and I was surprised about what is happening the same you were. But after reading the manual $PGSQLD/doc/html/rules-update.html Chapter 34. The Rule System and especially 34.3.1.1. A First Rule Step by Step it became obvious what's going on behind a rule execution. HTH Regards, Christoph