5 create domain domaindroptest int4;
6 comment on domain domaindroptest is 'About to drop this..';
7 create domain dependenttypetest domaindroptest;
8 -- fail because of dependent type
9 drop domain domaindroptest;
10 ERROR: cannot drop type domaindroptest because other objects depend on it
11 DETAIL: type dependenttypetest depends on type domaindroptest
12 HINT: Use DROP ... CASCADE to drop the dependent objects too.
13 drop domain domaindroptest cascade;
14 NOTICE: drop cascades to type dependenttypetest
15 -- this should fail because already gone
16 drop domain domaindroptest cascade;
17 ERROR: type "domaindroptest" does not exist
19 -- Note: the point of checking both INSERT and COPY FROM is that INSERT
20 -- exercises CoerceToDomain while COPY exercises domain_in.
21 create domain domainvarchar varchar(5);
22 create domain domainnumeric numeric(8,2);
23 create domain domainint4 int4;
24 create domain domaintext text;
25 -- Test explicit coercions --- these should succeed (and truncate)
26 SELECT cast('123456' as domainvarchar);
32 SELECT cast('12345' as domainvarchar);
38 -- Test tables using domains
39 create table basictest
42 , testvarchar domainvarchar
43 , testnumeric domainnumeric
45 INSERT INTO basictest values ('88', 'haha', 'short', '123.12'); -- Good
46 INSERT INTO basictest values ('88', 'haha', 'short text', '123.12'); -- Bad varchar
47 ERROR: value too long for type character varying(5)
48 INSERT INTO basictest values ('88', 'haha', 'short', '123.1212'); -- Truncate numeric
50 COPY basictest (testvarchar) FROM stdin; -- fail
51 ERROR: value too long for type character varying(5)
52 CONTEXT: COPY basictest, line 1, column testvarchar: "notsoshorttext"
53 COPY basictest (testvarchar) FROM stdin;
54 select * from basictest;
55 testint4 | testtext | testvarchar | testnumeric
56 ----------+----------+-------------+-------------
57 88 | haha | short | 123.12
58 88 | haha | short | 123.12
62 -- check that domains inherit operations from base types
63 select testtext || testvarchar as concat, testnumeric + 42 as sum
72 -- check that union/case/coalesce type resolution handles domains properly
73 select coalesce(4::domainint4, 7) is of (int4) as t;
79 select coalesce(4::domainint4, 7) is of (domainint4) as f;
85 select coalesce(4::domainint4, 7::domainint4) is of (domainint4) as t;
92 drop domain domainvarchar restrict;
93 drop domain domainnumeric restrict;
94 drop domain domainint4 restrict;
95 drop domain domaintext;
96 -- Test domains over array types
97 create domain domainint4arr int4[1];
98 create domain domainchar4arr varchar(4)[2][3];
99 create table domarrtest
100 ( testint4arr domainint4arr
101 , testchar4arr domainchar4arr
103 INSERT INTO domarrtest values ('{2,2}', '{{"a","b"},{"c","d"}}');
104 INSERT INTO domarrtest values ('{{2,2},{2,2}}', '{{"a","b"}}');
105 INSERT INTO domarrtest values ('{2,2}', '{{"a","b"},{"c","d"},{"e","f"}}');
106 INSERT INTO domarrtest values ('{2,2}', '{{"a"},{"c"}}');
107 INSERT INTO domarrtest values (NULL, '{{"a","b","c"},{"d","e","f"}}');
108 INSERT INTO domarrtest values (NULL, '{{"toolong","b","c"},{"d","e","f"}}');
109 ERROR: value too long for type character varying(4)
110 select * from domarrtest;
111 testint4arr | testchar4arr
112 ---------------+---------------------
113 {2,2} | {{a,b},{c,d}}
114 {{2,2},{2,2}} | {{a,b}}
115 {2,2} | {{a,b},{c,d},{e,f}}
120 select testint4arr[1], testchar4arr[2:2] from domarrtest;
121 testint4arr | testchar4arr
122 -------------+--------------
130 COPY domarrtest FROM stdin;
131 COPY domarrtest FROM stdin; -- fail
132 ERROR: value too long for type character varying(4)
133 CONTEXT: COPY domarrtest, line 1, column testchar4arr: "{qwerty,w,e}"
134 select * from domarrtest;
135 testint4arr | testchar4arr
136 ---------------+---------------------
137 {2,2} | {{a,b},{c,d}}
138 {{2,2},{2,2}} | {{a,b}}
139 {2,2} | {{a,b},{c,d},{e,f}}
146 drop table domarrtest;
147 drop domain domainint4arr restrict;
148 drop domain domainchar4arr restrict;
149 create domain dnotnull varchar(15) NOT NULL;
150 create domain dnull varchar(15);
151 create domain dcheck varchar(15) NOT NULL CHECK (VALUE = 'a' OR VALUE = 'c' OR VALUE = 'd');
152 create table nulltest
154 , col2 dnotnull NULL -- NOT NULL in the domain cannot be overridden
155 , col3 dnull NOT NULL
157 , col5 dcheck CHECK (col5 IN ('c', 'd'))
159 INSERT INTO nulltest DEFAULT VALUES;
160 ERROR: domain dnotnull does not allow null values
161 INSERT INTO nulltest values ('a', 'b', 'c', 'd', 'c'); -- Good
162 insert into nulltest values ('a', 'b', 'c', 'd', NULL);
163 ERROR: domain dcheck does not allow null values
164 insert into nulltest values ('a', 'b', 'c', 'd', 'a');
165 ERROR: new row for relation "nulltest" violates check constraint "nulltest_col5_check"
166 INSERT INTO nulltest values (NULL, 'b', 'c', 'd', 'd');
167 ERROR: domain dnotnull does not allow null values
168 INSERT INTO nulltest values ('a', NULL, 'c', 'd', 'c');
169 ERROR: domain dnotnull does not allow null values
170 INSERT INTO nulltest values ('a', 'b', NULL, 'd', 'c');
171 ERROR: null value in column "col3" violates not-null constraint
172 INSERT INTO nulltest values ('a', 'b', 'c', NULL, 'd'); -- Good
174 COPY nulltest FROM stdin; --fail
175 ERROR: null value in column "col3" violates not-null constraint
176 CONTEXT: COPY nulltest, line 1: "a b \N d d"
177 COPY nulltest FROM stdin; --fail
178 ERROR: domain dcheck does not allow null values
179 CONTEXT: COPY nulltest, line 1, column col5: null input
181 COPY nulltest FROM stdin;
182 ERROR: new row for relation "nulltest" violates check constraint "nulltest_col5_check"
183 CONTEXT: COPY nulltest, line 3: "a b c \N a"
184 select * from nulltest;
185 col1 | col2 | col3 | col4 | col5
186 ------+------+------+------+------
191 -- Test out coerced (casted) constraints
192 SELECT cast('1' as dnotnull);
198 SELECT cast(NULL as dnotnull); -- fail
199 ERROR: domain dnotnull does not allow null values
200 SELECT cast(cast(NULL as dnull) as dnotnull); -- fail
201 ERROR: domain dnotnull does not allow null values
202 SELECT cast(col4 as dnotnull) from nulltest; -- fail
203 ERROR: domain dnotnull does not allow null values
206 drop domain dnotnull restrict;
207 drop domain dnull restrict;
208 drop domain dcheck restrict;
209 create domain ddef1 int4 DEFAULT 3;
210 create domain ddef2 oid DEFAULT '12';
211 -- Type mixing, function returns int8
212 create domain ddef3 text DEFAULT 5;
213 create sequence ddef4_seq;
214 create domain ddef4 int4 DEFAULT nextval('ddef4_seq');
215 create domain ddef5 numeric(8,2) NOT NULL DEFAULT '12.12';
216 create table defaulttest
220 , col4 ddef4 PRIMARY KEY
221 , col5 ddef1 NOT NULL DEFAULT NULL
222 , col6 ddef2 DEFAULT '88'
223 , col7 ddef4 DEFAULT 8000
226 NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "defaulttest_pkey" for table "defaulttest"
227 insert into defaulttest(col4) values(0); -- fails, col5 defaults to null
228 ERROR: null value in column "col5" violates not-null constraint
229 alter table defaulttest alter column col5 drop default;
230 insert into defaulttest default values; -- succeeds, inserts domain default
231 -- We used to treat SET DEFAULT NULL as equivalent to DROP DEFAULT; wrong
232 alter table defaulttest alter column col5 set default null;
233 insert into defaulttest(col4) values(0); -- fails
234 ERROR: null value in column "col5" violates not-null constraint
235 alter table defaulttest alter column col5 drop default;
236 insert into defaulttest default values;
237 insert into defaulttest default values;
238 -- Test defaults with copy
239 COPY defaulttest(col5) FROM stdin;
240 select * from defaulttest;
241 col1 | col2 | col3 | col4 | col5 | col6 | col7 | col8
242 ------+------+------+------+------+------+------+-------
243 3 | 12 | 5 | 1 | 3 | 88 | 8000 | 12.12
244 3 | 12 | 5 | 2 | 3 | 88 | 8000 | 12.12
245 3 | 12 | 5 | 3 | 3 | 88 | 8000 | 12.12
246 3 | 12 | 5 | 4 | 42 | 88 | 8000 | 12.12
249 drop table defaulttest cascade;
250 -- Test ALTER DOMAIN .. NOT NULL
251 create domain dnotnulltest integer;
252 create table domnotnull
256 insert into domnotnull default values;
257 alter domain dnotnulltest set not null; -- fails
258 ERROR: column "col1" of table "domnotnull" contains null values
259 update domnotnull set col1 = 5;
260 alter domain dnotnulltest set not null; -- fails
261 ERROR: column "col2" of table "domnotnull" contains null values
262 update domnotnull set col2 = 6;
263 alter domain dnotnulltest set not null;
264 update domnotnull set col1 = null; -- fails
265 ERROR: domain dnotnulltest does not allow null values
266 alter domain dnotnulltest drop not null;
267 update domnotnull set col1 = null;
268 drop domain dnotnulltest cascade;
269 NOTICE: drop cascades to 2 other objects
270 DETAIL: drop cascades to table domnotnull column col1
271 drop cascades to table domnotnull column col2
272 -- Test ALTER DOMAIN .. DEFAULT ..
273 create table domdeftest (col1 ddef1);
274 insert into domdeftest default values;
275 select * from domdeftest;
281 alter domain ddef1 set default '42';
282 insert into domdeftest default values;
283 select * from domdeftest;
290 alter domain ddef1 drop default;
291 insert into domdeftest default values;
292 select * from domdeftest;
300 drop table domdeftest;
301 -- Test ALTER DOMAIN .. CONSTRAINT ..
302 create domain con as integer;
303 create table domcontest (col1 con);
304 insert into domcontest values (1);
305 insert into domcontest values (2);
306 alter domain con add constraint t check (VALUE < 1); -- fails
307 ERROR: column "col1" of table "domcontest" contains values that violate the new constraint
308 alter domain con add constraint t check (VALUE < 34);
309 alter domain con add check (VALUE > 0);
310 insert into domcontest values (-5); -- fails
311 ERROR: value for domain con violates check constraint "con_check"
312 insert into domcontest values (42); -- fails
313 ERROR: value for domain con violates check constraint "t"
314 insert into domcontest values (5);
315 alter domain con drop constraint t;
316 insert into domcontest values (-5); --fails
317 ERROR: value for domain con violates check constraint "con_check"
318 insert into domcontest values (42);
319 -- Confirm ALTER DOMAIN with RULES.
320 create table domtab (col1 integer);
321 create domain dom as integer;
322 create view domview as select cast(col1 as dom) from domtab;
323 insert into domtab (col1) values (null);
324 insert into domtab (col1) values (5);
325 select * from domview;
332 alter domain dom set not null;
333 select * from domview; -- fail
334 ERROR: domain dom does not allow null values
335 alter domain dom drop not null;
336 select * from domview;
343 alter domain dom add constraint domchkgt6 check(value > 6);
344 select * from domview; --fail
345 ERROR: value for domain dom violates check constraint "domchkgt6"
346 alter domain dom drop constraint domchkgt6 restrict;
347 select * from domview;
355 drop domain ddef1 restrict;
356 drop domain ddef2 restrict;
357 drop domain ddef3 restrict;
358 drop domain ddef4 restrict;
359 drop domain ddef5 restrict;
360 drop sequence ddef4_seq;
361 -- Test domains over domains
362 create domain vchar4 varchar(4);
363 create domain dinter vchar4 check (substring(VALUE, 1, 1) = 'x');
364 create domain dtop dinter check (substring(VALUE, 2, 1) = '1');
371 select 'x1234'::dtop; -- explicit coercion should truncate
377 select 'y1234'::dtop; -- fail
378 ERROR: value for domain dtop violates check constraint "dinter_check"
379 select 'y123'::dtop; -- fail
380 ERROR: value for domain dtop violates check constraint "dinter_check"
381 select 'yz23'::dtop; -- fail
382 ERROR: value for domain dtop violates check constraint "dinter_check"
383 select 'xz23'::dtop; -- fail
384 ERROR: value for domain dtop violates check constraint "dtop_check"
385 create temp table dtest(f1 dtop);
386 insert into dtest values('x123');
387 insert into dtest values('x1234'); -- fail, implicit coercion
388 ERROR: value too long for type character varying(4)
389 insert into dtest values('y1234'); -- fail, implicit coercion
390 ERROR: value too long for type character varying(4)
391 insert into dtest values('y123'); -- fail
392 ERROR: value for domain dtop violates check constraint "dinter_check"
393 insert into dtest values('yz23'); -- fail
394 ERROR: value for domain dtop violates check constraint "dinter_check"
395 insert into dtest values('xz23'); -- fail
396 ERROR: value for domain dtop violates check constraint "dtop_check"
398 drop domain vchar4 cascade;
399 NOTICE: drop cascades to 2 other objects
400 DETAIL: drop cascades to type dinter
401 drop cascades to type dtop
402 -- Make sure that constraints of newly-added domain columns are
403 -- enforced correctly, even if there's no default value for the new
404 -- column. Per bug #1433
405 create domain str_domain as text not null;
406 create table domain_test (a int, b int);
407 insert into domain_test values (1, 2);
408 insert into domain_test values (1, 2);
410 alter table domain_test add column c str_domain;
411 ERROR: domain str_domain does not allow null values
412 create domain str_domain2 as text check (value <> 'foo') default 'foo';
414 alter table domain_test add column d str_domain2;
415 ERROR: value for domain str_domain2 violates check constraint "str_domain2_check"
416 -- Check that domain constraints on prepared statement parameters of
417 -- unknown type are enforced correctly.
418 create domain pos_int as int4 check (value > 0) not null;
419 prepare s1 as select $1::pos_int = 10 as "is_ten";
426 execute s1(0); -- should fail
427 ERROR: value for domain pos_int violates check constraint "pos_int_check"
428 execute s1(NULL); -- should fail
429 ERROR: domain pos_int does not allow null values
430 -- Check that domain constraints on plpgsql function parameters, results,
431 -- and local variables are enforced correctly.
432 create function doubledecrement(p1 pos_int) returns pos_int as $$
436 end$$ language plpgsql;
437 select doubledecrement(3); -- fail because of implicit null assignment
438 ERROR: domain pos_int does not allow null values
439 CONTEXT: PL/pgSQL function "doubledecrement" line 2 during statement block local variable initialization
440 create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
441 declare v pos_int := 0;
444 end$$ language plpgsql;
445 select doubledecrement(3); -- fail at initialization assignment
446 ERROR: value for domain pos_int violates check constraint "pos_int_check"
447 CONTEXT: PL/pgSQL function "doubledecrement" line 2 during statement block local variable initialization
448 create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
449 declare v pos_int := 1;
453 end$$ language plpgsql;
454 select doubledecrement(null); -- fail before call
455 ERROR: domain pos_int does not allow null values
456 select doubledecrement(0); -- fail before call
457 ERROR: value for domain pos_int violates check constraint "pos_int_check"
458 select doubledecrement(1); -- fail at assignment to v
459 ERROR: value for domain pos_int violates check constraint "pos_int_check"
460 CONTEXT: PL/pgSQL function "doubledecrement" line 3 at assignment
461 select doubledecrement(2); -- fail at return
462 ERROR: value for domain pos_int violates check constraint "pos_int_check"
463 CONTEXT: PL/pgSQL function "doubledecrement" while casting return value to function's return type
464 select doubledecrement(3); -- good
470 -- Check that ALTER DOMAIN tests columns of derived types
471 create domain posint as int4;
472 -- Currently, this doesn't work for composite types, but verify it complains
473 create type ddtest1 as (f1 posint);
474 create table ddtest2(f1 ddtest1);
475 insert into ddtest2 values(row(-1));
476 alter domain posint add constraint c1 check(value >= 0);
477 ERROR: cannot alter type "posint" because column "ddtest2"."f1" uses it
479 create table ddtest2(f1 ddtest1[]);
480 insert into ddtest2 values('{(-1)}');
481 alter domain posint add constraint c1 check(value >= 0);
482 ERROR: cannot alter type "posint" because column "ddtest2"."f1" uses it
484 alter domain posint add constraint c1 check(value >= 0);
485 create domain posint2 as posint check (value % 2 = 0);
486 create table ddtest2(f1 posint2);
487 insert into ddtest2 values(11); -- fail
488 ERROR: value for domain posint2 violates check constraint "posint2_check"
489 insert into ddtest2 values(-2); -- fail
490 ERROR: value for domain posint2 violates check constraint "c1"
491 insert into ddtest2 values(2);
492 alter domain posint add constraint c2 check(value >= 10); -- fail
493 ERROR: column "f1" of table "ddtest2" contains values that violate the new constraint
494 alter domain posint add constraint c2 check(value > 0); -- OK
497 drop domain posint cascade;
498 NOTICE: drop cascades to type posint2