Problems with RULE - Mailing list pgsql-sql

From Jens Hartwig
Subject Problems with RULE
Date
Msg-id 001f01c0a60c$b6976f50$c10ac98a@0000864A433A
Whole thread Raw
Responses Re: Problems with RULE  (dev@archonet.com)
Re: Problems with RULE  (dev@archonet.com)
Re: Problems with RULE  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-sql
Hello all,

I tried to implement the following rule: if someone wants to delete a record
from a table t_xyz (id integer, deleted boolean) the record should get a
delete-flag (deleted = true). When this "pre-deleted" record is deleted for
the next time it should be physically deleted from the database.

I implemented the following rule:
 CREATE RULE r_del_xyz AS ON DELETE TO t_xyz WHERE (old.deleted = false) DO INSTEAD   UPDATE t_xyz   SET deleted = true
 WHERE id = old.id;
 

Now I tested the new rule:
 INSERT INTO t_xyz VALUES (1, false); INSERT INTO t_xyz VALUES (2, false); DELETE FROM t_xyz WHERE id = 1; SELECT *
FROMt_xyz ;
 
  id | deleted ----+---------   2 | f

What has happened? The rule seems to be ignored and the record was deleted!

I dropped the rule, deleted all records and recreated the rule without the
additional WHERE-Clause in the UPDATE-Statement:
 DROP RULE r_del_xyz;
 DELETE FROM t_xyz;
 CREATE RULE r_del_xyz AS ON DELETE TO t_xyz WHERE (old.deleted = false) DO INSTEAD   UPDATE t_xyz   SET deleted =
true;
 INSERT INTO t_xyz VALUES (1, false); INSERT INTO t_xyz VALUES (2, false);

The same test again:
 DELETE FROM t_xyz WHERE id = 1; SELECT * FROM t_xyz ;
  id | deleted ----+---------   2 | t

It seems to me that PostgreSQL executed the rule, but ignored the keyword
INSTEAD and deleted the record after having updated it?!

One last test with a slightly different rule (look at the WHERE-clause in
the "AS-ON"-clause):
 DROP RULE r_del_xyz;
 DELETE FROM t_xyz;
 CREATE RULE r_del_xyz AS ON DELETE TO t_xyz WHERE (1 = 1) DO INSTEAD   UPDATE t_xyz   SET deleted = true   WHERE id =
old.id;
 INSERT INTO t_xyz VALUES (1, false); INSERT INTO t_xyz VALUES (2, false);
 DELETE FROM t_xyz WHERE id = 1; SELECT * FROM t_xyz ;
  id | deleted ----+---------   2 | f   1 | t
 DELETE FROM t_xyz WHERE id = 1; SELECT * FROM t_xyz ;

Everything is alright now! Am I wrong? Is the WHERE-clause "WHERE
(old.deleted = false)" not correct? Any hints? Or it is really a bug?

Best regards, Jens Hartwig

PS: You will find the scripts in the attachment.

-----------------------------------------------------

T-Systems
Projektleiter
debis Systemhaus GEI GmbH
Hausanschrift: Eichhornstraße 3, 10785 Berlin
Postanschrift: 10785 Berlin
Telefon: (004930) 25 54-32 82
Telefax: (004930) 25 54-31 87
Mobiltelefon: (0170) 167 26 48
E-Mail: jens.hartwig@t-systems.de
Internet: http://www.t-systems.de

pgsql-sql by date:

Previous
From: Karel Zak
Date:
Subject: Re: No Documentation for to_char(INTERVAL, mask)
Next
From: Markus Fischer
Date:
Subject: Comparing dates