mirror of
https://github.com/postgres/postgres.git
synced 2025-12-12 02:37:31 +03:00
Support "OR condition ..." in plpgsql EXCEPTION clauses to make the syntax
more nearly Oracle-equivalent. Allow matching by category as well as specific error code. Document the set of available condition names (or more accurately, synchronize it with the existing documentation). In passing, update errcodes.sgml to include codes added during 7.5 development.
This commit is contained in:
@@ -1798,7 +1798,7 @@ drop table perform_test;
|
||||
--
|
||||
create function trap_zero_divide(int) returns int as $$
|
||||
declare x int;
|
||||
declare sx smallint;
|
||||
sx smallint;
|
||||
begin
|
||||
begin -- start a subtransaction
|
||||
raise notice 'should see this';
|
||||
@@ -1850,3 +1850,88 @@ NOTICE: should see this
|
||||
NOTICE: should see this only if -100 <> 0
|
||||
NOTICE: should see this only if -100 fits in smallint
|
||||
ERROR: -100 is less than zero
|
||||
create function trap_matching_test(int) returns int as $$
|
||||
declare x int;
|
||||
sx smallint;
|
||||
y int;
|
||||
begin
|
||||
begin -- start a subtransaction
|
||||
x := 100 / $1;
|
||||
sx := $1;
|
||||
select into y unique1 from tenk1 where unique2 =
|
||||
(select unique2 from tenk1 b where ten = $1);
|
||||
exception
|
||||
when data_exception then -- category match
|
||||
raise notice 'caught data_exception';
|
||||
x := -1;
|
||||
when NUMERIC_VALUE_OUT_OF_RANGE OR CARDINALITY_VIOLATION then
|
||||
raise notice 'caught numeric_value_out_of_range or cardinality_violation';
|
||||
x := -2;
|
||||
end;
|
||||
return x;
|
||||
end$$ language plpgsql;
|
||||
select trap_matching_test(50);
|
||||
trap_matching_test
|
||||
--------------------
|
||||
2
|
||||
(1 row)
|
||||
|
||||
select trap_matching_test(0);
|
||||
NOTICE: caught data_exception
|
||||
trap_matching_test
|
||||
--------------------
|
||||
-1
|
||||
(1 row)
|
||||
|
||||
select trap_matching_test(100000);
|
||||
NOTICE: caught data_exception
|
||||
trap_matching_test
|
||||
--------------------
|
||||
-1
|
||||
(1 row)
|
||||
|
||||
select trap_matching_test(1);
|
||||
NOTICE: caught numeric_value_out_of_range or cardinality_violation
|
||||
trap_matching_test
|
||||
--------------------
|
||||
-2
|
||||
(1 row)
|
||||
|
||||
create temp table foo (f1 int);
|
||||
create function blockme() returns int as $$
|
||||
declare x int;
|
||||
begin
|
||||
x := 1;
|
||||
insert into foo values(x);
|
||||
begin
|
||||
x := x + 1;
|
||||
insert into foo values(x);
|
||||
-- we assume this will take longer than 1 second:
|
||||
select count(*) into x from tenk1 a, tenk1 b, tenk1 c;
|
||||
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 1000;
|
||||
select blockme();
|
||||
NOTICE: nyeah nyeah, can't stop me
|
||||
blockme
|
||||
---------
|
||||
20
|
||||
(1 row)
|
||||
|
||||
reset statement_timeout;
|
||||
select * from foo;
|
||||
f1
|
||||
----
|
||||
1
|
||||
20
|
||||
(2 rows)
|
||||
|
||||
|
||||
@@ -1615,7 +1615,7 @@ drop table perform_test;
|
||||
|
||||
create function trap_zero_divide(int) returns int as $$
|
||||
declare x int;
|
||||
declare sx smallint;
|
||||
sx smallint;
|
||||
begin
|
||||
begin -- start a subtransaction
|
||||
raise notice 'should see this';
|
||||
@@ -1641,3 +1641,61 @@ select trap_zero_divide(50);
|
||||
select trap_zero_divide(0);
|
||||
select trap_zero_divide(100000);
|
||||
select trap_zero_divide(-100);
|
||||
|
||||
create function trap_matching_test(int) returns int as $$
|
||||
declare x int;
|
||||
sx smallint;
|
||||
y int;
|
||||
begin
|
||||
begin -- start a subtransaction
|
||||
x := 100 / $1;
|
||||
sx := $1;
|
||||
select into y unique1 from tenk1 where unique2 =
|
||||
(select unique2 from tenk1 b where ten = $1);
|
||||
exception
|
||||
when data_exception then -- category match
|
||||
raise notice 'caught data_exception';
|
||||
x := -1;
|
||||
when NUMERIC_VALUE_OUT_OF_RANGE OR CARDINALITY_VIOLATION then
|
||||
raise notice 'caught numeric_value_out_of_range or cardinality_violation';
|
||||
x := -2;
|
||||
end;
|
||||
return x;
|
||||
end$$ language plpgsql;
|
||||
|
||||
select trap_matching_test(50);
|
||||
select trap_matching_test(0);
|
||||
select trap_matching_test(100000);
|
||||
select trap_matching_test(1);
|
||||
|
||||
create temp table foo (f1 int);
|
||||
|
||||
create function blockme() returns int as $$
|
||||
declare x int;
|
||||
begin
|
||||
x := 1;
|
||||
insert into foo values(x);
|
||||
begin
|
||||
x := x + 1;
|
||||
insert into foo values(x);
|
||||
-- we assume this will take longer than 1 second:
|
||||
select count(*) into x from tenk1 a, tenk1 b, tenk1 c;
|
||||
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 1000;
|
||||
|
||||
select blockme();
|
||||
|
||||
reset statement_timeout;
|
||||
|
||||
select * from foo;
|
||||
|
||||
Reference in New Issue
Block a user