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 | Modifiers
21 --------+---------+--------------------
23 b | text | collate 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 | Modifiers
38 --------+---------+--------------------
40 b | text | collate 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, collate_test1.b FROM collate_test1 WHERE ((collate_test1.b COLLATE "C") >= 'bbc'::text);
200 collview2 | SELECT collate_test1.a, collate_test1.b FROM collate_test1 ORDER BY (collate_test1.b COLLATE "C");
201 collview3 | SELECT collate_test10.a, lower(((collate_test10.x || collate_test10.x) COLLATE "POSIX")) AS lower FROM collate_test10;
204 -- collation propagation in various expression type
205 SELECT a, coalesce(b, 'foo') FROM collate_test1 ORDER BY 2;
214 SELECT a, coalesce(b, 'foo') FROM collate_test2 ORDER BY 2;
223 SELECT a, lower(coalesce(x, 'foo')), lower(coalesce(y, 'foo')) FROM collate_test10;
230 SELECT a, b, greatest(b, 'CCC') FROM collate_test1 ORDER BY 3;
239 SELECT a, b, greatest(b, 'CCC') FROM collate_test2 ORDER BY 3;
248 SELECT a, x, y, lower(greatest(x, 'foo')), lower(greatest(y, 'foo')) FROM collate_test10;
249 a | x | y | lower | lower
250 ---+-----+-----+-------+-------
251 1 | hij | hij | hij | hij
252 2 | HIJ | HIJ | foo | foo
255 SELECT a, nullif(b, 'abc') FROM collate_test1 ORDER BY 2;
264 SELECT a, nullif(b, 'abc') FROM collate_test2 ORDER BY 2;
273 SELECT a, lower(nullif(x, 'foo')), lower(nullif(y, 'foo')) FROM collate_test10;
280 SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2;
289 SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2;
298 CREATE DOMAIN testdomain AS text;
299 SELECT a, b::testdomain FROM collate_test1 ORDER BY 2;
308 SELECT a, b::testdomain FROM collate_test2 ORDER BY 2;
317 SELECT a, b::testdomain_p FROM collate_test2 ORDER BY 2;
326 SELECT a, lower(x::testdomain), lower(y::testdomain) FROM collate_test10;
333 SELECT min(b), max(b) FROM collate_test1;
339 SELECT min(b), max(b) FROM collate_test2;
345 SELECT array_agg(b ORDER BY b) FROM collate_test1;
351 SELECT array_agg(b ORDER BY b) FROM collate_test2;
357 SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2;
370 SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2;
379 SELECT a, b FROM collate_test2 WHERE a < 4 INTERSECT SELECT a, b FROM collate_test2 WHERE a > 1 ORDER BY 2;
386 SELECT a, b FROM collate_test2 EXCEPT SELECT a, b FROM collate_test2 WHERE a < 2 ORDER BY 2;
394 SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
395 ERROR: could not determine which collation to use for string comparison
396 HINT: Use the COLLATE clause to set the collation explicitly.
397 SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2; -- ok
410 SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
411 ERROR: collation mismatch between implicit collations "C" and "POSIX"
412 LINE 1: SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collat...
414 HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
415 SELECT a, b COLLATE "C" FROM collate_test1 UNION SELECT a, b FROM collate_test2 ORDER BY 2; -- ok
424 SELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
425 ERROR: collation mismatch between implicit collations "C" and "POSIX"
426 LINE 1: ...ELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM col...
428 HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
429 SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
430 ERROR: collation mismatch between implicit collations "C" and "POSIX"
431 LINE 1: SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM colla...
433 HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
434 CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2; -- fail
435 ERROR: no collation was derived for column "b" with collatable type text
436 HINT: Use the COLLATE clause to set the collation explicitly.
437 -- ideally this would be a parse-time error, but for now it must be run-time:
438 select x < y from collate_test10; -- fail
439 ERROR: could not determine which collation to use for string comparison
440 HINT: Use the COLLATE clause to set the collation explicitly.
441 select x || y from collate_test10; -- ok, because || is not collation aware
448 select x, y from collate_test10 order by x || y; -- not so ok
449 ERROR: collation mismatch between implicit collations "C" and "POSIX"
450 LINE 1: select x, y from collate_test10 order by x || y;
452 HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
453 -- collation mismatch between recursive and non-recursive term
454 WITH RECURSIVE foo(x) AS
455 (SELECT x FROM (VALUES('a' COLLATE "C"),('b')) t(x)
457 SELECT (x || 'c') COLLATE "POSIX" FROM foo WHERE length(x) < 10)
459 ERROR: recursive query "foo" column 1 has collation "C" in non-recursive term but collation "POSIX" overall
460 LINE 2: (SELECT x FROM (VALUES('a' COLLATE "C"),('b')) t(x)
462 HINT: Use the COLLATE clause to set the collation of the non-recursive term.
464 SELECT CAST('42' AS text COLLATE "C");
465 ERROR: syntax error at or near "COLLATE"
466 LINE 1: SELECT CAST('42' AS text COLLATE "C");
468 SELECT a, CAST(b AS varchar) FROM collate_test1 ORDER BY 2;
477 SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2;
487 SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1;
496 SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1;
505 CREATE FUNCTION dup (anyelement) RETURNS anyelement
506 AS 'select $1' LANGUAGE sql;
507 SELECT a, dup(b) FROM collate_test1 ORDER BY 2;
516 SELECT a, dup(b) FROM collate_test2 ORDER BY 2;
526 CREATE INDEX collate_test1_idx1 ON collate_test1 (b);
527 CREATE INDEX collate_test1_idx2 ON collate_test1 (b COLLATE "POSIX");
528 CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "POSIX")); -- this is different grammatically
529 CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX"));
530 CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "POSIX"); -- fail
531 ERROR: collations are not supported by type integer
532 CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "POSIX")); -- fail
533 ERROR: collations are not supported by type integer
534 LINE 1: ...ATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "P...
536 SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1;
537 relname | pg_get_indexdef
538 --------------------+-----------------------------------------------------------------------------------------------------
539 collate_test1_idx1 | CREATE INDEX collate_test1_idx1 ON collate_test1 USING btree (b)
540 collate_test1_idx2 | CREATE INDEX collate_test1_idx2 ON collate_test1 USING btree (b COLLATE "POSIX")
541 collate_test1_idx3 | CREATE INDEX collate_test1_idx3 ON collate_test1 USING btree (b COLLATE "POSIX")
542 collate_test1_idx4 | CREATE INDEX collate_test1_idx4 ON collate_test1 USING btree (((b || 'foo'::text)) COLLATE "POSIX")
546 -- Clean up. Many of these table names will be re-used if the user is
547 -- trying to run any platform-specific collation tests later, so we
548 -- must get rid of them.
550 DROP SCHEMA collate_tests CASCADE;
551 NOTICE: drop cascades to 12 other objects
552 DETAIL: drop cascades to table collate_test1
553 drop cascades to table collate_test_like
554 drop cascades to table collate_test2
555 drop cascades to type testdomain_p
556 drop cascades to table collate_test4
557 drop cascades to table collate_test5
558 drop cascades to table collate_test10
559 drop cascades to view collview1
560 drop cascades to view collview2
561 drop cascades to view collview3
562 drop cascades to type testdomain
563 drop cascades to function dup(anyelement)