Обсуждение: Strange order of execution with rule

Поиск
Список
Период
Сортировка

Strange order of execution with rule

От
han.holl@informationslogik.nl
Дата:
Hello,

I have something like this:
CREATE or replace rule update_rule as on update
    to aview
    do instead (
      select func_display(new, old);
      select rubriek('reset', 0, '', 0);
    );

(Postgres 8.0.3).

I tried all kinds of variations (one select with two functions, and two
different update rules with a select each) but in _all_ cases the second
function is executed before the first, or possibly at the same time (but I
didn't think the backend is threaded).

Is this known behaviour, and what can I do to change it?

Thanks in advance for any suggestions,

Han Holl

P.S. I don't know if it's relevant but what func_display and rubriek do has
nothing to do with the database. Let's say they do some kind of logging.

Re: Strange order of execution with rule

От
Tom Lane
Дата:
han.holl@informationslogik.nl writes:
> I have something like this:
> CREATE or replace rule update_rule as on update
>     to aview
>     do instead (
>       select func_display(new, old);
>       select rubriek('reset', 0, '', 0);
>     );

> I tried all kinds of variations (one select with two functions, and two
> different update rules with a select each) but in _all_ cases the second
> function is executed before the first, or possibly at the same time (but I
> didn't think the backend is threaded).

Give us a test case to demonstrate this assertion.  It works as expected
AFAICT.

regression=# create function noti(text) returns int as $$
regression$# begin
regression$#   raise notice '%', $1;
regression$#   return 1;
regression$# end$$ language plpgsql;
CREATE FUNCTION
regression=# CREATE or replace rule update_rule as on update to zview
regression-# do instead (
regression(#   select noti('foo');
regression(#   select noti('bar');
regression(# );
CREATE RULE
regression=# update zview set q1 = q2;
NOTICE:  foo
NOTICE:  bar
 noti
------
    1
(1 row)


            regards, tom lane

Re: Strange order of execution with rule

От
han.holl@informationslogik.nl
Дата:
On Thursday 20 October 2005 23:48, Tom Lane wrote:

> Give us a test case to demonstrate this assertion.  It works as expected
> AFAICT.
>
Indeed it does. I forgot to mention that the first function to be called was
language plruby. Maybe that has anything to do with it.
I'll try to come with something more concrete.

Thanks,

Han Holl

Re: Strange order of execution with rule

От
han.holl@informationslogik.nl
Дата:
On Thursday 20 October 2005 23:48, Tom Lane wrote:

> Give us a test case to demonstrate this assertion.  It works as expected
> AFAICT.
>
Ok, it has to do with C functions:
#include <postgres.h>
#include <fmgr.h>
#include <sys/time.h>


PG_FUNCTION_INFO_V1(plg_cfie);
Datum
plg_cfie(PG_FUNCTION_ARGS)
{
        struct timeval before;
        gettimeofday(&before, 0);
        elog(NOTICE, "Called cfie %ld.%ld\n",before.tv_sec, before.tv_usec);
        PG_RETURN_NULL();
}
/* end-of-plg_cfie */
gcc -fpic -O2 -Wall -c -I /usr/include/pgsql/server/ plg_cfie.c
gcc -shared -o /tmp/plg_cfie.so plg_cfie.o

File test:
CREATE or replace FUNCTION func_display(udps, udps) RETURNS void AS '
  a = Time.now
  warn sprintf("Called func_display %d.%d", a.tv_sec, a.tv_usec)
  ' LANGUAGE 'plruby';

create or replace function plg_cfie() returns void as '/tmp/plg_cfie.so'
language c immutable;

CREATE or replace rule update_rule as on update
    to udps
    do instead (
      select func_display(new, old);
      select plg_cfie();
    );

update udps set ziekenhuis = 'olvg' where rapport = 'T105-00002';
-- end of file test
su postgres -c 'psql palga' <test

CREATE FUNCTION
CREATE FUNCTION
CREATE RULE
NOTICE:  Called cfie 1129893542.714536

NOTICE:  Called func_display 1129893542.732444
 plg_cfie
----------

(1 row)

It's not a plruby issue, I tested with plpgsql (your noti) as well.

Cheers,

Han Holl





Re: Strange order of execution with rule

От
Tom Lane
Дата:
han.holl@informationslogik.nl writes:
> On Thursday 20 October 2005 23:48, Tom Lane wrote:
>> Give us a test case to demonstrate this assertion.  It works as expected
>> AFAICT.

> Ok, it has to do with C functions:

> create or replace function plg_cfie() returns void as '/tmp/plg_cfie.so'
> language c immutable;

You should not declare a function "immutable" if it has side effects
(such as emitting a message).  That entitles the planner to pre-evaluate
the function at plan time, which is evidently what's happening here.

            regards, tom lane