v8-0002-initdb-emit-message-when-using-default-ICU-locale.patch

text/x-patch

Filename: v8-0002-initdb-emit-message-when-using-default-ICU-locale.patch
Type: text/x-patch
Part: 1
Message: Re: ICU locale validation / canonicalization

Patch

Format: format-patch
Series: patch v8-0002
Subject: initdb: emit message when using default ICU locale.
File+
src/bin/initdb/initdb.c 52 25
From 90e37d306320c0d4c33d12e89b28039570d05b30 Mon Sep 17 00:00:00 2001
From: Jeff Davis <jeff@j-davis.com>
Date: Wed, 22 Mar 2023 10:06:23 -0700
Subject: [PATCH v8 2/4] initdb: emit message when using default ICU locale.

Also, minor cleanup to separate the code that chooses the default ICU
locale from the code that verifies that a specified locale can be
opened with ucol_open(). This cleanup creates a better place for an
important comment.
---
 src/bin/initdb/initdb.c | 77 ++++++++++++++++++++++++++++-------------
 1 file changed, 52 insertions(+), 25 deletions(-)

diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index bae97539fc..9bf094500d 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -2242,46 +2242,73 @@ check_icu_locale_encoding(int user_enc)
 	return true;
 }
 
+#ifdef USE_ICU
+
 /*
- * Check that ICU accepts the locale name; or if not specified, retrieve the
- * default ICU locale.
+ * Determine default ICU locale by opening the default collator and reading
+ * its locale.
+ *
+ * NB: The default collator (opened using NULL) is different from the collator
+ * for the root locale (opened with "", "und", or "root"). The former depends
+ * on the environment (useful at initdb time) and the latter does not.
  */
-static void
-check_icu_locale(void)
+static char *
+default_icu_locale(void)
 {
-#ifdef USE_ICU
 	UCollator	*collator;
 	UErrorCode   status;
+	const char	*valid_locale;
+	char		*default_locale;
 
 	status = U_ZERO_ERROR;
-	collator = ucol_open(icu_locale, &status);
+	collator = ucol_open(NULL, &status);
+	if (U_FAILURE(status))
+		pg_fatal("could not open collator for default locale: %s",
+				 u_errorName(status));
+
+	status = U_ZERO_ERROR;
+	valid_locale = ucol_getLocaleByType(collator, ULOC_VALID_LOCALE,
+										&status);
 	if (U_FAILURE(status))
 	{
-		if (icu_locale)
-			pg_fatal("could not open collator for locale \"%s\": %s",
-					 icu_locale, u_errorName(status));
-		else
-			pg_fatal("could not open collator for default locale: %s",
-					 u_errorName(status));
+		ucol_close(collator);
+		pg_fatal("could not determine default ICU locale");
 	}
 
-	/* if not specified, get locale from default collator */
-	if (icu_locale == NULL)
-	{
-		const char	*default_locale;
+	default_locale = pg_strdup(valid_locale);
 
-		status = U_ZERO_ERROR;
-		default_locale = ucol_getLocaleByType(collator, ULOC_VALID_LOCALE,
-											  &status);
-		if (U_FAILURE(status))
-		{
-			ucol_close(collator);
-			pg_fatal("could not determine default ICU locale");
-		}
+	ucol_close(collator);
 
-		icu_locale = pg_strdup(default_locale);
+	return default_locale;
+}
+
+#endif
+
+/*
+ * If not specified, assign the default locale. Then check that ICU accepts
+ * the locale.
+ */
+static void
+check_icu_locale(void)
+{
+#ifdef USE_ICU
+	UCollator	*collator;
+	UErrorCode   status;
+
+	/* acquire default locale from the environment, if not specified */
+	if (icu_locale == NULL)
+	{
+		icu_locale = default_icu_locale();
+		printf(_("Using default ICU locale \"%s\".\n"), icu_locale);
 	}
 
+	/* check that the resulting locale can be opened */
+	status = U_ZERO_ERROR;
+	collator = ucol_open(icu_locale, &status);
+	if (U_FAILURE(status))
+		pg_fatal("could not open collator for locale \"%s\": %s",
+				 icu_locale, u_errorName(status));
+
 	ucol_close(collator);
 #endif
 }
-- 
2.34.1