proposal: better support for debugging of overloaded functions

Started by Pavel Stehuleabout 14 years ago9 messages
#1Pavel Stehule
pavel.stehule@gmail.com

Hello

I am missing a some unique identifier in exception info. I would to
use it in combination with \sf statement

I have a log

WARNING: NP_CPS: a cannot to build a RSLT object
DETAIL: dsql_text: SELECT * FROM
public._npacceptflatfile(order_nr:=to_number('O00000032',
'O99999999')::int,sequence_nr:=1,ref_sequence_nr:=2,recipient_op:=201,losing_op:=303)
message: cannot to identify real type for record type variable
CONTEXT: PL/pgSQL function "assign_rslts" line 50 at assignment
SQL statement "SELECT workflow.assign_rslts('2011-12-18',
'09:30:30',
to_operator := 201,
from_operator := 303)"
PL/pgSQL function "inline_code_block" line 855 at PERFORM

and I would to look on "assign_rslts" function, but
ohs=# \sf workflow.assign_rslts
ERROR: more than one function named "workflow.assign_rslts"

and I have to find a parameters and manually build a parameters list.
My proposal is enhancing l CONTEXT line about function's oid and
possibility to use this oid in \sf and \df function

some like

CONTEXT: PL/pgSQL function "assign_rslts" line 50 at assignment (oid: 65903)

...

\sf+ 65903

This simple feature can reduce a time that is necessary to identify a
bug in overloaded functions.

Other possibility is just enhancing context line to be more friendly
to \sf statement

CONTEXT: PL/pgSQL function workflow.assign_rslts(date,time without
time zone,operatorid_type,operatorid_type)"" line 50 at assignment

But this is not too readable and it implementation is harder, because
in exception time is not access to system tables - so this string
should be cached somewhere.

Notes, ideas??

Regards

Pavel Stehule

#2Robert Haas
robertmhaas@gmail.com
In reply to: Pavel Stehule (#1)
Re: proposal: better support for debugging of overloaded functions

On Fri, Nov 18, 2011 at 6:24 AM, Pavel Stehule <pavel.stehule@gmail.com> wrote:

CONTEXT:  PL/pgSQL function "assign_rslts" line 50 at assignment (oid: 65903)

\sf+ 65903

I'm pretty unenthused by the idea of making OIDs more user-visible
than they already are. If the message is ambiguous, we should include
argument types and (if not the object that would be visible under the
current search_path) a schema qualification. Spitting out a five (or
six or seven or eight) digit number doesn't seem like a usability
improvement.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

#3Pavel Stehule
pavel.stehule@gmail.com
In reply to: Robert Haas (#2)
Re: proposal: better support for debugging of overloaded functions

2011/11/18 Robert Haas <robertmhaas@gmail.com>:

On Fri, Nov 18, 2011 at 6:24 AM, Pavel Stehule <pavel.stehule@gmail.com> wrote:

CONTEXT:  PL/pgSQL function "assign_rslts" line 50 at assignment (oid: 65903)

\sf+ 65903

I'm pretty unenthused by the idea of making OIDs more user-visible
than they already are.  If the message is ambiguous, we should include
argument types and (if not the object that would be visible under the
current search_path) a schema qualification.  Spitting out a five (or
six or seven or eight) digit number doesn't seem like a usability
improvement.

yes - it's not nice - but it is simple and robust and doesn't depend
on actual search_path setting.

Nicer solution is a function signature - it can be assembled when
function is compiled. I see only one disadvantage - signature can be
too wide and can depend on search_path (and search_path can be
different when function is executed and when someone run sql console).
Signature should be prepared before execution, because there are no
access to system tables after exception.

I like any solution, because debugging of overloaded function is terrible now.

Regards

Pavel

Show quoted text

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

#4Pavel Stehule
pavel.stehule@gmail.com
In reply to: Robert Haas (#2)
Re: proposal: better support for debugging of overloaded functions

2011/11/18 Robert Haas <robertmhaas@gmail.com>:

On Fri, Nov 18, 2011 at 6:24 AM, Pavel Stehule <pavel.stehule@gmail.com> wrote:

CONTEXT:  PL/pgSQL function "assign_rslts" line 50 at assignment (oid: 65903)

\sf+ 65903

I'm pretty unenthused by the idea of making OIDs more user-visible
than they already are.  If the message is ambiguous, we should include
argument types and (if not the object that would be visible under the
current search_path) a schema qualification.  Spitting out a five (or
six or seven or eight) digit number doesn't seem like a usability
improvement.

Is possible to add GUC variable plpgsql.log_function_signature (maybe
just log_function_signature (for all PL))? I am not sure about GUC
name.

When this variable is true, then CONTEXT line will contain a qualified
function's signature instead function name

I don't would to check if function name is ambiguous or not after
exception is raised. There is a problem with access to system tables
and then exception handling can be slower. Using a qualified name is
necessary, because psql meta statements are not "smart" - they are
based on search_path and fact, so name is not ambiguous doesn't help
there.

Regards

Pavel Stehule

p.s. Other issue is missing CONTEXT line for RAISE EXCEPTION

Show quoted text

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

#5Robert Haas
robertmhaas@gmail.com
In reply to: Pavel Stehule (#4)
Re: proposal: better support for debugging of overloaded functions

On Sun, Nov 20, 2011 at 6:16 AM, Pavel Stehule <pavel.stehule@gmail.com> wrote:

Is possible to add GUC variable plpgsql.log_function_signature (maybe
just log_function_signature (for all PL))? I am not sure about GUC
name.

When this variable is true, then CONTEXT line will contain a qualified
function's signature instead function name

Sure, but why? If it's possible to do that, I think we should just do
it always. It might be a net reduction in readability for people who
don't use overloading but do have functions with very long names and
lots and lots of arguments, but even if you think that's good design,
I think the general principle that an error message should uniquely
identify the object responsible for the error ought to take
precedence.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

#6Pavel Stehule
pavel.stehule@gmail.com
In reply to: Robert Haas (#5)
1 attachment(s)
Re: proposal: better support for debugging of overloaded functions

Hello

2011/11/21 Robert Haas <robertmhaas@gmail.com>:

On Sun, Nov 20, 2011 at 6:16 AM, Pavel Stehule <pavel.stehule@gmail.com> wrote:

Is possible to add GUC variable plpgsql.log_function_signature (maybe
just log_function_signature (for all PL))? I am not sure about GUC
name.

When this variable is true, then CONTEXT line will contain a qualified
function's signature instead function name

Sure, but why?  If it's possible to do that, I think we should just do
it always.  It might be a net reduction in readability for people who
don't use overloading but do have functions with very long names and
lots and lots of arguments, but even if you think that's good design,
I think the general principle that an error message should uniquely
identify the object responsible for the error ought to take
precedence.

I inclined so this is good solution

there is a VIP patch

patch is relative long, but almost all are changes in regress tests.
Changes in plpgsql are 5 lines

Regards

Pavel

Show quoted text

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

Attachments:

fn_signature.difftext/x-patch; charset=US-ASCII; name=fn_signature.diffDownload
*** ./src/pl/plpgsql/src/pl_comp.c.orig	2011-11-24 12:51:45.000000000 +0100
--- ./src/pl/plpgsql/src/pl_comp.c	2011-11-24 17:28:06.885255584 +0100
***************
*** 342,347 ****
--- 342,348 ----
  	compile_tmp_cxt = MemoryContextSwitchTo(func_cxt);
  
  	function->fn_name = pstrdup(NameStr(procStruct->proname));
+ 	function->fn_signature = format_procedure(fcinfo->flinfo->fn_oid);
  	function->fn_oid = fcinfo->flinfo->fn_oid;
  	function->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
  	function->fn_tid = procTup->t_self;
*** ./src/pl/plpgsql/src/plpgsql.h.orig	2011-11-24 12:51:45.000000000 +0100
--- ./src/pl/plpgsql/src/plpgsql.h	2011-11-24 17:05:45.723119549 +0100
***************
*** 679,684 ****
--- 679,685 ----
  typedef struct PLpgSQL_function
  {								/* Complete compiled function	  */
  	char	   *fn_name;
+ 	char	   *fn_signature;
  	Oid			fn_oid;
  	TransactionId fn_xmin;
  	ItemPointerData fn_tid;
*** ./src/test/regress/expected/domain.out.orig	2011-11-24 12:51:45.000000000 +0100
--- ./src/test/regress/expected/domain.out	2011-11-24 17:32:27.000000000 +0100
***************
*** 483,489 ****
  end$$ language plpgsql;
  select doubledecrement(3); -- fail because of implicit null assignment
  ERROR:  domain pos_int does not allow null values
! CONTEXT:  PL/pgSQL function "doubledecrement" line 3 during statement block local variable initialization
  create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
  declare v pos_int := 0;
  begin
--- 483,489 ----
  end$$ language plpgsql;
  select doubledecrement(3); -- fail because of implicit null assignment
  ERROR:  domain pos_int does not allow null values
! CONTEXT:  PL/pgSQL function "doubledecrement(pos_int)" line 3 during statement block local variable initialization
  create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
  declare v pos_int := 0;
  begin
***************
*** 491,497 ****
  end$$ language plpgsql;
  select doubledecrement(3); -- fail at initialization assignment
  ERROR:  value for domain pos_int violates check constraint "pos_int_check"
! CONTEXT:  PL/pgSQL function "doubledecrement" line 3 during statement block local variable initialization
  create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
  declare v pos_int := 1;
  begin
--- 491,497 ----
  end$$ language plpgsql;
  select doubledecrement(3); -- fail at initialization assignment
  ERROR:  value for domain pos_int violates check constraint "pos_int_check"
! CONTEXT:  PL/pgSQL function "doubledecrement(pos_int)" line 3 during statement block local variable initialization
  create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
  declare v pos_int := 1;
  begin
***************
*** 504,513 ****
  ERROR:  value for domain pos_int violates check constraint "pos_int_check"
  select doubledecrement(1); -- fail at assignment to v
  ERROR:  value for domain pos_int violates check constraint "pos_int_check"
! CONTEXT:  PL/pgSQL function "doubledecrement" line 4 at assignment
  select doubledecrement(2); -- fail at return
  ERROR:  value for domain pos_int violates check constraint "pos_int_check"
! CONTEXT:  PL/pgSQL function "doubledecrement" while casting return value to function's return type
  select doubledecrement(3); -- good
   doubledecrement 
  -----------------
--- 504,513 ----
  ERROR:  value for domain pos_int violates check constraint "pos_int_check"
  select doubledecrement(1); -- fail at assignment to v
  ERROR:  value for domain pos_int violates check constraint "pos_int_check"
! CONTEXT:  PL/pgSQL function "doubledecrement(pos_int)" line 4 at assignment
  select doubledecrement(2); -- fail at return
  ERROR:  value for domain pos_int violates check constraint "pos_int_check"
! CONTEXT:  PL/pgSQL function "doubledecrement(pos_int)" while casting return value to function's return type
  select doubledecrement(3); -- good
   doubledecrement 
  -----------------
***************
*** 556,562 ****
  select array_elem_check(121.00);
  ERROR:  numeric field overflow
  DETAIL:  A field with precision 4, scale 2 must round to an absolute value less than 10^2.
! CONTEXT:  PL/pgSQL function "array_elem_check" line 5 at assignment
  select array_elem_check(1.23456);
   array_elem_check 
  ------------------
--- 556,562 ----
  select array_elem_check(121.00);
  ERROR:  numeric field overflow
  DETAIL:  A field with precision 4, scale 2 must round to an absolute value less than 10^2.
! CONTEXT:  PL/pgSQL function "array_elem_check(numeric)" line 5 at assignment
  select array_elem_check(1.23456);
   array_elem_check 
  ------------------
***************
*** 574,580 ****
  select array_elem_check(121.00);
  ERROR:  numeric field overflow
  DETAIL:  A field with precision 4, scale 2 must round to an absolute value less than 10^2.
! CONTEXT:  PL/pgSQL function "array_elem_check" line 5 at assignment
  select array_elem_check(1.23456);
   array_elem_check 
  ------------------
--- 574,580 ----
  select array_elem_check(121.00);
  ERROR:  numeric field overflow
  DETAIL:  A field with precision 4, scale 2 must round to an absolute value less than 10^2.
! CONTEXT:  PL/pgSQL function "array_elem_check(numeric)" line 5 at assignment
  select array_elem_check(1.23456);
   array_elem_check 
  ------------------
***************
*** 592,598 ****
  select array_elem_check(121.00);
  ERROR:  numeric field overflow
  DETAIL:  A field with precision 4, scale 2 must round to an absolute value less than 10^2.
! CONTEXT:  PL/pgSQL function "array_elem_check" line 5 at assignment
  select array_elem_check(1.23456);
   array_elem_check 
  ------------------
--- 592,598 ----
  select array_elem_check(121.00);
  ERROR:  numeric field overflow
  DETAIL:  A field with precision 4, scale 2 must round to an absolute value less than 10^2.
! CONTEXT:  PL/pgSQL function "array_elem_check(numeric)" line 5 at assignment
  select array_elem_check(1.23456);
   array_elem_check 
  ------------------
***************
*** 640,644 ****
  
  select array_elem_check(-1);
  ERROR:  value for domain orderedpair violates check constraint "orderedpair_check"
! CONTEXT:  PL/pgSQL function "array_elem_check" line 5 at assignment
  drop function array_elem_check(int);
--- 640,644 ----
  
  select array_elem_check(-1);
  ERROR:  value for domain orderedpair violates check constraint "orderedpair_check"
! CONTEXT:  PL/pgSQL function "array_elem_check(integer)" line 5 at assignment
  drop function array_elem_check(int);
*** ./src/test/regress/expected/guc.out.orig	2011-11-24 12:51:45.000000000 +0100
--- ./src/test/regress/expected/guc.out	2011-11-24 17:32:25.000000000 +0100
***************
*** 687,693 ****
  select myfunc(0);
  ERROR:  division by zero
  CONTEXT:  SQL statement "SELECT 1/$1"
! PL/pgSQL function "myfunc" line 4 at PERFORM
  select current_setting('work_mem');
   current_setting 
  -----------------
--- 687,693 ----
  select myfunc(0);
  ERROR:  division by zero
  CONTEXT:  SQL statement "SELECT 1/$1"
! PL/pgSQL function "myfunc(integer)" line 4 at PERFORM
  select current_setting('work_mem');
   current_setting 
  -----------------
*** ./src/test/regress/expected/plancache.out.orig	2011-11-24 12:51:45.000000000 +0100
--- ./src/test/regress/expected/plancache.out	2011-11-24 17:32:27.000000000 +0100
***************
*** 235,241 ****
  select cachebug();
  NOTICE:  table "temptable" does not exist, skipping
  CONTEXT:  SQL statement "drop table if exists temptable cascade"
! PL/pgSQL function "cachebug" line 4 at SQL statement
  NOTICE:  1
  NOTICE:  2
  NOTICE:  3
--- 235,241 ----
  select cachebug();
  NOTICE:  table "temptable" does not exist, skipping
  CONTEXT:  SQL statement "drop table if exists temptable cascade"
! PL/pgSQL function "cachebug()" line 4 at SQL statement
  NOTICE:  1
  NOTICE:  2
  NOTICE:  3
***************
*** 247,253 ****
  select cachebug();
  NOTICE:  drop cascades to view vv
  CONTEXT:  SQL statement "drop table if exists temptable cascade"
! PL/pgSQL function "cachebug" line 4 at SQL statement
  NOTICE:  1
  NOTICE:  2
  NOTICE:  3
--- 247,253 ----
  select cachebug();
  NOTICE:  drop cascades to view vv
  CONTEXT:  SQL statement "drop table if exists temptable cascade"
! PL/pgSQL function "cachebug()" line 4 at SQL statement
  NOTICE:  1
  NOTICE:  2
  NOTICE:  3
*** ./src/test/regress/expected/plpgsql.out.orig	2011-11-24 12:51:45.000000000 +0100
--- ./src/test/regress/expected/plpgsql.out	2011-11-24 17:32:30.000000000 +0100
***************
*** 1518,1533 ****
  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.
--- 1518,1533 ----
  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.
***************
*** 2067,2079 ****
  select test_variable_storage();
  NOTICE:  should see this
  CONTEXT:  SQL statement "SELECT trap_zero_divide(-100)"
! PL/pgSQL function "test_variable_storage" line 8 at PERFORM
  NOTICE:  should see this only if -100 <> 0
  CONTEXT:  SQL statement "SELECT trap_zero_divide(-100)"
! PL/pgSQL function "test_variable_storage" line 8 at PERFORM
  NOTICE:  should see this only if -100 fits in smallint
  CONTEXT:  SQL statement "SELECT trap_zero_divide(-100)"
! PL/pgSQL function "test_variable_storage" line 8 at PERFORM
   test_variable_storage 
  -----------------------
   123456789012
--- 2067,2079 ----
  select test_variable_storage();
  NOTICE:  should see this
  CONTEXT:  SQL statement "SELECT trap_zero_divide(-100)"
! PL/pgSQL function "test_variable_storage()" line 8 at PERFORM
  NOTICE:  should see this only if -100 <> 0
  CONTEXT:  SQL statement "SELECT trap_zero_divide(-100)"
! PL/pgSQL function "test_variable_storage()" line 8 at PERFORM
  NOTICE:  should see this only if -100 fits in smallint
  CONTEXT:  SQL statement "SELECT trap_zero_divide(-100)"
! PL/pgSQL function "test_variable_storage()" line 8 at PERFORM
   test_variable_storage 
  -----------------------
   123456789012
***************
*** 2302,2308 ****
  $$ language plpgsql;
  select raise_test1(5);
  ERROR:  too many parameters specified for RAISE
! CONTEXT:  PL/pgSQL function "raise_test1" line 3 at RAISE
  create function raise_test2(int) returns int as $$
  begin
      raise notice 'This message has too few parameters: %, %, %', $1, $1;
--- 2302,2308 ----
  $$ language plpgsql;
  select raise_test1(5);
  ERROR:  too many parameters specified for RAISE
! CONTEXT:  PL/pgSQL function "raise_test1(integer)" line 3 at RAISE
  create function raise_test2(int) returns int as $$
  begin
      raise notice 'This message has too few parameters: %, %, %', $1, $1;
***************
*** 2311,2317 ****
  $$ language plpgsql;
  select raise_test2(10);
  ERROR:  too few parameters specified for RAISE
! CONTEXT:  PL/pgSQL function "raise_test2" line 3 at RAISE
  -- Test re-RAISE inside a nested exception block.  This case is allowed
  -- by Oracle's PL/SQL but was handled differently by PG before 9.1.
  CREATE FUNCTION reraise_test() RETURNS void AS $$
--- 2311,2317 ----
  $$ language plpgsql;
  select raise_test2(10);
  ERROR:  too few parameters specified for RAISE
! CONTEXT:  PL/pgSQL function "raise_test2(integer)" line 3 at RAISE
  -- Test re-RAISE inside a nested exception block.  This case is allowed
  -- by Oracle's PL/SQL but was handled differently by PG before 9.1.
  CREATE FUNCTION reraise_test() RETURNS void AS $$
***************
*** 2401,2407 ****
  end;$$ language plpgsql;
  select missing_return_expr();
  ERROR:  control reached end of function without RETURN
! CONTEXT:  PL/pgSQL function "missing_return_expr"
  drop function void_return_expr();
  drop function missing_return_expr();
  --
--- 2401,2407 ----
  end;$$ language plpgsql;
  select missing_return_expr();
  ERROR:  control reached end of function without RETURN
! CONTEXT:  PL/pgSQL function "missing_return_expr()"
  drop function void_return_expr();
  drop function missing_return_expr();
  --
***************
*** 2453,2459 ****
  LINE 1: SELECT sqlstate
                 ^
  QUERY:  SELECT sqlstate
! CONTEXT:  PL/pgSQL function "excpt_test1" line 3 at RAISE
  create function excpt_test2() returns void as $$
  begin
      begin
--- 2453,2459 ----
  LINE 1: SELECT sqlstate
                 ^
  QUERY:  SELECT sqlstate
! CONTEXT:  PL/pgSQL function "excpt_test1()" line 3 at RAISE
  create function excpt_test2() returns void as $$
  begin
      begin
***************
*** 2468,2474 ****
  LINE 1: SELECT sqlstate
                 ^
  QUERY:  SELECT sqlstate
! CONTEXT:  PL/pgSQL function "excpt_test2" line 5 at RAISE
  create function excpt_test3() returns void as $$
  begin
      begin
--- 2468,2474 ----
  LINE 1: SELECT sqlstate
                 ^
  QUERY:  SELECT sqlstate
! CONTEXT:  PL/pgSQL function "excpt_test2()" line 5 at RAISE
  create function excpt_test3() returns void as $$
  begin
      begin
***************
*** 2674,2680 ****
  -- should fail
  select continue_test2();
  ERROR:  CONTINUE cannot be used outside a loop
! CONTEXT:  PL/pgSQL function "continue_test2"
  -- CONTINUE can't reference the label of a named block
  create function continue_test3() returns void as $$
  begin
--- 2674,2680 ----
  -- should fail
  select continue_test2();
  ERROR:  CONTINUE cannot be used outside a loop
! CONTEXT:  PL/pgSQL function "continue_test2()"
  -- CONTINUE can't reference the label of a named block
  create function continue_test3() returns void as $$
  begin
***************
*** 2689,2695 ****
  -- should fail
  select continue_test3();
  ERROR:  CONTINUE cannot be used outside a loop
! CONTEXT:  PL/pgSQL function "continue_test3"
  drop function continue_test1();
  drop function continue_test2();
  drop function continue_test3();
--- 2689,2695 ----
  -- should fail
  select continue_test3();
  ERROR:  CONTINUE cannot be used outside a loop
! CONTEXT:  PL/pgSQL function "continue_test3()"
  drop function continue_test1();
  drop function continue_test2();
  drop function continue_test3();
***************
*** 2850,2856 ****
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned more than one row
! CONTEXT:  PL/pgSQL function "footest" line 5 at SQL statement
  create or replace function footest() returns void as $$
  declare x record;
  begin
--- 2850,2856 ----
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned more than one row
! CONTEXT:  PL/pgSQL function "footest()" line 5 at SQL statement
  create or replace function footest() returns void as $$
  declare x record;
  begin
***************
*** 2913,2919 ****
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned no rows
! CONTEXT:  PL/pgSQL function "footest" line 5 at SQL statement
  create or replace function footest() returns void as $$
  declare x record;
  begin
--- 2913,2919 ----
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned no rows
! CONTEXT:  PL/pgSQL function "footest()" line 5 at SQL statement
  create or replace function footest() returns void as $$
  declare x record;
  begin
***************
*** 2923,2929 ****
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned more than one row
! CONTEXT:  PL/pgSQL function "footest" line 5 at SQL statement
  create or replace function footest() returns void as $$
  declare x record;
  begin
--- 2923,2929 ----
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned more than one row
! CONTEXT:  PL/pgSQL function "footest()" line 5 at SQL statement
  create or replace function footest() returns void as $$
  declare x record;
  begin
***************
*** 2947,2953 ****
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned no rows
! CONTEXT:  PL/pgSQL function "footest" line 5 at EXECUTE statement
  create or replace function footest() returns void as $$
  declare x record;
  begin
--- 2947,2953 ----
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned no rows
! CONTEXT:  PL/pgSQL function "footest()" line 5 at EXECUTE statement
  create or replace function footest() returns void as $$
  declare x record;
  begin
***************
*** 2957,2963 ****
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned more than one row
! CONTEXT:  PL/pgSQL function "footest" line 5 at EXECUTE statement
  drop function footest();
  -- test scrollable cursor support
  create function sc_test() returns setof integer as $$
--- 2957,2963 ----
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned more than one row
! CONTEXT:  PL/pgSQL function "footest()" line 5 at EXECUTE statement
  drop function footest();
  -- test scrollable cursor support
  create function sc_test() returns setof integer as $$
***************
*** 3001,3007 ****
  select * from sc_test();  -- fails because of NO SCROLL specification
  ERROR:  cursor can only scan forward
  HINT:  Declare it with SCROLL option to enable backward scan.
! CONTEXT:  PL/pgSQL function "sc_test" line 7 at FETCH
  create or replace function sc_test() returns setof integer as $$
  declare
    c refcursor;
--- 3001,3007 ----
  select * from sc_test();  -- fails because of NO SCROLL specification
  ERROR:  cursor can only scan forward
  HINT:  Declare it with SCROLL option to enable backward scan.
! CONTEXT:  PL/pgSQL function "sc_test()" line 7 at FETCH
  create or replace function sc_test() returns setof integer as $$
  declare
    c refcursor;
***************
*** 3588,3594 ****
  $$ language plpgsql;
  select raise_test();
  ERROR:  RAISE option already specified: MESSAGE
! CONTEXT:  PL/pgSQL function "raise_test" line 3 at RAISE
  -- conflict on errcode
  create or replace function raise_test() returns void as $$
  begin
--- 3588,3594 ----
  $$ language plpgsql;
  select raise_test();
  ERROR:  RAISE option already specified: MESSAGE
! CONTEXT:  PL/pgSQL function "raise_test()" line 3 at RAISE
  -- conflict on errcode
  create or replace function raise_test() returns void as $$
  begin
***************
*** 3597,3603 ****
  $$ language plpgsql;
  select raise_test();
  ERROR:  RAISE option already specified: ERRCODE
! CONTEXT:  PL/pgSQL function "raise_test" line 3 at RAISE
  -- nothing to re-RAISE
  create or replace function raise_test() returns void as $$
  begin
--- 3597,3603 ----
  $$ language plpgsql;
  select raise_test();
  ERROR:  RAISE option already specified: ERRCODE
! CONTEXT:  PL/pgSQL function "raise_test()" line 3 at RAISE
  -- nothing to re-RAISE
  create or replace function raise_test() returns void as $$
  begin
***************
*** 3606,3612 ****
  $$ language plpgsql;
  select raise_test();
  ERROR:  RAISE without parameters cannot be used outside an exception handler
! CONTEXT:  PL/pgSQL function "raise_test" line 3 at RAISE
  -- test access to exception data
  create function zero_divide() returns int as $$
  declare v int := 0;
--- 3606,3612 ----
  $$ language plpgsql;
  select raise_test();
  ERROR:  RAISE without parameters cannot be used outside an exception handler
! CONTEXT:  PL/pgSQL function "raise_test()" line 3 at RAISE
  -- test access to exception data
  create function zero_divide() returns int as $$
  declare v int := 0;
***************
*** 3637,3643 ****
  end;
  $$ language plpgsql;
  select stacked_diagnostics_test();
! NOTICE:  sqlstate: 22012, message: division by zero, context: [PL/pgSQL function "zero_divide" line 4 at RETURN <- SQL statement "SELECT zero_divide()" <- PL/pgSQL function "stacked_diagnostics_test" line 6 at PERFORM]
   stacked_diagnostics_test 
  --------------------------
   
--- 3637,3643 ----
  end;
  $$ language plpgsql;
  select stacked_diagnostics_test();
! NOTICE:  sqlstate: 22012, message: division by zero, context: [PL/pgSQL function "zero_divide()" line 4 at RETURN <- SQL statement "SELECT zero_divide()" <- PL/pgSQL function "stacked_diagnostics_test()" line 6 at PERFORM]
   stacked_diagnostics_test 
  --------------------------
   
***************
*** 3679,3685 ****
  $$ language plpgsql;
  select stacked_diagnostics_test();
  ERROR:  GET STACKED DIAGNOSTICS cannot be used outside an exception handler
! CONTEXT:  PL/pgSQL function "stacked_diagnostics_test" line 6 at GET DIAGNOSTICS
  drop function zero_divide();
  drop function stacked_diagnostics_test();
  -- check cases where implicit SQLSTATE variable could be confused with
--- 3679,3685 ----
  $$ language plpgsql;
  select stacked_diagnostics_test();
  ERROR:  GET STACKED DIAGNOSTICS cannot be used outside an exception handler
! CONTEXT:  PL/pgSQL function "stacked_diagnostics_test()" line 6 at GET DIAGNOSTICS
  drop function zero_divide();
  drop function stacked_diagnostics_test();
  -- check cases where implicit SQLSTATE variable could be confused with
***************
*** 3743,3749 ****
  select case_test(5); -- fails
  ERROR:  case not found
  HINT:  CASE statement is missing ELSE part.
! CONTEXT:  PL/pgSQL function "case_test" line 5 at CASE
  select case_test(8);
        case_test       
  ----------------------
--- 3743,3749 ----
  select case_test(5); -- fails
  ERROR:  case not found
  HINT:  CASE statement is missing ELSE part.
! CONTEXT:  PL/pgSQL function "case_test(bigint)" line 5 at CASE
  select case_test(8);
        case_test       
  ----------------------
***************
*** 3771,3777 ****
  select case_test(13); -- fails
  ERROR:  case not found
  HINT:  CASE statement is missing ELSE part.
! CONTEXT:  PL/pgSQL function "case_test" line 5 at CASE
  create or replace function catch() returns void as $$
  begin
    raise notice '%', case_test(6);
--- 3771,3777 ----
  select case_test(13); -- fails
  ERROR:  case not found
  HINT:  CASE statement is missing ELSE part.
! CONTEXT:  PL/pgSQL function "case_test(bigint)" line 5 at CASE
  create or replace function catch() returns void as $$
  begin
    raise notice '%', case_test(6);
***************
*** 4099,4105 ****
  select error2('nonexistent.stuffs');
  ERROR:  schema "nonexistent" does not exist
  CONTEXT:  SQL function "error1" statement 1
! PL/pgSQL function "error2" line 3 at RETURN
  ROLLBACK TO a;
  select error2('public.stuffs');
   error2 
--- 4099,4105 ----
  select error2('nonexistent.stuffs');
  ERROR:  schema "nonexistent" does not exist
  CONTEXT:  SQL function "error1" statement 1
! PL/pgSQL function "error2(text)" line 3 at RETURN
  ROLLBACK TO a;
  select error2('public.stuffs');
   error2 
***************
*** 4137,4143 ****
                 ^
  HINT:  Use the escape string syntax for backslashes, e.g., E'\\'.
  QUERY:  SELECT 'foo\\bar\041baz'
! CONTEXT:  PL/pgSQL function "strtest" line 4 at RETURN
     strtest   
  -------------
   foo\bar!baz
--- 4137,4143 ----
                 ^
  HINT:  Use the escape string syntax for backslashes, e.g., E'\\'.
  QUERY:  SELECT 'foo\\bar\041baz'
! CONTEXT:  PL/pgSQL function "strtest()" line 4 at RETURN
     strtest   
  -------------
   foo\bar!baz
***************
*** 4220,4226 ****
  LINE 1: SELECT rtrim(roomno) AS roomno, foo FROM Room ORDER BY roomn...
                                          ^
  QUERY:  SELECT rtrim(roomno) AS roomno, foo FROM Room ORDER BY roomno
! CONTEXT:  PL/pgSQL function "inline_code_block" line 4 at FOR over SELECT rows
  -- Check variable scoping -- a var is not available in its own or prior
  -- default expressions.
  create function scope_test() returns int as $$
--- 4220,4226 ----
  LINE 1: SELECT rtrim(roomno) AS roomno, foo FROM Room ORDER BY roomn...
                                          ^
  QUERY:  SELECT rtrim(roomno) AS roomno, foo FROM Room ORDER BY roomno
! CONTEXT:  PL/pgSQL function "(null)" line 4 at FOR over SELECT rows
  -- Check variable scoping -- a var is not available in its own or prior
  -- default expressions.
  create function scope_test() returns int as $$
***************
*** 4257,4263 ****
                 ^
  DETAIL:  It could refer to either a PL/pgSQL variable or a table column.
  QUERY:  select q1,q2 from int8_tbl
! CONTEXT:  PL/pgSQL function "conflict_test" line 5 at FOR over SELECT rows
  create or replace function conflict_test() returns setof int8_tbl as $$
  #variable_conflict use_variable
  declare r record;
--- 4257,4263 ----
                 ^
  DETAIL:  It could refer to either a PL/pgSQL variable or a table column.
  QUERY:  select q1,q2 from int8_tbl
! CONTEXT:  PL/pgSQL function "conflict_test()" line 5 at FOR over SELECT rows
  create or replace function conflict_test() returns setof int8_tbl as $$
  #variable_conflict use_variable
  declare r record;
***************
*** 4361,4370 ****
  -- should fail
  select foreach_test(ARRAY[1,2,3,4]);
  ERROR:  FOREACH ... SLICE loop variable must be of an array type
! CONTEXT:  PL/pgSQL function "foreach_test" line 4 at FOREACH over array
  select foreach_test(ARRAY[[1,2],[3,4]]);
  ERROR:  FOREACH ... SLICE loop variable must be of an array type
! CONTEXT:  PL/pgSQL function "foreach_test" line 4 at FOREACH over array
  create or replace function foreach_test(anyarray)
  returns void as $$
  declare x int[];
--- 4361,4370 ----
  -- should fail
  select foreach_test(ARRAY[1,2,3,4]);
  ERROR:  FOREACH ... SLICE loop variable must be of an array type
! CONTEXT:  PL/pgSQL function "foreach_test(anyarray)" line 4 at FOREACH over array
  select foreach_test(ARRAY[[1,2],[3,4]]);
  ERROR:  FOREACH ... SLICE loop variable must be of an array type
! CONTEXT:  PL/pgSQL function "foreach_test(anyarray)" line 4 at FOREACH over array
  create or replace function foreach_test(anyarray)
  returns void as $$
  declare x int[];
***************
*** 4404,4410 ****
  -- should fail
  select foreach_test(ARRAY[1,2,3,4]);
  ERROR:  slice dimension (2) is out of the valid range 0..1
! CONTEXT:  PL/pgSQL function "foreach_test" line 4 at FOREACH over array
  -- ok
  select foreach_test(ARRAY[[1,2],[3,4]]);
  NOTICE:  {{1,2},{3,4}}
--- 4404,4410 ----
  -- should fail
  select foreach_test(ARRAY[1,2,3,4]);
  ERROR:  slice dimension (2) is out of the valid range 0..1
! CONTEXT:  PL/pgSQL function "foreach_test(anyarray)" line 4 at FOREACH over array
  -- ok
  select foreach_test(ARRAY[[1,2],[3,4]]);
  NOTICE:  {{1,2},{3,4}}
***************
*** 4565,4573 ****
  
  select testoa(2,1,3); -- fail at initial assign
  ERROR:  value for domain orderedarray violates check constraint "sorted"
! CONTEXT:  PL/pgSQL function "testoa" line 4 at assignment
  select testoa(1,2,1); -- fail at update
  ERROR:  value for domain orderedarray violates check constraint "sorted"
! CONTEXT:  PL/pgSQL function "testoa" line 5 at assignment
  drop function arrayassign1();
  drop function testoa(x1 int, x2 int, x3 int);
--- 4565,4573 ----
  
  select testoa(2,1,3); -- fail at initial assign
  ERROR:  value for domain orderedarray violates check constraint "sorted"
! CONTEXT:  PL/pgSQL function "testoa(integer,integer,integer)" line 4 at assignment
  select testoa(1,2,1); -- fail at update
  ERROR:  value for domain orderedarray violates check constraint "sorted"
! CONTEXT:  PL/pgSQL function "testoa(integer,integer,integer)" line 5 at assignment
  drop function arrayassign1();
  drop function testoa(x1 int, x2 int, x3 int);
*** ./src/test/regress/expected/triggers.out.orig	2011-11-24 12:51:45.000000000 +0100
--- ./src/test/regress/expected/triggers.out	2011-11-24 17:32:17.000000000 +0100
***************
*** 965,974 ****
  NOTICE:  NEW: (20,30)
  NOTICE:  trigger_func(before_ins_stmt) called: action = INSERT, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
! PL/pgSQL function "view_trigger" line 17 at SQL statement
  NOTICE:  trigger_func(after_ins_stmt) called: action = INSERT, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
! PL/pgSQL function "view_trigger" line 17 at SQL statement
  NOTICE:  main_view AFTER INSERT STATEMENT (after_view_ins_stmt)
  INSERT 0 1
  INSERT INTO main_view VALUES (21, 31) RETURNING a, b;
--- 965,974 ----
  NOTICE:  NEW: (20,30)
  NOTICE:  trigger_func(before_ins_stmt) called: action = INSERT, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
! PL/pgSQL function "view_trigger()" line 17 at SQL statement
  NOTICE:  trigger_func(after_ins_stmt) called: action = INSERT, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
! PL/pgSQL function "view_trigger()" line 17 at SQL statement
  NOTICE:  main_view AFTER INSERT STATEMENT (after_view_ins_stmt)
  INSERT 0 1
  INSERT INTO main_view VALUES (21, 31) RETURNING a, b;
***************
*** 977,986 ****
  NOTICE:  NEW: (21,31)
  NOTICE:  trigger_func(before_ins_stmt) called: action = INSERT, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
! PL/pgSQL function "view_trigger" line 17 at SQL statement
  NOTICE:  trigger_func(after_ins_stmt) called: action = INSERT, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
! PL/pgSQL function "view_trigger" line 17 at SQL statement
  NOTICE:  main_view AFTER INSERT STATEMENT (after_view_ins_stmt)
   a  | b  
  ----+----
--- 977,986 ----
  NOTICE:  NEW: (21,31)
  NOTICE:  trigger_func(before_ins_stmt) called: action = INSERT, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
! PL/pgSQL function "view_trigger()" line 17 at SQL statement
  NOTICE:  trigger_func(after_ins_stmt) called: action = INSERT, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
! PL/pgSQL function "view_trigger()" line 17 at SQL statement
  NOTICE:  main_view AFTER INSERT STATEMENT (after_view_ins_stmt)
   a  | b  
  ----+----
***************
*** 995,1010 ****
  NOTICE:  OLD: (20,30), NEW: (20,31)
  NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(before_upd_a_row) called: action = UPDATE, when = BEFORE, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
  UPDATE 0
  UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b;
--- 995,1010 ----
  NOTICE:  OLD: (20,30), NEW: (20,31)
  NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(before_upd_a_row) called: action = UPDATE, when = BEFORE, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
  UPDATE 0
  UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b;
***************
*** 1013,1028 ****
  NOTICE:  OLD: (21,31), NEW: (21,32)
  NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(before_upd_a_row) called: action = UPDATE, when = BEFORE, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
   a | b 
  ---+---
--- 1013,1028 ----
  NOTICE:  OLD: (21,31), NEW: (21,32)
  NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(before_upd_a_row) called: action = UPDATE, when = BEFORE, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
   a | b 
  ---+---
***************
*** 1038,1056 ****
  NOTICE:  OLD: (20,30), NEW: (20,31)
  NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_a_b_row) called: action = UPDATE, when = AFTER, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_row) called: action = UPDATE, when = AFTER, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
  UPDATE 1
  UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b;
--- 1038,1056 ----
  NOTICE:  OLD: (20,30), NEW: (20,31)
  NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_a_b_row) called: action = UPDATE, when = AFTER, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_row) called: action = UPDATE, when = AFTER, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
  UPDATE 1
  UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b;
***************
*** 1059,1077 ****
  NOTICE:  OLD: (21,31), NEW: (21,32)
  NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_a_b_row) called: action = UPDATE, when = AFTER, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_row) called: action = UPDATE, when = AFTER, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
   a  | b  
  ----+----
--- 1059,1077 ----
  NOTICE:  OLD: (21,31), NEW: (21,32)
  NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_a_b_row) called: action = UPDATE, when = AFTER, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_row) called: action = UPDATE, when = AFTER, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
   a  | b  
  ----+----
#7Abhijit Menon-Sen
ams@toroid.org
In reply to: Pavel Stehule (#6)
1 attachment(s)
Re: proposal: better support for debugging of overloaded functions

At 2011-11-24 17:44:16 +0100, pavel.stehule@gmail.com wrote:

patch is relative long, but almost all are changes in regress tests.
Changes in plpgsql are 5 lines

The change looks good in principle. The patch applies to HEAD with a bit
of fuzz and builds fine… but it fails tests, because it's incomplete.

Pavel, your patch doesn't contain any changes to pl_exec.c. Did you just
forget to submit them? Anyway, some errcontext() calls need to be taught
to print ->fn_signature rather than ->fn_name. I made those changes, and
found some more failing tests.

Updated patch attached. Ready for committer.

-- ams

Attachments:

pavel-plpgsql-fnsig.difftext/x-diff; charset=us-asciiDownload
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 6ba1e5e..eee6f6c 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -342,6 +342,7 @@ do_compile(FunctionCallInfo fcinfo,
 	compile_tmp_cxt = MemoryContextSwitchTo(func_cxt);
 
 	function->fn_name = pstrdup(NameStr(procStruct->proname));
+	function->fn_signature = format_procedure(fcinfo->flinfo->fn_oid);
 	function->fn_oid = fcinfo->flinfo->fn_oid;
 	function->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
 	function->fn_tid = procTup->t_self;
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 5ce8d6e..57e337e 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -799,7 +799,7 @@ plpgsql_exec_error_callback(void *arg)
 			 * local variable initialization"
 			 */
 			errcontext("PL/pgSQL function \"%s\" line %d %s",
-					   estate->func->fn_name,
+					   estate->func->fn_signature,
 					   estate->err_stmt->lineno,
 					   _(estate->err_text));
 		}
@@ -810,7 +810,7 @@ plpgsql_exec_error_callback(void *arg)
 			 * arguments into local variables"
 			 */
 			errcontext("PL/pgSQL function \"%s\" %s",
-					   estate->func->fn_name,
+					   estate->func->fn_signature,
 					   _(estate->err_text));
 		}
 	}
@@ -818,13 +818,13 @@ plpgsql_exec_error_callback(void *arg)
 	{
 		/* translator: last %s is a plpgsql statement type name */
 		errcontext("PL/pgSQL function \"%s\" line %d at %s",
-				   estate->func->fn_name,
+				   estate->func->fn_signature,
 				   estate->err_stmt->lineno,
 				   plpgsql_stmt_typename(estate->err_stmt));
 	}
 	else
 		errcontext("PL/pgSQL function \"%s\"",
-				   estate->func->fn_name);
+				   estate->func->fn_signature);
 }
 
 
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index 0aef8dc..739b9e4 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -679,6 +679,7 @@ typedef struct PLpgSQL_func_hashkey
 typedef struct PLpgSQL_function
 {								/* Complete compiled function	  */
 	char	   *fn_name;
+	char	   *fn_signature;
 	Oid			fn_oid;
 	TransactionId fn_xmin;
 	ItemPointerData fn_tid;
diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out
index 4f47374..4da1c53 100644
--- a/src/test/regress/expected/domain.out
+++ b/src/test/regress/expected/domain.out
@@ -493,7 +493,7 @@ begin
 end$$ language plpgsql;
 select doubledecrement(3); -- fail because of implicit null assignment
 ERROR:  domain pos_int does not allow null values
-CONTEXT:  PL/pgSQL function "doubledecrement" line 3 during statement block local variable initialization
+CONTEXT:  PL/pgSQL function "doubledecrement(pos_int)" line 3 during statement block local variable initialization
 create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
 declare v pos_int := 0;
 begin
@@ -501,7 +501,7 @@ begin
 end$$ language plpgsql;
 select doubledecrement(3); -- fail at initialization assignment
 ERROR:  value for domain pos_int violates check constraint "pos_int_check"
-CONTEXT:  PL/pgSQL function "doubledecrement" line 3 during statement block local variable initialization
+CONTEXT:  PL/pgSQL function "doubledecrement(pos_int)" line 3 during statement block local variable initialization
 create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
 declare v pos_int := 1;
 begin
@@ -514,10 +514,10 @@ select doubledecrement(0); -- fail before call
 ERROR:  value for domain pos_int violates check constraint "pos_int_check"
 select doubledecrement(1); -- fail at assignment to v
 ERROR:  value for domain pos_int violates check constraint "pos_int_check"
-CONTEXT:  PL/pgSQL function "doubledecrement" line 4 at assignment
+CONTEXT:  PL/pgSQL function "doubledecrement(pos_int)" line 4 at assignment
 select doubledecrement(2); -- fail at return
 ERROR:  value for domain pos_int violates check constraint "pos_int_check"
-CONTEXT:  PL/pgSQL function "doubledecrement" while casting return value to function's return type
+CONTEXT:  PL/pgSQL function "doubledecrement(pos_int)" while casting return value to function's return type
 select doubledecrement(3); -- good
  doubledecrement 
 -----------------
@@ -566,7 +566,7 @@ end$$ language plpgsql;
 select array_elem_check(121.00);
 ERROR:  numeric field overflow
 DETAIL:  A field with precision 4, scale 2 must round to an absolute value less than 10^2.
-CONTEXT:  PL/pgSQL function "array_elem_check" line 5 at assignment
+CONTEXT:  PL/pgSQL function "array_elem_check(numeric)" line 5 at assignment
 select array_elem_check(1.23456);
  array_elem_check 
 ------------------
@@ -584,7 +584,7 @@ end$$ language plpgsql;
 select array_elem_check(121.00);
 ERROR:  numeric field overflow
 DETAIL:  A field with precision 4, scale 2 must round to an absolute value less than 10^2.
-CONTEXT:  PL/pgSQL function "array_elem_check" line 5 at assignment
+CONTEXT:  PL/pgSQL function "array_elem_check(numeric)" line 5 at assignment
 select array_elem_check(1.23456);
  array_elem_check 
 ------------------
@@ -602,7 +602,7 @@ end$$ language plpgsql;
 select array_elem_check(121.00);
 ERROR:  numeric field overflow
 DETAIL:  A field with precision 4, scale 2 must round to an absolute value less than 10^2.
-CONTEXT:  PL/pgSQL function "array_elem_check" line 5 at assignment
+CONTEXT:  PL/pgSQL function "array_elem_check(numeric)" line 5 at assignment
 select array_elem_check(1.23456);
  array_elem_check 
 ------------------
@@ -650,7 +650,7 @@ select array_elem_check(3);
 
 select array_elem_check(-1);
 ERROR:  value for domain orderedpair violates check constraint "orderedpair_check"
-CONTEXT:  PL/pgSQL function "array_elem_check" line 5 at assignment
+CONTEXT:  PL/pgSQL function "array_elem_check(integer)" line 5 at assignment
 drop function array_elem_check(int);
 --
 -- Renaming
diff --git a/src/test/regress/expected/guc.out b/src/test/regress/expected/guc.out
index 98671a2..2127285 100644
--- a/src/test/regress/expected/guc.out
+++ b/src/test/regress/expected/guc.out
@@ -687,7 +687,7 @@ set work_mem = '1MB';
 select myfunc(0);
 ERROR:  division by zero
 CONTEXT:  SQL statement "SELECT 1/$1"
-PL/pgSQL function "myfunc" line 4 at PERFORM
+PL/pgSQL function "myfunc(integer)" line 4 at PERFORM
 select current_setting('work_mem');
  current_setting 
 -----------------
diff --git a/src/test/regress/expected/plancache.out b/src/test/regress/expected/plancache.out
index 9a84a97..80322e8 100644
--- a/src/test/regress/expected/plancache.out
+++ b/src/test/regress/expected/plancache.out
@@ -235,7 +235,7 @@ end$$ language plpgsql;
 select cachebug();
 NOTICE:  table "temptable" does not exist, skipping
 CONTEXT:  SQL statement "drop table if exists temptable cascade"
-PL/pgSQL function "cachebug" line 4 at SQL statement
+PL/pgSQL function "cachebug()" line 4 at SQL statement
 NOTICE:  1
 NOTICE:  2
 NOTICE:  3
@@ -247,7 +247,7 @@ NOTICE:  3
 select cachebug();
 NOTICE:  drop cascades to view vv
 CONTEXT:  SQL statement "drop table if exists temptable cascade"
-PL/pgSQL function "cachebug" line 4 at SQL statement
+PL/pgSQL function "cachebug()" line 4 at SQL statement
 NOTICE:  1
 NOTICE:  2
 NOTICE:  3
diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out
index bdef259..141c4e1 100644
--- a/src/test/regress/expected/plpgsql.out
+++ b/src/test/regress/expected/plpgsql.out
@@ -1518,16 +1518,16 @@ ERROR:  duplicate key value violates unique constraint "pfield_name"
 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
+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
+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
+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
+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.
@@ -2067,13 +2067,13 @@ end$$ language plpgsql;
 select test_variable_storage();
 NOTICE:  should see this
 CONTEXT:  SQL statement "SELECT trap_zero_divide(-100)"
-PL/pgSQL function "test_variable_storage" line 8 at PERFORM
+PL/pgSQL function "test_variable_storage()" line 8 at PERFORM
 NOTICE:  should see this only if -100 <> 0
 CONTEXT:  SQL statement "SELECT trap_zero_divide(-100)"
-PL/pgSQL function "test_variable_storage" line 8 at PERFORM
+PL/pgSQL function "test_variable_storage()" line 8 at PERFORM
 NOTICE:  should see this only if -100 fits in smallint
 CONTEXT:  SQL statement "SELECT trap_zero_divide(-100)"
-PL/pgSQL function "test_variable_storage" line 8 at PERFORM
+PL/pgSQL function "test_variable_storage()" line 8 at PERFORM
  test_variable_storage 
 -----------------------
  123456789012
@@ -2397,7 +2397,7 @@ end $$ language plpgsql;
 select namedparmcursor_test7();
 ERROR:  division by zero
 CONTEXT:  SQL statement "SELECT 42/0 AS p1, 77 AS p2;"
-PL/pgSQL function "namedparmcursor_test7" line 6 at OPEN
+PL/pgSQL function "namedparmcursor_test7()" line 6 at OPEN
 -- check that line comments work correctly within the argument list (there
 -- is some special handling of this case in the code: the newline after the
 -- comment must be preserved when the argument-evaluating query is
@@ -2431,7 +2431,7 @@ end;
 $$ language plpgsql;
 select raise_test1(5);
 ERROR:  too many parameters specified for RAISE
-CONTEXT:  PL/pgSQL function "raise_test1" line 3 at RAISE
+CONTEXT:  PL/pgSQL function "raise_test1(integer)" line 3 at RAISE
 create function raise_test2(int) returns int as $$
 begin
     raise notice 'This message has too few parameters: %, %, %', $1, $1;
@@ -2440,7 +2440,7 @@ end;
 $$ language plpgsql;
 select raise_test2(10);
 ERROR:  too few parameters specified for RAISE
-CONTEXT:  PL/pgSQL function "raise_test2" line 3 at RAISE
+CONTEXT:  PL/pgSQL function "raise_test2(integer)" line 3 at RAISE
 -- Test re-RAISE inside a nested exception block.  This case is allowed
 -- by Oracle's PL/SQL but was handled differently by PG before 9.1.
 CREATE FUNCTION reraise_test() RETURNS void AS $$
@@ -2530,7 +2530,7 @@ begin
 end;$$ language plpgsql;
 select missing_return_expr();
 ERROR:  control reached end of function without RETURN
-CONTEXT:  PL/pgSQL function "missing_return_expr"
+CONTEXT:  PL/pgSQL function "missing_return_expr()"
 drop function void_return_expr();
 drop function missing_return_expr();
 --
@@ -2582,7 +2582,7 @@ ERROR:  column "sqlstate" does not exist
 LINE 1: SELECT sqlstate
                ^
 QUERY:  SELECT sqlstate
-CONTEXT:  PL/pgSQL function "excpt_test1" line 3 at RAISE
+CONTEXT:  PL/pgSQL function "excpt_test1()" line 3 at RAISE
 create function excpt_test2() returns void as $$
 begin
     begin
@@ -2597,7 +2597,7 @@ ERROR:  column "sqlstate" does not exist
 LINE 1: SELECT sqlstate
                ^
 QUERY:  SELECT sqlstate
-CONTEXT:  PL/pgSQL function "excpt_test2" line 5 at RAISE
+CONTEXT:  PL/pgSQL function "excpt_test2()" line 5 at RAISE
 create function excpt_test3() returns void as $$
 begin
     begin
@@ -2803,7 +2803,7 @@ $$ language plpgsql;
 -- should fail
 select continue_test2();
 ERROR:  CONTINUE cannot be used outside a loop
-CONTEXT:  PL/pgSQL function "continue_test2"
+CONTEXT:  PL/pgSQL function "continue_test2()"
 -- CONTINUE can't reference the label of a named block
 create function continue_test3() returns void as $$
 begin
@@ -2818,7 +2818,7 @@ $$ language plpgsql;
 -- should fail
 select continue_test3();
 ERROR:  CONTINUE cannot be used outside a loop
-CONTEXT:  PL/pgSQL function "continue_test3"
+CONTEXT:  PL/pgSQL function "continue_test3()"
 drop function continue_test1();
 drop function continue_test2();
 drop function continue_test3();
@@ -2979,7 +2979,7 @@ begin
 end$$ language plpgsql;
 select footest();
 ERROR:  query returned more than one row
-CONTEXT:  PL/pgSQL function "footest" line 5 at SQL statement
+CONTEXT:  PL/pgSQL function "footest()" line 5 at SQL statement
 create or replace function footest() returns void as $$
 declare x record;
 begin
@@ -3042,7 +3042,7 @@ begin
 end$$ language plpgsql;
 select footest();
 ERROR:  query returned no rows
-CONTEXT:  PL/pgSQL function "footest" line 5 at SQL statement
+CONTEXT:  PL/pgSQL function "footest()" line 5 at SQL statement
 create or replace function footest() returns void as $$
 declare x record;
 begin
@@ -3052,7 +3052,7 @@ begin
 end$$ language plpgsql;
 select footest();
 ERROR:  query returned more than one row
-CONTEXT:  PL/pgSQL function "footest" line 5 at SQL statement
+CONTEXT:  PL/pgSQL function "footest()" line 5 at SQL statement
 create or replace function footest() returns void as $$
 declare x record;
 begin
@@ -3076,7 +3076,7 @@ begin
 end$$ language plpgsql;
 select footest();
 ERROR:  query returned no rows
-CONTEXT:  PL/pgSQL function "footest" line 5 at EXECUTE statement
+CONTEXT:  PL/pgSQL function "footest()" line 5 at EXECUTE statement
 create or replace function footest() returns void as $$
 declare x record;
 begin
@@ -3086,7 +3086,7 @@ begin
 end$$ language plpgsql;
 select footest();
 ERROR:  query returned more than one row
-CONTEXT:  PL/pgSQL function "footest" line 5 at EXECUTE statement
+CONTEXT:  PL/pgSQL function "footest()" line 5 at EXECUTE statement
 drop function footest();
 -- test scrollable cursor support
 create function sc_test() returns setof integer as $$
@@ -3130,7 +3130,7 @@ $$ language plpgsql;
 select * from sc_test();  -- fails because of NO SCROLL specification
 ERROR:  cursor can only scan forward
 HINT:  Declare it with SCROLL option to enable backward scan.
-CONTEXT:  PL/pgSQL function "sc_test" line 7 at FETCH
+CONTEXT:  PL/pgSQL function "sc_test()" line 7 at FETCH
 create or replace function sc_test() returns setof integer as $$
 declare
   c refcursor;
@@ -3717,7 +3717,7 @@ end;
 $$ language plpgsql;
 select raise_test();
 ERROR:  RAISE option already specified: MESSAGE
-CONTEXT:  PL/pgSQL function "raise_test" line 3 at RAISE
+CONTEXT:  PL/pgSQL function "raise_test()" line 3 at RAISE
 -- conflict on errcode
 create or replace function raise_test() returns void as $$
 begin
@@ -3726,7 +3726,7 @@ end;
 $$ language plpgsql;
 select raise_test();
 ERROR:  RAISE option already specified: ERRCODE
-CONTEXT:  PL/pgSQL function "raise_test" line 3 at RAISE
+CONTEXT:  PL/pgSQL function "raise_test()" line 3 at RAISE
 -- nothing to re-RAISE
 create or replace function raise_test() returns void as $$
 begin
@@ -3735,7 +3735,7 @@ end;
 $$ language plpgsql;
 select raise_test();
 ERROR:  RAISE without parameters cannot be used outside an exception handler
-CONTEXT:  PL/pgSQL function "raise_test" line 3 at RAISE
+CONTEXT:  PL/pgSQL function "raise_test()" line 3 at RAISE
 -- test access to exception data
 create function zero_divide() returns int as $$
 declare v int := 0;
@@ -3766,7 +3766,7 @@ exception when others then
 end;
 $$ language plpgsql;
 select stacked_diagnostics_test();
-NOTICE:  sqlstate: 22012, message: division by zero, context: [PL/pgSQL function "zero_divide" line 4 at RETURN <- SQL statement "SELECT zero_divide()" <- PL/pgSQL function "stacked_diagnostics_test" line 6 at PERFORM]
+NOTICE:  sqlstate: 22012, message: division by zero, context: [PL/pgSQL function "zero_divide()" line 4 at RETURN <- SQL statement "SELECT zero_divide()" <- PL/pgSQL function "stacked_diagnostics_test()" line 6 at PERFORM]
  stacked_diagnostics_test 
 --------------------------
  
@@ -3808,7 +3808,7 @@ end;
 $$ language plpgsql;
 select stacked_diagnostics_test();
 ERROR:  GET STACKED DIAGNOSTICS cannot be used outside an exception handler
-CONTEXT:  PL/pgSQL function "stacked_diagnostics_test" line 6 at GET DIAGNOSTICS
+CONTEXT:  PL/pgSQL function "stacked_diagnostics_test()" line 6 at GET DIAGNOSTICS
 drop function zero_divide();
 drop function stacked_diagnostics_test();
 -- check cases where implicit SQLSTATE variable could be confused with
@@ -3872,7 +3872,7 @@ select case_test(4);
 select case_test(5); -- fails
 ERROR:  case not found
 HINT:  CASE statement is missing ELSE part.
-CONTEXT:  PL/pgSQL function "case_test" line 5 at CASE
+CONTEXT:  PL/pgSQL function "case_test(bigint)" line 5 at CASE
 select case_test(8);
       case_test       
 ----------------------
@@ -3900,7 +3900,7 @@ select case_test(12);
 select case_test(13); -- fails
 ERROR:  case not found
 HINT:  CASE statement is missing ELSE part.
-CONTEXT:  PL/pgSQL function "case_test" line 5 at CASE
+CONTEXT:  PL/pgSQL function "case_test(bigint)" line 5 at CASE
 create or replace function catch() returns void as $$
 begin
   raise notice '%', case_test(6);
@@ -4228,7 +4228,7 @@ SAVEPOINT a;
 select error2('nonexistent.stuffs');
 ERROR:  schema "nonexistent" does not exist
 CONTEXT:  SQL function "error1" statement 1
-PL/pgSQL function "error2" line 3 at RETURN
+PL/pgSQL function "error2(text)" line 3 at RETURN
 ROLLBACK TO a;
 select error2('public.stuffs');
  error2 
@@ -4266,7 +4266,7 @@ LINE 1: SELECT 'foo\\bar\041baz'
                ^
 HINT:  Use the escape string syntax for backslashes, e.g., E'\\'.
 QUERY:  SELECT 'foo\\bar\041baz'
-CONTEXT:  PL/pgSQL function "strtest" line 4 at RETURN
+CONTEXT:  PL/pgSQL function "strtest()" line 4 at RETURN
    strtest   
 -------------
  foo\bar!baz
@@ -4349,7 +4349,7 @@ ERROR:  column "foo" does not exist
 LINE 1: SELECT rtrim(roomno) AS roomno, foo FROM Room ORDER BY roomn...
                                         ^
 QUERY:  SELECT rtrim(roomno) AS roomno, foo FROM Room ORDER BY roomno
-CONTEXT:  PL/pgSQL function "inline_code_block" line 4 at FOR over SELECT rows
+CONTEXT:  PL/pgSQL function "(null)" line 4 at FOR over SELECT rows
 -- Check variable scoping -- a var is not available in its own or prior
 -- default expressions.
 create function scope_test() returns int as $$
@@ -4386,7 +4386,7 @@ LINE 1: select q1,q2 from int8_tbl
                ^
 DETAIL:  It could refer to either a PL/pgSQL variable or a table column.
 QUERY:  select q1,q2 from int8_tbl
-CONTEXT:  PL/pgSQL function "conflict_test" line 5 at FOR over SELECT rows
+CONTEXT:  PL/pgSQL function "conflict_test()" line 5 at FOR over SELECT rows
 create or replace function conflict_test() returns setof int8_tbl as $$
 #variable_conflict use_variable
 declare r record;
@@ -4490,10 +4490,10 @@ $$ language plpgsql;
 -- should fail
 select foreach_test(ARRAY[1,2,3,4]);
 ERROR:  FOREACH ... SLICE loop variable must be of an array type
-CONTEXT:  PL/pgSQL function "foreach_test" line 4 at FOREACH over array
+CONTEXT:  PL/pgSQL function "foreach_test(anyarray)" line 4 at FOREACH over array
 select foreach_test(ARRAY[[1,2],[3,4]]);
 ERROR:  FOREACH ... SLICE loop variable must be of an array type
-CONTEXT:  PL/pgSQL function "foreach_test" line 4 at FOREACH over array
+CONTEXT:  PL/pgSQL function "foreach_test(anyarray)" line 4 at FOREACH over array
 create or replace function foreach_test(anyarray)
 returns void as $$
 declare x int[];
@@ -4533,7 +4533,7 @@ $$ language plpgsql;
 -- should fail
 select foreach_test(ARRAY[1,2,3,4]);
 ERROR:  slice dimension (2) is out of the valid range 0..1
-CONTEXT:  PL/pgSQL function "foreach_test" line 4 at FOREACH over array
+CONTEXT:  PL/pgSQL function "foreach_test(anyarray)" line 4 at FOREACH over array
 -- ok
 select foreach_test(ARRAY[[1,2],[3,4]]);
 NOTICE:  {{1,2},{3,4}}
@@ -4694,9 +4694,9 @@ select testoa(1,2,3); -- try again to exercise internal caching
 
 select testoa(2,1,3); -- fail at initial assign
 ERROR:  value for domain orderedarray violates check constraint "sorted"
-CONTEXT:  PL/pgSQL function "testoa" line 4 at assignment
+CONTEXT:  PL/pgSQL function "testoa(integer,integer,integer)" line 4 at assignment
 select testoa(1,2,1); -- fail at update
 ERROR:  value for domain orderedarray violates check constraint "sorted"
-CONTEXT:  PL/pgSQL function "testoa" line 5 at assignment
+CONTEXT:  PL/pgSQL function "testoa(integer,integer,integer)" line 5 at assignment
 drop function arrayassign1();
 drop function testoa(x1 int, x2 int, x3 int);
diff --git a/src/test/regress/expected/triggers.out b/src/test/regress/expected/triggers.out
index d039b6e..3c96c89 100644
--- a/src/test/regress/expected/triggers.out
+++ b/src/test/regress/expected/triggers.out
@@ -965,10 +965,10 @@ NOTICE:  main_view INSTEAD OF INSERT ROW (instead_of_ins)
 NOTICE:  NEW: (20,30)
 NOTICE:  trigger_func(before_ins_stmt) called: action = INSERT, when = BEFORE, level = STATEMENT
 CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
-PL/pgSQL function "view_trigger" line 17 at SQL statement
+PL/pgSQL function "view_trigger()" line 17 at SQL statement
 NOTICE:  trigger_func(after_ins_stmt) called: action = INSERT, when = AFTER, level = STATEMENT
 CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
-PL/pgSQL function "view_trigger" line 17 at SQL statement
+PL/pgSQL function "view_trigger()" line 17 at SQL statement
 NOTICE:  main_view AFTER INSERT STATEMENT (after_view_ins_stmt)
 INSERT 0 1
 INSERT INTO main_view VALUES (21, 31) RETURNING a, b;
@@ -977,10 +977,10 @@ NOTICE:  main_view INSTEAD OF INSERT ROW (instead_of_ins)
 NOTICE:  NEW: (21,31)
 NOTICE:  trigger_func(before_ins_stmt) called: action = INSERT, when = BEFORE, level = STATEMENT
 CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
-PL/pgSQL function "view_trigger" line 17 at SQL statement
+PL/pgSQL function "view_trigger()" line 17 at SQL statement
 NOTICE:  trigger_func(after_ins_stmt) called: action = INSERT, when = AFTER, level = STATEMENT
 CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
-PL/pgSQL function "view_trigger" line 17 at SQL statement
+PL/pgSQL function "view_trigger()" line 17 at SQL statement
 NOTICE:  main_view AFTER INSERT STATEMENT (after_view_ins_stmt)
  a  | b  
 ----+----
@@ -995,16 +995,16 @@ NOTICE:  main_view INSTEAD OF UPDATE ROW (instead_of_upd)
 NOTICE:  OLD: (20,30), NEW: (20,31)
 NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  trigger_func(before_upd_a_row) called: action = UPDATE, when = BEFORE, level = ROW
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
 UPDATE 0
 UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b;
@@ -1013,16 +1013,16 @@ NOTICE:  main_view INSTEAD OF UPDATE ROW (instead_of_upd)
 NOTICE:  OLD: (21,31), NEW: (21,32)
 NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  trigger_func(before_upd_a_row) called: action = UPDATE, when = BEFORE, level = ROW
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
  a | b 
 ---+---
@@ -1038,19 +1038,19 @@ NOTICE:  main_view INSTEAD OF UPDATE ROW (instead_of_upd)
 NOTICE:  OLD: (20,30), NEW: (20,31)
 NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  trigger_func(after_upd_a_b_row) called: action = UPDATE, when = AFTER, level = ROW
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  trigger_func(after_upd_b_row) called: action = UPDATE, when = AFTER, level = ROW
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
 UPDATE 1
 UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b;
@@ -1059,19 +1059,19 @@ NOTICE:  main_view INSTEAD OF UPDATE ROW (instead_of_upd)
 NOTICE:  OLD: (21,31), NEW: (21,32)
 NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  trigger_func(after_upd_a_b_row) called: action = UPDATE, when = AFTER, level = ROW
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  trigger_func(after_upd_b_row) called: action = UPDATE, when = AFTER, level = ROW
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
 CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
-PL/pgSQL function "view_trigger" line 23 at SQL statement
+PL/pgSQL function "view_trigger()" line 23 at SQL statement
 NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
  a  | b  
 ----+----
@@ -1503,28 +1503,28 @@ insert into depth_a values (1);
 NOTICE:  depth_a_tr: depth = 1
 NOTICE:  depth_b_tr: depth = 2
 CONTEXT:  SQL statement "insert into depth_b values (new.id)"
-PL/pgSQL function "depth_a_tf" line 4 at SQL statement
+PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
 NOTICE:  depth_c_tr: depth = 3
 CONTEXT:  SQL statement "insert into depth_c values (1)"
-PL/pgSQL function "depth_b_tf" line 5 at EXECUTE statement
+PL/pgSQL function "depth_b_tf()" line 5 at EXECUTE statement
 SQL statement "insert into depth_b values (new.id)"
-PL/pgSQL function "depth_a_tf" line 4 at SQL statement
+PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
 NOTICE:  SQLSTATE = U9999: depth = 2
 CONTEXT:  SQL statement "insert into depth_b values (new.id)"
-PL/pgSQL function "depth_a_tf" line 4 at SQL statement
+PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
 NOTICE:  depth_b_tr: depth = 2
 CONTEXT:  SQL statement "insert into depth_b values (new.id)"
-PL/pgSQL function "depth_a_tf" line 4 at SQL statement
+PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
 NOTICE:  depth_c_tr: depth = 3
 CONTEXT:  SQL statement "insert into depth_c values (1)"
-PL/pgSQL function "depth_b_tf" line 12 at EXECUTE statement
+PL/pgSQL function "depth_b_tf()" line 12 at EXECUTE statement
 SQL statement "insert into depth_b values (new.id)"
-PL/pgSQL function "depth_a_tf" line 4 at SQL statement
+PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
 ERROR:  U9999
 CONTEXT:  SQL statement "insert into depth_c values (1)"
-PL/pgSQL function "depth_b_tf" line 12 at EXECUTE statement
+PL/pgSQL function "depth_b_tf()" line 12 at EXECUTE statement
 SQL statement "insert into depth_b values (new.id)"
-PL/pgSQL function "depth_a_tf" line 4 at SQL statement
+PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
 select pg_trigger_depth();
  pg_trigger_depth 
 ------------------
@@ -1535,20 +1535,20 @@ insert into depth_a values (2);
 NOTICE:  depth_a_tr: depth = 1
 NOTICE:  depth_b_tr: depth = 2
 CONTEXT:  SQL statement "insert into depth_b values (new.id)"
-PL/pgSQL function "depth_a_tf" line 4 at SQL statement
+PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
 NOTICE:  depth_c_tr: depth = 3
 CONTEXT:  SQL statement "insert into depth_c values (2)"
-PL/pgSQL function "depth_b_tf" line 5 at EXECUTE statement
+PL/pgSQL function "depth_b_tf()" line 5 at EXECUTE statement
 SQL statement "insert into depth_b values (new.id)"
-PL/pgSQL function "depth_a_tf" line 4 at SQL statement
+PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
 NOTICE:  depth_c_tr: depth = 3
 CONTEXT:  SQL statement "insert into depth_c values (2)"
-PL/pgSQL function "depth_b_tf" line 5 at EXECUTE statement
+PL/pgSQL function "depth_b_tf()" line 5 at EXECUTE statement
 SQL statement "insert into depth_b values (new.id)"
-PL/pgSQL function "depth_a_tf" line 4 at SQL statement
+PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
 NOTICE:  depth_b_tr: depth = 2
 CONTEXT:  SQL statement "insert into depth_b values (new.id)"
-PL/pgSQL function "depth_a_tf" line 4 at SQL statement
+PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
 NOTICE:  depth_a_tr: depth = 1
 select pg_trigger_depth();
  pg_trigger_depth 
#8Pavel Stehule
pavel.stehule@gmail.com
In reply to: Abhijit Menon-Sen (#7)
1 attachment(s)
Re: proposal: better support for debugging of overloaded functions

Hello

2012/1/26 Abhijit Menon-Sen <ams@toroid.org>:

At 2011-11-24 17:44:16 +0100, pavel.stehule@gmail.com wrote:

patch is relative long, but almost all are changes in regress tests.
Changes in plpgsql are 5 lines

The change looks good in principle. The patch applies to HEAD with a bit
of fuzz and builds fine… but it fails tests, because it's incomplete.

Pavel, your patch doesn't contain any changes to pl_exec.c. Did you just
forget to submit them? Anyway, some errcontext() calls need to be taught
to print ->fn_signature rather than ->fn_name. I made those changes, and
found some more failing tests.

It was my mistake - using fn_signature for runtime errors is good idea

Updated patch attached. Ready for committer.

I found a small issue - there was uninitialized fn_signature for
online blocks so I append line

function->fn_signature = pstrdup(func_name); to
plpgsql_compile_inline(char *proc_source) function

modified patch is in attachment

Pavel

Show quoted text

-- ams

Attachments:

pavel-plpgsql-fnsig_rev.difftext/x-patch; charset=US-ASCII; name=pavel-plpgsql-fnsig_rev.diffDownload
*** ./src/pl/plpgsql/src/pl_comp.c.orig	2012-01-27 14:05:07.396126134 +0100
--- ./src/pl/plpgsql/src/pl_comp.c	2012-01-27 14:34:26.822180737 +0100
***************
*** 342,347 ****
--- 342,348 ----
  	compile_tmp_cxt = MemoryContextSwitchTo(func_cxt);
  
  	function->fn_name = pstrdup(NameStr(procStruct->proname));
+ 	function->fn_signature = format_procedure(fcinfo->flinfo->fn_oid);
  	function->fn_oid = fcinfo->flinfo->fn_oid;
  	function->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
  	function->fn_tid = procTup->t_self;
***************
*** 803,808 ****
--- 804,810 ----
  	compile_tmp_cxt = MemoryContextSwitchTo(func_cxt);
  
  	function->fn_name = pstrdup(func_name);
+ 	function->fn_signature = pstrdup(func_name);
  	function->fn_is_trigger = false;
  	function->fn_input_collation = InvalidOid;
  	function->fn_cxt = func_cxt;
*** ./src/pl/plpgsql/src/pl_exec.c.orig	2012-01-27 14:05:07.398126114 +0100
--- ./src/pl/plpgsql/src/pl_exec.c	2012-01-27 14:06:37.594259250 +0100
***************
*** 799,805 ****
  			 * local variable initialization"
  			 */
  			errcontext("PL/pgSQL function \"%s\" line %d %s",
! 					   estate->func->fn_name,
  					   estate->err_stmt->lineno,
  					   _(estate->err_text));
  		}
--- 799,805 ----
  			 * local variable initialization"
  			 */
  			errcontext("PL/pgSQL function \"%s\" line %d %s",
! 					   estate->func->fn_signature,
  					   estate->err_stmt->lineno,
  					   _(estate->err_text));
  		}
***************
*** 810,816 ****
  			 * arguments into local variables"
  			 */
  			errcontext("PL/pgSQL function \"%s\" %s",
! 					   estate->func->fn_name,
  					   _(estate->err_text));
  		}
  	}
--- 810,816 ----
  			 * arguments into local variables"
  			 */
  			errcontext("PL/pgSQL function \"%s\" %s",
! 					   estate->func->fn_signature,
  					   _(estate->err_text));
  		}
  	}
***************
*** 818,830 ****
  	{
  		/* translator: last %s is a plpgsql statement type name */
  		errcontext("PL/pgSQL function \"%s\" line %d at %s",
! 				   estate->func->fn_name,
  				   estate->err_stmt->lineno,
  				   plpgsql_stmt_typename(estate->err_stmt));
  	}
  	else
  		errcontext("PL/pgSQL function \"%s\"",
! 				   estate->func->fn_name);
  }
  
  
--- 818,830 ----
  	{
  		/* translator: last %s is a plpgsql statement type name */
  		errcontext("PL/pgSQL function \"%s\" line %d at %s",
! 				   estate->func->fn_signature,
  				   estate->err_stmt->lineno,
  				   plpgsql_stmt_typename(estate->err_stmt));
  	}
  	else
  		errcontext("PL/pgSQL function \"%s\"",
! 				   estate->func->fn_signature);
  }
  
  
*** ./src/pl/plpgsql/src/plpgsql.h.orig	2012-01-27 14:05:07.400126094 +0100
--- ./src/pl/plpgsql/src/plpgsql.h	2012-01-27 14:06:37.596259232 +0100
***************
*** 679,684 ****
--- 679,685 ----
  typedef struct PLpgSQL_function
  {								/* Complete compiled function	  */
  	char	   *fn_name;
+ 	char	   *fn_signature;
  	Oid			fn_oid;
  	TransactionId fn_xmin;
  	ItemPointerData fn_tid;
*** ./src/test/regress/expected/domain.out.orig	2012-01-27 14:05:07.401126084 +0100
--- ./src/test/regress/expected/domain.out	2012-01-27 14:06:37.597259223 +0100
***************
*** 493,499 ****
  end$$ language plpgsql;
  select doubledecrement(3); -- fail because of implicit null assignment
  ERROR:  domain pos_int does not allow null values
! CONTEXT:  PL/pgSQL function "doubledecrement" line 3 during statement block local variable initialization
  create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
  declare v pos_int := 0;
  begin
--- 493,499 ----
  end$$ language plpgsql;
  select doubledecrement(3); -- fail because of implicit null assignment
  ERROR:  domain pos_int does not allow null values
! CONTEXT:  PL/pgSQL function "doubledecrement(pos_int)" line 3 during statement block local variable initialization
  create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
  declare v pos_int := 0;
  begin
***************
*** 501,507 ****
  end$$ language plpgsql;
  select doubledecrement(3); -- fail at initialization assignment
  ERROR:  value for domain pos_int violates check constraint "pos_int_check"
! CONTEXT:  PL/pgSQL function "doubledecrement" line 3 during statement block local variable initialization
  create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
  declare v pos_int := 1;
  begin
--- 501,507 ----
  end$$ language plpgsql;
  select doubledecrement(3); -- fail at initialization assignment
  ERROR:  value for domain pos_int violates check constraint "pos_int_check"
! CONTEXT:  PL/pgSQL function "doubledecrement(pos_int)" line 3 during statement block local variable initialization
  create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
  declare v pos_int := 1;
  begin
***************
*** 514,523 ****
  ERROR:  value for domain pos_int violates check constraint "pos_int_check"
  select doubledecrement(1); -- fail at assignment to v
  ERROR:  value for domain pos_int violates check constraint "pos_int_check"
! CONTEXT:  PL/pgSQL function "doubledecrement" line 4 at assignment
  select doubledecrement(2); -- fail at return
  ERROR:  value for domain pos_int violates check constraint "pos_int_check"
! CONTEXT:  PL/pgSQL function "doubledecrement" while casting return value to function's return type
  select doubledecrement(3); -- good
   doubledecrement 
  -----------------
--- 514,523 ----
  ERROR:  value for domain pos_int violates check constraint "pos_int_check"
  select doubledecrement(1); -- fail at assignment to v
  ERROR:  value for domain pos_int violates check constraint "pos_int_check"
! CONTEXT:  PL/pgSQL function "doubledecrement(pos_int)" line 4 at assignment
  select doubledecrement(2); -- fail at return
  ERROR:  value for domain pos_int violates check constraint "pos_int_check"
! CONTEXT:  PL/pgSQL function "doubledecrement(pos_int)" while casting return value to function's return type
  select doubledecrement(3); -- good
   doubledecrement 
  -----------------
***************
*** 566,572 ****
  select array_elem_check(121.00);
  ERROR:  numeric field overflow
  DETAIL:  A field with precision 4, scale 2 must round to an absolute value less than 10^2.
! CONTEXT:  PL/pgSQL function "array_elem_check" line 5 at assignment
  select array_elem_check(1.23456);
   array_elem_check 
  ------------------
--- 566,572 ----
  select array_elem_check(121.00);
  ERROR:  numeric field overflow
  DETAIL:  A field with precision 4, scale 2 must round to an absolute value less than 10^2.
! CONTEXT:  PL/pgSQL function "array_elem_check(numeric)" line 5 at assignment
  select array_elem_check(1.23456);
   array_elem_check 
  ------------------
***************
*** 584,590 ****
  select array_elem_check(121.00);
  ERROR:  numeric field overflow
  DETAIL:  A field with precision 4, scale 2 must round to an absolute value less than 10^2.
! CONTEXT:  PL/pgSQL function "array_elem_check" line 5 at assignment
  select array_elem_check(1.23456);
   array_elem_check 
  ------------------
--- 584,590 ----
  select array_elem_check(121.00);
  ERROR:  numeric field overflow
  DETAIL:  A field with precision 4, scale 2 must round to an absolute value less than 10^2.
! CONTEXT:  PL/pgSQL function "array_elem_check(numeric)" line 5 at assignment
  select array_elem_check(1.23456);
   array_elem_check 
  ------------------
***************
*** 602,608 ****
  select array_elem_check(121.00);
  ERROR:  numeric field overflow
  DETAIL:  A field with precision 4, scale 2 must round to an absolute value less than 10^2.
! CONTEXT:  PL/pgSQL function "array_elem_check" line 5 at assignment
  select array_elem_check(1.23456);
   array_elem_check 
  ------------------
--- 602,608 ----
  select array_elem_check(121.00);
  ERROR:  numeric field overflow
  DETAIL:  A field with precision 4, scale 2 must round to an absolute value less than 10^2.
! CONTEXT:  PL/pgSQL function "array_elem_check(numeric)" line 5 at assignment
  select array_elem_check(1.23456);
   array_elem_check 
  ------------------
***************
*** 650,656 ****
  
  select array_elem_check(-1);
  ERROR:  value for domain orderedpair violates check constraint "orderedpair_check"
! CONTEXT:  PL/pgSQL function "array_elem_check" line 5 at assignment
  drop function array_elem_check(int);
  --
  -- Renaming
--- 650,656 ----
  
  select array_elem_check(-1);
  ERROR:  value for domain orderedpair violates check constraint "orderedpair_check"
! CONTEXT:  PL/pgSQL function "array_elem_check(integer)" line 5 at assignment
  drop function array_elem_check(int);
  --
  -- Renaming
*** ./src/test/regress/expected/guc.out.orig	2012-01-27 14:05:07.403126066 +0100
--- ./src/test/regress/expected/guc.out	2012-01-27 14:06:37.597259223 +0100
***************
*** 687,693 ****
  select myfunc(0);
  ERROR:  division by zero
  CONTEXT:  SQL statement "SELECT 1/$1"
! PL/pgSQL function "myfunc" line 4 at PERFORM
  select current_setting('work_mem');
   current_setting 
  -----------------
--- 687,693 ----
  select myfunc(0);
  ERROR:  division by zero
  CONTEXT:  SQL statement "SELECT 1/$1"
! PL/pgSQL function "myfunc(integer)" line 4 at PERFORM
  select current_setting('work_mem');
   current_setting 
  -----------------
*** ./src/test/regress/expected/plancache.out.orig	2012-01-27 14:05:07.404126057 +0100
--- ./src/test/regress/expected/plancache.out	2012-01-27 14:06:37.598259213 +0100
***************
*** 235,241 ****
  select cachebug();
  NOTICE:  table "temptable" does not exist, skipping
  CONTEXT:  SQL statement "drop table if exists temptable cascade"
! PL/pgSQL function "cachebug" line 4 at SQL statement
  NOTICE:  1
  NOTICE:  2
  NOTICE:  3
--- 235,241 ----
  select cachebug();
  NOTICE:  table "temptable" does not exist, skipping
  CONTEXT:  SQL statement "drop table if exists temptable cascade"
! PL/pgSQL function "cachebug()" line 4 at SQL statement
  NOTICE:  1
  NOTICE:  2
  NOTICE:  3
***************
*** 247,253 ****
  select cachebug();
  NOTICE:  drop cascades to view vv
  CONTEXT:  SQL statement "drop table if exists temptable cascade"
! PL/pgSQL function "cachebug" line 4 at SQL statement
  NOTICE:  1
  NOTICE:  2
  NOTICE:  3
--- 247,253 ----
  select cachebug();
  NOTICE:  drop cascades to view vv
  CONTEXT:  SQL statement "drop table if exists temptable cascade"
! PL/pgSQL function "cachebug()" line 4 at SQL statement
  NOTICE:  1
  NOTICE:  2
  NOTICE:  3
*** ./src/test/regress/expected/plpgsql.out.orig	2012-01-27 14:05:07.406126038 +0100
--- ./src/test/regress/expected/plpgsql.out	2012-01-27 14:35:17.000000000 +0100
***************
*** 1518,1533 ****
  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.
--- 1518,1533 ----
  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.
***************
*** 2067,2079 ****
  select test_variable_storage();
  NOTICE:  should see this
  CONTEXT:  SQL statement "SELECT trap_zero_divide(-100)"
! PL/pgSQL function "test_variable_storage" line 8 at PERFORM
  NOTICE:  should see this only if -100 <> 0
  CONTEXT:  SQL statement "SELECT trap_zero_divide(-100)"
! PL/pgSQL function "test_variable_storage" line 8 at PERFORM
  NOTICE:  should see this only if -100 fits in smallint
  CONTEXT:  SQL statement "SELECT trap_zero_divide(-100)"
! PL/pgSQL function "test_variable_storage" line 8 at PERFORM
   test_variable_storage 
  -----------------------
   123456789012
--- 2067,2079 ----
  select test_variable_storage();
  NOTICE:  should see this
  CONTEXT:  SQL statement "SELECT trap_zero_divide(-100)"
! PL/pgSQL function "test_variable_storage()" line 8 at PERFORM
  NOTICE:  should see this only if -100 <> 0
  CONTEXT:  SQL statement "SELECT trap_zero_divide(-100)"
! PL/pgSQL function "test_variable_storage()" line 8 at PERFORM
  NOTICE:  should see this only if -100 fits in smallint
  CONTEXT:  SQL statement "SELECT trap_zero_divide(-100)"
! PL/pgSQL function "test_variable_storage()" line 8 at PERFORM
   test_variable_storage 
  -----------------------
   123456789012
***************
*** 2397,2403 ****
  select namedparmcursor_test7();
  ERROR:  division by zero
  CONTEXT:  SQL statement "SELECT 42/0 AS p1, 77 AS p2;"
! PL/pgSQL function "namedparmcursor_test7" line 6 at OPEN
  -- check that line comments work correctly within the argument list (there
  -- is some special handling of this case in the code: the newline after the
  -- comment must be preserved when the argument-evaluating query is
--- 2397,2403 ----
  select namedparmcursor_test7();
  ERROR:  division by zero
  CONTEXT:  SQL statement "SELECT 42/0 AS p1, 77 AS p2;"
! PL/pgSQL function "namedparmcursor_test7()" line 6 at OPEN
  -- check that line comments work correctly within the argument list (there
  -- is some special handling of this case in the code: the newline after the
  -- comment must be preserved when the argument-evaluating query is
***************
*** 2431,2437 ****
  $$ language plpgsql;
  select raise_test1(5);
  ERROR:  too many parameters specified for RAISE
! CONTEXT:  PL/pgSQL function "raise_test1" line 3 at RAISE
  create function raise_test2(int) returns int as $$
  begin
      raise notice 'This message has too few parameters: %, %, %', $1, $1;
--- 2431,2437 ----
  $$ language plpgsql;
  select raise_test1(5);
  ERROR:  too many parameters specified for RAISE
! CONTEXT:  PL/pgSQL function "raise_test1(integer)" line 3 at RAISE
  create function raise_test2(int) returns int as $$
  begin
      raise notice 'This message has too few parameters: %, %, %', $1, $1;
***************
*** 2440,2446 ****
  $$ language plpgsql;
  select raise_test2(10);
  ERROR:  too few parameters specified for RAISE
! CONTEXT:  PL/pgSQL function "raise_test2" line 3 at RAISE
  -- Test re-RAISE inside a nested exception block.  This case is allowed
  -- by Oracle's PL/SQL but was handled differently by PG before 9.1.
  CREATE FUNCTION reraise_test() RETURNS void AS $$
--- 2440,2446 ----
  $$ language plpgsql;
  select raise_test2(10);
  ERROR:  too few parameters specified for RAISE
! CONTEXT:  PL/pgSQL function "raise_test2(integer)" line 3 at RAISE
  -- Test re-RAISE inside a nested exception block.  This case is allowed
  -- by Oracle's PL/SQL but was handled differently by PG before 9.1.
  CREATE FUNCTION reraise_test() RETURNS void AS $$
***************
*** 2530,2536 ****
  end;$$ language plpgsql;
  select missing_return_expr();
  ERROR:  control reached end of function without RETURN
! CONTEXT:  PL/pgSQL function "missing_return_expr"
  drop function void_return_expr();
  drop function missing_return_expr();
  --
--- 2530,2536 ----
  end;$$ language plpgsql;
  select missing_return_expr();
  ERROR:  control reached end of function without RETURN
! CONTEXT:  PL/pgSQL function "missing_return_expr()"
  drop function void_return_expr();
  drop function missing_return_expr();
  --
***************
*** 2582,2588 ****
  LINE 1: SELECT sqlstate
                 ^
  QUERY:  SELECT sqlstate
! CONTEXT:  PL/pgSQL function "excpt_test1" line 3 at RAISE
  create function excpt_test2() returns void as $$
  begin
      begin
--- 2582,2588 ----
  LINE 1: SELECT sqlstate
                 ^
  QUERY:  SELECT sqlstate
! CONTEXT:  PL/pgSQL function "excpt_test1()" line 3 at RAISE
  create function excpt_test2() returns void as $$
  begin
      begin
***************
*** 2597,2603 ****
  LINE 1: SELECT sqlstate
                 ^
  QUERY:  SELECT sqlstate
! CONTEXT:  PL/pgSQL function "excpt_test2" line 5 at RAISE
  create function excpt_test3() returns void as $$
  begin
      begin
--- 2597,2603 ----
  LINE 1: SELECT sqlstate
                 ^
  QUERY:  SELECT sqlstate
! CONTEXT:  PL/pgSQL function "excpt_test2()" line 5 at RAISE
  create function excpt_test3() returns void as $$
  begin
      begin
***************
*** 2803,2809 ****
  -- should fail
  select continue_test2();
  ERROR:  CONTINUE cannot be used outside a loop
! CONTEXT:  PL/pgSQL function "continue_test2"
  -- CONTINUE can't reference the label of a named block
  create function continue_test3() returns void as $$
  begin
--- 2803,2809 ----
  -- should fail
  select continue_test2();
  ERROR:  CONTINUE cannot be used outside a loop
! CONTEXT:  PL/pgSQL function "continue_test2()"
  -- CONTINUE can't reference the label of a named block
  create function continue_test3() returns void as $$
  begin
***************
*** 2818,2824 ****
  -- should fail
  select continue_test3();
  ERROR:  CONTINUE cannot be used outside a loop
! CONTEXT:  PL/pgSQL function "continue_test3"
  drop function continue_test1();
  drop function continue_test2();
  drop function continue_test3();
--- 2818,2824 ----
  -- should fail
  select continue_test3();
  ERROR:  CONTINUE cannot be used outside a loop
! CONTEXT:  PL/pgSQL function "continue_test3()"
  drop function continue_test1();
  drop function continue_test2();
  drop function continue_test3();
***************
*** 2979,2985 ****
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned more than one row
! CONTEXT:  PL/pgSQL function "footest" line 5 at SQL statement
  create or replace function footest() returns void as $$
  declare x record;
  begin
--- 2979,2985 ----
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned more than one row
! CONTEXT:  PL/pgSQL function "footest()" line 5 at SQL statement
  create or replace function footest() returns void as $$
  declare x record;
  begin
***************
*** 3042,3048 ****
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned no rows
! CONTEXT:  PL/pgSQL function "footest" line 5 at SQL statement
  create or replace function footest() returns void as $$
  declare x record;
  begin
--- 3042,3048 ----
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned no rows
! CONTEXT:  PL/pgSQL function "footest()" line 5 at SQL statement
  create or replace function footest() returns void as $$
  declare x record;
  begin
***************
*** 3052,3058 ****
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned more than one row
! CONTEXT:  PL/pgSQL function "footest" line 5 at SQL statement
  create or replace function footest() returns void as $$
  declare x record;
  begin
--- 3052,3058 ----
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned more than one row
! CONTEXT:  PL/pgSQL function "footest()" line 5 at SQL statement
  create or replace function footest() returns void as $$
  declare x record;
  begin
***************
*** 3076,3082 ****
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned no rows
! CONTEXT:  PL/pgSQL function "footest" line 5 at EXECUTE statement
  create or replace function footest() returns void as $$
  declare x record;
  begin
--- 3076,3082 ----
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned no rows
! CONTEXT:  PL/pgSQL function "footest()" line 5 at EXECUTE statement
  create or replace function footest() returns void as $$
  declare x record;
  begin
***************
*** 3086,3092 ****
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned more than one row
! CONTEXT:  PL/pgSQL function "footest" line 5 at EXECUTE statement
  drop function footest();
  -- test scrollable cursor support
  create function sc_test() returns setof integer as $$
--- 3086,3092 ----
  end$$ language plpgsql;
  select footest();
  ERROR:  query returned more than one row
! CONTEXT:  PL/pgSQL function "footest()" line 5 at EXECUTE statement
  drop function footest();
  -- test scrollable cursor support
  create function sc_test() returns setof integer as $$
***************
*** 3130,3136 ****
  select * from sc_test();  -- fails because of NO SCROLL specification
  ERROR:  cursor can only scan forward
  HINT:  Declare it with SCROLL option to enable backward scan.
! CONTEXT:  PL/pgSQL function "sc_test" line 7 at FETCH
  create or replace function sc_test() returns setof integer as $$
  declare
    c refcursor;
--- 3130,3136 ----
  select * from sc_test();  -- fails because of NO SCROLL specification
  ERROR:  cursor can only scan forward
  HINT:  Declare it with SCROLL option to enable backward scan.
! CONTEXT:  PL/pgSQL function "sc_test()" line 7 at FETCH
  create or replace function sc_test() returns setof integer as $$
  declare
    c refcursor;
***************
*** 3717,3723 ****
  $$ language plpgsql;
  select raise_test();
  ERROR:  RAISE option already specified: MESSAGE
! CONTEXT:  PL/pgSQL function "raise_test" line 3 at RAISE
  -- conflict on errcode
  create or replace function raise_test() returns void as $$
  begin
--- 3717,3723 ----
  $$ language plpgsql;
  select raise_test();
  ERROR:  RAISE option already specified: MESSAGE
! CONTEXT:  PL/pgSQL function "raise_test()" line 3 at RAISE
  -- conflict on errcode
  create or replace function raise_test() returns void as $$
  begin
***************
*** 3726,3732 ****
  $$ language plpgsql;
  select raise_test();
  ERROR:  RAISE option already specified: ERRCODE
! CONTEXT:  PL/pgSQL function "raise_test" line 3 at RAISE
  -- nothing to re-RAISE
  create or replace function raise_test() returns void as $$
  begin
--- 3726,3732 ----
  $$ language plpgsql;
  select raise_test();
  ERROR:  RAISE option already specified: ERRCODE
! CONTEXT:  PL/pgSQL function "raise_test()" line 3 at RAISE
  -- nothing to re-RAISE
  create or replace function raise_test() returns void as $$
  begin
***************
*** 3735,3741 ****
  $$ language plpgsql;
  select raise_test();
  ERROR:  RAISE without parameters cannot be used outside an exception handler
! CONTEXT:  PL/pgSQL function "raise_test" line 3 at RAISE
  -- test access to exception data
  create function zero_divide() returns int as $$
  declare v int := 0;
--- 3735,3741 ----
  $$ language plpgsql;
  select raise_test();
  ERROR:  RAISE without parameters cannot be used outside an exception handler
! CONTEXT:  PL/pgSQL function "raise_test()" line 3 at RAISE
  -- test access to exception data
  create function zero_divide() returns int as $$
  declare v int := 0;
***************
*** 3766,3772 ****
  end;
  $$ language plpgsql;
  select stacked_diagnostics_test();
! NOTICE:  sqlstate: 22012, message: division by zero, context: [PL/pgSQL function "zero_divide" line 4 at RETURN <- SQL statement "SELECT zero_divide()" <- PL/pgSQL function "stacked_diagnostics_test" line 6 at PERFORM]
   stacked_diagnostics_test 
  --------------------------
   
--- 3766,3772 ----
  end;
  $$ language plpgsql;
  select stacked_diagnostics_test();
! NOTICE:  sqlstate: 22012, message: division by zero, context: [PL/pgSQL function "zero_divide()" line 4 at RETURN <- SQL statement "SELECT zero_divide()" <- PL/pgSQL function "stacked_diagnostics_test()" line 6 at PERFORM]
   stacked_diagnostics_test 
  --------------------------
   
***************
*** 3808,3814 ****
  $$ language plpgsql;
  select stacked_diagnostics_test();
  ERROR:  GET STACKED DIAGNOSTICS cannot be used outside an exception handler
! CONTEXT:  PL/pgSQL function "stacked_diagnostics_test" line 6 at GET DIAGNOSTICS
  drop function zero_divide();
  drop function stacked_diagnostics_test();
  -- check cases where implicit SQLSTATE variable could be confused with
--- 3808,3814 ----
  $$ language plpgsql;
  select stacked_diagnostics_test();
  ERROR:  GET STACKED DIAGNOSTICS cannot be used outside an exception handler
! CONTEXT:  PL/pgSQL function "stacked_diagnostics_test()" line 6 at GET DIAGNOSTICS
  drop function zero_divide();
  drop function stacked_diagnostics_test();
  -- check cases where implicit SQLSTATE variable could be confused with
***************
*** 3872,3878 ****
  select case_test(5); -- fails
  ERROR:  case not found
  HINT:  CASE statement is missing ELSE part.
! CONTEXT:  PL/pgSQL function "case_test" line 5 at CASE
  select case_test(8);
        case_test       
  ----------------------
--- 3872,3878 ----
  select case_test(5); -- fails
  ERROR:  case not found
  HINT:  CASE statement is missing ELSE part.
! CONTEXT:  PL/pgSQL function "case_test(bigint)" line 5 at CASE
  select case_test(8);
        case_test       
  ----------------------
***************
*** 3900,3906 ****
  select case_test(13); -- fails
  ERROR:  case not found
  HINT:  CASE statement is missing ELSE part.
! CONTEXT:  PL/pgSQL function "case_test" line 5 at CASE
  create or replace function catch() returns void as $$
  begin
    raise notice '%', case_test(6);
--- 3900,3906 ----
  select case_test(13); -- fails
  ERROR:  case not found
  HINT:  CASE statement is missing ELSE part.
! CONTEXT:  PL/pgSQL function "case_test(bigint)" line 5 at CASE
  create or replace function catch() returns void as $$
  begin
    raise notice '%', case_test(6);
***************
*** 4228,4234 ****
  select error2('nonexistent.stuffs');
  ERROR:  schema "nonexistent" does not exist
  CONTEXT:  SQL function "error1" statement 1
! PL/pgSQL function "error2" line 3 at RETURN
  ROLLBACK TO a;
  select error2('public.stuffs');
   error2 
--- 4228,4234 ----
  select error2('nonexistent.stuffs');
  ERROR:  schema "nonexistent" does not exist
  CONTEXT:  SQL function "error1" statement 1
! PL/pgSQL function "error2(text)" line 3 at RETURN
  ROLLBACK TO a;
  select error2('public.stuffs');
   error2 
***************
*** 4266,4272 ****
                 ^
  HINT:  Use the escape string syntax for backslashes, e.g., E'\\'.
  QUERY:  SELECT 'foo\\bar\041baz'
! CONTEXT:  PL/pgSQL function "strtest" line 4 at RETURN
     strtest   
  -------------
   foo\bar!baz
--- 4266,4272 ----
                 ^
  HINT:  Use the escape string syntax for backslashes, e.g., E'\\'.
  QUERY:  SELECT 'foo\\bar\041baz'
! CONTEXT:  PL/pgSQL function "strtest()" line 4 at RETURN
     strtest   
  -------------
   foo\bar!baz
***************
*** 4386,4392 ****
                 ^
  DETAIL:  It could refer to either a PL/pgSQL variable or a table column.
  QUERY:  select q1,q2 from int8_tbl
! CONTEXT:  PL/pgSQL function "conflict_test" line 5 at FOR over SELECT rows
  create or replace function conflict_test() returns setof int8_tbl as $$
  #variable_conflict use_variable
  declare r record;
--- 4386,4392 ----
                 ^
  DETAIL:  It could refer to either a PL/pgSQL variable or a table column.
  QUERY:  select q1,q2 from int8_tbl
! CONTEXT:  PL/pgSQL function "conflict_test()" line 5 at FOR over SELECT rows
  create or replace function conflict_test() returns setof int8_tbl as $$
  #variable_conflict use_variable
  declare r record;
***************
*** 4490,4499 ****
  -- should fail
  select foreach_test(ARRAY[1,2,3,4]);
  ERROR:  FOREACH ... SLICE loop variable must be of an array type
! CONTEXT:  PL/pgSQL function "foreach_test" line 4 at FOREACH over array
  select foreach_test(ARRAY[[1,2],[3,4]]);
  ERROR:  FOREACH ... SLICE loop variable must be of an array type
! CONTEXT:  PL/pgSQL function "foreach_test" line 4 at FOREACH over array
  create or replace function foreach_test(anyarray)
  returns void as $$
  declare x int[];
--- 4490,4499 ----
  -- should fail
  select foreach_test(ARRAY[1,2,3,4]);
  ERROR:  FOREACH ... SLICE loop variable must be of an array type
! CONTEXT:  PL/pgSQL function "foreach_test(anyarray)" line 4 at FOREACH over array
  select foreach_test(ARRAY[[1,2],[3,4]]);
  ERROR:  FOREACH ... SLICE loop variable must be of an array type
! CONTEXT:  PL/pgSQL function "foreach_test(anyarray)" line 4 at FOREACH over array
  create or replace function foreach_test(anyarray)
  returns void as $$
  declare x int[];
***************
*** 4533,4539 ****
  -- should fail
  select foreach_test(ARRAY[1,2,3,4]);
  ERROR:  slice dimension (2) is out of the valid range 0..1
! CONTEXT:  PL/pgSQL function "foreach_test" line 4 at FOREACH over array
  -- ok
  select foreach_test(ARRAY[[1,2],[3,4]]);
  NOTICE:  {{1,2},{3,4}}
--- 4533,4539 ----
  -- should fail
  select foreach_test(ARRAY[1,2,3,4]);
  ERROR:  slice dimension (2) is out of the valid range 0..1
! CONTEXT:  PL/pgSQL function "foreach_test(anyarray)" line 4 at FOREACH over array
  -- ok
  select foreach_test(ARRAY[[1,2],[3,4]]);
  NOTICE:  {{1,2},{3,4}}
***************
*** 4694,4702 ****
  
  select testoa(2,1,3); -- fail at initial assign
  ERROR:  value for domain orderedarray violates check constraint "sorted"
! CONTEXT:  PL/pgSQL function "testoa" line 4 at assignment
  select testoa(1,2,1); -- fail at update
  ERROR:  value for domain orderedarray violates check constraint "sorted"
! CONTEXT:  PL/pgSQL function "testoa" line 5 at assignment
  drop function arrayassign1();
  drop function testoa(x1 int, x2 int, x3 int);
--- 4694,4702 ----
  
  select testoa(2,1,3); -- fail at initial assign
  ERROR:  value for domain orderedarray violates check constraint "sorted"
! CONTEXT:  PL/pgSQL function "testoa(integer,integer,integer)" line 4 at assignment
  select testoa(1,2,1); -- fail at update
  ERROR:  value for domain orderedarray violates check constraint "sorted"
! CONTEXT:  PL/pgSQL function "testoa(integer,integer,integer)" line 5 at assignment
  drop function arrayassign1();
  drop function testoa(x1 int, x2 int, x3 int);
*** ./src/test/regress/expected/triggers.out.orig	2012-01-27 14:05:07.407126028 +0100
--- ./src/test/regress/expected/triggers.out	2012-01-27 14:06:37.603259164 +0100
***************
*** 965,974 ****
  NOTICE:  NEW: (20,30)
  NOTICE:  trigger_func(before_ins_stmt) called: action = INSERT, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
! PL/pgSQL function "view_trigger" line 17 at SQL statement
  NOTICE:  trigger_func(after_ins_stmt) called: action = INSERT, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
! PL/pgSQL function "view_trigger" line 17 at SQL statement
  NOTICE:  main_view AFTER INSERT STATEMENT (after_view_ins_stmt)
  INSERT 0 1
  INSERT INTO main_view VALUES (21, 31) RETURNING a, b;
--- 965,974 ----
  NOTICE:  NEW: (20,30)
  NOTICE:  trigger_func(before_ins_stmt) called: action = INSERT, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
! PL/pgSQL function "view_trigger()" line 17 at SQL statement
  NOTICE:  trigger_func(after_ins_stmt) called: action = INSERT, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
! PL/pgSQL function "view_trigger()" line 17 at SQL statement
  NOTICE:  main_view AFTER INSERT STATEMENT (after_view_ins_stmt)
  INSERT 0 1
  INSERT INTO main_view VALUES (21, 31) RETURNING a, b;
***************
*** 977,986 ****
  NOTICE:  NEW: (21,31)
  NOTICE:  trigger_func(before_ins_stmt) called: action = INSERT, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
! PL/pgSQL function "view_trigger" line 17 at SQL statement
  NOTICE:  trigger_func(after_ins_stmt) called: action = INSERT, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
! PL/pgSQL function "view_trigger" line 17 at SQL statement
  NOTICE:  main_view AFTER INSERT STATEMENT (after_view_ins_stmt)
   a  | b  
  ----+----
--- 977,986 ----
  NOTICE:  NEW: (21,31)
  NOTICE:  trigger_func(before_ins_stmt) called: action = INSERT, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
! PL/pgSQL function "view_trigger()" line 17 at SQL statement
  NOTICE:  trigger_func(after_ins_stmt) called: action = INSERT, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)"
! PL/pgSQL function "view_trigger()" line 17 at SQL statement
  NOTICE:  main_view AFTER INSERT STATEMENT (after_view_ins_stmt)
   a  | b  
  ----+----
***************
*** 995,1010 ****
  NOTICE:  OLD: (20,30), NEW: (20,31)
  NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(before_upd_a_row) called: action = UPDATE, when = BEFORE, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
  UPDATE 0
  UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b;
--- 995,1010 ----
  NOTICE:  OLD: (20,30), NEW: (20,31)
  NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(before_upd_a_row) called: action = UPDATE, when = BEFORE, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
  UPDATE 0
  UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b;
***************
*** 1013,1028 ****
  NOTICE:  OLD: (21,31), NEW: (21,32)
  NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(before_upd_a_row) called: action = UPDATE, when = BEFORE, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
   a | b 
  ---+---
--- 1013,1028 ----
  NOTICE:  OLD: (21,31), NEW: (21,32)
  NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(before_upd_a_row) called: action = UPDATE, when = BEFORE, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
   a | b 
  ---+---
***************
*** 1038,1056 ****
  NOTICE:  OLD: (20,30), NEW: (20,31)
  NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_a_b_row) called: action = UPDATE, when = AFTER, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_row) called: action = UPDATE, when = AFTER, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
  UPDATE 1
  UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b;
--- 1038,1056 ----
  NOTICE:  OLD: (20,30), NEW: (20,31)
  NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_a_b_row) called: action = UPDATE, when = AFTER, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_row) called: action = UPDATE, when = AFTER, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
  UPDATE 1
  UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b;
***************
*** 1059,1077 ****
  NOTICE:  OLD: (21,31), NEW: (21,32)
  NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_a_b_row) called: action = UPDATE, when = AFTER, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_row) called: action = UPDATE, when = AFTER, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger" line 23 at SQL statement
  NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
   a  | b  
  ----+----
--- 1059,1077 ----
  NOTICE:  OLD: (21,31), NEW: (21,32)
  NOTICE:  trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_a_b_row) called: action = UPDATE, when = AFTER, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_row) called: action = UPDATE, when = AFTER, level = ROW
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT
  CONTEXT:  SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b"
! PL/pgSQL function "view_trigger()" line 23 at SQL statement
  NOTICE:  main_view AFTER UPDATE STATEMENT (after_view_upd_stmt)
   a  | b  
  ----+----
***************
*** 1503,1530 ****
  NOTICE:  depth_a_tr: depth = 1
  NOTICE:  depth_b_tr: depth = 2
  CONTEXT:  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf" line 4 at SQL statement
  NOTICE:  depth_c_tr: depth = 3
  CONTEXT:  SQL statement "insert into depth_c values (1)"
! PL/pgSQL function "depth_b_tf" line 5 at EXECUTE statement
  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf" line 4 at SQL statement
  NOTICE:  SQLSTATE = U9999: depth = 2
  CONTEXT:  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf" line 4 at SQL statement
  NOTICE:  depth_b_tr: depth = 2
  CONTEXT:  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf" line 4 at SQL statement
  NOTICE:  depth_c_tr: depth = 3
  CONTEXT:  SQL statement "insert into depth_c values (1)"
! PL/pgSQL function "depth_b_tf" line 12 at EXECUTE statement
  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf" line 4 at SQL statement
  ERROR:  U9999
  CONTEXT:  SQL statement "insert into depth_c values (1)"
! PL/pgSQL function "depth_b_tf" line 12 at EXECUTE statement
  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf" line 4 at SQL statement
  select pg_trigger_depth();
   pg_trigger_depth 
  ------------------
--- 1503,1530 ----
  NOTICE:  depth_a_tr: depth = 1
  NOTICE:  depth_b_tr: depth = 2
  CONTEXT:  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
  NOTICE:  depth_c_tr: depth = 3
  CONTEXT:  SQL statement "insert into depth_c values (1)"
! PL/pgSQL function "depth_b_tf()" line 5 at EXECUTE statement
  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
  NOTICE:  SQLSTATE = U9999: depth = 2
  CONTEXT:  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
  NOTICE:  depth_b_tr: depth = 2
  CONTEXT:  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
  NOTICE:  depth_c_tr: depth = 3
  CONTEXT:  SQL statement "insert into depth_c values (1)"
! PL/pgSQL function "depth_b_tf()" line 12 at EXECUTE statement
  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
  ERROR:  U9999
  CONTEXT:  SQL statement "insert into depth_c values (1)"
! PL/pgSQL function "depth_b_tf()" line 12 at EXECUTE statement
  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
  select pg_trigger_depth();
   pg_trigger_depth 
  ------------------
***************
*** 1535,1554 ****
  NOTICE:  depth_a_tr: depth = 1
  NOTICE:  depth_b_tr: depth = 2
  CONTEXT:  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf" line 4 at SQL statement
  NOTICE:  depth_c_tr: depth = 3
  CONTEXT:  SQL statement "insert into depth_c values (2)"
! PL/pgSQL function "depth_b_tf" line 5 at EXECUTE statement
  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf" line 4 at SQL statement
  NOTICE:  depth_c_tr: depth = 3
  CONTEXT:  SQL statement "insert into depth_c values (2)"
! PL/pgSQL function "depth_b_tf" line 5 at EXECUTE statement
  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf" line 4 at SQL statement
  NOTICE:  depth_b_tr: depth = 2
  CONTEXT:  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf" line 4 at SQL statement
  NOTICE:  depth_a_tr: depth = 1
  select pg_trigger_depth();
   pg_trigger_depth 
--- 1535,1554 ----
  NOTICE:  depth_a_tr: depth = 1
  NOTICE:  depth_b_tr: depth = 2
  CONTEXT:  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
  NOTICE:  depth_c_tr: depth = 3
  CONTEXT:  SQL statement "insert into depth_c values (2)"
! PL/pgSQL function "depth_b_tf()" line 5 at EXECUTE statement
  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
  NOTICE:  depth_c_tr: depth = 3
  CONTEXT:  SQL statement "insert into depth_c values (2)"
! PL/pgSQL function "depth_b_tf()" line 5 at EXECUTE statement
  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
  NOTICE:  depth_b_tr: depth = 2
  CONTEXT:  SQL statement "insert into depth_b values (new.id)"
! PL/pgSQL function "depth_a_tf()" line 4 at SQL statement
  NOTICE:  depth_a_tr: depth = 1
  select pg_trigger_depth();
   pg_trigger_depth 
#9Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Pavel Stehule (#8)
Re: proposal: better support for debugging of overloaded functions

On 27.01.2012 15:48, Pavel Stehule wrote:

2012/1/26 Abhijit Menon-Sen<ams@toroid.org>:

Updated patch attached. Ready for committer.

I found a small issue - there was uninitialized fn_signature for
online blocks so I append line

function->fn_signature = pstrdup(func_name); to
plpgsql_compile_inline(char *proc_source) function

modified patch is in attachment

Thanks, committed!

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com