From 773f594408b9abbddba558303678de6437f50c64 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Wed, 23 Jan 2019 22:46:45 -0500
Subject: [PATCH] Blind attempt to fix _configthreadlocale() failures on MinGW.

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 |  2 +-
 src/interfaces/ecpg/ecpglib/execute.c    | 20 +++++++++++---------
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c
index 3caeff5806d..aa31655c63b 100644
--- a/src/interfaces/ecpg/ecpglib/descriptor.c
+++ b/src/interfaces/ecpg/ecpglib/descriptor.c
@@ -518,7 +518,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
 	}
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index eb414f7ca15..aa5d4d99d7c 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1779,7 +1779,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);
@@ -1797,11 +1799,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)
@@ -2018,12 +2015,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);
-- 
GitLab