Eschew "RESET statement_timeout" in tests.

Instead, use transaction abort.  Given an unlucky bout of latency, the
timeout would cancel the RESET itself.  Buildfarm members gharial,
lapwing, mereswine, shearwater, and sungazer witness that.  Back-patch
to 9.1 (all supported versions).  The query_canceled test still could
timeout before entering its subtransaction; for whatever reason, that
has yet to happen on the buildfarm.
This commit is contained in:
Noah Misch 2015-10-20 00:37:22 -04:00
parent 9f1e642d50
commit 8e3b4d9d40
5 changed files with 66 additions and 34 deletions

View File

@ -2020,7 +2020,7 @@ NOTICE: caught numeric_value_out_of_range or cardinality_violation
(1 row)
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;
@ -2028,28 +2028,20 @@ 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();
NOTICE: nyeah nyeah, can't stop me
blockme
---------
20
select subxact_rollback_semantics();
subxact_rollback_semantics
----------------------------
20
(1 row)
reset statement_timeout;
select * from foo;
f1
----
@ -2058,6 +2050,29 @@ select * from foo;
(2 rows)
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();
NOTICE: nyeah nyeah, can't stop me
ERROR: end of function
CONTEXT: PL/pgSQL function trap_timeout() line 15 at RAISE
rollback;
-- Test for pass-by-ref values being stored in proper context
create function test_variable_storage() returns text as $$
declare x text;

View File

@ -194,10 +194,11 @@ SELECT gid FROM pg_prepared_xacts;
(2 rows)
-- pxtest3 should be locked because of the pending DROP
begin;
set statement_timeout to 2000;
SELECT * FROM pxtest3;
ERROR: canceling statement due to statement timeout
reset statement_timeout;
rollback;
-- Disconnect, we will continue testing in a different backend
\c -
-- There should still be two prepared transactions
@ -209,10 +210,11 @@ SELECT gid FROM pg_prepared_xacts;
(2 rows)
-- pxtest3 should still be locked because of the pending DROP
begin;
set statement_timeout to 2000;
SELECT * FROM pxtest3;
ERROR: canceling statement due to statement timeout
reset statement_timeout;
rollback;
-- Commit table creation
COMMIT PREPARED 'regress-one';
\d pxtest2

View File

@ -198,13 +198,14 @@ SELECT gid FROM pg_prepared_xacts;
(0 rows)
-- pxtest3 should be locked because of the pending DROP
begin;
set statement_timeout to 2000;
SELECT * FROM pxtest3;
fff
-----
(0 rows)
reset statement_timeout;
rollback;
-- Disconnect, we will continue testing in a different backend
\c -
-- There should still be two prepared transactions
@ -214,13 +215,14 @@ SELECT gid FROM pg_prepared_xacts;
(0 rows)
-- pxtest3 should still be locked because of the pending DROP
begin;
set statement_timeout to 2000;
SELECT * FROM pxtest3;
fff
-----
(0 rows)
reset statement_timeout;
rollback;
-- Commit table creation
COMMIT PREPARED 'regress-one';
ERROR: prepared transaction with identifier "regress-one" does not exist

View File

@ -1745,7 +1745,7 @@ select trap_matching_test(1);
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;
@ -1753,30 +1753,41 @@ 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();
reset statement_timeout;
select subxact_rollback_semantics();
select * from foo;
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();
rollback;
-- Test for pass-by-ref values being stored in proper context
create function test_variable_storage() returns text as $$
declare x text;

View File

@ -122,9 +122,10 @@ SELECT * FROM pxtest2;
SELECT gid FROM pg_prepared_xacts;
-- pxtest3 should be locked because of the pending DROP
begin;
set statement_timeout to 2000;
SELECT * FROM pxtest3;
reset statement_timeout;
rollback;
-- Disconnect, we will continue testing in a different backend
\c -
@ -133,9 +134,10 @@ reset statement_timeout;
SELECT gid FROM pg_prepared_xacts;
-- pxtest3 should still be locked because of the pending DROP
begin;
set statement_timeout to 2000;
SELECT * FROM pxtest3;
reset statement_timeout;
rollback;
-- Commit table creation
COMMIT PREPARED 'regress-one';