Ensure the global locale gets used by localeconv()

A loaded library, such as libperl, may call uselocale() underneath us.
This can result in localeconv() grabbing the wrong locale for
numeric and monetary symbols and formatting. Fix that by resetting
to the global locale determined by setlocale(). Backpatch to all
supported versions.

Author: Joe Conway
Reviewed-By: Tom Lane
Reported by: Guido Brugnara
Discussion: https://postgr.es/m/flat/17946-3e84cb577e9551c3%40postgresql.org
Backpatch-through: 11

diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 31e3b16..9dba161 100644
*** a/src/backend/utils/adt/pg_locale.c
--- b/src/backend/utils/adt/pg_locale.c
*************** PGLC_localeconv(void)
*** 505,510 ****
--- 505,517 ----
  	}
  
  	/*
+ 	 * Ensure the global locale will be used by localeconv().
+ 	 * This is necessary, for example, if another loaded library
+ 	 * such as libperl has done uselocale() underneath us.
+ 	 */
+ 	uselocale(LC_GLOBAL_LOCALE);
+ 
+ 	/*
  	 * This is tricky because we really don't want to risk throwing error
  	 * while the locale is set to other than our usual settings.  Therefore,
  	 * the process is: collect the usual settings, set locale to special
diff --git a/src/fe_utils/print.c b/src/fe_utils/print.c
index 7af1ccb..5d80e77 100644
*** a/src/fe_utils/print.c
--- b/src/fe_utils/print.c
*************** setDecimalLocale(void)
*** 3628,3633 ****
--- 3628,3639 ----
  {
  	struct lconv *extlconv;
  
+ 	/*
+ 	 * Ensure the global locale will be used by localeconv().
+ 	 * This is necessary, for example, if another loaded library
+ 	 * has done uselocale() underneath us.
+ 	 */
+ 	uselocale(LC_GLOBAL_LOCALE);
  	extlconv = localeconv();
  
  	/* Don't accept an empty decimal_point string */
