2 * This test is intended to pass on all platforms supported by Postgres.
3 * We can therefore only assume that the default, C, and POSIX collations
4 * are available --- and since the regression tests are often run in a
5 * C-locale database, these may well all have the same behavior. But
6 * fortunately, the system doesn't know that and will treat them as
7 * incompatible collations. It is therefore at least possible to test
8 * parser behaviors such as collation conflict resolution. This test will,
9 * however, be more revealing when run in a database with non-C locale,
10 * since any departure from C sorting behavior will show as a failure.
12 CREATE SCHEMA collate_tests;
13 SET search_path = collate_tests;
14 CREATE TABLE collate_test1 (
16 b text COLLATE "C" NOT NULL
19 Table "collate_tests.collate_test1"
20 Column | Type | Collation | Nullable | Default
21 --------+---------+-----------+----------+---------
23 b | text | C | not null |
25 CREATE TABLE collate_test_fail (
29 ERROR: collations are not supported by type integer
30 LINE 2: a int COLLATE "C",
32 CREATE TABLE collate_test_like (
36 Table "collate_tests.collate_test_like"
37 Column | Type | Collation | Nullable | Default
38 --------+---------+-----------+----------+---------
40 b | text | C | not null |
42 CREATE TABLE collate_test2 (
44 b text COLLATE "POSIX"
46 INSERT INTO collate_test1 VALUES (1, 'abc'), (2, 'Abc'), (3, 'bbc'), (4, 'ABD');
47 INSERT INTO collate_test2 SELECT * FROM collate_test1;
48 SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'abc';
55 SELECT * FROM collate_test1 WHERE b >= 'abc' COLLATE "C";
62 SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'abc' COLLATE "C";
69 SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "POSIX"; -- fail
70 ERROR: collation mismatch between explicit collations "C" and "POSIX"
71 LINE 1: ...* FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "P...
73 CREATE DOMAIN testdomain_p AS text COLLATE "POSIX";
74 CREATE DOMAIN testdomain_i AS int COLLATE "POSIX"; -- fail
75 ERROR: collations are not supported by type integer
76 CREATE TABLE collate_test4 (
80 INSERT INTO collate_test4 SELECT * FROM collate_test1;
81 SELECT a, b FROM collate_test4 ORDER BY b;
90 CREATE TABLE collate_test5 (
92 b testdomain_p COLLATE "C"
94 INSERT INTO collate_test5 SELECT * FROM collate_test1;
95 SELECT a, b FROM collate_test5 ORDER BY b;
104 SELECT a, b FROM collate_test1 ORDER BY b;
113 SELECT a, b FROM collate_test2 ORDER BY b;
122 SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C";
132 SELECT * FROM collate_test1 ORDER BY b;
141 SELECT * FROM collate_test2 ORDER BY b;
150 -- constant expression folding
151 SELECT 'bbc' COLLATE "C" > 'Abc' COLLATE "C" AS "true";
157 SELECT 'bbc' COLLATE "POSIX" < 'Abc' COLLATE "POSIX" AS "false";
164 CREATE TABLE collate_test10 (
167 y text COLLATE "POSIX"
169 INSERT INTO collate_test10 VALUES (1, 'hij', 'hij'), (2, 'HIJ', 'HIJ');
170 SELECT a, lower(x), lower(y), upper(x), upper(y), initcap(x), initcap(y) FROM collate_test10;
171 a | lower | lower | upper | upper | initcap | initcap
172 ---+-------+-------+-------+-------+---------+---------
173 1 | hij | hij | HIJ | HIJ | Hij | Hij
174 2 | hij | hij | HIJ | HIJ | Hij | Hij
177 SELECT a, lower(x COLLATE "C"), lower(y COLLATE "C") FROM collate_test10;
184 SELECT a, x, y FROM collate_test10 ORDER BY lower(y), a;
192 CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc';
193 CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C";
194 CREATE VIEW collview3 AS SELECT a, lower((x || x) COLLATE "POSIX") FROM collate_test10;
195 SELECT table_name, view_definition FROM information_schema.views
196 WHERE table_name LIKE 'collview%' ORDER BY 1;
197 table_name | view_definition
198 ------------+------------------------------------------------------------------------------
199 collview1 | SELECT collate_test1.a, +
201 | FROM collate_test1 +
202 | WHERE ((collate_test1.b COLLATE "C") >= 'bbc'::text);
203 collview2 | SELECT collate_test1.a, +
205 | FROM collate_test1 +
206 | ORDER BY (collate_test1.b COLLATE "C");
207 collview3 | SELECT collate_test10.a, +
208 | lower(((collate_test10.x || collate_test10.x) COLLATE "POSIX")) AS lower+
209 | FROM collate_test10;
212 -- collation propagation in various expression types
213 SELECT a, coalesce(b, 'foo') FROM collate_test1 ORDER BY 2;
222 SELECT a, coalesce(b, 'foo') FROM collate_test2 ORDER BY 2;
231 SELECT a, lower(coalesce(x, 'foo')), lower(coalesce(y, 'foo')) FROM collate_test10;
238 SELECT a, b, greatest(b, 'CCC') FROM collate_test1 ORDER BY 3;
247 SELECT a, b, greatest(b, 'CCC') FROM collate_test2 ORDER BY 3;
256 SELECT a, x, y, lower(greatest(x, 'foo')), lower(greatest(y, 'foo')) FROM collate_test10;
257 a | x | y | lower | lower
258 ---+-----+-----+-------+-------
259 1 | hij | hij | hij | hij
260 2 | HIJ | HIJ | foo | foo
263 SELECT a, nullif(b, 'abc') FROM collate_test1 ORDER BY 2;
272 SELECT a, nullif(b, 'abc') FROM collate_test2 ORDER BY 2;
281 SELECT a, lower(nullif(x, 'foo')), lower(nullif(y, 'foo')) FROM collate_test10;
288 SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2;
297 SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2;
306 CREATE DOMAIN testdomain AS text;
307 SELECT a, b::testdomain FROM collate_test1 ORDER BY 2;
316 SELECT a, b::testdomain FROM collate_test2 ORDER BY 2;
325 SELECT a, b::testdomain_p FROM collate_test2 ORDER BY 2;
334 SELECT a, lower(x::testdomain), lower(y::testdomain) FROM collate_test10;
341 SELECT min(b), max(b) FROM collate_test1;
347 SELECT min(b), max(b) FROM collate_test2;
353 SELECT array_agg(b ORDER BY b) FROM collate_test1;
359 SELECT array_agg(b ORDER BY b) FROM collate_test2;
365 -- In aggregates, ORDER BY expressions don't affect aggregate's collation
366 SELECT string_agg(x COLLATE "C", y COLLATE "POSIX") FROM collate_test10; -- fail
367 ERROR: collation mismatch between explicit collations "C" and "POSIX"
368 LINE 1: SELECT string_agg(x COLLATE "C", y COLLATE "POSIX") FROM col...
370 SELECT array_agg(x COLLATE "C" ORDER BY y COLLATE "POSIX") FROM collate_test10;
376 SELECT array_agg(a ORDER BY x COLLATE "C", y COLLATE "POSIX") FROM collate_test10;
382 SELECT array_agg(a ORDER BY x||y) FROM collate_test10; -- fail
383 ERROR: collation mismatch between implicit collations "C" and "POSIX"
384 LINE 1: SELECT array_agg(a ORDER BY x||y) FROM collate_test10;
386 HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
387 SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2;
400 SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2;
409 SELECT a, b FROM collate_test2 WHERE a < 4 INTERSECT SELECT a, b FROM collate_test2 WHERE a > 1 ORDER BY 2;
416 SELECT a, b FROM collate_test2 EXCEPT SELECT a, b FROM collate_test2 WHERE a < 2 ORDER BY 2;
424 SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
425 ERROR: could not determine which collation to use for string comparison
426 HINT: Use the COLLATE clause to set the collation explicitly.
427 SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2; -- ok
440 SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
441 ERROR: collation mismatch between implicit collations "C" and "POSIX"
442 LINE 1: SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collat...
444 HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
445 SELECT a, b COLLATE "C" FROM collate_test1 UNION SELECT a, b FROM collate_test2 ORDER BY 2; -- ok
454 SELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
455 ERROR: collation mismatch between implicit collations "C" and "POSIX"
456 LINE 1: ...ELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM col...
458 HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
459 SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
460 ERROR: collation mismatch between implicit collations "C" and "POSIX"
461 LINE 1: SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM colla...
463 HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
464 CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2; -- fail
465 ERROR: no collation was derived for column "b" with collatable type text
466 HINT: Use the COLLATE clause to set the collation explicitly.
467 -- ideally this would be a parse-time error, but for now it must be run-time:
468 select x < y from collate_test10; -- fail
469 ERROR: could not determine which collation to use for string comparison
470 HINT: Use the COLLATE clause to set the collation explicitly.
471 select x || y from collate_test10; -- ok, because || is not collation aware
478 select x, y from collate_test10 order by x || y; -- not so ok
479 ERROR: collation mismatch between implicit collations "C" and "POSIX"
480 LINE 1: select x, y from collate_test10 order by x || y;
482 HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
483 -- collation mismatch between recursive and non-recursive term
484 WITH RECURSIVE foo(x) AS
485 (SELECT x FROM (VALUES('a' COLLATE "C"),('b')) t(x)
487 SELECT (x || 'c') COLLATE "POSIX" FROM foo WHERE length(x) < 10)
489 ERROR: recursive query "foo" column 1 has collation "C" in non-recursive term but collation "POSIX" overall
490 LINE 2: (SELECT x FROM (VALUES('a' COLLATE "C"),('b')) t(x)
492 HINT: Use the COLLATE clause to set the collation of the non-recursive term.
493 SELECT a, b, a < b as lt FROM
494 (VALUES ('a', 'B'), ('A', 'b' COLLATE "C")) v(a,b);
501 -- collation mismatch in subselects
502 SELECT * FROM collate_test10 WHERE (x, y) NOT IN (SELECT y, x FROM collate_test10);
503 ERROR: could not determine which collation to use for string hashing
504 HINT: Use the COLLATE clause to set the collation explicitly.
505 -- now it works with overrides
506 SELECT * FROM collate_test10 WHERE (x COLLATE "POSIX", y COLLATE "C") NOT IN (SELECT y, x FROM collate_test10);
511 SELECT * FROM collate_test10 WHERE (x, y) NOT IN (SELECT y COLLATE "C", x COLLATE "POSIX" FROM collate_test10);
517 SELECT CAST('42' AS text COLLATE "C");
518 ERROR: syntax error at or near "COLLATE"
519 LINE 1: SELECT CAST('42' AS text COLLATE "C");
521 SELECT a, CAST(b AS varchar) FROM collate_test1 ORDER BY 2;
530 SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2;
539 -- result of a SQL function
540 CREATE FUNCTION vc (text) RETURNS text LANGUAGE sql
541 AS 'select $1::varchar';
542 SELECT a, b FROM collate_test1 ORDER BY a, vc(b);
552 SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1;
561 SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1;
570 CREATE FUNCTION dup (anyelement) RETURNS anyelement
571 AS 'select $1' LANGUAGE sql;
572 SELECT a, dup(b) FROM collate_test1 ORDER BY 2;
581 SELECT a, dup(b) FROM collate_test2 ORDER BY 2;
591 CREATE INDEX collate_test1_idx1 ON collate_test1 (b);
592 CREATE INDEX collate_test1_idx2 ON collate_test1 (b COLLATE "POSIX");
593 CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "POSIX")); -- this is different grammatically
594 CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX"));
595 CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "POSIX"); -- fail
596 ERROR: collations are not supported by type integer
597 CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "POSIX")); -- fail
598 ERROR: collations are not supported by type integer
599 LINE 1: ...ATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "P...
601 SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1;
602 relname | pg_get_indexdef
603 --------------------+-------------------------------------------------------------------------------------------------------------------
604 collate_test1_idx1 | CREATE INDEX collate_test1_idx1 ON collate_tests.collate_test1 USING btree (b)
605 collate_test1_idx2 | CREATE INDEX collate_test1_idx2 ON collate_tests.collate_test1 USING btree (b COLLATE "POSIX")
606 collate_test1_idx3 | CREATE INDEX collate_test1_idx3 ON collate_tests.collate_test1 USING btree (b COLLATE "POSIX")
607 collate_test1_idx4 | CREATE INDEX collate_test1_idx4 ON collate_tests.collate_test1 USING btree (((b || 'foo'::text)) COLLATE "POSIX")
611 -- force indexes and mergejoins to be used for FK checking queries,
612 -- else they might not exercise collation-dependent operators
613 SET enable_seqscan TO 0;
614 SET enable_hashjoin TO 0;
615 SET enable_nestloop TO 0;
616 CREATE TABLE collate_test20 (f1 text COLLATE "C" PRIMARY KEY);
617 INSERT INTO collate_test20 VALUES ('foo'), ('bar');
618 CREATE TABLE collate_test21 (f2 text COLLATE "POSIX" REFERENCES collate_test20);
619 INSERT INTO collate_test21 VALUES ('foo'), ('bar');
620 INSERT INTO collate_test21 VALUES ('baz'); -- fail
621 ERROR: insert or update on table "collate_test21" violates foreign key constraint "collate_test21_f2_fkey"
622 DETAIL: Key (f2)=(baz) is not present in table "collate_test20".
623 CREATE TABLE collate_test22 (f2 text COLLATE "POSIX");
624 INSERT INTO collate_test22 VALUES ('foo'), ('bar'), ('baz');
625 ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20; -- fail
626 ERROR: insert or update on table "collate_test22" violates foreign key constraint "collate_test22_f2_fkey"
627 DETAIL: Key (f2)=(baz) is not present in table "collate_test20".
628 DELETE FROM collate_test22 WHERE f2 = 'baz';
629 ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20;
630 RESET enable_seqscan;
631 RESET enable_hashjoin;
632 RESET enable_nestloop;
635 SELECT * FROM collate_test10 ORDER BY x, y;
637 ----------------------------------------------
639 Sort Key: x COLLATE "C", y COLLATE "POSIX"
640 -> Seq Scan on collate_test10
644 SELECT * FROM collate_test10 ORDER BY x DESC, y COLLATE "C" ASC NULLS FIRST;
646 -----------------------------------------------------------
648 Sort Key: x COLLATE "C" DESC, y COLLATE "C" NULLS FIRST
649 -> Seq Scan on collate_test10
652 -- CREATE/DROP COLLATION
653 CREATE COLLATION mycoll1 FROM "C";
654 CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
655 CREATE COLLATION mycoll3 FROM "default"; -- intentionally unsupported
656 ERROR: collation "default" cannot be copied
657 DROP COLLATION mycoll1;
658 CREATE TABLE collate_test23 (f1 text collate mycoll2);
659 DROP COLLATION mycoll2; -- fail
660 ERROR: cannot drop collation mycoll2 because other objects depend on it
661 DETAIL: column f1 of table collate_test23 depends on collation mycoll2
662 HINT: Use DROP ... CASCADE to drop the dependent objects too.
663 -- invalid: non-lowercase quoted identifiers
664 CREATE COLLATION case_coll ("Lc_Collate" = "POSIX", "Lc_Ctype" = "POSIX");
665 ERROR: collation attribute "Lc_Collate" not recognized
666 LINE 1: CREATE COLLATION case_coll ("Lc_Collate" = "POSIX", "Lc_Ctyp...
668 -- 9.1 bug with useless COLLATE in an expression subject to length coercion
669 CREATE TEMP TABLE vctable (f1 varchar(25));
670 INSERT INTO vctable VALUES ('foo' COLLATE "C");
671 SELECT collation for ('foo'); -- unknown type - null
677 SELECT collation for ('foo'::text);
683 SELECT collation for ((SELECT a FROM collate_test1 LIMIT 1)); -- non-collatable type - error
684 ERROR: collations are not supported by type integer
685 SELECT collation for ((SELECT b FROM collate_test1 LIMIT 1));
691 -- old bug with not dropping COLLATE when coercing to non-collatable type
692 CREATE VIEW collate_on_int AS
693 SELECT c1+1 AS c1p FROM
694 (SELECT ('4' COLLATE "C")::INT AS c1) ss;
696 View "collate_tests.collate_on_int"
697 Column | Type | Collation | Nullable | Default | Storage | Description
698 --------+---------+-----------+----------+---------+---------+-------------
699 c1p | integer | | | | plain |
701 SELECT ss.c1 + 1 AS c1p
702 FROM ( SELECT 4 AS c1) ss;
704 -- Check conflicting or redundant options in CREATE COLLATION
706 CREATE COLLATION coll_dup_chk (LC_COLLATE = "POSIX", LC_COLLATE = "NONSENSE", LC_CTYPE = "POSIX");
707 ERROR: conflicting or redundant options
708 LINE 1: ...ATE COLLATION coll_dup_chk (LC_COLLATE = "POSIX", LC_COLLATE...
711 CREATE COLLATION coll_dup_chk (LC_CTYPE = "POSIX", LC_CTYPE = "NONSENSE", LC_COLLATE = "POSIX");
712 ERROR: conflicting or redundant options
713 LINE 1: ...REATE COLLATION coll_dup_chk (LC_CTYPE = "POSIX", LC_CTYPE =...
716 CREATE COLLATION coll_dup_chk (PROVIDER = icu, PROVIDER = NONSENSE, LC_COLLATE = "POSIX", LC_CTYPE = "POSIX");
717 ERROR: conflicting or redundant options
718 LINE 1: CREATE COLLATION coll_dup_chk (PROVIDER = icu, PROVIDER = NO...
721 CREATE COLLATION case_sensitive (LOCALE = '', LOCALE = "NONSENSE");
722 ERROR: conflicting or redundant options
723 LINE 1: CREATE COLLATION case_sensitive (LOCALE = '', LOCALE = "NONS...
726 CREATE COLLATION coll_dup_chk (DETERMINISTIC = TRUE, DETERMINISTIC = NONSENSE, LOCALE = '');
727 ERROR: conflicting or redundant options
728 LINE 1: ...ATE COLLATION coll_dup_chk (DETERMINISTIC = TRUE, DETERMINIS...
731 CREATE COLLATION coll_dup_chk (VERSION = '1', VERSION = "NONSENSE", LOCALE = '');
732 ERROR: conflicting or redundant options
733 LINE 1: CREATE COLLATION coll_dup_chk (VERSION = '1', VERSION = "NON...
735 -- LOCALE conflicts with LC_COLLATE and LC_CTYPE
736 CREATE COLLATION coll_dup_chk (LC_COLLATE = "POSIX", LC_CTYPE = "POSIX", LOCALE = '');
737 ERROR: conflicting or redundant options
738 DETAIL: LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE.
739 -- LOCALE conflicts with LC_COLLATE
740 CREATE COLLATION coll_dup_chk (LC_COLLATE = "POSIX", LOCALE = '');
741 ERROR: conflicting or redundant options
742 DETAIL: LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE.
743 -- LOCALE conflicts with LC_CTYPE
744 CREATE COLLATION coll_dup_chk (LC_CTYPE = "POSIX", LOCALE = '');
745 ERROR: conflicting or redundant options
746 DETAIL: LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE.
747 -- FROM conflicts with any other option
748 CREATE COLLATION coll_dup_chk (FROM = "C", VERSION = "1");
749 ERROR: conflicting or redundant options
750 DETAIL: FROM cannot be specified together with any other options.
752 -- Clean up. Many of these table names will be re-used if the user is
753 -- trying to run any platform-specific collation tests later, so we
754 -- must get rid of them.
756 DROP SCHEMA collate_tests CASCADE;
757 NOTICE: drop cascades to 19 other objects
758 DETAIL: drop cascades to table collate_test1
759 drop cascades to table collate_test_like
760 drop cascades to table collate_test2
761 drop cascades to type testdomain_p
762 drop cascades to table collate_test4
763 drop cascades to table collate_test5
764 drop cascades to table collate_test10
765 drop cascades to view collview1
766 drop cascades to view collview2
767 drop cascades to view collview3
768 drop cascades to type testdomain
769 drop cascades to function vc(text)
770 drop cascades to function dup(anyelement)
771 drop cascades to table collate_test20
772 drop cascades to table collate_test21
773 drop cascades to table collate_test22
774 drop cascades to collation mycoll2
775 drop cascades to table collate_test23
776 drop cascades to view collate_on_int