Try to deliver a sane message for _create_locale() failure on Windows.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 1 Aug 2017 20:11:51 +0000 (16:11 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 1 Aug 2017 20:11:51 +0000 (16:11 -0400)
We were just printing errno, which is certainly not gonna work on
Windows.  Now, it's not entirely clear from Microsoft's documentation
whether _create_locale() adheres to standard Windows error reporting
conventions, but let's assume it does and try to map the GetLastError
result to an errno.  If this turns out not to work, probably the best
thing to do will be to assume the error is always ENOENT on Windows.

This is a longstanding bug, but given the lack of previous field
complaints, I'm not excited about back-patching it.

Per report from Murtuza Zabuawala.

Discussion: https://postgr.es/m/CAKKotZS-wcDcofXDCH=sidiuajE+nqHn2CGjLLX78anyDmi3gQ@mail.gmail.com

src/backend/utils/adt/pg_locale.c
src/test/regress/expected/collate.out
src/test/regress/sql/collate.sql

index 12419fc8df9089bd86e0278103eb65a51b94305f..9500c6b39f851052be068a9420b278a49f965d6d 100644 (file)
@@ -1227,13 +1227,18 @@ lc_ctype_is_c(Oid collation)
 static void
 report_newlocale_failure(const char *localename)
 {
-   /* copy errno in case one of the ereport auxiliary functions changes it */
-   int         save_errno = errno;
+   int         save_errno;
+
+   /* On Windows, transform _create_locale() error to errno */
+#ifdef WIN32
+   _dosmaperr(GetLastError());
+#endif
 
    /*
     * ENOENT means "no such locale", not "no such file", so clarify that
     * errno with an errdetail message.
     */
+   save_errno = errno;         /* auxiliary funcs might change errno */
    ereport(ERROR,
            (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
             errmsg("could not create locale \"%s\": %m",
index b0025c0a87e80b07a35bf1fa64de29e619d9937e..70866df000b92dce7dc23950b6c2350268b0f20d 100644 (file)
@@ -627,6 +627,9 @@ CREATE COLLATION mycoll1 FROM "C";
 CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
 CREATE COLLATION mycoll3 FROM "default";  -- intentionally unsupported
 ERROR:  collation "default" cannot be copied
+CREATE COLLATION mycoll4 ( LOCALE = "no_such_locale" );  -- fail
+ERROR:  could not create locale "no_such_locale": No such file or directory
+DETAIL:  The operating system could not find any locale data for the locale name "no_such_locale".
 DROP COLLATION mycoll1;
 CREATE TABLE collate_test23 (f1 text collate mycoll2);
 DROP COLLATION mycoll2;  -- fail
index 698f57749068ba8b05f5c0647010ab46a4d4b86c..f095ae08be777b03afc5ab56fd7e1f0b3906be97 100644 (file)
@@ -234,6 +234,7 @@ EXPLAIN (COSTS OFF)
 CREATE COLLATION mycoll1 FROM "C";
 CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
 CREATE COLLATION mycoll3 FROM "default";  -- intentionally unsupported
+CREATE COLLATION mycoll4 ( LOCALE = "no_such_locale" );  -- fail
 
 DROP COLLATION mycoll1;
 CREATE TABLE collate_test23 (f1 text collate mycoll2);