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 LINE 1: CREATE DOMAIN testdomain_i AS int COLLATE "POSIX";
78 CREATE TABLE collate_test4 (
82 INSERT INTO collate_test4 SELECT * FROM collate_test1;
83 SELECT a, b FROM collate_test4 ORDER BY b;
92 CREATE TABLE collate_test5 (
94 b testdomain_p COLLATE "C"
96 INSERT INTO collate_test5 SELECT * FROM collate_test1;
97 SELECT a, b FROM collate_test5 ORDER BY b;
106 SELECT a, b FROM collate_test1 ORDER BY b;
115 SELECT a, b FROM collate_test2 ORDER BY b;
124 SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C";
134 SELECT * FROM collate_test1 ORDER BY b;
143 SELECT * FROM collate_test2 ORDER BY b;
152 -- constant expression folding
153 SELECT 'bbc' COLLATE "C" > 'Abc' COLLATE "C" AS "true";
159 SELECT 'bbc' COLLATE "POSIX" < 'Abc' COLLATE "POSIX" AS "false";
166 CREATE TABLE collate_test10 (
169 y text COLLATE "POSIX"
171 INSERT INTO collate_test10 VALUES (1, 'hij', 'hij'), (2, 'HIJ', 'HIJ');
172 SELECT a, lower(x), lower(y), upper(x), upper(y), initcap(x), initcap(y) FROM collate_test10;
173 a | lower | lower | upper | upper | initcap | initcap
174 ---+-------+-------+-------+-------+---------+---------
175 1 | hij | hij | HIJ | HIJ | Hij | Hij
176 2 | hij | hij | HIJ | HIJ | Hij | Hij
179 SELECT a, lower(x COLLATE "C"), lower(y COLLATE "C") FROM collate_test10;
186 SELECT a, x, y FROM collate_test10 ORDER BY lower(y), a;
194 CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc';
195 CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C";
196 CREATE VIEW collview3 AS SELECT a, lower((x || x) COLLATE "POSIX") FROM collate_test10;
197 SELECT table_name, view_definition FROM information_schema.views
198 WHERE table_name LIKE 'collview%' ORDER BY 1;
199 table_name | view_definition
200 ------------+------------------------------------------------
201 collview1 | SELECT a, +
203 | FROM collate_test1 +
204 | WHERE ((b COLLATE "C") >= 'bbc'::text);
205 collview2 | SELECT a, +
207 | FROM collate_test1 +
208 | ORDER BY (b COLLATE "C");
209 collview3 | SELECT a, +
210 | lower(((x || x) COLLATE "POSIX")) AS lower+
211 | FROM collate_test10;
214 -- collation propagation in various expression types
215 SELECT a, coalesce(b, 'foo') FROM collate_test1 ORDER BY 2;
224 SELECT a, coalesce(b, 'foo') FROM collate_test2 ORDER BY 2;
233 SELECT a, lower(coalesce(x, 'foo')), lower(coalesce(y, 'foo')) FROM collate_test10;
240 SELECT a, b, greatest(b, 'CCC') FROM collate_test1 ORDER BY 3;
249 SELECT a, b, greatest(b, 'CCC') FROM collate_test2 ORDER BY 3;
258 SELECT a, x, y, lower(greatest(x, 'foo')), lower(greatest(y, 'foo')) FROM collate_test10;
259 a | x | y | lower | lower
260 ---+-----+-----+-------+-------
261 1 | hij | hij | hij | hij
262 2 | HIJ | HIJ | foo | foo
265 SELECT a, nullif(b, 'abc') FROM collate_test1 ORDER BY 2;
274 SELECT a, nullif(b, 'abc') FROM collate_test2 ORDER BY 2;
283 SELECT a, lower(nullif(x, 'foo')), lower(nullif(y, 'foo')) FROM collate_test10;
290 SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2;
299 SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2;
308 CREATE DOMAIN testdomain AS text;
309 SELECT a, b::testdomain FROM collate_test1 ORDER BY 2;
318 SELECT a, b::testdomain FROM collate_test2 ORDER BY 2;
327 SELECT a, b::testdomain_p FROM collate_test2 ORDER BY 2;
336 SELECT a, lower(x::testdomain), lower(y::testdomain) FROM collate_test10;
343 SELECT min(b), max(b) FROM collate_test1;
349 SELECT min(b), max(b) FROM collate_test2;
355 SELECT array_agg(b ORDER BY b) FROM collate_test1;
361 SELECT array_agg(b ORDER BY b) FROM collate_test2;
367 -- In aggregates, ORDER BY expressions don't affect aggregate's collation
368 SELECT string_agg(x COLLATE "C", y COLLATE "POSIX") FROM collate_test10; -- fail
369 ERROR: collation mismatch between explicit collations "C" and "POSIX"
370 LINE 1: SELECT string_agg(x COLLATE "C", y COLLATE "POSIX") FROM col...
372 SELECT array_agg(x COLLATE "C" ORDER BY y COLLATE "POSIX") FROM collate_test10;
378 SELECT array_agg(a ORDER BY x COLLATE "C", y COLLATE "POSIX") FROM collate_test10;
384 SELECT array_agg(a ORDER BY x||y) FROM collate_test10; -- fail
385 ERROR: collation mismatch between implicit collations "C" and "POSIX"
386 LINE 1: SELECT array_agg(a ORDER BY x||y) FROM collate_test10;
388 HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
389 SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2;
402 SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2;
411 SELECT a, b FROM collate_test2 WHERE a < 4 INTERSECT SELECT a, b FROM collate_test2 WHERE a > 1 ORDER BY 2;
418 SELECT a, b FROM collate_test2 EXCEPT SELECT a, b FROM collate_test2 WHERE a < 2 ORDER BY 2;
426 SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
427 ERROR: could not determine which collation to use for string comparison
428 HINT: Use the COLLATE clause to set the collation explicitly.
429 SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2; -- ok
442 SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
443 ERROR: collation mismatch between implicit collations "C" and "POSIX"
444 LINE 1: SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collat...
446 HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
447 SELECT a, b COLLATE "C" FROM collate_test1 UNION SELECT a, b FROM collate_test2 ORDER BY 2; -- ok
456 SELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
457 ERROR: collation mismatch between implicit collations "C" and "POSIX"
458 LINE 1: ...ELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM col...
460 HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
461 SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
462 ERROR: collation mismatch between implicit collations "C" and "POSIX"
463 LINE 1: SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM colla...
465 HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
466 CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2; -- fail
467 ERROR: no collation was derived for column "b" with collatable type text
468 HINT: Use the COLLATE clause to set the collation explicitly.
469 -- ideally this would be a parse-time error, but for now it must be run-time:
470 select x < y from collate_test10; -- fail
471 ERROR: could not determine which collation to use for string comparison
472 HINT: Use the COLLATE clause to set the collation explicitly.
473 select x || y from collate_test10; -- ok, because || is not collation aware
480 select x, y from collate_test10 order by x || y; -- not so ok
481 ERROR: collation mismatch between implicit collations "C" and "POSIX"
482 LINE 1: select x, y from collate_test10 order by x || y;
484 HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
485 -- collation mismatch between recursive and non-recursive term
486 WITH RECURSIVE foo(x) AS
487 (SELECT x FROM (VALUES('a' COLLATE "C"),('b')) t(x)
489 SELECT (x || 'c') COLLATE "POSIX" FROM foo WHERE length(x) < 10)
491 ERROR: recursive query "foo" column 1 has collation "C" in non-recursive term but collation "POSIX" overall
492 LINE 2: (SELECT x FROM (VALUES('a' COLLATE "C"),('b')) t(x)
494 HINT: Use the COLLATE clause to set the collation of the non-recursive term.
495 SELECT a, b, a < b as lt FROM
496 (VALUES ('a', 'B'), ('A', 'b' COLLATE "C")) v(a,b);
503 -- collation mismatch in subselects
504 SELECT * FROM collate_test10 WHERE (x, y) NOT IN (SELECT y, x FROM collate_test10);
505 ERROR: could not determine which collation to use for string hashing
506 HINT: Use the COLLATE clause to set the collation explicitly.
507 -- now it works with overrides
508 SELECT * FROM collate_test10 WHERE (x COLLATE "POSIX", y COLLATE "C") NOT IN (SELECT y, x FROM collate_test10);
513 SELECT * FROM collate_test10 WHERE (x, y) NOT IN (SELECT y COLLATE "C", x COLLATE "POSIX" FROM collate_test10);
519 SELECT CAST('42' AS text COLLATE "C");
520 ERROR: syntax error at or near "COLLATE"
521 LINE 1: SELECT CAST('42' AS text COLLATE "C");
523 SELECT a, CAST(b AS varchar) FROM collate_test1 ORDER BY 2;
532 SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2;
541 -- result of a SQL function
542 CREATE FUNCTION vc (text) RETURNS text LANGUAGE sql
543 AS 'select $1::varchar';
544 SELECT a, b FROM collate_test1 ORDER BY a, vc(b);
554 SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1;
563 SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1;
572 CREATE FUNCTION dup (anyelement) RETURNS anyelement
573 AS 'select $1' LANGUAGE sql;
574 SELECT a, dup(b) FROM collate_test1 ORDER BY 2;
583 SELECT a, dup(b) FROM collate_test2 ORDER BY 2;
593 CREATE INDEX collate_test1_idx1 ON collate_test1 (b);
594 CREATE INDEX collate_test1_idx2 ON collate_test1 (b COLLATE "POSIX");
595 CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "POSIX")); -- this is different grammatically
596 CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX"));
597 CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "POSIX"); -- fail
598 ERROR: collations are not supported by type integer
599 CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "POSIX")); -- fail
600 ERROR: collations are not supported by type integer
601 LINE 1: ...ATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "P...
603 SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1;
604 relname | pg_get_indexdef
605 --------------------+-------------------------------------------------------------------------------------------------------------------
606 collate_test1_idx1 | CREATE INDEX collate_test1_idx1 ON collate_tests.collate_test1 USING btree (b)
607 collate_test1_idx2 | CREATE INDEX collate_test1_idx2 ON collate_tests.collate_test1 USING btree (b COLLATE "POSIX")
608 collate_test1_idx3 | CREATE INDEX collate_test1_idx3 ON collate_tests.collate_test1 USING btree (b COLLATE "POSIX")
609 collate_test1_idx4 | CREATE INDEX collate_test1_idx4 ON collate_tests.collate_test1 USING btree (((b || 'foo'::text)) COLLATE "POSIX")
613 -- force indexes and mergejoins to be used for FK checking queries,
614 -- else they might not exercise collation-dependent operators
615 SET enable_seqscan TO 0;
616 SET enable_hashjoin TO 0;
617 SET enable_nestloop TO 0;
618 CREATE TABLE collate_test20 (f1 text COLLATE "C" PRIMARY KEY);
619 INSERT INTO collate_test20 VALUES ('foo'), ('bar');
620 CREATE TABLE collate_test21 (f2 text COLLATE "POSIX" REFERENCES collate_test20);
621 INSERT INTO collate_test21 VALUES ('foo'), ('bar');
622 INSERT INTO collate_test21 VALUES ('baz'); -- fail
623 ERROR: insert or update on table "collate_test21" violates foreign key constraint "collate_test21_f2_fkey"
624 DETAIL: Key (f2)=(baz) is not present in table "collate_test20".
625 CREATE TABLE collate_test22 (f2 text COLLATE "POSIX");
626 INSERT INTO collate_test22 VALUES ('foo'), ('bar'), ('baz');
627 ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20; -- fail
628 ERROR: insert or update on table "collate_test22" violates foreign key constraint "collate_test22_f2_fkey"
629 DETAIL: Key (f2)=(baz) is not present in table "collate_test20".
630 DELETE FROM collate_test22 WHERE f2 = 'baz';
631 ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20;
632 RESET enable_seqscan;
633 RESET enable_hashjoin;
634 RESET enable_nestloop;
637 SELECT * FROM collate_test10 ORDER BY x, y;
639 ----------------------------------------------
641 Sort Key: x COLLATE "C", y COLLATE "POSIX"
642 -> Seq Scan on collate_test10
646 SELECT * FROM collate_test10 ORDER BY x DESC, y COLLATE "C" ASC NULLS FIRST;
648 -----------------------------------------------------------
650 Sort Key: x COLLATE "C" DESC, y COLLATE "C" NULLS FIRST
651 -> Seq Scan on collate_test10
654 -- CREATE/DROP COLLATION
655 CREATE COLLATION builtin_c ( PROVIDER = builtin, LOCALE = "C" );
656 SELECT b FROM collate_test1 ORDER BY b COLLATE builtin_c;
665 CREATE COLLATION builtin2 ( PROVIDER = builtin ); -- fails
666 ERROR: parameter "locale" must be specified
667 CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "en_US" ); -- fails
668 ERROR: invalid locale name "en_US" for builtin provider
669 CREATE COLLATION builtin2 ( PROVIDER = builtin, LC_CTYPE = "C", LC_COLLATE = "C" ); -- fails
670 ERROR: parameter "locale" must be specified
671 CREATE COLLATION mycoll1 FROM "C";
672 CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
673 CREATE COLLATION mycoll3 FROM "default"; -- intentionally unsupported
674 ERROR: collation "default" cannot be copied
675 DROP COLLATION mycoll1;
676 CREATE TABLE collate_test23 (f1 text collate mycoll2);
677 DROP COLLATION mycoll2; -- fail
678 ERROR: cannot drop collation mycoll2 because other objects depend on it
679 DETAIL: column f1 of table collate_test23 depends on collation mycoll2
680 HINT: Use DROP ... CASCADE to drop the dependent objects too.
681 -- invalid: non-lowercase quoted identifiers
682 CREATE COLLATION case_coll ("Lc_Collate" = "POSIX", "Lc_Ctype" = "POSIX");
683 ERROR: collation attribute "Lc_Collate" not recognized
684 LINE 1: CREATE COLLATION case_coll ("Lc_Collate" = "POSIX", "Lc_Ctyp...
686 -- 9.1 bug with useless COLLATE in an expression subject to length coercion
687 CREATE TEMP TABLE vctable (f1 varchar(25));
688 INSERT INTO vctable VALUES ('foo' COLLATE "C");
689 SELECT collation for ('foo'); -- unknown type - null
695 SELECT collation for ('foo'::text);
701 SELECT collation for ((SELECT a FROM collate_test1 LIMIT 1)); -- non-collatable type - error
702 ERROR: collations are not supported by type integer
703 SELECT collation for ((SELECT b FROM collate_test1 LIMIT 1));
709 -- old bug with not dropping COLLATE when coercing to non-collatable type
710 CREATE VIEW collate_on_int AS
711 SELECT c1+1 AS c1p FROM
712 (SELECT ('4' COLLATE "C")::INT AS c1) ss;
714 View "collate_tests.collate_on_int"
715 Column | Type | Collation | Nullable | Default | Storage | Description
716 --------+---------+-----------+----------+---------+---------+-------------
717 c1p | integer | | | | plain |
720 FROM ( SELECT 4 AS c1) ss;
722 -- Check conflicting or redundant options in CREATE COLLATION
724 CREATE COLLATION coll_dup_chk (LC_COLLATE = "POSIX", LC_COLLATE = "NONSENSE", LC_CTYPE = "POSIX");
725 ERROR: conflicting or redundant options
726 LINE 1: ...ATE COLLATION coll_dup_chk (LC_COLLATE = "POSIX", LC_COLLATE...
729 CREATE COLLATION coll_dup_chk (LC_CTYPE = "POSIX", LC_CTYPE = "NONSENSE", LC_COLLATE = "POSIX");
730 ERROR: conflicting or redundant options
731 LINE 1: ...REATE COLLATION coll_dup_chk (LC_CTYPE = "POSIX", LC_CTYPE =...
734 CREATE COLLATION coll_dup_chk (PROVIDER = icu, PROVIDER = NONSENSE, LC_COLLATE = "POSIX", LC_CTYPE = "POSIX");
735 ERROR: conflicting or redundant options
736 LINE 1: CREATE COLLATION coll_dup_chk (PROVIDER = icu, PROVIDER = NO...
739 CREATE COLLATION case_sensitive (LOCALE = '', LOCALE = "NONSENSE");
740 ERROR: conflicting or redundant options
741 LINE 1: CREATE COLLATION case_sensitive (LOCALE = '', LOCALE = "NONS...
744 CREATE COLLATION coll_dup_chk (DETERMINISTIC = TRUE, DETERMINISTIC = NONSENSE, LOCALE = '');
745 ERROR: conflicting or redundant options
746 LINE 1: ...ATE COLLATION coll_dup_chk (DETERMINISTIC = TRUE, DETERMINIS...
749 CREATE COLLATION coll_dup_chk (VERSION = '1', VERSION = "NONSENSE", LOCALE = '');
750 ERROR: conflicting or redundant options
751 LINE 1: CREATE COLLATION coll_dup_chk (VERSION = '1', VERSION = "NON...
753 -- LOCALE conflicts with LC_COLLATE and LC_CTYPE
754 CREATE COLLATION coll_dup_chk (LC_COLLATE = "POSIX", LC_CTYPE = "POSIX", LOCALE = '');
755 ERROR: conflicting or redundant options
756 DETAIL: LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE.
757 -- LOCALE conflicts with LC_COLLATE
758 CREATE COLLATION coll_dup_chk (LC_COLLATE = "POSIX", LOCALE = '');
759 ERROR: conflicting or redundant options
760 DETAIL: LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE.
761 -- LOCALE conflicts with LC_CTYPE
762 CREATE COLLATION coll_dup_chk (LC_CTYPE = "POSIX", LOCALE = '');
763 ERROR: conflicting or redundant options
764 DETAIL: LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE.
765 -- FROM conflicts with any other option
766 CREATE COLLATION coll_dup_chk (FROM = "C", VERSION = "1");
767 ERROR: conflicting or redundant options
768 DETAIL: FROM cannot be specified together with any other options.
770 -- Clean up. Many of these table names will be re-used if the user is
771 -- trying to run any platform-specific collation tests later, so we
772 -- must get rid of them.
774 DROP SCHEMA collate_tests CASCADE;
775 NOTICE: drop cascades to 20 other objects
776 DETAIL: drop cascades to table collate_test1
777 drop cascades to table collate_test_like
778 drop cascades to table collate_test2
779 drop cascades to type testdomain_p
780 drop cascades to table collate_test4
781 drop cascades to table collate_test5
782 drop cascades to table collate_test10
783 drop cascades to view collview1
784 drop cascades to view collview2
785 drop cascades to view collview3
786 drop cascades to type testdomain
787 drop cascades to function vc(text)
788 drop cascades to function dup(anyelement)
789 drop cascades to table collate_test20
790 drop cascades to table collate_test21
791 drop cascades to table collate_test22
792 drop cascades to collation builtin_c
793 drop cascades to collation mycoll2
794 drop cascades to table collate_test23
795 drop cascades to view collate_on_int