Bug in contrib/spi/refint.c
От | Anand Surelia |
---|---|
Тема | Bug in contrib/spi/refint.c |
Дата | |
Msg-id | 36154C43.122C2BFE@bytekinc.com обсуждение исходный текст |
Ответы |
Re: [GENERAL] Bug in contrib/spi/refint.c
|
Список | pgsql-hackers |
There is a bug in check_foreign_key of refint.c which is bundled with the standard distribution. It occurs when a trigger calling this function recursively fires another trigger which calls the same function. The calling check_foreign_key loses its plan informantion and when it tries to use it the backend closes its channel. You can check it with the sql script I am attaching below. The solution to this is to do a find_plan again before executing it at line 483 of refint.c. Therefore two more lines should be added before line 483: sprintf(ident, "%s$%u", trigger->tgname, rel->rd_id); plan = find_plan(ident, &FPlans, &nFPlans); before line 483 which is: ret = SPI_execp(plan->splan[r], kvals, NULL, tcount); Here is the script to check it: create table a ( a int4 primary key, b int4, c int4, d int4 ); create table b ( a int4 primary key, b int4,-- foreign key references a c int4, d int4 ); create table ab ( a int4 primary key, b int4, c int4, d int4 ); create table bc ( a int4 primary key, b int4, c int4, d int4 ); create function check_primary_key() returns opaque as '/home/bye2data/postgresql-6.3.2/contrib/spi/refint.so' language 'c'; create function check_foreign_key() returns opaque as '/home/bye2data/postgresql-6.3.2/contrib/spi/refint.so' language 'c'; create trigger t1 before delete or update on a for each row execute procedure check_foreign_key(1,'cascade','a','b','b'); create trigger t2 before insert or update on b for each row execute procedure check_primary_key('b','a','a'); create trigger t3 before delete or update on ab for each row execute procedure check_foreign_key(2,'cascade','a','a','a','bc','a'); create trigger t4 before insert or update on a for each row execute procedure check_primary_key('a','ab','a'); create trigger t5 before insert or update on bc for each row execute procedure check_primary_key('a','ab','a'); insert into ab values(1,1,1,1); insert into bc values (1,1,1,1); insert into a values (1,1,1,1); delete from ab where a=1; Sorry for the confusing names of tables and attributes. - Anand.
В списке pgsql-hackers по дате отправления: