Unix Technical Forum

Rule problem with OLD / NEW record set

This is a discussion on Rule problem with OLD / NEW record set within the pgsql Sql forums, part of the PostgreSQL category; --> Hello everyone, given is a table with a version history kind of thing I am currently working on. Upon ...


Go Back   Unix Technical Forum > Database Server Software > PostgreSQL > pgsql Sql

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 04-19-2008, 10:54 AM
Ralph Graulich
 
Posts: n/a
Default Rule problem with OLD / NEW record set

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 ...

---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?

http://www.postgresql.org/docs/faq

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 04-19-2008, 10:56 AM
Christoph Haller
 
Posts: n/a
Default Re: Rule problem with OLD / NEW record set

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

---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 09:51 PM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
www.UnixAdminTalk.com