Support PG_UNICODE_FAST locale in the builtin collation provider.
[pgsql.git] / src / test / regress / expected / enum.out
blob4d9f36d0d36779573a095eda54a8eed56640a527
1 --
2 -- Enum tests
3 --
4 CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple');
5 --
6 -- Did it create the right number of rows?
7 --
8 SELECT COUNT(*) FROM pg_enum WHERE enumtypid = 'rainbow'::regtype;
9  count 
10 -------
11      6
12 (1 row)
15 -- I/O functions
17 SELECT 'red'::rainbow;
18  rainbow 
19 ---------
20  red
21 (1 row)
23 SELECT 'mauve'::rainbow;
24 ERROR:  invalid input value for enum rainbow: "mauve"
25 LINE 1: SELECT 'mauve'::rainbow;
26                ^
27 -- Also try it with non-error-throwing API
28 SELECT pg_input_is_valid('red', 'rainbow');
29  pg_input_is_valid 
30 -------------------
31  t
32 (1 row)
34 SELECT pg_input_is_valid('mauve', 'rainbow');
35  pg_input_is_valid 
36 -------------------
37  f
38 (1 row)
40 SELECT * FROM pg_input_error_info('mauve', 'rainbow');
41                     message                    | detail | hint | sql_error_code 
42 -----------------------------------------------+--------+------+----------------
43  invalid input value for enum rainbow: "mauve" |        |      | 22P02
44 (1 row)
47 SELECT * FROM pg_input_error_info(repeat('too_long', 32), 'rainbow');
48 -[ RECORD 1 ]--+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
49 message        | invalid input value for enum rainbow: "too_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_long"
50 detail         | 
51 hint           | 
52 sql_error_code | 22P02
56 -- adding new values
58 CREATE TYPE planets AS ENUM ( 'venus', 'earth', 'mars' );
59 SELECT enumlabel, enumsortorder
60 FROM pg_enum
61 WHERE enumtypid = 'planets'::regtype
62 ORDER BY 2;
63  enumlabel | enumsortorder 
64 -----------+---------------
65  venus     |             1
66  earth     |             2
67  mars      |             3
68 (3 rows)
70 ALTER TYPE planets ADD VALUE 'uranus';
71 SELECT enumlabel, enumsortorder
72 FROM pg_enum
73 WHERE enumtypid = 'planets'::regtype
74 ORDER BY 2;
75  enumlabel | enumsortorder 
76 -----------+---------------
77  venus     |             1
78  earth     |             2
79  mars      |             3
80  uranus    |             4
81 (4 rows)
83 ALTER TYPE planets ADD VALUE 'mercury' BEFORE 'venus';
84 ALTER TYPE planets ADD VALUE 'saturn' BEFORE 'uranus';
85 ALTER TYPE planets ADD VALUE 'jupiter' AFTER 'mars';
86 ALTER TYPE planets ADD VALUE 'neptune' AFTER 'uranus';
87 SELECT enumlabel, enumsortorder
88 FROM pg_enum
89 WHERE enumtypid = 'planets'::regtype
90 ORDER BY 2;
91  enumlabel | enumsortorder 
92 -----------+---------------
93  mercury   |             0
94  venus     |             1
95  earth     |             2
96  mars      |             3
97  jupiter   |          3.25
98  saturn    |           3.5
99  uranus    |             4
100  neptune   |             5
101 (8 rows)
103 SELECT enumlabel, enumsortorder
104 FROM pg_enum
105 WHERE enumtypid = 'planets'::regtype
106 ORDER BY enumlabel::planets;
107  enumlabel | enumsortorder 
108 -----------+---------------
109  mercury   |             0
110  venus     |             1
111  earth     |             2
112  mars      |             3
113  jupiter   |          3.25
114  saturn    |           3.5
115  uranus    |             4
116  neptune   |             5
117 (8 rows)
119 -- errors for adding labels
120 ALTER TYPE planets ADD VALUE
121   'plutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutopluto';
122 ERROR:  invalid enum label "plutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutopluto"
123 DETAIL:  Labels must be 63 bytes or less.
124 ALTER TYPE planets ADD VALUE 'pluto' AFTER 'zeus';
125 ERROR:  "zeus" is not an existing enum label
126 -- if not exists tests
127 --  existing value gives error
128 ALTER TYPE planets ADD VALUE 'mercury';
129 ERROR:  enum label "mercury" already exists
130 -- unless IF NOT EXISTS is specified
131 ALTER TYPE planets ADD VALUE IF NOT EXISTS 'mercury';
132 NOTICE:  enum label "mercury" already exists, skipping
133 -- should be neptune, not mercury
134 SELECT enum_last(NULL::planets);
135  enum_last 
136 -----------
137  neptune
138 (1 row)
140 ALTER TYPE planets ADD VALUE IF NOT EXISTS 'pluto';
141 -- should be pluto, i.e. the new value
142 SELECT enum_last(NULL::planets);
143  enum_last 
144 -----------
145  pluto
146 (1 row)
149 -- Test inserting so many values that we have to renumber
151 create type insenum as enum ('L1', 'L2');
152 alter type insenum add value 'i1' before 'L2';
153 alter type insenum add value 'i2' before 'L2';
154 alter type insenum add value 'i3' before 'L2';
155 alter type insenum add value 'i4' before 'L2';
156 alter type insenum add value 'i5' before 'L2';
157 alter type insenum add value 'i6' before 'L2';
158 alter type insenum add value 'i7' before 'L2';
159 alter type insenum add value 'i8' before 'L2';
160 alter type insenum add value 'i9' before 'L2';
161 alter type insenum add value 'i10' before 'L2';
162 alter type insenum add value 'i11' before 'L2';
163 alter type insenum add value 'i12' before 'L2';
164 alter type insenum add value 'i13' before 'L2';
165 alter type insenum add value 'i14' before 'L2';
166 alter type insenum add value 'i15' before 'L2';
167 alter type insenum add value 'i16' before 'L2';
168 alter type insenum add value 'i17' before 'L2';
169 alter type insenum add value 'i18' before 'L2';
170 alter type insenum add value 'i19' before 'L2';
171 alter type insenum add value 'i20' before 'L2';
172 alter type insenum add value 'i21' before 'L2';
173 alter type insenum add value 'i22' before 'L2';
174 alter type insenum add value 'i23' before 'L2';
175 alter type insenum add value 'i24' before 'L2';
176 alter type insenum add value 'i25' before 'L2';
177 alter type insenum add value 'i26' before 'L2';
178 alter type insenum add value 'i27' before 'L2';
179 alter type insenum add value 'i28' before 'L2';
180 alter type insenum add value 'i29' before 'L2';
181 alter type insenum add value 'i30' before 'L2';
182 -- The exact values of enumsortorder will now depend on the local properties
183 -- of float4, but in any reasonable implementation we should get at least
184 -- 20 splits before having to renumber; so only hide values > 20.
185 SELECT enumlabel,
186        case when enumsortorder > 20 then null else enumsortorder end as so
187 FROM pg_enum
188 WHERE enumtypid = 'insenum'::regtype
189 ORDER BY enumsortorder;
190  enumlabel | so 
191 -----------+----
192  L1        |  1
193  i1        |  2
194  i2        |  3
195  i3        |  4
196  i4        |  5
197  i5        |  6
198  i6        |  7
199  i7        |  8
200  i8        |  9
201  i9        | 10
202  i10       | 11
203  i11       | 12
204  i12       | 13
205  i13       | 14
206  i14       | 15
207  i15       | 16
208  i16       | 17
209  i17       | 18
210  i18       | 19
211  i19       | 20
212  i20       |   
213  i21       |   
214  i22       |   
215  i23       |   
216  i24       |   
217  i25       |   
218  i26       |   
219  i27       |   
220  i28       |   
221  i29       |   
222  i30       |   
223  L2        |   
224 (32 rows)
227 -- Basic table creation, row selection
229 CREATE TABLE enumtest (col rainbow);
230 INSERT INTO enumtest values ('red'), ('orange'), ('yellow'), ('green');
231 COPY enumtest FROM stdin;
232 SELECT * FROM enumtest;
233   col   
234 --------
235  red
236  orange
237  yellow
238  green
239  blue
240  purple
241 (6 rows)
244 -- Operators, no index
246 SELECT * FROM enumtest WHERE col = 'orange';
247   col   
248 --------
249  orange
250 (1 row)
252 SELECT * FROM enumtest WHERE col <> 'orange' ORDER BY col;
253   col   
254 --------
255  red
256  yellow
257  green
258  blue
259  purple
260 (5 rows)
262 SELECT * FROM enumtest WHERE col > 'yellow' ORDER BY col;
263   col   
264 --------
265  green
266  blue
267  purple
268 (3 rows)
270 SELECT * FROM enumtest WHERE col >= 'yellow' ORDER BY col;
271   col   
272 --------
273  yellow
274  green
275  blue
276  purple
277 (4 rows)
279 SELECT * FROM enumtest WHERE col < 'green' ORDER BY col;
280   col   
281 --------
282  red
283  orange
284  yellow
285 (3 rows)
287 SELECT * FROM enumtest WHERE col <= 'green' ORDER BY col;
288   col   
289 --------
290  red
291  orange
292  yellow
293  green
294 (4 rows)
297 -- Cast to/from text
299 SELECT 'red'::rainbow::text || 'hithere';
300   ?column?  
301 ------------
302  redhithere
303 (1 row)
305 SELECT 'red'::text::rainbow = 'red'::rainbow;
306  ?column? 
307 ----------
309 (1 row)
312 -- Aggregates
314 SELECT min(col) FROM enumtest;
315  min 
316 -----
317  red
318 (1 row)
320 SELECT max(col) FROM enumtest;
321   max   
322 --------
323  purple
324 (1 row)
326 SELECT max(col) FROM enumtest WHERE col < 'green';
327   max   
328 --------
329  yellow
330 (1 row)
333 -- Index tests, force use of index
335 SET enable_seqscan = off;
336 SET enable_bitmapscan = off;
338 -- Btree index / opclass with the various operators
340 CREATE UNIQUE INDEX enumtest_btree ON enumtest USING btree (col);
341 SELECT * FROM enumtest WHERE col = 'orange';
342   col   
343 --------
344  orange
345 (1 row)
347 SELECT * FROM enumtest WHERE col <> 'orange' ORDER BY col;
348   col   
349 --------
350  red
351  yellow
352  green
353  blue
354  purple
355 (5 rows)
357 SELECT * FROM enumtest WHERE col > 'yellow' ORDER BY col;
358   col   
359 --------
360  green
361  blue
362  purple
363 (3 rows)
365 SELECT * FROM enumtest WHERE col >= 'yellow' ORDER BY col;
366   col   
367 --------
368  yellow
369  green
370  blue
371  purple
372 (4 rows)
374 SELECT * FROM enumtest WHERE col < 'green' ORDER BY col;
375   col   
376 --------
377  red
378  orange
379  yellow
380 (3 rows)
382 SELECT * FROM enumtest WHERE col <= 'green' ORDER BY col;
383   col   
384 --------
385  red
386  orange
387  yellow
388  green
389 (4 rows)
391 SELECT min(col) FROM enumtest;
392  min 
393 -----
394  red
395 (1 row)
397 SELECT max(col) FROM enumtest;
398   max   
399 --------
400  purple
401 (1 row)
403 SELECT max(col) FROM enumtest WHERE col < 'green';
404   max   
405 --------
406  yellow
407 (1 row)
409 DROP INDEX enumtest_btree;
411 -- Hash index / opclass with the = operator
413 CREATE INDEX enumtest_hash ON enumtest USING hash (col);
414 SELECT * FROM enumtest WHERE col = 'orange';
415   col   
416 --------
417  orange
418 (1 row)
420 DROP INDEX enumtest_hash;
422 -- End index tests
424 RESET enable_seqscan;
425 RESET enable_bitmapscan;
427 -- Domains over enums
429 CREATE DOMAIN rgb AS rainbow CHECK (VALUE IN ('red', 'green', 'blue'));
430 SELECT 'red'::rgb;
431  rgb 
432 -----
433  red
434 (1 row)
436 SELECT 'purple'::rgb;
437 ERROR:  value for domain rgb violates check constraint "rgb_check"
438 SELECT 'purple'::rainbow::rgb;
439 ERROR:  value for domain rgb violates check constraint "rgb_check"
440 DROP DOMAIN rgb;
442 -- Arrays
444 SELECT '{red,green,blue}'::rainbow[];
445      rainbow      
446 ------------------
447  {red,green,blue}
448 (1 row)
450 SELECT ('{red,green,blue}'::rainbow[])[2];
451  rainbow 
452 ---------
453  green
454 (1 row)
456 SELECT 'red' = ANY ('{red,green,blue}'::rainbow[]);
457  ?column? 
458 ----------
460 (1 row)
462 SELECT 'yellow' = ANY ('{red,green,blue}'::rainbow[]);
463  ?column? 
464 ----------
466 (1 row)
468 SELECT 'red' = ALL ('{red,green,blue}'::rainbow[]);
469  ?column? 
470 ----------
472 (1 row)
474 SELECT 'red' = ALL ('{red,red}'::rainbow[]);
475  ?column? 
476 ----------
478 (1 row)
481 -- Support functions
483 SELECT enum_first(NULL::rainbow);
484  enum_first 
485 ------------
486  red
487 (1 row)
489 SELECT enum_last('green'::rainbow);
490  enum_last 
491 -----------
492  purple
493 (1 row)
495 SELECT enum_range(NULL::rainbow);
496               enum_range               
497 ---------------------------------------
498  {red,orange,yellow,green,blue,purple}
499 (1 row)
501 SELECT enum_range('orange'::rainbow, 'green'::rainbow);
502       enum_range       
503 -----------------------
504  {orange,yellow,green}
505 (1 row)
507 SELECT enum_range(NULL, 'green'::rainbow);
508         enum_range         
509 ---------------------------
510  {red,orange,yellow,green}
511 (1 row)
513 SELECT enum_range('orange'::rainbow, NULL);
514             enum_range             
515 -----------------------------------
516  {orange,yellow,green,blue,purple}
517 (1 row)
519 SELECT enum_range(NULL::rainbow, NULL);
520               enum_range               
521 ---------------------------------------
522  {red,orange,yellow,green,blue,purple}
523 (1 row)
526 -- User functions, can't test perl/python etc here since may not be compiled.
528 CREATE FUNCTION echo_me(anyenum) RETURNS text AS $$
529 BEGIN
530 RETURN $1::text || 'omg';
532 $$ LANGUAGE plpgsql;
533 SELECT echo_me('red'::rainbow);
534  echo_me 
535 ---------
536  redomg
537 (1 row)
540 -- Concrete function should override generic one
542 CREATE FUNCTION echo_me(rainbow) RETURNS text AS $$
543 BEGIN
544 RETURN $1::text || 'wtf';
546 $$ LANGUAGE plpgsql;
547 SELECT echo_me('red'::rainbow);
548  echo_me 
549 ---------
550  redwtf
551 (1 row)
554 -- If we drop the original generic one, we don't have to qualify the type
555 -- anymore, since there's only one match
557 DROP FUNCTION echo_me(anyenum);
558 SELECT echo_me('red');
559  echo_me 
560 ---------
561  redwtf
562 (1 row)
564 DROP FUNCTION echo_me(rainbow);
566 -- RI triggers on enum types
568 CREATE TABLE enumtest_parent (id rainbow PRIMARY KEY);
569 CREATE TABLE enumtest_child (parent rainbow REFERENCES enumtest_parent);
570 INSERT INTO enumtest_parent VALUES ('red');
571 INSERT INTO enumtest_child VALUES ('red');
572 INSERT INTO enumtest_child VALUES ('blue');  -- fail
573 ERROR:  insert or update on table "enumtest_child" violates foreign key constraint "enumtest_child_parent_fkey"
574 DETAIL:  Key (parent)=(blue) is not present in table "enumtest_parent".
575 DELETE FROM enumtest_parent;  -- fail
576 ERROR:  update or delete on table "enumtest_parent" violates foreign key constraint "enumtest_child_parent_fkey" on table "enumtest_child"
577 DETAIL:  Key (id)=(red) is still referenced from table "enumtest_child".
579 -- cross-type RI should fail
581 CREATE TYPE bogus AS ENUM('good', 'bad', 'ugly');
582 CREATE TABLE enumtest_bogus_child(parent bogus REFERENCES enumtest_parent);
583 ERROR:  foreign key constraint "enumtest_bogus_child_parent_fkey" cannot be implemented
584 DETAIL:  Key columns "parent" of the referencing table and "id" of the referenced table are of incompatible types: bogus and rainbow.
585 DROP TYPE bogus;
586 -- check renaming a value
587 ALTER TYPE rainbow RENAME VALUE 'red' TO 'crimson';
588 SELECT enumlabel, enumsortorder
589 FROM pg_enum
590 WHERE enumtypid = 'rainbow'::regtype
591 ORDER BY 2;
592  enumlabel | enumsortorder 
593 -----------+---------------
594  crimson   |             1
595  orange    |             2
596  yellow    |             3
597  green     |             4
598  blue      |             5
599  purple    |             6
600 (6 rows)
602 -- check that renaming a non-existent value fails
603 ALTER TYPE rainbow RENAME VALUE 'red' TO 'crimson';
604 ERROR:  "red" is not an existing enum label
605 -- check that renaming to an existent value fails
606 ALTER TYPE rainbow RENAME VALUE 'blue' TO 'green';
607 ERROR:  enum label "green" already exists
609 -- check transactional behaviour of ALTER TYPE ... ADD VALUE
611 CREATE TYPE bogus AS ENUM('good');
612 -- check that we can add new values to existing enums in a transaction
613 -- but we can't use them
614 BEGIN;
615 ALTER TYPE bogus ADD VALUE 'new';
616 SAVEPOINT x;
617 SELECT 'new'::bogus;  -- unsafe
618 ERROR:  unsafe use of new value "new" of enum type bogus
619 LINE 1: SELECT 'new'::bogus;
620                ^
621 HINT:  New enum values must be committed before they can be used.
622 ROLLBACK TO x;
623 SELECT enum_first(null::bogus);  -- safe
624  enum_first 
625 ------------
626  good
627 (1 row)
629 SELECT enum_last(null::bogus);  -- unsafe
630 ERROR:  unsafe use of new value "new" of enum type bogus
631 HINT:  New enum values must be committed before they can be used.
632 ROLLBACK TO x;
633 SELECT enum_range(null::bogus);  -- unsafe
634 ERROR:  unsafe use of new value "new" of enum type bogus
635 HINT:  New enum values must be committed before they can be used.
636 ROLLBACK TO x;
637 COMMIT;
638 SELECT 'new'::bogus;  -- now safe
639  bogus 
640 -------
641  new
642 (1 row)
644 SELECT enumlabel, enumsortorder
645 FROM pg_enum
646 WHERE enumtypid = 'bogus'::regtype
647 ORDER BY 2;
648  enumlabel | enumsortorder 
649 -----------+---------------
650  good      |             1
651  new       |             2
652 (2 rows)
654 -- check that we recognize the case where the enum already existed but was
655 -- modified in the current txn; this should not be considered safe
656 BEGIN;
657 ALTER TYPE bogus RENAME TO bogon;
658 ALTER TYPE bogon ADD VALUE 'bad';
659 SELECT 'bad'::bogon;
660 ERROR:  unsafe use of new value "bad" of enum type bogon
661 LINE 1: SELECT 'bad'::bogon;
662                ^
663 HINT:  New enum values must be committed before they can be used.
664 ROLLBACK;
665 -- but a renamed value is safe to use later in same transaction
666 BEGIN;
667 ALTER TYPE bogus RENAME VALUE 'good' to 'bad';
668 SELECT 'bad'::bogus;
669  bogus 
670 -------
671  bad
672 (1 row)
674 ROLLBACK;
675 DROP TYPE bogus;
676 -- check that values created during CREATE TYPE can be used in any case
677 BEGIN;
678 CREATE TYPE bogus AS ENUM('good','bad','ugly');
679 ALTER TYPE bogus RENAME TO bogon;
680 select enum_range(null::bogon);
681    enum_range    
682 -----------------
683  {good,bad,ugly}
684 (1 row)
686 ROLLBACK;
687 -- we must allow this usage to support pg_dump in binary upgrade mode
688 BEGIN;
689 CREATE TYPE bogus AS ENUM('good');
690 ALTER TYPE bogus RENAME TO bogon;
691 ALTER TYPE bogon ADD VALUE 'bad';
692 ALTER TYPE bogon ADD VALUE 'ugly';
693 select enum_range(null::bogon);
694    enum_range    
695 -----------------
696  {good,bad,ugly}
697 (1 row)
699 ROLLBACK;
701 -- Cleanup
703 DROP TABLE enumtest_child;
704 DROP TABLE enumtest_parent;
705 DROP TABLE enumtest;
706 DROP TYPE rainbow;
708 -- Verify properly cleaned up
710 SELECT COUNT(*) FROM pg_type WHERE typname = 'rainbow';
711  count 
712 -------
713      0
714 (1 row)
716 SELECT * FROM pg_enum WHERE NOT EXISTS
717   (SELECT 1 FROM pg_type WHERE pg_type.oid = enumtypid);
718  oid | enumtypid | enumsortorder | enumlabel 
719 -----+-----------+---------------+-----------
720 (0 rows)