1
0
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:
Tom Lane
2004-07-31 23:04:58 +00:00
parent ad4d2e9711
commit 9c8d0850c3
11 changed files with 350 additions and 89 deletions

View File

@@ -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)

View File

@@ -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;