with and trigger

Started by Marcos Pegoraroalmost 7 years ago8 messagesgeneral
Jump to latest
#1Marcos Pegoraro
marcos@f10.com.br

We like to use With to insert, update and return some value to user. But some
informations of those related tables are not available on that time, is that
a bug ?

with
Master(Master_ID) as (insert into Master(Customer_ID, Field2) values(1,
'BlaBla') returning Master_ID),
Detail as (insert into Detail(Master_ID, Product_ID, ProductValue) select
Master_ID, 5, 50 from Master)
select Master_ID from Master;

This code works but not as expected because we have a trigger which does not
see that data yet.
Suppose a trigger on Detail which needs to find any info from a table which
was inserted on this With. That info is not available, like ...
create function DetailOfDetail() returns trigger() as -- this trigger
function is before insert on Detail
begin
new.Discount = (select discount from Customer inner join Master
using(Customer_ID) where Master_ID = new.Master_ID)
end;
This trigger will not work because Master record was not inserted yet.

If change it to a DO it would work but we would like that result, so ...
This trigger is obviously an example, our tables have more complex
structures but here we want only to understand the way postgres works or if
it´s not working properly.

--
Sent from: http://www.postgresql-archive.org/PostgreSQL-general-f1843780.html

#2Geoff Winkless
pgsqladmin@geoff.dj
In reply to: Marcos Pegoraro (#1)
Re: with and trigger

On Wed, 29 May 2019 at 12:52, PegoraroF10 <marcos@f10.com.br> wrote:

This trigger will not work because Master record was not inserted yet.

That seems reasonable. Since the transaction is meant to be atomic any
select within the query should return data from tables as they are at the
start of the transaction, the insert won't happen (as far as the rest of
the query is concerned) until it commits.

Or have I misunderstood what you're saying?

Geoff

#3Fabrízio de Royes Mello
fabriziomello@gmail.com
In reply to: Marcos Pegoraro (#1)
Re: with and trigger

Em qua, 29 de mai de 2019 às 08:52, PegoraroF10 <marcos@f10.com.br>
escreveu:

We like to use With to insert, update and return some value to user. But

some

informations of those related tables are not available on that time, is

that

a bug ?

with
Master(Master_ID) as (insert into Master(Customer_ID, Field2) values(1,
'BlaBla') returning Master_ID),
Detail as (insert into Detail(Master_ID, Product_ID, ProductValue)

select

Master_ID, 5, 50 from Master)
select Master_ID from Master;

This code works but not as expected because we have a trigger which does

not

see that data yet.
Suppose a trigger on Detail which needs to find any info from a table

which

was inserted on this With. That info is not available, like ...
create function DetailOfDetail() returns trigger() as -- this trigger
function is before insert on Detail
begin
new.Discount = (select discount from Customer inner join Master
using(Customer_ID) where Master_ID = new.Master_ID)
end;
This trigger will not work because Master record was not inserted yet.

If change it to a DO it would work but we would like that result, so ...
This trigger is obviously an example, our tables have more complex
structures but here we want only to understand the way postgres works or

if

it´s not working properly.

To see updated data using a trigger in the same transaction you should
create trigger on AFTER event.

Regards,

--
Fabrízio de Royes Mello Timbira - http://www.timbira.com.br/
PostgreSQL: Consultoria, Desenvolvimento, Suporte 24x7 e Treinamento

#4Marcos Pegoraro
marcos@f10.com.br
In reply to: Geoff Winkless (#2)
Re: with and trigger

Well, I think is not a transaction problem, because if you do the same thing
on a DO it will work.
DO $$
declare vMaster_ID integer;
begin
insert into Master(Customer_ID, Field2) values(1, 'BlaBla') returning
Master_ID into vMaster_ID;
insert into Detail(Master_ID, Product_ID, ProductValue) values(vMaster_ID,
5, 50);
end $$

As you can see, works exactly the same way and Detail trigger works as
expected, why ?

--
Sent from: http://www.postgresql-archive.org/PostgreSQL-general-f1843780.html

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Marcos Pegoraro (#1)
Re: with and trigger

PegoraroF10 <marcos@f10.com.br> writes:

We like to use With to insert, update and return some value to user. But some
informations of those related tables are not available on that time, is that
a bug ?

No, see the "WITH Clause" section of the SELECT reference page:

The primary query and the WITH queries are all (notionally) executed
at the same time. This implies that the effects of a data-modifying
statement in WITH cannot be seen from other parts of the query, other
than by reading its RETURNING output. If two such data-modifying
statements attempt to modify the same row, the results are
unspecified.

This doesn't explicitly talk about triggers, but I think our attitude
about the case you're discussing is that the results are unspecified.
If a trigger fired in one WITH arm tries to look at the table(s)
modified by other WITH arms, it might or might not see those changes.

regards, tom lane

#6Ron
ronljohnsonjr@gmail.com
In reply to: Tom Lane (#5)
Re: with and trigger

On 5/29/19 8:26 AM, Tom Lane wrote:

PegoraroF10 <marcos@f10.com.br> writes:

We like to use With to insert, update and return some value to user. But some
informations of those related tables are not available on that time, is that
a bug ?

No, see the "WITH Clause" section of the SELECT reference page:

The primary query and the WITH queries are all (notionally) executed
at the same time. This implies that the effects of a data-modifying
statement in WITH cannot be seen from other parts of the query, other
than by reading its RETURNING output. If two such data-modifying
statements attempt to modify the same row, the results are
unspecified.

This doesn't explicitly talk about triggers, but I think our attitude
about the case you're discussing is that the results are unspecified.
If a trigger fired in one WITH arm tries to look at the table(s)
modified by other WITH arms, it might or might not see those changes.

Are CTEs still optimization fences?
https://www.2ndquadrant.com/en/blog/postgresql-ctes-are-optimization-fences/

--
Angular momentum makes the world go 'round.

#7Andreas Kretschmer
andreas@a-kretschmer.de
In reply to: Ron (#6)
Re: with and trigger

Are CTEs still optimization fences?
https://www.2ndquadrant.com/en/blog/postgresql-ctes-are-optimization-fences/

Yes, but not in 12.

Regards, Andreas

--
2ndQuadrant - The PostgreSQL Support Company

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Ron (#6)
Re: with and trigger

Ron <ronljohnsonjr@gmail.com> writes:

On 5/29/19 8:26 AM, Tom Lane wrote:

This doesn't explicitly talk about triggers, but I think our attitude
about the case you're discussing is that the results are unspecified.
If a trigger fired in one WITH arm tries to look at the table(s)
modified by other WITH arms, it might or might not see those changes.

Are CTEs still optimization fences?
https://www.2ndquadrant.com/en/blog/postgresql-ctes-are-optimization-fences/

Yes, if they contain data-modifying statements ... but that's not
relevant to the point at hand, which is that the run-time behavior
is not specified.

regards, tom lane