pavel-plpgsql-fnsig_rev.diff

text/x-patch

Filename: pavel-plpgsql-fnsig_rev.diff
Type: text/x-patch
Part: 0
Message: Re: proposal: better support for debugging of overloaded functions

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: context
File+
src/pl/plpgsql/src/pl_comp.c 2 0
src/pl/plpgsql/src/pl_exec.c 4 4
src/pl/plpgsql/src/plpgsql.h 1 0
src/test/regress/expected/domain.out 8 8
src/test/regress/expected/guc.out 1 1
src/test/regress/expected/plancache.out 2 2
src/test/regress/expected/plpgsql.out 36 36
src/test/regress/expected/triggers.out 37 37
*** ./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