Thread: Rule trouble (looks to me exactly like the example)

Rule trouble (looks to me exactly like the example)

From
Frank Joerdens
Date:
This is my table:

CREATE TABLE tree (
id                      serial PRIMARY KEY,
parentid            int4 NOT NULL REFERENCES tree ( id ),
ordering        int4 NOT NULL,
leveling        int4 NOT NULL,
status            int4 NOT NULL,
title            text NOT NULL
);

And here's the rule (it doesn't do anything real or interesting, I just
simplified it to the point where it looked like the example):

CREATE RULE insert_level AS
ON INSERT TO tree
WHERE new.id > 0 DO
UPDATE tree SET leveling = 1
WHERE tree.oid = new.oid;

which looks to me like one of the examples in Bruce's book (page 299 in
my pdf version):

CREATE RULE example_5 AS
ON INERT TO emp
WHERE new.salary > 5000 DO
UPDATE emp SET salary = 5000
WHERE emp.oid = new.oid;

If I do an insert like

INSERT INTO tree (parentid,ordering,leveling,status,title)
VALUES (0,0,0,1,'foo');

nothing happens to the leveling column though:

archiweb=# select * from tree ;id | parentid | ordering | leveling | status |   title
----+----------+----------+----------+--------+----------- 0 |        0 |        0 |        0 |      0 | root node11 |
     0 |        0 |        0 |      1 | foo12 |        0 |        0 |        0 |      1 | foo
 
(3 rows)

Although the rule definitely is there:

archiweb=# select tablename,rulename from pg_rules;tablename |   rulename
-----------+--------------tree      | insert_level
(1 row)

(the definition column looks ok too, I didn't include it because it'd
look all messed up in the email here because it's in a single line.)

I am using Postgres version 7.2.1 on Linux.

Can anyone explain that?

Regards, Frank


Re: Rule trouble (looks to me exactly like the example)

From
Tom Lane
Date:
Frank Joerdens <frank@joerdens.de> writes:
> And here's the rule (it doesn't do anything real or interesting, I just
> simplified it to the point where it looked like the example):

> CREATE RULE insert_level AS
> ON INSERT TO tree
> WHERE new.id > 0 DO
> UPDATE tree SET leveling = 1
> WHERE tree.oid = new.oid;

What's happening is that "new.id" is effectively still NULL at the point
where the rule is processed, so the rule WHERE condition fails.  I'm not
sure why you're bothering with that WHERE condition anyway ... but this
seems to be another argument for moving INSERT's default-value-insertion
step to before the rule rewriter.  (There was some discussion of this
point just a few days ago, IIRC.)
        regards, tom lane


Re: Rule trouble (looks to me exactly like the example)

From
Tom Lane
Date:
I wrote:
> What's happening is that "new.id" is effectively still NULL at the point
> where the rule is processed, so the rule WHERE condition fails.  I'm not
> sure why you're bothering with that WHERE condition anyway ... but this
> seems to be another argument for moving INSERT's default-value-insertion
> step to before the rule rewriter.

I've committed fixes for this into CVS tip.
        regards, tom lane


Re: Rule trouble (looks to me exactly like the example)

From
Frank Joerdens
Date:
On Thu, Apr 04, 2002 at 02:29:13PM -0500, Tom Lane wrote:
> Frank Joerdens <frank@joerdens.de> writes:
> > And here's the rule (it doesn't do anything real or interesting, I just
> > simplified it to the point where it looked like the example):
> 
> > CREATE RULE insert_level AS
> > ON INSERT TO tree
> > WHERE new.id > 0 DO
> > UPDATE tree SET leveling = 1
> > WHERE tree.oid = new.oid;
> 
> What's happening is that "new.id" is effectively still NULL at the point
> where the rule is processed, so the rule WHERE condition fails.  I'm not
> sure why you're bothering with that WHERE condition anyway ... 

Without the WHERE condition, all rows are affected by the update, and
not just the newly inserted one.

Regards, Frank


Re: Rule trouble (looks to me exactly like the example)

From
Tom Lane
Date:
Frank Joerdens <frank@joerdens.de> writes:
>> What's happening is that "new.id" is effectively still NULL at the point
>> where the rule is processed, so the rule WHERE condition fails.  I'm not
>> sure why you're bothering with that WHERE condition anyway ... 

> Without the WHERE condition, all rows are affected by the update, and
> not just the newly inserted one.

I was speaking of the WHERE new.id > 0 part.  However, given that you
want to affect only the newly-inserted row, ISTM you'd be a lot better
off with a trigger instead of a rule.
        regards, tom lane


Re: Rule trouble (looks to me exactly like the example)

From
Frank Joerdens
Date:
On Fri, Apr 05, 2002 at 10:42:18AM -0500, Tom Lane wrote:
> Frank Joerdens <frank@joerdens.de> writes:
> >> What's happening is that "new.id" is effectively still NULL at the point
> >> where the rule is processed, so the rule WHERE condition fails.  I'm not
> >> sure why you're bothering with that WHERE condition anyway ... 
> 
> > Without the WHERE condition, all rows are affected by the update, and
> > not just the newly inserted one.
> 
> I was speaking of the WHERE new.id > 0 part.

Oh yes, that's silly indeed. I just put it there to make the query look like
the example.

>  However, given that you
> want to affect only the newly-inserted row, ISTM you'd be a lot better
> off with a trigger instead of a rule.

I'll give that a try!

Thanks, Frank