Resolve most regression failures in plpgsql suite
authorTomas Vondra <[email protected]>
Sat, 17 Jun 2017 18:49:15 +0000 (20:49 +0200)
committerTomas Vondra <[email protected]>
Sat, 17 Jun 2017 18:49:15 +0000 (20:49 +0200)
The fixed differences had mostly trivial causes:

1) The expected output was missing for several tests, most likely due to
   initial resolution of a merge conflict (while it was not possible to
   run the tests, making verification impossible). This includes blocks
   labeled as

     - Test handling of expanded arrays
     - Test for proper handling of cast-expression caching

   and a few more smaller ones.

2) Change in spelling of messages, e.g. from

     CONTEXT:  PL/pgSQL function footest() line 5 at EXECUTE statement

   to

     CONTEXT:  PL/pgSQL function footest() line 5 at EXECUTE

3) Change in displaying context for notices, warnings and errors, which
   was reworked by 0426f349effb6bde2061f3398a71db7180c97dd9. Since that
   commit we only show the context for errors by default.

src/test/regress/expected/plpgsql_1.out

index a337e4a440848517d466c7c9299f403cb9e1c9f1..e1185201e2b5b8af5951f62d93d97b8011269ee1 100644 (file)
@@ -2036,7 +2036,7 @@ select trap_matching_test(1);
 ERROR:  Internal subtransactions not supported in Postgres-XL
 CONTEXT:  PL/pgSQL function trap_matching_test(integer) line 6 during statement block entry
 create temp table foo (f1 int);
-create function blockme() returns int as $$
+create function subxact_rollback_semantics() returns int as $$
 declare x int;
 begin
   x := 1;
@@ -2044,31 +2044,46 @@ begin
   begin
     x := x + 1;
     insert into foo values(x);
-    -- we assume this will take longer than 2 seconds:
-    select count(*) into x from tenk1 a, tenk1 b, tenk1 c;
+    raise exception 'inner';
   exception
     when others then
-      raise notice 'caught others?';
-      return -1;
-    when query_canceled then
-      raise notice 'nyeah nyeah, can''t stop me';
       x := x * 10;
   end;
   insert into foo values(x);
   return x;
 end$$ language plpgsql;
-set statement_timeout to 2000;
-select blockme();
+select subxact_rollback_semantics();
 ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function blockme() line 6 during statement block entry
-reset statement_timeout;
-select * from foo order by 1;
+CONTEXT:  PL/pgSQL function subxact_rollback_semantics() line 6 during statement block entry
+select * from foo;
  f1 
 ----
   1
 (1 row)
 
 drop table foo;
+create function trap_timeout() returns void as $$
+begin
+  declare x int;
+  begin
+    -- we assume this will take longer than 2 seconds:
+    select count(*) into x from tenk1 a, tenk1 b, tenk1 c;
+  exception
+    when others then
+      raise notice 'caught others?';
+    when query_canceled then
+      raise notice 'nyeah nyeah, can''t stop me';
+  end;
+  -- Abort transaction to abandon the statement_timeout setting.  Otherwise,
+  -- the next top-level statement would be vulnerable to the timeout.
+  raise exception 'end of function';
+end$$ language plpgsql;
+begin;
+set statement_timeout to 2000;
+select trap_timeout();
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function trap_timeout() line 4 during statement block entry
+rollback;
 -- Test for pass-by-ref values being stored in proper context
 create function test_variable_storage() returns text as $$
 declare x text;
@@ -2808,21 +2823,58 @@ NOTICE:  10
  
 (1 row)
 
--- CONTINUE is only legal inside a loop
-create function continue_test2() returns void as $$
+drop function continue_test1();
+drop table conttesttbl;
+-- should fail: CONTINUE is only legal inside a loop
+create function continue_error1() returns void as $$
 begin
     begin
         continue;
     end;
-    return;
 end;
 $$ language plpgsql;
--- 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 $$
+LINE 4:         continue;
+                ^
+-- should fail: unlabeled EXIT is only legal inside a loop
+create function exit_error1() returns void as $$
+begin
+    begin
+        exit;
+    end;
+end;
+$$ language plpgsql;
+ERROR:  EXIT cannot be used outside a loop, unless it has a label
+LINE 4:         exit;
+                ^
+-- should fail: no such label
+create function continue_error2() returns void as $$
+begin
+    begin
+        loop
+            continue no_such_label;
+        end loop;
+    end;
+end;
+$$ language plpgsql;
+ERROR:  there is no label "no_such_label" attached to any block or loop enclosing this statement
+LINE 5:             continue no_such_label;
+                             ^
+-- should fail: no such label
+create function exit_error2() returns void as $$
+begin
+    begin
+        loop
+            exit no_such_label;
+        end loop;
+    end;
+end;
+$$ language plpgsql;
+ERROR:  there is no label "no_such_label" attached to any block or loop enclosing this statement
+LINE 5:             exit no_such_label;
+                         ^
+-- should fail: CONTINUE can't reference the label of a named block
+create function continue_error3() returns void as $$
 begin
     <<begin_block1>>
     begin
@@ -2832,14 +2884,28 @@ begin
     end;
 end;
 $$ language plpgsql;
--- 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();
-drop table conttesttbl;
+ERROR:  block label "begin_block1" cannot be used in CONTINUE
+LINE 6:             continue begin_block1;
+                             ^
+-- On the other hand, EXIT *can* reference the label of a named block
+create function exit_block1() returns void as $$
+begin
+    <<begin_block1>>
+    begin
+        loop
+            exit begin_block1;
+            raise exception 'should not get here';
+        end loop;
+    end;
+end;
+$$ language plpgsql;
+select exit_block1();
+ exit_block1 
+-------------
+(1 row)
+
+drop function exit_block1();
 -- verbose end block and end loop
 create function end_label1() returns void as $$
 <<blbl>>
@@ -2869,7 +2935,7 @@ begin
   end loop flbl1;
 end;
 $$ language plpgsql;
-ERROR:  label does not exist at or near "flbl1"
+ERROR:  end label "flbl1" specified for unlabelled block
 LINE 5:   end loop flbl1;
                    ^
 -- should fail: end label does not match start label
@@ -3094,7 +3160,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
 create or replace function footest() returns void as $$
 declare x record;
 begin
@@ -3104,7 +3170,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
 drop function footest();
 -- test printing parameters after failure due to STRICT
 set plpgsql.print_strict_params to true;
@@ -3156,7 +3222,7 @@ end$$ language plpgsql;
 select footest();
 ERROR:  query returned no rows
 DETAIL:  parameters: $1 = '0', $2 = 'foo'
-CONTEXT:  PL/pgSQL function footest() line 5 at EXECUTE statement
+CONTEXT:  PL/pgSQL function footest() line 5 at EXECUTE
 create or replace function footest() returns void as $$
 declare x record;
 begin
@@ -3167,7 +3233,7 @@ end$$ language plpgsql;
 select footest();
 ERROR:  query returned more than one row
 DETAIL:  parameters: $1 = '1'
-CONTEXT:  PL/pgSQL function footest() line 5 at EXECUTE statement
+CONTEXT:  PL/pgSQL function footest() line 5 at EXECUTE
 create or replace function footest() returns void as $$
 declare x record;
 begin
@@ -3177,7 +3243,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
 create or replace function footest() returns void as $$
 -- override the global
 #print_strict_params off
@@ -3996,6 +4062,7 @@ DETAIL:  some detail info
 HINT:  some hint
 ERROR:  1 2 3
 DETAIL:  some detail info
+CONTEXT:  PL/pgSQL function raise_test() line 5 at RAISE
 -- Since we can't actually see the thrown SQLSTATE in default psql output,
 -- test it like this; this also tests re-RAISE
 create or replace function raise_test() returns void as $$
@@ -4057,6 +4124,7 @@ end;
 $$ language plpgsql;
 select raise_test();
 ERROR:  division_by_zero
+CONTEXT:  PL/pgSQL function raise_test() line 3 at RAISE
 create or replace function raise_test() returns void as $$
 begin
   raise sqlstate '1234F';
@@ -4064,6 +4132,7 @@ end;
 $$ language plpgsql;
 select raise_test();
 ERROR:  1234F
+CONTEXT:  PL/pgSQL function raise_test() line 3 at RAISE
 create or replace function raise_test() returns void as $$
 begin
   raise division_by_zero using message = 'custom' || ' message';
@@ -4071,6 +4140,7 @@ end;
 $$ language plpgsql;
 select raise_test();
 ERROR:  custom message
+CONTEXT:  PL/pgSQL function raise_test() line 3 at RAISE
 create or replace function raise_test() returns void as $$
 begin
   raise using message = 'custom' || ' message', errcode = '22012';
@@ -4078,6 +4148,7 @@ end;
 $$ language plpgsql;
 select raise_test();
 ERROR:  custom message
+CONTEXT:  PL/pgSQL function raise_test() line 3 at RAISE
 -- conflict on message
 create or replace function raise_test() returns void as $$
 begin
@@ -4169,7 +4240,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 STACKED DIAGNOSTICS
 drop function zero_divide();
 drop function stacked_diagnostics_test();
 -- check cases where implicit SQLSTATE variable could be confused with
@@ -4613,6 +4684,75 @@ ERROR:  current transaction is aborted, commands ignored until end of transactio
 rollback;
 drop function error2(p_name_table text);
 drop function error1(text);
+-- Test for proper handling of cast-expression caching
+create function sql_to_date(integer) returns date as $$
+select $1::text::date
+$$ language sql immutable strict;
+create cast (integer as date) with function sql_to_date(integer) as assignment;
+create function cast_invoker(integer) returns date as $$
+begin
+  return $1;
+end$$ language plpgsql;
+select cast_invoker(20150717);
+ cast_invoker 
+--------------
+ 07-17-2015
+(1 row)
+
+select cast_invoker(20150718);  -- second call crashed in pre-release 9.5
+ cast_invoker 
+--------------
+ 07-18-2015
+(1 row)
+
+begin;
+select cast_invoker(20150717);
+ cast_invoker 
+--------------
+ 07-17-2015
+(1 row)
+
+select cast_invoker(20150718);
+ cast_invoker 
+--------------
+ 07-18-2015
+(1 row)
+
+savepoint s1;
+select cast_invoker(20150718);
+ cast_invoker 
+--------------
+ 07-18-2015
+(1 row)
+
+select cast_invoker(-1); -- fails
+ERROR:  invalid input syntax for type date: "-1"
+CONTEXT:  SQL function "sql_to_date" statement 1
+PL/pgSQL function cast_invoker(integer) while casting return value to function's return type
+rollback to savepoint s1;
+select cast_invoker(20150719);
+ cast_invoker 
+--------------
+ 07-19-2015
+(1 row)
+
+select cast_invoker(20150720);
+ cast_invoker 
+--------------
+ 07-20-2015
+(1 row)
+
+commit;
+drop function cast_invoker(integer);
+drop function sql_to_date(integer) cascade;
+NOTICE:  drop cascades to cast from integer to date
+-- Test handling of cast cache inside DO blocks
+-- (to check the original crash case, this must be a cast not previously
+-- used in this session)
+begin;
+do $$ declare x text[]; begin x := '{1.23, 4.56}'::numeric[]; end $$;
+do $$ declare x text[]; begin x := '{1.23, 4.56}'::numeric[]; end $$;
+end;
 -- Test for consistent reporting of error context
 create function fail() returns int language plpgsql as $$
 begin
@@ -4655,7 +4795,6 @@ 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
    strtest   
 -------------
  foo\bar!baz
@@ -5219,16 +5358,8 @@ SELECT TestJoinTempTable();
 -- passdown. So add that to the test case
 SELECT TestJoinTempTable();
 NOTICE:  relation "realtable" already exists, skipping
-CONTEXT:  SQL statement "CREATE TABLE IF NOT EXISTS RealTable(ProductId int, ScenarioId int)"
-PL/pgSQL function testjointemptable() line 3 at SQL statement
 NOTICE:  relation "tmpbar" already exists, skipping
-CONTEXT:  SQL statement "CREATE TEMPORARY TABLE IF NOT EXISTS TmpBar(NodeId int)
-                DISTRIBUTE BY REPLICATION"
-PL/pgSQL function testjointemptable() line 6 at SQL statement
 NOTICE:  relation "tmpfoo" already exists, skipping
-CONTEXT:  SQL statement "CREATE TEMPORARY TABLE IF NOT EXISTS TmpFoo(TempId int)
-                DISTRIBUTE BY REPLICATION"
-PL/pgSQL function testjointemptable() line 8 at SQL statement
  testjointemptable 
 -------------------
  
@@ -5236,16 +5367,8 @@ PL/pgSQL function testjointemptable() line 8 at SQL statement
 
 SELECT TestJoinTempTable();
 NOTICE:  relation "realtable" already exists, skipping
-CONTEXT:  SQL statement "CREATE TABLE IF NOT EXISTS RealTable(ProductId int, ScenarioId int)"
-PL/pgSQL function testjointemptable() line 3 at SQL statement
 NOTICE:  relation "tmpbar" already exists, skipping
-CONTEXT:  SQL statement "CREATE TEMPORARY TABLE IF NOT EXISTS TmpBar(NodeId int)
-                DISTRIBUTE BY REPLICATION"
-PL/pgSQL function testjointemptable() line 6 at SQL statement
 NOTICE:  relation "tmpfoo" already exists, skipping
-CONTEXT:  SQL statement "CREATE TEMPORARY TABLE IF NOT EXISTS TmpFoo(TempId int)
-                DISTRIBUTE BY REPLICATION"
-PL/pgSQL function testjointemptable() line 8 at SQL statement
  testjointemptable 
 -------------------
  
@@ -5254,7 +5377,77 @@ PL/pgSQL function testjointemptable() line 8 at SQL statement
 DROP TABLE RealTable;
 DROP TABLE TmpBar;
 DROP TABLE TmpFoo;
--- access to call stack
+--
+-- Test handling of expanded arrays
+--
+create function returns_rw_array(int) returns int[]
+language plpgsql as $$
+  declare r int[];
+  begin r := array[$1, $1]; return r; end;
+$$ stable;
+create function consumes_rw_array(int[]) returns int
+language plpgsql as $$
+  begin return $1[1]; end;
+$$ stable;
+-- bug #14174
+explain (verbose, costs off)
+select i, a from
+  (select returns_rw_array(1) as a offset 0) ss,
+  lateral consumes_rw_array(a) i;
+                           QUERY PLAN                            
+-----------------------------------------------------------------
+ Nested Loop
+   Output: i.i, (returns_rw_array(1))
+   ->  Result
+         Output: returns_rw_array(1)
+   ->  Function Scan on public.consumes_rw_array i
+         Output: i.i
+         Function Call: consumes_rw_array((returns_rw_array(1)))
+(7 rows)
+
+select i, a from
+  (select returns_rw_array(1) as a offset 0) ss,
+  lateral consumes_rw_array(a) i;
+ i |   a   
+---+-------
+ 1 | {1,1}
+(1 row)
+
+explain (verbose, costs off)
+select consumes_rw_array(a), a from returns_rw_array(1) a;
+                 QUERY PLAN                 
+--------------------------------------------
+ Function Scan on public.returns_rw_array a
+   Output: consumes_rw_array(a), a
+   Function Call: returns_rw_array(1)
+(3 rows)
+
+select consumes_rw_array(a), a from returns_rw_array(1) a;
+ consumes_rw_array |   a   
+-------------------+-------
+                 1 | {1,1}
+(1 row)
+
+explain (verbose, costs off)
+select consumes_rw_array(a), a from
+  (values (returns_rw_array(1)), (returns_rw_array(2))) v(a);
+                             QUERY PLAN                              
+---------------------------------------------------------------------
+ Values Scan on "*VALUES*"
+   Output: consumes_rw_array("*VALUES*".column1), "*VALUES*".column1
+(2 rows)
+
+select consumes_rw_array(a), a from
+  (values (returns_rw_array(1)), (returns_rw_array(2))) v(a);
+ consumes_rw_array |   a   
+-------------------+-------
+                 1 | {1,1}
+                 2 | {2,2}
+(2 rows)
+
+--
+-- Test access to call stack
+--
 create function inner_func(int)
 returns int as $$
 declare _context text;
@@ -5293,22 +5486,14 @@ $$ language plpgsql;
 select outer_outer_func(10);
 NOTICE:  calling down into outer_func()
 NOTICE:  calling down into inner_func()
-CONTEXT:  PL/pgSQL function outer_outer_func(integer) line 6 at assignment
 NOTICE:  ***PL/pgSQL function inner_func(integer) line 4 at GET DIAGNOSTICS
 PL/pgSQL function outer_func(integer) line 6 at assignment
 PL/pgSQL function outer_outer_func(integer) line 6 at assignment***
-CONTEXT:  PL/pgSQL function outer_func(integer) line 6 at assignment
-PL/pgSQL function outer_outer_func(integer) line 6 at assignment
 NOTICE:  ***PL/pgSQL function inner_func(integer) line 7 at GET DIAGNOSTICS
 PL/pgSQL function outer_func(integer) line 6 at assignment
 PL/pgSQL function outer_outer_func(integer) line 6 at assignment***
-CONTEXT:  PL/pgSQL function outer_func(integer) line 6 at assignment
-PL/pgSQL function outer_outer_func(integer) line 6 at assignment
 NOTICE:  lets make sure we didnt break anything
-CONTEXT:  PL/pgSQL function outer_func(integer) line 6 at assignment
-PL/pgSQL function outer_outer_func(integer) line 6 at assignment
 NOTICE:  inner_func() done
-CONTEXT:  PL/pgSQL function outer_outer_func(integer) line 6 at assignment
 NOTICE:  outer_func() done
  outer_outer_func 
 ------------------
@@ -5319,22 +5504,14 @@ NOTICE:  outer_func() done
 select outer_outer_func(20);
 NOTICE:  calling down into outer_func()
 NOTICE:  calling down into inner_func()
-CONTEXT:  PL/pgSQL function outer_outer_func(integer) line 6 at assignment
 NOTICE:  ***PL/pgSQL function inner_func(integer) line 4 at GET DIAGNOSTICS
 PL/pgSQL function outer_func(integer) line 6 at assignment
 PL/pgSQL function outer_outer_func(integer) line 6 at assignment***
-CONTEXT:  PL/pgSQL function outer_func(integer) line 6 at assignment
-PL/pgSQL function outer_outer_func(integer) line 6 at assignment
 NOTICE:  ***PL/pgSQL function inner_func(integer) line 7 at GET DIAGNOSTICS
 PL/pgSQL function outer_func(integer) line 6 at assignment
 PL/pgSQL function outer_outer_func(integer) line 6 at assignment***
-CONTEXT:  PL/pgSQL function outer_func(integer) line 6 at assignment
-PL/pgSQL function outer_outer_func(integer) line 6 at assignment
 NOTICE:  lets make sure we didnt break anything
-CONTEXT:  PL/pgSQL function outer_func(integer) line 6 at assignment
-PL/pgSQL function outer_outer_func(integer) line 6 at assignment
 NOTICE:  inner_func() done
-CONTEXT:  PL/pgSQL function outer_outer_func(integer) line 6 at assignment
 NOTICE:  outer_func() done
  outer_outer_func 
 ------------------
@@ -5391,7 +5568,6 @@ $$ language plpgsql;
 select outer_outer_func(10);
 NOTICE:  calling down into outer_func()
 NOTICE:  calling down into inner_func()
-CONTEXT:  PL/pgSQL function outer_outer_func(integer) line 6 at assignment
 ERROR:  Internal subtransactions not supported in Postgres-XL
 CONTEXT:  PL/pgSQL function inner_func(integer) line 6 during statement block entry
 PL/pgSQL function outer_func(integer) line 6 at assignment
@@ -5400,7 +5576,6 @@ PL/pgSQL function outer_outer_func(integer) line 6 at assignment
 select outer_outer_func(20);
 NOTICE:  calling down into outer_func()
 NOTICE:  calling down into inner_func()
-CONTEXT:  PL/pgSQL function outer_outer_func(integer) line 6 at assignment
 ERROR:  Internal subtransactions not supported in Postgres-XL
 CONTEXT:  PL/pgSQL function inner_func(integer) line 6 during statement block entry
 PL/pgSQL function outer_func(integer) line 6 at assignment