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;
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;
(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
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>>
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
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
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;
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
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
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
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 $$
$$ 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';
$$ 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';
$$ 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';
$$ 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
$$ 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
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
^
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
-- 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
-------------------
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
-------------------
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;
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
------------------
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
------------------
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
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