Skip to content

Commit f972565

Browse files
committed
Allow creation of C/POSIX collations without depending on libc behavior.
Most of our collations code has special handling for the locale names "C" and "POSIX", allowing those collations to be used whether or not the system libraries think those locale names are valid, or indeed whether said libraries even have any locale support. But we missed handling things that way in CREATE COLLATION. This meant you couldn't clone the C/POSIX collations, nor explicitly define a new collation using those locale names, unless the libraries allow it. That's pretty pointless, as well as being a violation of pg_newlocale_from_collation's API specification. The practical effect of this change is quite limited: it allows creating such collations even on platforms that don't HAVE_LOCALE_T, and it allows making "POSIX" collation objects on Windows, which before this would only let you make "C" collation objects. Hence, even though this is a bug fix IMO, it doesn't seem worth the trouble to back-patch. In passing, suppress the DROP CASCADE detail messages at the end of the collation regression test. I'm surprised we've never been bit by message ordering issues there. Per report from Murtuza Zabuawala. Discussion: https://postgr.es/m/CAKKotZS-wcDcofXDCH=sidiuajE+nqHn2CGjLLX78anyDmi3gQ@mail.gmail.com
1 parent b21c569 commit f972565

File tree

3 files changed

+33
-20
lines changed

3 files changed

+33
-20
lines changed

src/backend/commands/collationcmds.c

+8-4
Original file line numberDiff line numberDiff line change
@@ -214,11 +214,15 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
214214
if (!OidIsValid(newoid))
215215
return InvalidObjectAddress;
216216

217-
ObjectAddressSet(address, CollationRelationId, newoid);
218-
219-
/* check that the locales can be loaded */
217+
/*
218+
* Check that the locales can be loaded. NB: pg_newlocale_from_collation
219+
* is only supposed to be called on non-C-equivalent locales.
220+
*/
220221
CommandCounterIncrement();
221-
(void) pg_newlocale_from_collation(newoid);
222+
if (!lc_collate_is_c(newoid) || !lc_ctype_is_c(newoid))
223+
(void) pg_newlocale_from_collation(newoid);
224+
225+
ObjectAddressSet(address, CollationRelationId, newoid);
222226

223227
return address;
224228
}

src/test/regress/expected/collate.out

+13-16
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,17 @@ EXPLAIN (COSTS OFF)
622622
-> Seq Scan on collate_test10
623623
(3 rows)
624624

625+
-- CREATE/DROP COLLATION
626+
CREATE COLLATION mycoll1 FROM "C";
627+
CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
628+
CREATE COLLATION mycoll3 FROM "default"; -- intentionally unsupported
629+
ERROR: collation "default" cannot be copied
630+
DROP COLLATION mycoll1;
631+
CREATE TABLE collate_test23 (f1 text collate mycoll2);
632+
DROP COLLATION mycoll2; -- fail
633+
ERROR: cannot drop collation mycoll2 because other objects depend on it
634+
DETAIL: table collate_test23 column f1 depends on collation mycoll2
635+
HINT: Use DROP ... CASCADE to drop the dependent objects too.
625636
-- 9.1 bug with useless COLLATE in an expression subject to length coercion
626637
CREATE TEMP TABLE vctable (f1 varchar(25));
627638
INSERT INTO vctable VALUES ('foo' COLLATE "C");
@@ -650,20 +661,6 @@ SELECT collation for ((SELECT b FROM collate_test1 LIMIT 1));
650661
-- trying to run any platform-specific collation tests later, so we
651662
-- must get rid of them.
652663
--
664+
\set VERBOSITY terse
653665
DROP SCHEMA collate_tests CASCADE;
654-
NOTICE: drop cascades to 15 other objects
655-
DETAIL: drop cascades to table collate_test1
656-
drop cascades to table collate_test_like
657-
drop cascades to table collate_test2
658-
drop cascades to type testdomain_p
659-
drop cascades to table collate_test4
660-
drop cascades to table collate_test5
661-
drop cascades to table collate_test10
662-
drop cascades to view collview1
663-
drop cascades to view collview2
664-
drop cascades to view collview3
665-
drop cascades to type testdomain
666-
drop cascades to function dup(anyelement)
667-
drop cascades to table collate_test20
668-
drop cascades to table collate_test21
669-
drop cascades to table collate_test22
666+
NOTICE: drop cascades to 17 other objects

src/test/regress/sql/collate.sql

+12
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,17 @@ EXPLAIN (COSTS OFF)
229229
SELECT * FROM collate_test10 ORDER BY x DESC, y COLLATE "C" ASC NULLS FIRST;
230230

231231

232+
-- CREATE/DROP COLLATION
233+
234+
CREATE COLLATION mycoll1 FROM "C";
235+
CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
236+
CREATE COLLATION mycoll3 FROM "default"; -- intentionally unsupported
237+
238+
DROP COLLATION mycoll1;
239+
CREATE TABLE collate_test23 (f1 text collate mycoll2);
240+
DROP COLLATION mycoll2; -- fail
241+
242+
232243
-- 9.1 bug with useless COLLATE in an expression subject to length coercion
233244

234245
CREATE TEMP TABLE vctable (f1 varchar(25));
@@ -246,4 +257,5 @@ SELECT collation for ((SELECT b FROM collate_test1 LIMIT 1));
246257
-- trying to run any platform-specific collation tests later, so we
247258
-- must get rid of them.
248259
--
260+
\set VERBOSITY terse
249261
DROP SCHEMA collate_tests CASCADE;

0 commit comments

Comments
 (0)