| From: | "Jens Hartwig" <jens(dot)hartwig(at)t-systems(dot)de> | 
|---|---|
| To: | "PSQL-Sql \(E-Mail\)" <pgsql-sql(at)postgresql(dot)org> | 
| Subject: | Problems with RULE | 
| Date: | 2001-03-06 07:11:48 | 
| Message-ID: | 001f01c0a60c$b6976f50$c10ac98a@0000864A433A | 
| Views: | Whole Thread | Raw Message | Download mbox | Resend email | 
| Thread: | |
| Lists: | 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 * FROM t_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(dot)hartwig(at)t-systems(dot)de
Internet: http://www.t-systems.de
| Attachment | Content-Type | Size | 
|---|---|---|
| rule_error_1.sql | application/octet-stream | 387 bytes | 
| rule_error_2.sql | application/octet-stream | 367 bytes | 
| rule_error_3.sql | application/octet-stream | 377 bytes | 
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Karel Zak | 2001-03-06 08:13:16 | Re: No Documentation for to_char(INTERVAL, mask) | 
| Previous Message | John GM | 2001-03-06 05:55:05 | Newbie: execute function error! |