Thread: "strange" rule behavior with nextval on new.* fields

"strange" rule behavior with nextval on new.* fields

From
Fabien COELHO
Date:
Dear debuggers,

I'd like to report the following "strange" behavior that I encountered
while trying (a bad idea, I know) to use a rule as a "poor man sql-trigger".

It seems that "on update do also" rules the new.* fields are evaluated
several times instead of being computed once, which is a bad idea, esp.
for "nextval".

As a consequence, my update does not work, i.e. new.id is actually
different from the id being used by the insert in the example so the
expected behavior that previous . [Note that even if it would work as I
expected, concurrent transaction could break the property.]

Anyway, it really looks like a strange behavior to me, so misleading and
unexpected that it could be qualified as a bug rather than a feature. I
did not spot such caveats by a quick look thru the documentation.

In the attached file, the result of 4 inserts is:

  id | data  | islast
----+-------+--------
   1 | one   | f
   3 | two   | f
   6 | three | f
  10 | four  | f

last_val is 14

Where I would rather have expected:

  id | data  | islast
----+-------+--------
   1 | one   | f
   2 | two   | f
   3 | three | f
   4 | four  | t

last_val should be 4

Have a nice day,

--
Fabien.

Re: "strange" rule behavior with nextval on new.* fields

From
Fabien COELHO
Date:
> I'd like to report the following "strange" behavior that I encountered
> while trying (a bad idea, I know) to use a rule as a "poor man sql-trigger".

I noticed that I forget about the bug report guidelines...

The above mentionned strange behavior is with a recent cvs tree, between
beta3 and beta4, on a debian linux box under an intel architecture.

--
Fabien Coelho - coelho@cri.ensmp.fr

Re: "strange" rule behavior with nextval on new.* fields

From
Michael Fuhr
Date:
On Wed, Nov 10, 2004 at 10:23:41AM +0100, Fabien COELHO wrote:

> It seems that "on update do also" rules the new.* fields are evaluated
> several times instead of being computed once, which is a bad idea, esp.
> for "nextval".

This comes up often and the response is usually something like,
"Rules are macros, which is why referring to NEW.id causes another
evaluation of nextval().  If you don't want that to happen then use
a trigger."

> Anyway, it really looks like a strange behavior to me, so misleading and
> unexpected that it could be qualified as a bug rather than a feature. I
> did not spot such caveats by a quick look thru the documentation.

This comes up often enough that maybe it warrants a "Caveats with
Rules" section in "The Rule System" chapter and a link to that
section in the CREATE RULE documentation, as well as mention in the
FAQ.

Thoughts from the developers?  I'd offer to write the additional
documentation but my understanding of the rule system is pretty
shallow.  Nevertheless, maybe I could at least write something
that others could build on.

--
Michael Fuhr
http://www.fuhr.org/~mfuhr/

Re: "strange" rule behavior with nextval on new.* fields

From
Tom Lane
Date:
Michael Fuhr <mike@fuhr.org> writes:
> This comes up often enough that maybe it warrants a "Caveats with
> Rules" section in "The Rule System" chapter and a link to that
> section in the CREATE RULE documentation, as well as mention in the
> FAQ.

Yeah.  I have also thought about reorganizing the docs so that triggers
are presented as being simpler than rules (come first, etc).  I think
right now the docs actively mislead newbies into choosing rules in cases
where triggers would be much better.

            regards, tom lane

Re: "strange" rule behavior with nextval on new.* fields

From
Fabien COELHO
Date:
Dear Tom,

>> This comes up often enough that maybe it warrants a "Caveats with
>> Rules" section in "The Rule System" chapter and a link to that section
>> in the CREATE RULE documentation, as well as mention in the FAQ.
>
> Yeah.  I have also thought about reorganizing the docs so that triggers
> are presented as being simpler than rules (come first, etc).  I think
> right now the docs actively mislead newbies into choosing rules in cases
> where triggers would be much better.

ISTM that having SQL as a language for trivial triggers would also help.
RULEs are SQL, although triggers must be C or PL*.

That could also be a candidate TODO, next to "improve the doc"?

Thanks for your answer,

--
Fabien Coelho - coelho@cri.ensmp.fr

Re: "strange" rule behavior with nextval on new.* fields

From
Fabien COELHO
Date:
Dear Michael,

> This comes up often and the response is usually something like,
> "Rules are macros, which is why referring to NEW.id causes another
> evaluation of nextval().  If you don't want that to happen then use
> a trigger."

That is indeed what I gathered;-)

It might be sensible to avoid multiple evaluations for the new.*
attributes when possible. I can foresee that it makes the implementation
less straightforward wrt to a pure tree-rewriting stuff.

Also, there is no such thing as a SQL trigger, so one needs to install
plpgsql to develop a simple trigger.

> This comes up often enough that maybe it warrants a "Caveats with
> Rules" section in "The Rule System" chapter

There is neither such section nor subsection in chapter "the rule system".
Maybe a sub-sub-section somewhere?

Table of Contents
32.1. The Query Tree
32.2. Views and the Rule System
     32.2.1. How SELECT Rules Work
     32.2.2. View Rules in Non-SELECT Statements
     32.2.3. The Power of Views in PostgreSQL
     32.2.4. Updating a View
32.3. Rules on INSERT, UPDATE, and DELETE
     32.3.1. How Update Rules Work
     32.3.2. Cooperation with Views
32.4. Rules and Privileges
32.5. Rules and Command Status
32.6. Rules versus Triggers

> and a link to that section in the CREATE RULE documentation, as well as
> mention in the FAQ.

I must admit that I did not look at the FAQ.

The general tone of the rule documentation is "look how great and powerful
it is", and somehow it is nearly as great as promised, but nearly only.

Well, thanks for your comment,

--
Fabien.