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