Hello There are small issue in PL/pgSQL and custom exceptions. Custom exception doesn't set a CONTEXT field. I propose change this behave for WARNING or EXCEPTION level. The goal is same behave for custom exception and builtin exception and it can help to identify a RAISE statement that is responsible to exception.
./pl_exec.c *** ./pl_exec.c.orig 2011-11-24 17:29:08.000000000 +0100 --- ./pl_exec.c 2011-11-24 18:23:51.513136718 +0100 *************** *** 2827,2833 **** /* * Throw the error (may or may not come back) */ ! estate->err_text = raise_skip_msg; /* suppress traceback of raise */ ereport(stmt->elog_level, (err_code ? errcode(err_code) : 0, --- 2827,2834 ---- /* * Throw the error (may or may not come back) */ ! if (stmt->elog_level < WARNING) ! estate->err_text = raise_skip_msg; /* suppress traceback of raise notice */ ereport(stmt->elog_level, (err_code ? errcode(err_code) : 0, Regards Pavel Stehule
*** ./src/pl/plpgsql/src/pl_exec.c.orig 2011-11-24 17:29:08.000000000 +0100 --- ./src/pl/plpgsql/src/pl_exec.c 2011-11-24 18:23:51.513136718 +0100 *************** *** 2827,2833 **** /* * Throw the error (may or may not come back) */ ! estate->err_text = raise_skip_msg; /* suppress traceback of raise */ ereport(stmt->elog_level, (err_code ? errcode(err_code) : 0, --- 2827,2834 ---- /* * Throw the error (may or may not come back) */ ! if (stmt->elog_level < WARNING) ! estate->err_text = raise_skip_msg; /* suppress traceback of raise notice */ ereport(stmt->elog_level, (err_code ? errcode(err_code) : 0, *** ./src/test/regress/expected/plpgsql.out.orig 2011-11-24 17:32:30.000000000 +0100 --- ./src/test/regress/expected/plpgsql.out 2011-11-24 18:26:30.000000000 +0100 *************** *** 1518,1544 **** DETAIL: Key (name)=(PF1_1) already exists. update PSlot set backlink = 'WS.not.there' where slotname = 'PS.base.a1'; ERROR: WS.not.there does not exist ! CONTEXT: PL/pgSQL function "tg_backlink_a()" line 17 at assignment update PSlot set backlink = 'XX.illegal' where slotname = 'PS.base.a1'; ERROR: illegal backlink beginning with XX ! CONTEXT: PL/pgSQL function "tg_backlink_a()" line 17 at assignment update PSlot set slotlink = 'PS.not.there' where slotname = 'PS.base.a1'; ERROR: PS.not.there does not exist ! CONTEXT: PL/pgSQL function "tg_slotlink_a()" line 17 at assignment update PSlot set slotlink = 'XX.illegal' where slotname = 'PS.base.a1'; ERROR: illegal slotlink beginning with XX ! CONTEXT: PL/pgSQL function "tg_slotlink_a()" line 17 at assignment insert into HSlot values ('HS', 'base.hub1', 1, ''); ERROR: duplicate key value violates unique constraint "hslot_name" DETAIL: Key (slotname)=(HS.base.hub1.1 ) already exists. insert into HSlot values ('HS', 'base.hub1', 20, ''); ERROR: no manual manipulation of HSlot delete from HSlot; ERROR: no manual manipulation of HSlot insert into IFace values ('IF', 'notthere', 'eth0', ''); ERROR: system "notthere" does not exist insert into IFace values ('IF', 'orion', 'ethernet_interface_name_too_long', ''); ERROR: IFace slotname "IF.orion.ethernet_interface_name_too_long" too long (20 char max) -- -- The following tests are unrelated to the scenario outlined above; -- they merely exercise specific parts of PL/pgSQL --- 1518,1552 ---- DETAIL: Key (name)=(PF1_1) already exists. update PSlot set backlink = 'WS.not.there' where slotname = 'PS.base.a1'; ERROR: WS.not.there does not exist ! CONTEXT: PL/pgSQL function "tg_backlink_set(character,character)" line 30 at RAISE ! PL/pgSQL function "tg_backlink_a()" line 17 at assignment update PSlot set backlink = 'XX.illegal' where slotname = 'PS.base.a1'; ERROR: illegal backlink beginning with XX ! CONTEXT: PL/pgSQL function "tg_backlink_set(character,character)" line 47 at RAISE ! PL/pgSQL function "tg_backlink_a()" line 17 at assignment update PSlot set slotlink = 'PS.not.there' where slotname = 'PS.base.a1'; ERROR: PS.not.there does not exist ! CONTEXT: PL/pgSQL function "tg_slotlink_set(character,character)" line 30 at RAISE ! PL/pgSQL function "tg_slotlink_a()" line 17 at assignment update PSlot set slotlink = 'XX.illegal' where slotname = 'PS.base.a1'; ERROR: illegal slotlink beginning with XX ! CONTEXT: PL/pgSQL function "tg_slotlink_set(character,character)" line 77 at RAISE ! PL/pgSQL function "tg_slotlink_a()" line 17 at assignment insert into HSlot values ('HS', 'base.hub1', 1, ''); ERROR: duplicate key value violates unique constraint "hslot_name" DETAIL: Key (slotname)=(HS.base.hub1.1 ) already exists. insert into HSlot values ('HS', 'base.hub1', 20, ''); ERROR: no manual manipulation of HSlot + CONTEXT: PL/pgSQL function "tg_hslot_biu()" line 12 at RAISE delete from HSlot; ERROR: no manual manipulation of HSlot + CONTEXT: PL/pgSQL function "tg_hslot_bd()" line 12 at RAISE insert into IFace values ('IF', 'notthere', 'eth0', ''); ERROR: system "notthere" does not exist + CONTEXT: PL/pgSQL function "tg_iface_biu()" line 8 at RAISE insert into IFace values ('IF', 'orion', 'ethernet_interface_name_too_long', ''); ERROR: IFace slotname "IF.orion.ethernet_interface_name_too_long" too long (20 char max) + CONTEXT: PL/pgSQL function "tg_iface_biu()" line 14 at RAISE -- -- The following tests are unrelated to the scenario outlined above; -- they merely exercise specific parts of PL/pgSQL *************** *** 1963,1968 **** --- 1971,1977 ---- NOTICE: should see this only if -100 <> 0 NOTICE: should see this only if -100 fits in smallint ERROR: -100 is less than zero + CONTEXT: PL/pgSQL function "trap_zero_divide(integer)" line 12 at RAISE create function trap_matching_test(int) returns int as $$ declare x int; sx smallint; *************** *** 3494,3499 **** --- 3503,3509 ---- HINT: some hint ERROR: 1 2 3 DETAIL: some detail info + CONTEXT: PL/pgSQL function "raise_test()" line 5 at RAISE -- Since we can't actually see the thrown SQLSTATE in default psql output, -- test it like this; this also tests re-RAISE create or replace function raise_test() returns void as $$ *************** *** 3510,3515 **** --- 3520,3526 ---- NOTICE: SQLSTATE: 22012 SQLERRM: check me ERROR: check me DETAIL: some detail info + CONTEXT: PL/pgSQL function "raise_test()" line 3 at RAISE create or replace function raise_test() returns void as $$ begin raise 'check me' *************** *** 3524,3529 **** --- 3535,3541 ---- NOTICE: SQLSTATE: 1234F SQLERRM: check me ERROR: check me DETAIL: some detail info + CONTEXT: PL/pgSQL function "raise_test()" line 3 at RAISE -- SQLSTATE specification in WHEN create or replace function raise_test() returns void as $$ begin *************** *** 3539,3544 **** --- 3551,3557 ---- NOTICE: SQLSTATE: 1234F SQLERRM: check me ERROR: check me DETAIL: some detail info + CONTEXT: PL/pgSQL function "raise_test()" line 3 at RAISE create or replace function raise_test() returns void as $$ begin raise division_by_zero using detail = 'some detail info'; *************** *** 3552,3557 **** --- 3565,3571 ---- NOTICE: SQLSTATE: 22012 SQLERRM: division_by_zero ERROR: division_by_zero DETAIL: some detail info + CONTEXT: PL/pgSQL function "raise_test()" line 3 at RAISE create or replace function raise_test() returns void as $$ begin raise division_by_zero; *************** *** 3559,3564 **** --- 3573,3579 ---- $$ language plpgsql; select raise_test(); ERROR: division_by_zero + CONTEXT: PL/pgSQL function "raise_test()" line 3 at RAISE create or replace function raise_test() returns void as $$ begin raise sqlstate '1234F'; *************** *** 3566,3571 **** --- 3581,3587 ---- $$ language plpgsql; select raise_test(); ERROR: 1234F + CONTEXT: PL/pgSQL function "raise_test()" line 3 at RAISE create or replace function raise_test() returns void as $$ begin raise division_by_zero using message = 'custom' || ' message'; *************** *** 3573,3578 **** --- 3589,3595 ---- $$ language plpgsql; select raise_test(); ERROR: custom message + CONTEXT: PL/pgSQL function "raise_test()" line 3 at RAISE create or replace function raise_test() returns void as $$ begin raise using message = 'custom' || ' message', errcode = '22012'; *************** *** 3580,3585 **** --- 3597,3603 ---- $$ language plpgsql; select raise_test(); ERROR: custom message + CONTEXT: PL/pgSQL function "raise_test()" line 3 at RAISE -- conflict on message create or replace function raise_test() returns void as $$ begin *************** *** 3696,3701 **** --- 3714,3720 ---- select raise_test(); NOTICE: 22012 ERROR: substitute message + CONTEXT: PL/pgSQL function "raise_test()" line 7 at RAISE drop function raise_test(); -- test CASE statement create or replace function case_test(bigint) returns text as $$
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers