Subject: Re: initdb --no-locale=C doesn't work as specified when the environment is not C

From: Tom Lane <[email-masked]>
Date: Wed, 22 Nov 2023 11:04:01 -0500

Kyotaro Horiguchi <[email-masked]> writes:
> Commit 3e51b278db leaves lc_* conf lines as commented-out when
> their value is "C". This leads to the following behavior.

Hmm ... I see a contributing factor here: this bit in
postgresql.conf.sample is a lie:

#lc_messages = 'C'			# locale for system error message
					# strings

A look in guc_tables.c shows that the actual default is '' (empty
string), which means "use the environment", and that matches how the
variable is documented in config.sgml.  Somebody --- quite possibly me
--- was misled by the contents of postgresql.conf.sample into thinking
that the lc_xxx GUCs all default to C, when that's only true for the
others.

I think that a more correct fix for this would treat lc_messages
differently from the other lc_xxx GUCs.  Maybe just eliminate the
hack about not substituting "C" for that one?

In any case, we need to fix this mistake in postgresql.conf.sample.

			regards, tom lane

---

From: Kyotaro Horiguchi <[email-masked]>
Date: Mon, 27 Nov 2023 12:00:42 +0900 (JST)

At Wed, 22 Nov 2023 11:04:01 -0500, Tom Lane <[email-masked]> wrote in 
> that the lc_xxx GUCs all default to C, when that's only true for the

It seems somewhat intentional that only lc_messages references the
environment at boot time. On the other hand, previously, in the
absence of a specified locale, initdb would embed the environmental
value in the configuration file, as it seems to be documented. Given
that initdb is always used for cluster creation, it's unlikey that
systems depend on this boot-time default for their operation.

> hack about not substituting "C" for that one?

For example, the --no-locale option for initdb is supposed to set all
categories to 'C'. That approach would lead to the postgres
referencing the runtime environment for all categories except
lc_messages, which I believe contradicts the documentation. In my
biew, if lc_messages is exempted from that hack, then all other
categories should be similarly excluded as in the second approach
among the attached in the previous mail.

> In any case, we need to fix this mistake in postgresql.conf.sample.

If you are not particularly concerned about the presence of quotation
marks, I think it would be fine to go with the second approach and
make the necessary modification to the configuration file accordingly.

With the attached patch, initdb --no-locale generates the following
lines in the configuration file.

> lc_messages = C				# locale for system error message
> 					# strings
> lc_monetary = C				# locale for monetary formatting
> lc_numeric = C				# locale for number formatting
> lc_time = C				# locale for time formatting

By the way, the lines around lc_* in the sample file seem to have
somewhat inconsistent indentations. Wouldnt' it be preferable to fix
this? (The attached doesn't that.)

regards.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index e48c066a5b..133dd3da7d 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -726,7 +726,7 @@
 					# encoding
 
 # These settings are initialized by initdb, but they can be changed.
-#lc_messages = 'C'			# locale for system error message
+#lc_messages = ''			# locale for system error message
 					# strings
 #lc_monetary = 'C'			# locale for monetary formatting
 #lc_numeric = 'C'			# locale for number formatting
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 0c6f5ceb0a..646e8f29f6 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -1226,25 +1226,17 @@ setup_config(void)
 	conflines = replace_guc_value(conflines, "shared_buffers",
 								  repltok, false);
 
-	/*
-	 * Hack: don't replace the LC_XXX GUCs when their value is 'C', because
-	 * replace_guc_value will decide not to quote that, which looks strange.
-	 */
-	if (strcmp(lc_messages, "C") != 0)
-		conflines = replace_guc_value(conflines, "lc_messages",
-									  lc_messages, false);
+	conflines = replace_guc_value(conflines, "lc_messages",
+								  lc_messages, false);
 
-	if (strcmp(lc_monetary, "C") != 0)
-		conflines = replace_guc_value(conflines, "lc_monetary",
-									  lc_monetary, false);
+	conflines = replace_guc_value(conflines, "lc_monetary",
+								  lc_monetary, false);
 
-	if (strcmp(lc_numeric, "C") != 0)
-		conflines = replace_guc_value(conflines, "lc_numeric",
-									  lc_numeric, false);
+	conflines = replace_guc_value(conflines, "lc_numeric",
+								  lc_numeric, false);
 
-	if (strcmp(lc_time, "C") != 0)
-		conflines = replace_guc_value(conflines, "lc_time",
-									  lc_time, false);
+	conflines = replace_guc_value(conflines, "lc_time",
+								  lc_time, false);
 
 	switch (locale_date_order(lc_time))
 	{