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

Reply via email to