From: Tomas Vondra Date: Sat, 17 Jun 2017 18:49:15 +0000 (+0200) Subject: Resolve most regression failures in plpgsql suite X-Git-Tag: XL_10_R1BETA1~265^2~6 X-Git-Url: http://git.postgresql.org/gitweb/-?a=commitdiff_plain;h=7647eec8f641e06d4165267ec133f87f96032d55;p=postgres-xl.git Resolve most regression failures in plpgsql suite 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. --- diff --git a/src/test/regress/expected/plpgsql_1.out b/src/test/regress/expected/plpgsql_1.out index a337e4a440..e1185201e2 100644 --- a/src/test/regress/expected/plpgsql_1.out +++ b/src/test/regress/expected/plpgsql_1.out @@ -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 @@ -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 + 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 $$ <> @@ -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