From 5b94e2bd4d5430f5ea4e965a32727a6006972a55 Mon Sep 17 00:00:00 2001 From: Noah Misch Date: Sat, 2 Jul 2022 13:00:30 -0700 Subject: ecpglib: call newlocale() once per process. ecpglib has been calling it once per SQL query and once per EXEC SQL GET DESCRIPTOR. Instead, if newlocale() has not succeeded before, call it while establishing a connection. This mitigates three problems: - If newlocale() failed in EXEC SQL GET DESCRIPTOR, the command silently proceeded without the intended locale change. - On AIX, each newlocale()+freelocale() cycle leaked memory. - newlocale() CPU usage may have been nontrivial. Fail the connection attempt if newlocale() fails. Rearrange ecpg_do_prologue() to validate the connection before its uselocale(). The sort of program that may regress is one running in an environment where newlocale() fails. If that program establishes connections without running SQL statements, it will stop working in response to this change. I'm betting against the importance of such an ECPG use case. Most SQL execution (any using ECPGdo()) has long required newlocale() success, so there's little a connection could do without newlocale(). Back-patch to v10 (all supported versions). Reviewed by Tom Lane. Reported by Guillaume Lelarge. Discussion: https://postgr.es/m/20220101074055.GA54621@rfd.leadboat.com --- src/interfaces/ecpg/ecpglib/ecpglib_extern.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/interfaces/ecpg/ecpglib/ecpglib_extern.h') diff --git a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h index 1a98dea1b55..c438cfb8209 100644 --- a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h +++ b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h @@ -59,6 +59,10 @@ struct ECPGtype_information_cache enum ARRAY_TYPE isarray; }; +#ifdef HAVE_USELOCALE +extern locale_t ecpg_clocale; /* LC_NUMERIC=C */ +#endif + /* structure to store one statement */ struct statement { @@ -73,7 +77,6 @@ struct statement struct variable *inlist; struct variable *outlist; #ifdef HAVE_USELOCALE - locale_t clocale; locale_t oldlocale; #else char *oldlocale; -- cgit v1.2.3