Re: Segmentation fault during update inside ExecBRUpdateTriggers

Поиск
Список
Период
Сортировка
Искать
От
Tom Lane
Тема
Re: Segmentation fault during update inside ExecBRUpdateTriggers
Дата
Msg-id
12395.1565911617@sss.pgh.pa.us
Ответ на
Список
Дерево обсуждения
Segmentation fault during update inside ExecBRUpdateTriggers Piotr Gabriel Kosinski <pg.kosinski@gmail.com>
Re: Segmentation fault during update inside ExecBRUpdateTriggers Thomas Munro <thomas.munro@gmail.com>
Re: Segmentation fault during update inside ExecBRUpdateTriggers Tom Lane <tgl@sss.pgh.pa.us>
Re: Segmentation fault during update inside ExecBRUpdateTriggers Tom Lane <tgl@sss.pgh.pa.us>
Re: Segmentation fault during update inside ExecBRUpdateTriggers Thomas Munro <thomas.munro@gmail.com>
Re: Segmentation fault during update inside ExecBRUpdateTriggers Tom Lane <tgl@sss.pgh.pa.us>
Re: Segmentation fault during update inside ExecBRUpdateTriggers Andres Freund <andres@anarazel.de>
Re: Segmentation fault during update inside ExecBRUpdateTriggers Tom Lane <tgl@sss.pgh.pa.us>
I wrote:
> [ thinks some more... ]  Actually, I'm beginning to recall that
> we made changes here because v11 plpgsql is capable of actually
> returning "trigtuple" where before it would always have made a copy.
> If that's accurate, then very likely the bug exists further back
> but requires some other PL than plpgsql to manifest.

As I suspected ... the attached test case crashes 9.4 through 11.
We already had some problems in this area, which is why a suitable
trigger is already at hand in regress.c.

			regards, tom lane

diff --git a/src/test/regress/expected/triggers.out b/src/test/regress/expected/triggers.out
index c64151b..1e4053c 100644
--- a/src/test/regress/expected/triggers.out
+++ b/src/test/regress/expected/triggers.out
@@ -144,6 +144,76 @@ select * from trigtest;
 ----+----
 (0 rows)
 
+-- Also check what happens when such a trigger runs before or after others
+create function f1_times_10() returns trigger as
+$$ begin new.f1 := new.f1 * 10; return new; end $$ language plpgsql;
+create trigger trigger_alpha
+	before insert or update on trigtest
+	for each row execute procedure f1_times_10();
+insert into trigtest values(1, 'foo');
+select * from trigtest;
+ f1 | f2  
+----+-----
+ 10 | foo
+(1 row)
+
+update trigtest set f2 = f2 || 'bar';
+select * from trigtest;
+ f1 | f2  
+----+-----
+ 10 | foo
+(1 row)
+
+delete from trigtest;
+select * from trigtest;
+ f1 | f2 
+----+----
+(0 rows)
+
+create trigger trigger_zed
+	before insert or update on trigtest
+	for each row execute procedure f1_times_10();
+insert into trigtest values(1, 'foo');
+select * from trigtest;
+ f1  | f2  
+-----+-----
+ 100 | foo
+(1 row)
+
+update trigtest set f2 = f2 || 'bar';
+select * from trigtest;
+  f1  | f2  
+------+-----
+ 1000 | foo
+(1 row)
+
+delete from trigtest;
+select * from trigtest;
+ f1 | f2 
+----+----
+(0 rows)
+
+drop trigger trigger_alpha on trigtest;
+insert into trigtest values(1, 'foo');
+select * from trigtest;
+ f1 | f2  
+----+-----
+ 10 | foo
+(1 row)
+
+update trigtest set f2 = f2 || 'bar';
+select * from trigtest;
+ f1  | f2  
+-----+-----
+ 100 | foo
+(1 row)
+
+delete from trigtest;
+select * from trigtest;
+ f1 | f2 
+----+----
+(0 rows)
+
 drop table trigtest;
 create sequence ttdummy_seq increment 10 start 0 minvalue 0;
 create table tttest (
diff --git a/src/test/regress/sql/triggers.sql b/src/test/regress/sql/triggers.sql
index 4534dc9..c21b6c1 100644
--- a/src/test/regress/sql/triggers.sql
+++ b/src/test/regress/sql/triggers.sql
@@ -117,6 +117,41 @@ select * from trigtest;
 delete from trigtest;
 select * from trigtest;
 
+-- Also check what happens when such a trigger runs before or after others
+create function f1_times_10() returns trigger as
+$$ begin new.f1 := new.f1 * 10; return new; end $$ language plpgsql;
+
+create trigger trigger_alpha
+	before insert or update on trigtest
+	for each row execute procedure f1_times_10();
+
+insert into trigtest values(1, 'foo');
+select * from trigtest;
+update trigtest set f2 = f2 || 'bar';
+select * from trigtest;
+delete from trigtest;
+select * from trigtest;
+
+create trigger trigger_zed
+	before insert or update on trigtest
+	for each row execute procedure f1_times_10();
+
+insert into trigtest values(1, 'foo');
+select * from trigtest;
+update trigtest set f2 = f2 || 'bar';
+select * from trigtest;
+delete from trigtest;
+select * from trigtest;
+
+drop trigger trigger_alpha on trigtest;
+
+insert into trigtest values(1, 'foo');
+select * from trigtest;
+update trigtest set f2 = f2 || 'bar';
+select * from trigtest;
+delete from trigtest;
+select * from trigtest;
+
 drop table trigtest;
 
 create sequence ttdummy_seq increment 10 start 0 minvalue 0;
В списке pgsql-bugs по дате отправления
От: Andres Freund
Дата:
От: Thomas Munro
Дата:
FAQ