diff options
| author | Tom Lane | 2006-04-05 22:11:58 +0000 |
|---|---|---|
| committer | Tom Lane | 2006-04-05 22:11:58 +0000 |
| commit | 7fdb4305db20f64bce27e6bac0a0f9c972e4dec8 (patch) | |
| tree | 18efa90dfcf996675cf1c7bb938d8575f7e551ad /src/test | |
| parent | 89a67e523e744eb168b41d192b83d17a395b4137 (diff) | |
Fix a bunch of problems with domains by making them use special input functions
that apply the necessary domain constraint checks immediately. This fixes
cases where domain constraints went unchecked for statement parameters,
PL function local variables and results, etc. We can also eliminate existing
special cases for domains in places that had gotten it right, eg COPY.
Also, allow domains over domains (base of a domain is another domain type).
This almost worked before, but was disallowed because the original patch
hadn't gotten it quite right.
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/regress/expected/domain.out | 84 | ||||
| -rw-r--r-- | src/test/regress/sql/domain.sql | 56 |
2 files changed, 131 insertions, 9 deletions
diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out index c89be9535f1..86e2ca54bf9 100644 --- a/src/test/regress/expected/domain.out +++ b/src/test/regress/expected/domain.out @@ -1,10 +1,17 @@ +-- +-- Test domains. +-- -- Test Comment / Drop create domain domaindroptest int4; comment on domain domaindroptest is 'About to drop this..'; --- currently this will be disallowed -create domain basetypetest domaindroptest; -ERROR: "domaindroptest" is not a valid base type for a domain +create domain dependenttypetest domaindroptest; +-- fail because of dependent type drop domain domaindroptest; +NOTICE: type dependenttypetest depends on type domaindroptest +ERROR: cannot drop type domaindroptest because other objects depend on it +HINT: Use DROP ... CASCADE to drop the dependent objects too. +drop domain domaindroptest cascade; +NOTICE: drop cascades to type dependenttypetest -- this should fail because already gone drop domain domaindroptest cascade; ERROR: type "domaindroptest" does not exist @@ -40,7 +47,7 @@ INSERT INTO basictest values ('88', 'haha', 'short', '123.1212'); -- Truncate -- Test copy COPY basictest (testvarchar) FROM stdin; -- fail ERROR: value too long for type character varying(5) -CONTEXT: COPY basictest, line 1: "notsoshorttext" +CONTEXT: COPY basictest, line 1, column testvarchar: "notsoshorttext" COPY basictest (testvarchar) FROM stdin; select * from basictest; testint4 | testtext | testvarchar | testnumeric @@ -126,8 +133,11 @@ ERROR: null value in column "col3" violates not-null constraint INSERT INTO nulltest values ('a', 'b', 'c', NULL, 'd'); -- Good -- Test copy COPY nulltest FROM stdin; --fail +ERROR: null value in column "col3" violates not-null constraint +CONTEXT: COPY nulltest, line 1: "a b \N d d" +COPY nulltest FROM stdin; --fail ERROR: domain dcheck does not allow null values -CONTEXT: COPY nulltest, line 1: "a b \N d \N" +CONTEXT: COPY nulltest, line 1, column col5: NULL input -- Last row is bad COPY nulltest FROM stdin; ERROR: new row for relation "nulltest" violates check constraint "nulltest_col5_check" @@ -300,6 +310,46 @@ drop domain ddef3 restrict; drop domain ddef4 restrict; drop domain ddef5 restrict; drop sequence ddef4_seq; +-- Test domains over domains +create domain vchar4 varchar(4); +create domain dinter vchar4 check (substring(VALUE, 1, 1) = 'x'); +create domain dtop dinter check (substring(VALUE, 2, 1) = '1'); +select 'x123'::dtop; + dtop +------ + x123 +(1 row) + +select 'x1234'::dtop; -- explicit coercion should truncate + dtop +------ + x123 +(1 row) + +select 'y1234'::dtop; -- fail +ERROR: value for domain dtop violates check constraint "dinter_check" +select 'y123'::dtop; -- fail +ERROR: value for domain dtop violates check constraint "dinter_check" +select 'yz23'::dtop; -- fail +ERROR: value for domain dtop violates check constraint "dinter_check" +select 'xz23'::dtop; -- fail +ERROR: value for domain dtop violates check constraint "dtop_check" +create temp table dtest(f1 dtop); +insert into dtest values('x123'); +insert into dtest values('x1234'); -- fail, implicit coercion +ERROR: value too long for type character varying(4) +insert into dtest values('y1234'); -- fail, implicit coercion +ERROR: value too long for type character varying(4) +insert into dtest values('y123'); -- fail +ERROR: value for domain dtop violates check constraint "dinter_check" +insert into dtest values('yz23'); -- fail +ERROR: value for domain dtop violates check constraint "dinter_check" +insert into dtest values('xz23'); -- fail +ERROR: value for domain dtop violates check constraint "dtop_check" +drop table dtest; +drop domain vchar4 cascade; +NOTICE: drop cascades to type dinter +NOTICE: drop cascades to type dtop -- Make sure that constraints of newly-added domain columns are -- enforced correctly, even if there's no default value for the new -- column. Per bug #1433 @@ -328,3 +378,27 @@ execute s1(0); -- should fail ERROR: value for domain pos_int violates check constraint "pos_int_check" execute s1(NULL); -- should fail ERROR: domain pos_int does not allow null values +-- Check that domain constraints on plpgsql function parameters, results, +-- and local variables are enforced correctly. +create function doubledecrement(p1 pos_int) returns pos_int as $$ +declare v pos_int; +begin + v := p1 - 1; + return v - 1; +end$$ language plpgsql; +select doubledecrement(null); -- fail before call +ERROR: domain pos_int does not allow null values +select doubledecrement(0); -- fail before call +ERROR: value for domain pos_int violates check constraint "pos_int_check" +select doubledecrement(1); -- fail at assignment to v +ERROR: value for domain pos_int violates check constraint "pos_int_check" +CONTEXT: PL/pgSQL function "doubledecrement" line 3 at assignment +select doubledecrement(2); -- fail at return +ERROR: value for domain pos_int violates check constraint "pos_int_check" +CONTEXT: PL/pgSQL function "doubledecrement" while casting return value to function's return type +select doubledecrement(3); -- good + doubledecrement +----------------- + 1 +(1 row) + diff --git a/src/test/regress/sql/domain.sql b/src/test/regress/sql/domain.sql index f6010e636cb..21940e0e618 100644 --- a/src/test/regress/sql/domain.sql +++ b/src/test/regress/sql/domain.sql @@ -1,14 +1,18 @@ - +-- +-- Test domains. +-- -- Test Comment / Drop create domain domaindroptest int4; comment on domain domaindroptest is 'About to drop this..'; --- currently this will be disallowed -create domain basetypetest domaindroptest; +create domain dependenttypetest domaindroptest; +-- fail because of dependent type drop domain domaindroptest; +drop domain domaindroptest cascade; + -- this should fail because already gone drop domain domaindroptest cascade; @@ -101,7 +105,11 @@ INSERT INTO nulltest values ('a', 'b', 'c', NULL, 'd'); -- Good -- Test copy COPY nulltest FROM stdin; --fail -a b \N d \N +a b \N d d +\. + +COPY nulltest FROM stdin; --fail +a b c d \N \. -- Last row is bad @@ -245,6 +253,30 @@ drop domain ddef4 restrict; drop domain ddef5 restrict; drop sequence ddef4_seq; +-- Test domains over domains +create domain vchar4 varchar(4); +create domain dinter vchar4 check (substring(VALUE, 1, 1) = 'x'); +create domain dtop dinter check (substring(VALUE, 2, 1) = '1'); + +select 'x123'::dtop; +select 'x1234'::dtop; -- explicit coercion should truncate +select 'y1234'::dtop; -- fail +select 'y123'::dtop; -- fail +select 'yz23'::dtop; -- fail +select 'xz23'::dtop; -- fail + +create temp table dtest(f1 dtop); + +insert into dtest values('x123'); +insert into dtest values('x1234'); -- fail, implicit coercion +insert into dtest values('y1234'); -- fail, implicit coercion +insert into dtest values('y123'); -- fail +insert into dtest values('yz23'); -- fail +insert into dtest values('xz23'); -- fail + +drop table dtest; +drop domain vchar4 cascade; + -- Make sure that constraints of newly-added domain columns are -- enforced correctly, even if there's no default value for the new -- column. Per bug #1433 @@ -271,3 +303,19 @@ prepare s1 as select $1::pos_int = 10 as "is_ten"; execute s1(10); execute s1(0); -- should fail execute s1(NULL); -- should fail + +-- Check that domain constraints on plpgsql function parameters, results, +-- and local variables are enforced correctly. + +create function doubledecrement(p1 pos_int) returns pos_int as $$ +declare v pos_int; +begin + v := p1 - 1; + return v - 1; +end$$ language plpgsql; + +select doubledecrement(null); -- fail before call +select doubledecrement(0); -- fail before call +select doubledecrement(1); -- fail at assignment to v +select doubledecrement(2); -- fail at return +select doubledecrement(3); -- good |
