From 4f0900616d4943537520d6f5bb62ca991558e9ab Mon Sep 17 00:00:00 2001
From: Davinder Singh <davindersingh2692@gmail.com>
Date: Thu, 9 Apr 2020 13:43:53 +0530
Subject: [PATCH] PG compilation error with VS 2015/2017/2019

This fix is to resolve undefined struct/union compilation error while
accessing _locale_name.
---
 src/backend/utils/adt/pg_locale.c | 65 +++++++++++++++++++------------
 1 file changed, 41 insertions(+), 24 deletions(-)

diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 2562eb5416..52b1a0473e 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -989,7 +989,8 @@ IsoLocaleName(const char *winlocname)
 {
 #ifdef _MSC_VER
 	static char iso_lc_messages[32];
-	_locale_t	loct = NULL;
+	size_t		rc;
+	char*		hyphen;
 
 	if (pg_strcasecmp("c", winlocname) == 0 ||
 		pg_strcasecmp("posix", winlocname) == 0)
@@ -997,38 +998,54 @@ IsoLocaleName(const char *winlocname)
 		strcpy(iso_lc_messages, "C");
 		return iso_lc_messages;
 	}
+#if _WIN32_WINNT >= 0x0600
+	WCHAR		wc_locale_name[LOCALE_NAME_MAX_LENGTH];
+	WCHAR		buffer[LOCALE_NAME_MAX_LENGTH];
+
+	memset(wc_locale_name, 0, sizeof(wc_locale_name));
+	memset(buffer, 0, sizeof(buffer));
+	MultiByteToWideChar(CP_ACP, 0, winlocname, -1, wc_locale_name,
+						LOCALE_NAME_MAX_LENGTH);
+	if ((GetLocaleInfoEx(wc_locale_name, LOCALE_SNAME,
+		(LPWSTR)&buffer, LOCALE_NAME_MAX_LENGTH)) > 0) {
+		rc = wchar2char(iso_lc_messages, buffer, sizeof(iso_lc_messages),
+						NULL);
+	}
+#else   	/* _WIN32_WINNT < 0x0600 */
+	_locale_t	loct = NULL;
 
 	loct = _create_locale(LC_CTYPE, winlocname);
 	if (loct != NULL)
 	{
-		size_t		rc;
-		char	   *hyphen;
-
 		/* Locale names use only ASCII, any conversion locale suffices. */
 		rc = wchar2char(iso_lc_messages, loct->locinfo->locale_name[LC_CTYPE],
 						sizeof(iso_lc_messages), NULL);
 		_free_locale(loct);
-		if (rc == -1 || rc == sizeof(iso_lc_messages))
-			return NULL;
-
-		/*
-		 * Since the message catalogs sit on a case-insensitive filesystem, we
-		 * need not standardize letter case here.  So long as we do not ship
-		 * message catalogs for which it would matter, we also need not
-		 * translate the script/variant portion, e.g. uz-Cyrl-UZ to
-		 * uz_UZ@cyrillic.  Simply replace the hyphen with an underscore.
-		 *
-		 * Note that the locale name can be less-specific than the value we
-		 * would derive under earlier Visual Studio releases.  For example,
-		 * French_France.1252 yields just "fr".  This does not affect any of
-		 * the country-specific message catalogs available as of this writing
-		 * (pt_BR, zh_CN, zh_TW).
-		 */
-		hyphen = strchr(iso_lc_messages, '-');
-		if (hyphen)
-			*hyphen = '_';
-		return iso_lc_messages;
 	}
+#endif		/* _WIN32_WINNT >= 0x0600 */
+	else
+		return NULL;
+
+	if (rc == -1 || rc == sizeof(iso_lc_messages))
+		return NULL;
+
+	/*
+	 * Since the message catalogs sit on a case-insensitive filesystem, we
+	 * need not standardize letter case here.  So long as we do not ship
+	 * message catalogs for which it would matter, we also need not
+	 * translate the script/variant portion, e.g. uz-Cyrl-UZ to
+	 * uz_UZ@cyrillic.  Simply replace the hyphen with an underscore.
+	 *
+	 * Note that the locale name can be less-specific than the value we
+	 * would derive under earlier Visual Studio releases.  For example,
+	 * French_France.1252 yields just "fr".  This does not affect any of
+	 * the country-specific message catalogs available as of this writing
+	 * (pt_BR, zh_CN, zh_TW).
+	 */
+	hyphen = strchr(iso_lc_messages, '-');
+	if (hyphen)
+		*hyphen = '_';
+	return iso_lc_messages;
 #endif							/* _MSC_VER */
 	return NULL;				/* Not supported on this version of msvc/mingw */
 }
-- 
2.24.0.windows.2

