Fix obsolete comment regarding FSM truncation.
[PostgreSQL.git] / src / test / regress / expected / domain.out
blobfd88b16ccee0553aba2bbcdbb1650fa0de327c87
1 --
2 -- Test domains.
3 --
4 -- Test Comment / Drop
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
18 -- Test domain input.
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);
27  domainvarchar 
28 ---------------
29  12345
30 (1 row)
32 SELECT cast('12345' as domainvarchar);
33  domainvarchar 
34 ---------------
35  12345
36 (1 row)
38 -- Test tables using domains
39 create table basictest
40            ( testint4 domainint4
41            , testtext domaintext
42            , testvarchar domainvarchar
43            , testnumeric domainnumeric
44            );
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
49 -- Test copy
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
59           |          | short       |            
60 (3 rows)
62 -- check that domains inherit operations from base types
63 select testtext || testvarchar as concat, testnumeric + 42 as sum
64 from basictest;
65   concat   |  sum   
66 -----------+--------
67  hahashort | 165.12
68  hahashort | 165.12
69            |       
70 (3 rows)
72 -- check that union/case/coalesce type resolution handles domains properly
73 select coalesce(4::domainint4, 7) is of (int4) as t;
74  t 
75 ---
76  t
77 (1 row)
79 select coalesce(4::domainint4, 7) is of (domainint4) as f;
80  f 
81 ---
82  f
83 (1 row)
85 select coalesce(4::domainint4, 7::domainint4) is of (domainint4) as t;
86  t 
87 ---
88  t
89 (1 row)
91 drop table basictest;
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
102             );
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}}
116  {2,2}         | {{a},{c}}
117                | {{a,b,c},{d,e,f}}
118 (5 rows)
120 select testint4arr[1], testchar4arr[2:2] from domarrtest;
121  testint4arr | testchar4arr 
122 -------------+--------------
123            2 | {{c,d}}
124              | {}
125            2 | {{c,d}}
126            2 | {{c}}
127              | {{d,e,f}}
128 (5 rows)
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}}
140  {2,2}         | {{a},{c}}
141                | {{a,b,c},{d,e,f}}
142  {3,4}         | {q,w,e}
143                | 
144 (7 rows)
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
153            ( col1 dnotnull
154            , col2 dnotnull NULL  -- NOT NULL in the domain cannot be overridden
155            , col3 dnull    NOT NULL
156            , col4 dnull
157            , col5 dcheck CHECK (col5 IN ('c', 'd'))
158            );
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
173 -- Test copy
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
180 -- Last row is bad
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 ------+------+------+------+------
187  a    | b    | c    | d    | c
188  a    | b    | c    |      | d
189 (2 rows)
191 -- Test out coerced (casted) constraints
192 SELECT cast('1' as dnotnull);
193  dnotnull 
194 ----------
196 (1 row)
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
204 -- cleanup
205 drop table nulltest;
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
217             ( col1 ddef1
218             , col2 ddef2
219             , col3 ddef3
220             , col4 ddef4 PRIMARY KEY
221             , col5 ddef1 NOT NULL DEFAULT NULL
222             , col6 ddef2 DEFAULT '88'
223             , col7 ddef4 DEFAULT 8000
224             , col8 ddef5
225             );
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
247 (4 rows)
249 drop table defaulttest cascade;
250 -- Test ALTER DOMAIN .. NOT NULL
251 create domain dnotnulltest integer;
252 create table domnotnull
253 ( col1 dnotnulltest
254 , col2 dnotnulltest
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;
276  col1 
277 ------
278     3
279 (1 row)
281 alter domain ddef1 set default '42';
282 insert into domdeftest default values;
283 select * from domdeftest;
284  col1 
285 ------
286     3
287    42
288 (2 rows)
290 alter domain ddef1 drop default;
291 insert into domdeftest default values;
292 select * from domdeftest;
293  col1 
294 ------
295     3
296    42
297      
298 (3 rows)
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;
326  col1 
327 ------
328      
329     5
330 (2 rows)
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;
337  col1 
338 ------
339      
340     5
341 (2 rows)
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;
348  col1 
349 ------
350      
351     5
352 (2 rows)
354 -- cleanup
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');
365 select 'x123'::dtop;
366  dtop 
367 ------
368  x123
369 (1 row)
371 select 'x1234'::dtop; -- explicit coercion should truncate
372  dtop 
373 ------
374  x123
375 (1 row)
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"
397 drop table dtest;
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);
409 -- should fail
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';
413 -- should fail
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";
420 execute s1(10);
421  is_ten 
422 --------
424 (1 row)
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 $$
433 declare v pos_int;
434 begin
435     return p1;
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;
442 begin
443     return p1;
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;
450 begin
451     v := p1 - 1;
452     return v - 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
465  doubledecrement 
466 -----------------
467                1
468 (1 row)
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
478 drop table ddtest2;
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
483 drop table ddtest2;
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
495 drop table ddtest2;
496 drop type ddtest1;
497 drop domain posint cascade;
498 NOTICE:  drop cascades to type posint2