Re: BUG #17827: Rule on insert into table doesn't work when excepting select from the table itself

From: Hanna Yanchurevich <hyanchurevich(at)spotware(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #17827: Rule on insert into table doesn't work when excepting select from the table itself
Date: 2023-03-10 08:18:54
Message-ID: CAGcHEgJkHDr875wD2eAb4j2JFGqGXb-Wff6TG3QLZrLd0TvxTQ@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Hello Tom,
Thank you for the answer. Now it is more clear for me.

According to this information I can cause another kind of error:

--drop table tbl cascade;

--drop table rule_stat cascade;

create table tbl (id serial primary key, msg text);

create table rule_stat (msg text, id int references tbl(id));

create rule rule_tbl as on insert to tbl do insert into rule_stat values('Last
inserted id was ',new.id);

insert into tbl (msg)

select 'I`m an insert';

Result:

SQL Error [23503]: ERROR: insert or update on table "rule_stat" violates
foreign key constraint "rule_stat_id_fkey"
Detail: Key (id)=(2) is not present in table "tbl".

Such behaviour is a bit confusing. Because by using new.* I expect to get a
recently inserted row, but not the result of some query running the second
time (which causes implicit incrementing of id serial).

Best regards,

Hanna

On Thu, Mar 9, 2023 at 5:01 PM Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:

> PG Bug reporting form <noreply(at)postgresql(dot)org> writes:
> > create table tbl (id int);
> > create table rule_stat (msg text, id int);
> > create rule rule_tbl as on insert to tbl do insert into rule_stat
> > values('Rule triggered for ',new.id);
>
> > insert into tbl
> > select 1
> > except
> > select id from tbl;
>
> > table rule_stat; -- no rows
>
> This is not a bug. The DO ALSO command executes after the original
> INSERT command, and what it executes looks basically like
>
> insert into rule_stat
> select 'Rule triggered for ', id from
> (select 1
> except
> select id from tbl);
>
> But at this point we've already completed the original INSERT,
> so now there is a row with id 1 in "tbl", and thus the EXCEPT
> produces nothing.
>
> While there are use-cases for this sort of behavior, most people
> find that propagating data to another table is better done with
> an AFTER trigger. It's far easier to understand what will happen.
>
> regards, tom lane
>

--
This e-mail and any files transmitted with it contain confidential and/or
privileged information.
Any unauthorized copying, disclosure or
distribution of the material in this e-mail is strictly forbidden.
By
messaging with Spotware you consent to the foregoing.

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Peter Eisentraut 2023-03-10 08:40:19 Re: unaccent fails when datlocprovider=i and datctype=C
Previous Message Tom Lane 2023-03-09 16:57:55 Re: BUG #17828: postgres_fdw leaks file descriptors on error and aborts aborted transaction in lack of fds