Blind attempt to fix _configthreadlocale() failures on MinGW.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 24 Jan 2019 03:46:45 +0000 (22:46 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 24 Jan 2019 03:46:45 +0000 (22:46 -0500)
Apparently, some builds of MinGW contain a version of
_configthreadlocale() that always returns -1, indicating failure.
Rather than treating that as a curl-up-and-die condition, soldier on
as though the function didn't exist.  This leaves us without thread
safety on such MinGW versions, but we didn't have it anyway.

Discussion: https://postgr.es/m/d06a16bc-52d6-9f0d-2379-21242d7dbe81@2ndQuadrant.com

src/interfaces/ecpg/ecpglib/descriptor.c
src/interfaces/ecpg/ecpglib/execute.c

index aeb33636607911eb3fc6c2236740b8e647ac6294..5fca4dde20dca7c61bb57a76dd622bd4be40ab0c 100644 (file)
@@ -519,7 +519,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
        }
 #ifdef HAVE__CONFIGTHREADLOCALE
        if (stmt.oldthreadlocale != -1)
-           _configthreadlocale(stmt.oldthreadlocale);
+           (void) _configthreadlocale(stmt.oldthreadlocale);
 #endif
 #endif
    }
index a9f945e6188d65706ec09f78fe05f0c0c2fa6d66..e25f7ebf825b7ef409a3aa46c7f1e6ad4217156b 100644 (file)
@@ -1778,7 +1778,9 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
     * Make sure we do NOT honor the locale for numeric input/output since the
     * database wants the standard decimal point.  If available, use
     * uselocale() for this because it's thread-safe.  Windows doesn't have
-    * that, but it usually does have _configthreadlocale().
+    * that, but it usually does have _configthreadlocale().  In some versions
+    * of MinGW, _configthreadlocale() exists but always returns -1 --- so
+    * treat that situation as if the function doesn't exist.
     */
 #ifdef HAVE_USELOCALE
    stmt->clocale = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
@@ -1796,11 +1798,6 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
 #else
 #ifdef HAVE__CONFIGTHREADLOCALE
    stmt->oldthreadlocale = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
-   if (stmt->oldthreadlocale == -1)
-   {
-       ecpg_do_epilogue(stmt);
-       return false;
-   }
 #endif
    stmt->oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
    if (stmt->oldlocale == NULL)
@@ -2017,12 +2014,17 @@ ecpg_do_epilogue(struct statement *stmt)
        uselocale(stmt->oldlocale);
 #else
    if (stmt->oldlocale)
-   {
        setlocale(LC_NUMERIC, stmt->oldlocale);
 #ifdef HAVE__CONFIGTHREADLOCALE
-       _configthreadlocale(stmt->oldthreadlocale);
+
+   /*
+    * This is a bit trickier than it looks: if we failed partway through
+    * statement initialization, oldthreadlocale could still be 0.  But that's
+    * okay because a call with 0 is defined to be a no-op.
+    */
+   if (stmt->oldthreadlocale != -1)
+       (void) _configthreadlocale(stmt->oldthreadlocale);
 #endif
-   }
 #endif
 
    free_statement(stmt);