From 867901db9efbdae05270931daeb92042dc285710 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut <peter_e@gmx.net> Date: Wed, 3 Apr 2002 05:39:33 +0000 Subject: [PATCH] Locale support is on by default. The choice of locale is done in initdb and/or with GUC variables. --- configure | 39 ----- configure.in | 12 +- doc/src/sgml/charset.sgml | 131 +++++++++-------- doc/src/sgml/datatype.sgml | 10 +- doc/src/sgml/installation.sgml | 13 +- doc/src/sgml/ref/initdb.sgml | 54 ++++++- doc/src/sgml/release.sgml | 3 +- doc/src/sgml/runtime.sgml | 98 +++++++++++-- src/backend/access/transam/xlog.c | 22 +-- src/backend/main/main.c | 36 +++-- src/backend/utils/adt/cash.c | 28 +--- src/backend/utils/adt/formatting.c | 12 +- src/backend/utils/adt/pg_locale.c | 223 ++++++++++++----------------- src/backend/utils/adt/selfuncs.c | 87 +++++------ src/backend/utils/adt/varlena.c | 48 ++++--- src/backend/utils/misc/guc.c | 23 ++- src/bin/initdb/initdb.sh | 103 ++++++++++++- src/include/pg_config.h.in | 5 +- src/include/utils/pg_locale.h | 64 ++++----- 19 files changed, 543 insertions(+), 468 deletions(-) diff --git a/configure b/configure index 17e1db1e3e8..01c0a9d9467 100755 --- a/configure +++ b/configure @@ -845,7 +845,6 @@ if test -n "$ac_init_help"; then Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-locale enable locale support --enable-recode enable character set recode support --enable-multibyte enable multibyte character support --enable-nls[=LANGUAGES] enable Native Language Support @@ -1570,44 +1569,6 @@ fi; -# -# Locale (--enable-locale) -# -echo "$as_me:$LINENO: checking whether to build with locale support" >&5 -echo $ECHO_N "checking whether to build with locale support... $ECHO_C" >&6 - - -# Check whether --enable-locale or --disable-locale was given. -if test "${enable_locale+set}" = set; then - enableval="$enable_locale" - - case $enableval in - yes) - -cat >>confdefs.h <<\_ACEOF -#define USE_LOCALE 1 -_ACEOF - - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --enable-locale option" >&5 -echo "$as_me: error: no argument expected for --enable-locale option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - enable_locale=no - -fi; - -echo "$as_me:$LINENO: result: $enable_locale" >&5 -echo "${ECHO_T}$enable_locale" >&6 - - # # Character set recode (--enable-recode) # diff --git a/configure.in b/configure.in index 1d5a3703f9c..7fbf76e32b4 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -dnl $Header: /cvsroot/pgsql/configure.in,v 1.174 2002/04/01 01:11:00 tgl Exp $ +dnl $Header: /cvsroot/pgsql/configure.in,v 1.175 2002/04/03 05:39:27 petere Exp $ dnl Developers, please strive to achieve this order: dnl @@ -140,16 +140,6 @@ PGAC_ARG_REQ(with, libs, [ --with-libs=DIRS alternative spelling of [LIBRARY_DIRS=$withval]) -# -# Locale (--enable-locale) -# -AC_MSG_CHECKING([whether to build with locale support]) -PGAC_ARG_BOOL(enable, locale, no, [ --enable-locale enable locale support], - [AC_DEFINE([USE_LOCALE], 1, - [Set to 1 if you want LOCALE support (--enable-locale)])]) -AC_MSG_RESULT([$enable_locale]) - - # # Character set recode (--enable-recode) # diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml index 29cc7e528ef..a19940ce9a6 100644 --- a/doc/src/sgml/charset.sgml +++ b/doc/src/sgml/charset.sgml @@ -1,4 +1,4 @@ -<!-- $Header: /cvsroot/pgsql/doc/src/sgml/charset.sgml,v 2.23 2002/03/22 19:20:05 petere Exp $ --> +<!-- $Header: /cvsroot/pgsql/doc/src/sgml/charset.sgml,v 2.24 2002/04/03 05:39:27 petere Exp $ --> <chapter id="charset"> <title>Localization</> @@ -63,35 +63,24 @@ <sect2> <title>Overview</> - <para> - Locale support is not built into <productname>PostgreSQL</> by - default; to enable it, supply the <option>--enable-locale</> option - to the <filename>configure</> script: -<informalexample> + <para> + Locale support is automatically initialized when a database + cluster is created using <command>initdb</command>. + <command>initdb</command> will initialize the database cluster + with the locale setting of its execution environment; so if your + system is already set to use the locale that you want in your + database cluster then there is nothing else you need to do. If + you want to use a different locale (or you are not sure which + locale your system is set to), you can tell + <command>initdb</command> exactly which locale you want with the + option <option>--locale</option>. For example: <screen> -<prompt>$ </><userinput>./configure --enable-locale</> +<prompt>$ </><userinput>initdb --locale=sv_SE</> </screen> -</informalexample> - Locale support only affects the server; all clients are compatible - with servers with or without locale support. - </para> - - <para> - To enable messages translated to the user's preferred language, - the <option>--enable-nls</option> option must be used. This - option is independent of the other locale support. </para> <para> - The information about which particular cultural rules to use is - determined by standard environment variables. If you are getting - localized behavior from other programs you probably have them set - up already. The simplest way to set the localization information - is the <envar>LANG</> variable, for example: -<programlisting> -export LANG=sv_SE -</programlisting> - This sets the locale to Swedish (<literal>sv</>) as spoken in + This example sets the locale to Swedish (<literal>sv</>) as spoken in Sweden (<literal>SE</>). Other possibilities might be <literal>en_US</> (U.S. English) and <literal>fr_CA</> (Canada, French). If more than one character set can be useful for a locale @@ -103,9 +92,9 @@ export LANG=sv_SE <para> Occasionally it is useful to mix rules from several locales, e.g., - use U.S. collation rules but Spanish messages. To do that a set of - environment variables exist that override the default of - <envar>LANG</> for a particular category: + use U.S. collation rules but Spanish messages. To support that, a + set of locale subcategories exist that control only a certain + aspect of the localization rules. <informaltable> <tgroup cols="2"> @@ -138,49 +127,79 @@ export LANG=sv_SE </tgroup> </informaltable> - Additionally, all of these specific variables and the - <envar>LANG</> variable can be overridden with the - <envar>LC_ALL</> environment variable. + The category names translate into names of + <command>initdb</command> options to override the locale choice + for a specific category. For instance, to set the locale to + French Canadian, but use U.S. rules for formatting currency, use + <literal>initdb --locale=fr_CA --lc-monetary=en_US</literal>. </para> - <note> - <para> - Some message localization libraries also look at the environment - variable <envar>LANGUAGE</envar> which overrides all other locale - settings for the purpose of setting the language of messages. If - in doubt, please refer to the documentation of your operating - system, in particular the - <citerefentry><refentrytitle>gettext</><manvolnum>3</></> manual - page, for more information. - </para> - </note> - <para> If you want the system to behave as if it had no locale support, - use the special locale <literal>C</> or <literal>POSIX</>, or - simply unset all locale-related variables. + use the special locale <literal>C</> or <literal>POSIX</>. + </para> + + <para> + The nature of some locale categories is that their value has to be + fixed for the lifetime of a database cluster. That is, once + <command>initdb</command> has run, you cannot change them anymore. + <literal>LC_COLLATE</literal> and <literal>LC_CTYPE</literal> are + those categories. They affect the sort order of indexes, so they + must be kept fixed, or indexes on text columns will become corrupt. + <productname>PostgreSQL</productname> enforces this by recording + the values of <envar>LC_COLLATE</> and <envar>LC_CTYPE</> that are + seen by <command>initdb</>. The server automatically adopts + those two values when it is started. + </para> + + <para> + The other locale categories can be changed as desired whenever the + server is started by setting the run-time configuration variables + that have the same name as the locale categories (see <xref + linkend="runtime-config"> for details). The defaults that are + chosen by <command>initdb</command> are actually only written into + the configuration file <filename>postgresql.conf</filename> to + serve as defaults when the server is started. If you delete the + assignments from <filename>postgresql.conf</filename> then the + server will inherit the settings from the execution environment. </para> <para> Note that the locale behavior of the server is determined by the environment variables seen by the server, not by the environment - of any client. Therefore, be careful to set these variables + of any client. Therefore, be careful to configure the correct locale settings before starting the server. A consequence of this is that if client and server are set up to different locales, messages may appear in different languages depending on where they originated. </para> + <note> + <para> + When we speak of inheriting the locale from the execution + environment, this means the following on most operating systems: + For a given locale category, say the collation, the following + environment variables are consulted in this order until one is + found to be set: <envar>LC_ALL</envar>, <envar>LC_COLLATE</envar> + (the variable corresponding to the respective category), + <envar>LANG</envar>. If none of these environment variables are + set then the locale defaults to <literal>C</literal>. + </para> + + <para> + Some message localization libraries also look at the environment + variable <envar>LANGUAGE</envar> which overrides all other locale + settings for the purpose of setting the language of messages. If + in doubt, please refer to the documentation of your operating + system, in particular the + <citerefentry><refentrytitle>gettext</><manvolnum>3</></> manual + page, for more information. + </para> + </note> + <para> - The <envar>LC_COLLATE</> and <envar>LC_CTYPE</> variables affect the - sort order of indexes. Therefore, these values must be kept fixed - for any particular database cluster, or indexes on text columns will - become corrupt. <productname>PostgreSQL</productname> enforces this - by recording the values of <envar>LC_COLLATE</> and <envar>LC_CTYPE</> - that are seen by <application>initdb</>. The server automatically adopts - those two values when it is started; only the other <envar>LC_</> - categories can be set from the environment at server start-up. - In short, only one collation order can be used in a database cluster, - and it is chosen at <application>initdb</> time. + To enable messages translated to the user's preferred language, + the <option>--enable-nls</option> option must be used. This + option is independent of the other locale support. </para> </sect2> diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml index a792d52e424..1dbf460cf4c 100644 --- a/doc/src/sgml/datatype.sgml +++ b/doc/src/sgml/datatype.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.86 2002/03/22 19:20:07 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.87 2002/04/03 05:39:27 petere Exp $ --> <chapter id="datatype"> @@ -724,11 +724,9 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl </note> <para> - The <type>money</type> type stores U.S.-style currency with fixed - decimal point representation. If - <productname>PostgreSQL</productname> is compiled with locale - support then the <type>money</type> type uses locale-specific - output formatting. + The <type>money</type> type stores a currency amount with fixed + decimal point representation. The output format is + locale-specific. </para> <para> diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml index c8aa0dd0c95..e5f9de741af 100644 --- a/doc/src/sgml/installation.sgml +++ b/doc/src/sgml/installation.sgml @@ -1,4 +1,4 @@ -<!-- $Header: /cvsroot/pgsql/doc/src/sgml/installation.sgml,v 1.74 2002/01/20 05:45:18 tgl Exp $ --> +<!-- $Header: /cvsroot/pgsql/doc/src/sgml/installation.sgml,v 1.75 2002/04/03 05:39:28 petere Exp $ --> <chapter id="installation"> <title><![%standalone-include[<productname>PostgreSQL</>]]> @@ -531,17 +531,6 @@ su - postgres </listitem> </varlistentry> - <varlistentry> - <term><option>--enable-locale</option></term> - <listitem> - <para> - Enables locale support. There is a performance penalty - associated with locale support, but if you are not in an - English-speaking environment you will most likely need this. - </para> - </listitem> - </varlistentry> - <varlistentry> <term><option>--enable-recode</option></term> <listitem> diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml index 3bbe44aeee8..8ac524e3dc8 100644 --- a/doc/src/sgml/ref/initdb.sgml +++ b/doc/src/sgml/ref/initdb.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/initdb.sgml,v 1.19 2001/12/08 03:24:37 thomas Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/initdb.sgml,v 1.20 2002/04/03 05:39:29 petere Exp $ PostgreSQL documentation --> @@ -38,6 +38,13 @@ PostgreSQL documentation <arg>-E </arg> <replaceable>encoding</replaceable> </group> + <arg>--locale <replaceable>locale</replaceable></arg> + <arg>--lc-collate <replaceable>locale</replaceable></arg> + <arg>--lc-ctype <replaceable>locale</replaceable></arg> + <arg>--lc-messages <replaceable>locale</replaceable></arg> + <arg>--lc-monetary <replaceable>locale</replaceable></arg> + <arg>--lc-numeric <replaceable>locale</replaceable></arg> + <arg>--lc-time <replaceable>locale</replaceable></arg> <arg>-L <replaceable>directory</replaceable></arg> <group><arg>--noclean</arg><arg>-n</arg></group> <group><arg>--debug</arg><arg>-d</arg></group> @@ -66,6 +73,25 @@ PostgreSQL documentation built-in types. </para> + <para> + <command>initdb</command> initializes the database cluster's + default locale and character set encoding. Some locale categories + are fixed for the lifetime of the cluster, so it is important to + make the right choice when running <command>initdb</command>. + Other locale categories can be changed later when the server is + started. <command>initdb</command> will write those locale + settings into the <filename>postgresql.conf</filename> + configuration file so they are the default, but they can be changed + by editing that file. To set the locale that + <command>initdb</command> uses, see the description of the + <option>--locale</option> option. The character set encoding can + be set separately for each database as it is created. + <command>initdb</command> determines the encoding for the + <literal>template1</literal> database, which will serve as the + default for all other databases. To alter the default encoding use + the <option>--encoding</option> option. + </para> + <para> <command>initdb</command> must be run as the user that will own the server process, because the server needs to have access to the @@ -150,6 +176,32 @@ PostgreSQL documentation </listitem> </varlistentry> + <varlistentry> + <term>--locale=<replaceable>locale</replaceable></term> + <listitem> + <para> + Sets the default locale for the database cluster. If this + option is not specified, the locale is inherited from the + environment that <command>initdb</command> runs in. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>--lc-collate=<replaceable>locale</replaceable></term> + <term>--lc-ctype=<replaceable>locale</replaceable></term> + <term>--lc-messages=<replaceable>locale</replaceable></term> + <term>--lc-monetary=<replaceable>locale</replaceable></term> + <term>--lc-numeric=<replaceable>locale</replaceable></term> + <term>--lc-time=<replaceable>locale</replaceable></term> + + <listitem> + <para> + Like <option>--locale</option>, but only sets the locale in + the specified category. + </para> + </listitem> + </varlistentry> </variablelist> </para> diff --git a/doc/src/sgml/release.sgml b/doc/src/sgml/release.sgml index c3e52dd948b..dfb96e4ff8e 100644 --- a/doc/src/sgml/release.sgml +++ b/doc/src/sgml/release.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.129 2002/04/01 04:35:37 tgl Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.130 2002/04/03 05:39:28 petere Exp $ --> <appendix id="release"> @@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without worries about funny characters. --> <literallayout><![CDATA[ +Locale support is now built by default; choice of locale is set by initdb and/or at run-time ALTER TABLE ALTER COLUMN SET/DROP NOT NULL EXPLAIN output comes out as a query result, not a NOTICE message DOMAINs (types that are constrained versions of base types) diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index 43b6931fe18..2b0a4ad6349 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.111 2002/04/01 03:34:24 tgl Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.112 2002/04/03 05:39:29 petere Exp $ --> <Chapter Id="runtime"> @@ -135,8 +135,14 @@ postgres$ <userinput>initdb -D /usr/local/pgsql/data</userinput> </para> <para> + <indexterm><primary>locale</></> <indexterm><primary>LC_COLLATE</></> - One surprise you might encounter while running + <command>initdb</command> also initializes the default locale for + the database cluster. Normally, it will just take the locale + settings in the environment and apply them to the initialized + database. It is possible to specify a different locale for the + database; more information about that can be found in <xref + linkend="locale">. One surprise you might encounter while running <command>initdb</command> is a notice similar to this: <screen> WARNING: Initializing database with en_US collation order. @@ -145,18 +151,17 @@ WARNING: Initializing database with en_US collation order. such queries, you may wish to set LC_COLLATE to "C" and re-initdb. For more information see the Administrator's Guide. </screen> - This is intended to warn you that the currently selected locale will - cause indexes to be sorted in an order that prevents them from being - used for LIKE and regular-expression searches. If you need good - performance in such searches, you should set your current locale to - <literal>C</> and re-run <command>initdb</command>. On most systems, - setting the current locale is done by changing the value of the - environment variable <literal>LC_ALL</literal> or - <literal>LANG</literal>. The sort order used within a particular - database cluster is set by <command>initdb</command> and cannot be - changed later, short of dumping all data, rerunning - <command>initdb</command>, and reloading the data. So it's important - to make this choice correctly the first time. + This is intended to warn you that the currently selected locale + will cause indexes to be sorted in an order that prevents them from + being used for LIKE and regular-expression searches. If you need + good performance in such searches, you should set your current + locale to <literal>C</> and re-run <command>initdb</command>, e.g., + by running <literal>initdb --lc-collate=C</literal>. The sort + order used within a particular database cluster is set by + <command>initdb</command> and cannot be changed later, short of + dumping all data, rerunning <command>initdb</command>, and + reloading the data. So it's important to make this choice correctly + the first time. </para> </sect1> @@ -1316,6 +1321,71 @@ dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir' </listitem> </varlistentry> + <varlistentry> + <term><varname>LC_MESSAGES</varname> (<type>string</type>)</term> + <listitem> + <para> + Sets the language in which messages are displayed. Acceptable + values are system-dependent; see <xref linkend="locale"> for + more information. If this variable is set to the empty string + (which is the default) then the value is inherited from the + execution environment of the server in a system-dependent way. + </para> + + <para> + On some systems, this locale category does not exist. Setting + this variable will still work, but there will be no effect. + Also, there is a chance that no translated messages for the + desired language exist. In that case you will continue to see + the English messages. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><varname>LC_MONETARY</varname> (<type>string</type>)</term> + <listitem> + <para> + Sets the locale to use for formatting monetary amounts. + Acceptable values are system-dependent; see <xref + linkend="locale"> for more information. If this variable is + set to the empty string (which is the default) then the value + is inherited from the execution environment of the server in a + system-dependent way. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><varname>LC_NUMERIC</varname> (<type>string</type>)</term> + <listitem> + <para> + Sets the locale to use for formatting numbers, for example + with the <function>to_char()</function> family of + functions. Acceptable values are system-dependent; see <xref + linkend="locale"> for more information. If this variable is + set to the empty string (which is the default) then the value + is inherited from the execution environment of the server in a + system-dependent way. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><varname>LC_TIME</varname> (<type>string</type>)</term> + <listitem> + <para> + Sets the locale to use for formatting date and time values, + for example with the <function>to_char()</function> family of + functions. Acceptable values are system-dependent; see <xref + linkend="locale"> for more information. If this variable is + set to the empty string (which is the default) then the value + is inherited from the execution environment of the server in a + system-dependent way. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><varname>MAX_CONNECTIONS</varname> (<type>integer</type>)</term> <listitem> diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 7e29f6cd026..c148f3d4e4d 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.90 2002/03/15 19:20:30 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.91 2002/04/03 05:39:29 petere Exp $ * *------------------------------------------------------------------------- */ @@ -22,9 +22,7 @@ #include <sys/time.h> #include <sys/types.h> #include <dirent.h> -#ifdef USE_LOCALE #include <locale.h> -#endif #include "access/clog.h" #include "access/transam.h" @@ -2081,10 +2079,7 @@ WriteControlFile(void) { int fd; char buffer[BLCKSZ]; /* need not be aligned */ - -#ifdef USE_LOCALE char *localeptr; -#endif /* * Initialize version and compatibility-check fields @@ -2093,7 +2088,6 @@ WriteControlFile(void) ControlFile->catalog_version_no = CATALOG_VERSION_NO; ControlFile->blcksz = BLCKSZ; ControlFile->relseg_size = RELSEG_SIZE; -#ifdef USE_LOCALE localeptr = setlocale(LC_COLLATE, NULL); if (!localeptr) elog(PANIC, "invalid LC_COLLATE setting"); @@ -2115,10 +2109,6 @@ WriteControlFile(void) "\n\tsuch queries, you may wish to set LC_COLLATE to \"C\" and" "\n\tre-initdb. For more information see the Administrator's Guide.", ControlFile->lc_collate); -#else /* not USE_LOCALE */ - strcpy(ControlFile->lc_collate, "C"); - strcpy(ControlFile->lc_ctype, "C"); -#endif /* not USE_LOCALE */ /* Contents are protected with a CRC */ INIT_CRC64(ControlFile->crc); @@ -2232,7 +2222,6 @@ ReadControlFile(void) "\tbut the backend was compiled with RELSEG_SIZE %d.\n" "\tIt looks like you need to initdb.", ControlFile->relseg_size, RELSEG_SIZE); -#ifdef USE_LOCALE if (setlocale(LC_COLLATE, ControlFile->lc_collate) == NULL) elog(PANIC, "The database cluster was initialized with LC_COLLATE '%s',\n" @@ -2245,15 +2234,6 @@ ReadControlFile(void) "\twhich is not recognized by setlocale().\n" "\tIt looks like you need to initdb.", ControlFile->lc_ctype); -#else /* not USE_LOCALE */ - if (strcmp(ControlFile->lc_collate, "C") != 0 || - strcmp(ControlFile->lc_ctype, "C") != 0) - elog(PANIC, - "The database cluster was initialized with LC_COLLATE '%s' and\n" - "\tLC_CTYPE '%s', but the server was compiled without locale support.\n" - "\tIt looks like you need to initdb or recompile.", - ControlFile->lc_collate, ControlFile->lc_ctype); -#endif /* not USE_LOCALE */ } void diff --git a/src/backend/main/main.c b/src/backend/main/main.c index b1be0781412..9c79e7b78d9 100644 --- a/src/backend/main/main.c +++ b/src/backend/main/main.c @@ -13,7 +13,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/main/main.c,v 1.49 2001/11/05 17:46:25 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/main/main.c,v 1.50 2002/04/03 05:39:29 petere Exp $ * *------------------------------------------------------------------------- */ @@ -21,9 +21,7 @@ #include <pwd.h> #include <unistd.h> -#if defined(USE_LOCALE) || defined(ENABLE_NLS) #include <locale.h> -#endif #if defined(__alpha) && defined(__osf__) #include <sys/sysinfo.h> @@ -122,11 +120,25 @@ main(int argc, char *argv[]) new_argv[i] = strdup(argv[i]); new_argv[argc] = NULL; - /* Initialize NLS settings so we can give localized error messages */ -#ifdef ENABLE_NLS + /* + * Set up locale information from environment. Note that CTYPE + * and COLLATE will be overridden later from pg_control if we are + * in an already-initialized database. We set them here so that + * they will be available to fill pg_control during initdb. The + * other ones will get reset later in ResetAllOptions, but we set + * them here to get already localized behavior during startup + * (e.g., error messages). + */ + setlocale(LC_COLLATE, ""); + setlocale(LC_CTYPE, ""); #ifdef LC_MESSAGES setlocale(LC_MESSAGES, ""); #endif + setlocale(LC_MONETARY, ""); + setlocale(LC_NUMERIC, ""); + setlocale(LC_TIME, ""); + +#ifdef ENABLE_NLS bindtextdomain("postgres", LOCALEDIR); textdomain("postgres"); #endif @@ -178,20 +190,6 @@ main(int argc, char *argv[]) } } - /* - * Set up locale information from environment, in only the categories - * needed by Postgres; leave other categories set to default "C". - * (Note that CTYPE and COLLATE will be overridden later from - * pg_control if we are in an already-initialized database. We set - * them here so that they will be available to fill pg_control during - * initdb.) - */ -#ifdef USE_LOCALE - setlocale(LC_CTYPE, ""); - setlocale(LC_COLLATE, ""); - setlocale(LC_MONETARY, ""); -#endif - /* * Now dispatch to one of PostmasterMain, PostgresMain, or * BootstrapMain depending on the program name (and possibly first diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c index c2af4a64fa9..4a8ddcf19b6 100644 --- a/src/backend/utils/adt/cash.c +++ b/src/backend/utils/adt/cash.c @@ -9,7 +9,7 @@ * workings can be found in the book "Software Solutions in C" by * Dale Schumacher, Academic Press, ISBN: 0-12-632360-7. * - * $Header: /cvsroot/pgsql/src/backend/utils/adt/cash.c,v 1.52 2002/02/19 22:19:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/cash.c,v 1.53 2002/04/03 05:39:29 petere Exp $ */ #include "postgres.h" @@ -17,9 +17,7 @@ #include <limits.h> #include <ctype.h> #include <math.h> -#ifdef USE_LOCALE #include <locale.h> -#endif #include "miscadmin.h" #include "utils/builtins.h" @@ -83,11 +81,7 @@ cash_in(PG_FUNCTION_ARGS) psymbol, *nsymbol; -#ifdef USE_LOCALE struct lconv *lconvert = PGLC_localeconv(); -#endif - -#ifdef USE_LOCALE /* * frac_digits will be CHAR_MAX in some locales, notably C. However, @@ -108,14 +102,6 @@ cash_in(PG_FUNCTION_ARGS) csymbol = ((*lconvert->currency_symbol != '\0') ? lconvert->currency_symbol : "$"); psymbol = ((*lconvert->positive_sign != '\0') ? *lconvert->positive_sign : '+'); nsymbol = ((*lconvert->negative_sign != '\0') ? lconvert->negative_sign : "-"); -#else - fpoint = 2; - dsymbol = '.'; - ssymbol = ','; - csymbol = "$"; - psymbol = '+'; - nsymbol = "-"; -#endif #ifdef CASHDEBUG printf("cashin- precision '%d'; decimal '%c'; thousands '%c'; currency '%s'; positive '%c'; negative '%s'\n", @@ -241,11 +227,8 @@ cash_out(PG_FUNCTION_ARGS) *nsymbol; char convention; -#ifdef USE_LOCALE struct lconv *lconvert = PGLC_localeconv(); -#endif -#ifdef USE_LOCALE /* see comments about frac_digits in cash_in() */ points = lconvert->frac_digits; if (points < 0 || points > 10) @@ -264,15 +247,6 @@ cash_out(PG_FUNCTION_ARGS) dsymbol = ((*lconvert->mon_decimal_point != '\0') ? *lconvert->mon_decimal_point : '.'); csymbol = ((*lconvert->currency_symbol != '\0') ? lconvert->currency_symbol : "$"); nsymbol = ((*lconvert->negative_sign != '\0') ? lconvert->negative_sign : "-"); -#else - points = 2; - mon_group = 3; - comma = ','; - convention = 0; - dsymbol = '.'; - csymbol = "$"; - nsymbol = "-"; -#endif point_pos = LAST_DIGIT - points; diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c index 199630e0cc4..231bad2ca6d 100644 --- a/src/backend/utils/adt/formatting.c +++ b/src/backend/utils/adt/formatting.c @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------- * formatting.c * - * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.51 2002/03/06 06:10:12 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.52 2002/04/03 05:39:29 petere Exp $ * * * Portions Copyright (c) 1999-2000, PostgreSQL Global Development Group @@ -72,9 +72,7 @@ #include <ctype.h> #include <sys/time.h> #include <unistd.h> -#ifdef USE_LOCALE #include <locale.h> -#endif #include <math.h> #include <float.h> @@ -3380,9 +3378,6 @@ int_to_roman(int number) static void NUM_prepare_locale(NUMProc *Np) { - -#ifdef USE_LOCALE - if (Np->Num->need_locale) { @@ -3436,8 +3431,6 @@ NUM_prepare_locale(NUMProc *Np) } else { -#endif - /* * Default values */ @@ -3446,10 +3439,7 @@ NUM_prepare_locale(NUMProc *Np) Np->decimal = "."; Np->L_thousands_sep = ","; Np->L_currency_symbol = " "; - -#ifdef USE_LOCALE } -#endif } /* ---------- diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 2c86ff5bcf1..c5c8d312d3f 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -1,173 +1,144 @@ -/* ----------------------------------------------------------------------- - * pg_locale.c +/*----------------------------------------------------------------------- * - * The PostgreSQL locale utils. + * PostgreSQL locale utilities * + * $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v 1.16 2002/04/03 05:39:31 petere Exp $ * - * $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v 1.15 2002/03/06 06:10:14 momjian Exp $ + * Portions Copyright (c) 2002, PostgreSQL Global Development Group * - * Portions Copyright (c) 1999-2000, PostgreSQL Global Development Group - * - * Karel Zak - * - * ----------------------------------------------------------------------- + *----------------------------------------------------------------------- */ #include "postgres.h" - -#ifdef USE_LOCALE - -#include <locale.h> - #include "utils/pg_locale.h" - -/* #define DEBUG_LOCALE_UTILS */ +#include <locale.h> -static bool CurrentLocaleConvValid = false; -static struct lconv CurrentLocaleConv; +/* GUC storage area */ +char * locale_messages; +char * locale_monetary; +char * locale_numeric; +char * locale_time; -static void PGLC_setlocale(PG_LocaleCategories *lc); +/* GUC parse hooks */ -/*------ - * Frees memory used in PG_LocaleCategories -- this memory is - * allocated in PGLC_current(). - *------ - */ -void -PGLC_free_categories(PG_LocaleCategories *lc) +bool locale_messages_check(const char *proposed) { - if (lc->lc_ctype) - pfree(lc->lc_ctype); - if (lc->lc_numeric) - pfree(lc->lc_numeric); - if (lc->lc_time) - pfree(lc->lc_time); - if (lc->lc_collate) - pfree(lc->lc_collate); - if (lc->lc_monetary); - pfree(lc->lc_monetary); #ifdef LC_MESSAGES - if (lc->lc_messages) - pfree(lc->lc_messages); + return chklocale(LC_MESSAGES, proposed); +#else + /* We return true here so LC_MESSAGES can be set in the + configuration file on every system. */ + return true; #endif } -/*------ - * Return in PG_LocaleCategories the current locale settings. - * - * NB: strings are allocated in the current memory context! - *------ - */ -void -PGLC_current(PG_LocaleCategories *lc) +bool locale_monetary_check(const char *proposed) { - lc->lang = getenv("LANG"); + return chklocale(LC_MONETARY, proposed); +} - lc->lc_ctype = pstrdup(setlocale(LC_CTYPE, NULL)); - lc->lc_numeric = pstrdup(setlocale(LC_NUMERIC, NULL)); - lc->lc_time = pstrdup(setlocale(LC_TIME, NULL)); - lc->lc_collate = pstrdup(setlocale(LC_COLLATE, NULL)); - lc->lc_monetary = pstrdup(setlocale(LC_MONETARY, NULL)); -#ifdef LC_MESSAGES - lc->lc_messages = pstrdup(setlocale(LC_MESSAGES, NULL)); -#endif +bool locale_numeric_check(const char *proposed) +{ + return chklocale(LC_NUMERIC, proposed); } +bool locale_time_check(const char *proposed) +{ + return chklocale(LC_TIME, proposed); +} -#ifdef DEBUG_LOCALE_UTILS +/* GUC assign hooks */ -/*------ - * Print a PG_LocaleCategories struct as DEBUG - *------ - */ -static void -PGLC_debug_lc(PG_LocaleCategories *lc) +void locale_messages_assign(const char *value) { #ifdef LC_MESSAGES - elog(LOG, "CURRENT LOCALE ENVIRONMENT:\n\nLANG: \t%s\nLC_CTYPE:\t%s\nLC_NUMERIC:\t%s\nLC_TIME:\t%s\nLC_COLLATE:\t%s\nLC_MONETARY:\t%s\nLC_MESSAGES:\t%s\n", - lc->lang, - lc->lc_ctype, - lc->lc_numeric, - lc->lc_time, - lc->lc_collate, - lc->lc_monetary, - lc->lc_messages); -#else - elog(LOG, "CURRENT LOCALE ENVIRONMENT:\n\nLANG: \t%s\nLC_CTYPE:\t%s\nLC_NUMERIC:\t%s\nLC_TIME:\t%s\nLC_COLLATE:\t%s\nLC_MONETARY:\t%s\n", - lc->lang, - lc->lc_ctype, - lc->lc_numeric, - lc->lc_time, - lc->lc_collate, - lc->lc_monetary); + setlocale(LC_MESSAGES, value); #endif } -#endif -/*------ - * Set locales via a PG_LocaleCategories struct - * - * NB: it would be very dangerous to set the locale values to any random - * choice of locale, since that could cause indexes to become corrupt, etc. - * Therefore this routine is NOT exported from this module. It should be - * used only to restore previous locale settings during PGLC_localeconv. - *------ +void locale_monetary_assign(const char *value) +{ + setlocale(LC_MONETARY, value); +} + +void locale_numeric_assign(const char *value) +{ + setlocale(LC_NUMERIC, value); +} + +void locale_time_assign(const char *value) +{ + setlocale(LC_TIME, value); +} + + +/* + * Returns true if the proposed string represents a valid locale of + * the given category. This is probably pretty slow, but it's not + * called in critical places. */ -static void -PGLC_setlocale(PG_LocaleCategories *lc) +bool +chklocale(int category, const char *proposed) { - if (!setlocale(LC_COLLATE, lc->lc_collate)) - elog(WARNING, "pg_setlocale(): 'LC_COLLATE=%s' cannot be honored.", - lc->lc_collate); + char *save; - if (!setlocale(LC_CTYPE, lc->lc_ctype)) - elog(WARNING, "pg_setlocale(): 'LC_CTYPE=%s' cannot be honored.", - lc->lc_ctype); + save = setlocale(category, NULL); + if (!save) + return false; - if (!setlocale(LC_NUMERIC, lc->lc_numeric)) - elog(WARNING, "pg_setlocale(): 'LC_NUMERIC=%s' cannot be honored.", - lc->lc_numeric); + if (!setlocale(category, proposed)) + return false; - if (!setlocale(LC_TIME, lc->lc_time)) - elog(WARNING, "pg_setlocale(): 'LC_TIME=%s' cannot be honored.", - lc->lc_time); + setlocale(category, save); + return true; +} - if (!setlocale(LC_MONETARY, lc->lc_monetary)) - elog(WARNING, "pg_setlocale(): 'LC_MONETARY=%s' cannot be honored.", - lc->lc_monetary); -#ifdef LC_MESSAGES - if (!setlocale(LC_MESSAGES, lc->lc_messages)) - elog(WARNING, "pg_setlocale(): 'LC_MESSAGES=%s' cannot be honored.", - lc->lc_messages); -#endif +/* + * We'd like to cache whether LC_COLLATE is C (or POSIX), so we can + * optimize a few code paths in various places. + */ +bool +lc_collate_is_c(void) +{ + /* Cache result so we only have to compute it once */ + static int result = -1; + char *localeptr; + + if (result >= 0) + return (bool) result; + localeptr = setlocale(LC_COLLATE, NULL); + if (!localeptr) + elog(PANIC, "Invalid LC_COLLATE setting"); + + if (strcmp(localeptr, "C") == 0) + result = true; + else if (strcmp(localeptr, "POSIX") == 0) + result = true; + else + result = false; + return (bool) result; } -/*------ - * Return the POSIX lconv struct (contains number/money formatting information) - * with locale information for all categories. Note that returned lconv - * does not depend on currently active category settings, but on external - * environment variables for locale. - *------ + + +/* + * Return the POSIX lconv struct (contains number/money formatting + * information) with locale information for all categories. */ struct lconv * PGLC_localeconv(void) { - PG_LocaleCategories lc; struct lconv *extlconv; + static bool CurrentLocaleConvValid = false; + static struct lconv CurrentLocaleConv; /* Did we do it already? */ if (CurrentLocaleConvValid) return &CurrentLocaleConv; - /* Save current locale setting to lc */ - PGLC_current(&lc); - - /* Set all locale categories based on postmaster's environment vars */ - setlocale(LC_ALL, ""); - /* Get formatting information for the external environment */ extlconv = localeconv(); @@ -187,14 +158,6 @@ PGLC_localeconv(void) CurrentLocaleConv.negative_sign = strdup(extlconv->negative_sign); CurrentLocaleConv.positive_sign = strdup(extlconv->positive_sign); - /* Restore Postgres' internal locale settings */ - PGLC_setlocale(&lc); - - /* Deallocate category settings allocated in PGLC_current() */ - PGLC_free_categories(&lc); - CurrentLocaleConvValid = true; return &CurrentLocaleConv; } - -#endif /* USE_LOCALE */ diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index f5fb2adf2eb..e8e71dec25a 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.106 2002/03/08 04:29:01 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.107 2002/04/03 05:39:31 petere Exp $ * *------------------------------------------------------------------------- */ @@ -70,9 +70,7 @@ #include <ctype.h> #include <math.h> -#ifdef USE_LOCALE #include <locale.h> -#endif #include "access/heapam.h" #include "catalog/catname.h" @@ -95,6 +93,7 @@ #include "utils/datum.h" #include "utils/int8.h" #include "utils/lsyscache.h" +#include "utils/pg_locale.h" #include "utils/selfuncs.h" #include "utils/syscache.h" @@ -2240,19 +2239,16 @@ convert_one_string_to_scalar(unsigned char *value, int rangelo, int rangehi) /* * Convert a string-type Datum into a palloc'd, null-terminated string. * - * If USE_LOCALE is defined, we must pass the string through strxfrm() + * When using a non-C locale, we must pass the string through strxfrm() * before continuing, so as to generate correct locale-specific results. */ static unsigned char * convert_string_datum(Datum value, Oid typid) { char *val; - -#ifdef USE_LOCALE char *xfrmstr; size_t xfrmsize; size_t xfrmlen; -#endif switch (typid) { @@ -2290,21 +2286,22 @@ convert_string_datum(Datum value, Oid typid) return NULL; } -#ifdef USE_LOCALE - /* Guess that transformed string is not much bigger than original */ - xfrmsize = strlen(val) + 32; /* arbitrary pad value here... */ - xfrmstr = (char *) palloc(xfrmsize); - xfrmlen = strxfrm(xfrmstr, val, xfrmsize); - if (xfrmlen >= xfrmsize) + if (!lc_collate_is_c()) { - /* Oops, didn't make it */ - pfree(xfrmstr); - xfrmstr = (char *) palloc(xfrmlen + 1); - xfrmlen = strxfrm(xfrmstr, val, xfrmlen + 1); + /* Guess that transformed string is not much bigger than original */ + xfrmsize = strlen(val) + 32; /* arbitrary pad value here... */ + xfrmstr = (char *) palloc(xfrmsize); + xfrmlen = strxfrm(xfrmstr, val, xfrmsize); + if (xfrmlen >= xfrmsize) + { + /* Oops, didn't make it */ + pfree(xfrmstr); + xfrmstr = (char *) palloc(xfrmlen + 1); + xfrmlen = strxfrm(xfrmstr, val, xfrmlen + 1); + } + pfree(val); + val = xfrmstr; } - pfree(val); - val = xfrmstr; -#endif return (unsigned char *) val; } @@ -3147,44 +3144,28 @@ pattern_selectivity(char *patt, Pattern_Type ptype) return result; } + /* - * Test whether the database's LOCALE setting is safe for LIKE/regexp index - * optimization. The key requirement here is that given a prefix string, - * say "foo", we must be able to generate another string "fop" that is - * greater than all strings "foobar" starting with "foo". Unfortunately, - * many non-C locales have bizarre collation rules in which "fop" > "foo" - * is not sufficient to ensure "fop" > "foobar". Until we can come up - * with a more bulletproof way of generating the upper-bound string, - * disable the optimization in locales where it is not known to be safe. + * We want test whether the database's LC_COLLATE setting is safe for + * LIKE/regexp index optimization. + * + * The key requirement here is that given a prefix string, say "foo", + * we must be able to generate another string "fop" that is greater + * than all strings "foobar" starting with "foo". Unfortunately, a + * non-C locale may have arbitrary collation rules in which "fop" > + * "foo" is not sufficient to ensure "fop" > "foobar". Until we can + * come up with a more bulletproof way of generating the upper-bound + * string, the optimization is disabled in all non-C locales. + * + * (In theory, locales other than C may be LIKE-safe so this function + * could be different from lc_collate_is_c(), but in a different + * theory, non-C locales are completely unpredicable so it's unlikely + * to happen.) */ bool locale_is_like_safe(void) { -#ifdef USE_LOCALE - /* Cache result so we only have to compute it once */ - static int result = -1; - char *localeptr; - - if (result >= 0) - return (bool) result; - localeptr = setlocale(LC_COLLATE, NULL); - if (!localeptr) - elog(PANIC, "Invalid LC_COLLATE setting"); - - /* - * Currently we accept only "C" and "POSIX" (do any systems still - * return "POSIX"?). Which other locales allow safe optimization? - */ - if (strcmp(localeptr, "C") == 0) - result = true; - else if (strcmp(localeptr, "POSIX") == 0) - result = true; - else - result = false; - return (bool) result; -#else /* not USE_LOCALE */ - return true; /* We must be in C locale, which is OK */ -#endif /* USE_LOCALE */ + return lc_collate_is_c(); } /* diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index 5afaf398879..0cd38a76bee 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.81 2002/04/01 03:34:26 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.82 2002/04/03 05:39:32 petere Exp $ * *------------------------------------------------------------------------- */ @@ -19,6 +19,7 @@ #include "mb/pg_wchar.h" #include "miscadmin.h" #include "utils/builtins.h" +#include "utils/pg_locale.h" static int text_cmp(text *arg1, text *arg2); @@ -493,29 +494,36 @@ varstr_cmp(char *arg1, int len1, char *arg2, int len2) char *a1p, *a2p; -#ifdef USE_LOCALE - a1p = (char *) palloc(len1 + 1); - a2p = (char *) palloc(len2 + 1); - - memcpy(a1p, arg1, len1); - *(a1p + len1) = '\0'; - memcpy(a2p, arg2, len2); - *(a2p + len2) = '\0'; - - result = strcoll(a1p, a2p); + /* + * Unfortunately, there is no strncoll(), so in the non-C locale + * case we have to do some memory copying. This turns out to be + * significantly slower, so we optimize the case were LC_COLLATE + * is C. + */ + if (!lc_collate_is_c()) + { + a1p = (char *) palloc(len1 + 1); + a2p = (char *) palloc(len2 + 1); - pfree(a1p); - pfree(a2p); + memcpy(a1p, arg1, len1); + *(a1p + len1) = '\0'; + memcpy(a2p, arg2, len2); + *(a2p + len2) = '\0'; -#else + result = strcoll(a1p, a2p); - a1p = arg1; - a2p = arg2; + pfree(a1p); + pfree(a2p); + } + else + { + a1p = arg1; + a2p = arg2; - result = strncmp(a1p, a2p, Min(len1, len2)); - if ((result == 0) && (len1 != len2)) - result = (len1 < len2) ? -1 : 1; -#endif + result = strncmp(a1p, a2p, Min(len1, len2)); + if ((result == 0) && (len1 != len2)) + result = (len1 < len2) ? -1 : 1; + } return result; } diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 9c35f0949aa..8abf451b630 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -4,7 +4,7 @@ * Support for grand unified configuration scheme, including SET * command, configuration file, and command line options. * - * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.64 2002/04/01 03:34:26 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.65 2002/04/03 05:39:32 petere Exp $ * * Copyright 2000 by PostgreSQL Global Development Group * Written by Peter Eisentraut <peter_e@gmx.net>. @@ -41,6 +41,7 @@ #include "utils/builtins.h" #include "utils/datetime.h" #include "utils/elog.h" +#include "utils/pg_locale.h" #include "pgstat.h" @@ -585,6 +586,26 @@ static struct config_string PG_KRB_SRVTAB, NULL, NULL }, + { + "lc_messages", PGC_POSTMASTER, PGC_S_DEFAULT, &locale_messages, + "", locale_messages_check, locale_messages_assign + }, + + { + "lc_monetary", PGC_POSTMASTER, PGC_S_DEFAULT, &locale_monetary, + "", locale_monetary_check, locale_monetary_assign + }, + + { + "lc_numeric", PGC_POSTMASTER, PGC_S_DEFAULT, &locale_numeric, + "", locale_numeric_check, locale_numeric_assign + }, + + { + "lc_time", PGC_POSTMASTER, PGC_S_DEFAULT, &locale_time, + "", locale_time_check, locale_time_assign + }, + { "server_min_messages", PGC_USERSET, PGC_S_DEFAULT, &server_min_messages_str, server_min_messages_str_default, check_server_min_messages, diff --git a/src/bin/initdb/initdb.sh b/src/bin/initdb/initdb.sh index 2bb413844f1..e028ac1b10e 100644 --- a/src/bin/initdb/initdb.sh +++ b/src/bin/initdb/initdb.sh @@ -27,7 +27,7 @@ # Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # -# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.145 2002/03/02 21:39:34 momjian Exp $ +# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.146 2002/04/03 05:39:32 petere Exp $ # #------------------------------------------------------------------------- @@ -51,6 +51,26 @@ exit_nicely(){ exit 1 } +pg_getlocale(){ + arg=$1 + unset ret + + for var in "PGLC_$arg" PGLOCALE LC_ALL "LC_$arg" LANG; do + varset=`eval echo '${'"$var"'+set}'` + varval=`eval echo '$'"$var"` + if test "$varset" = set; then + ret=$varval + break + fi + done + + if test "${ret+set}" != set; then + ret=C + fi + + echo "$ret" +} + CMDNAME=`basename $0` @@ -251,11 +271,61 @@ do -E*) MULTIBYTE=`echo $1 | sed 's/^-E//'` ;; +# Locale flags + --locale) + PGLOCALE="$2" + shift;; + --locale=*) + PGLOCALE=`echo $1 | sed 's/^[^=]*=//'` + ;; + --no-locale) + PGLOCALE=C + ;; + + --lc-collate) + PGLC_COLLATE=$2 + shift;; + --lc-collate=*) + PGLC_COLLATE=`echo $1 | sed 's/^[^=]*=//'` + ;; + --lc-ctype) + PGLC_CTYPE=$2 + shift;; + --lc-ctype=*) + PGLC_CTYPE=`echo $1 | sed 's/^[^=]*=//'` + ;; + --lc-messages) + PGLC_MESSAGES=$2 + shift;; + --lc-messages=*) + PGLC_MESSAGES=`echo $1 | sed 's/^[^=]*=//'` + ;; + --lc-monetary) + PGLC_MONETARY=$2 + shift;; + --lc-monetary=*) + PGLC_MONETARY=`echo $1 | sed 's/^[^=]*=//'` + ;; + --lc-numeric) + PGLC_NUMERIC=$2 + shift;; + --lc-numeric=*) + PGLC_NUMERIC=`echo $1 | sed 's/^[^=]*=//'` + ;; + --lc-time) + PGLC_TIME=$2 + shift;; + --lc-time=*) + PGLC_TIME=`echo $1 | sed 's/^[^=]*=//'` + ;; + -*) echo "$CMDNAME: invalid option: $1" echo "Try '$CMDNAME --help' for more information." exit 1 ;; + +# Non-option argument specifies data directory *) PGDATA=$1 ;; @@ -275,6 +345,13 @@ if [ "$usage" ]; then if [ -n "$MULTIBYTE" ] ; then echo " -E, --encoding ENCODING Set default encoding for new databases" fi + echo " --locale LOCALE Initialize database cluster with given locale" + echo " --lc-collate, --lc-ctype, --lc-messages LOCALE" + echo " --lc-monetary, --lc-numeric, --lc-time LOCALE" + echo " Initialize database cluster with given locale" + echo " in the respective category" + echo " (default taken from environment)" + echo " --no-locale Equivalent to --locale=C" echo " -U, --username NAME Database superuser name" echo "Less commonly used options: " echo " -L DIRECTORY Where to find the input files" @@ -469,7 +546,15 @@ echo "$short_version" > "$PGDATA/PG_VERSION" || exit_nicely cat "$POSTGRES_BKI" \ | sed -e "s/POSTGRES/$POSTGRES_SUPERUSERNAME/g" \ -e "s/ENCODING/$MULTIBYTEID/g" \ -| "$PGPATH"/postgres -boot -x1 $PGSQL_OPT $BACKEND_TALK_ARG template1 \ +| +( + LC_COLLATE=`pg_getlocale COLLATE` + LC_CTYPE=`pg_getlocale CTYPE` + export LC_COLLATE + export LC_CTYPE + unset LC_ALL + "$PGPATH"/postgres -boot -x1 $PGSQL_OPT $BACKEND_TALK_ARG template1 +) \ || exit_nicely # Make the per-database PGVERSION for template1 only after init'ing it @@ -485,7 +570,19 @@ $ECHO_N "creating configuration files... "$ECHO_C cp "$PG_HBA_SAMPLE" "$PGDATA"/pg_hba.conf || exit_nicely cp "$PG_IDENT_SAMPLE" "$PGDATA"/pg_ident.conf || exit_nicely -cp "$POSTGRESQL_CONF_SAMPLE" "$PGDATA"/postgresql.conf || exit_nicely +( + cat "$POSTGRESQL_CONF_SAMPLE" + echo + echo + echo "#" + echo "# Locale settings" + echo "#" + echo "# (initialized by initdb -- may be changed)" + for cat in MESSAGES MONETARY NUMERIC TIME; do + echo "LC_$cat = '`pg_getlocale $cat`'" + done +) > "$PGDATA"/postgresql.conf || exit_nicely + chmod 0600 "$PGDATA"/pg_hba.conf "$PGDATA"/pg_ident.conf \ "$PGDATA"/postgresql.conf diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 8a509e3d89a..cd27d28fa3c 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -8,7 +8,7 @@ * or in pg_config.h afterwards. Of course, if you edit pg_config.h, then your * changes will be overwritten the next time you run configure. * - * $Id: pg_config.h.in,v 1.19 2002/03/29 17:32:55 petere Exp $ + * $Id: pg_config.h.in,v 1.20 2002/04/03 05:39:33 petere Exp $ */ #ifndef PG_CONFIG_H @@ -33,9 +33,6 @@ /* A canonical string containing the version number, platform, and C compiler */ #undef PG_VERSION_STR -/* Set to 1 if you want LOCALE support (--enable-locale) */ -#undef USE_LOCALE - /* Set to 1 if you want cyrillic recode (--enable-recode) */ #undef CYR_RECODE diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h index 03330682b75..b5056e6ca80 100644 --- a/src/include/utils/pg_locale.h +++ b/src/include/utils/pg_locale.h @@ -1,56 +1,42 @@ -/* ----------------------------------------------------------------------- - * pg_locale.h +/*----------------------------------------------------------------------- * - * The PostgreSQL locale utils. + * PostgreSQL locale utilities * + * $Header: /cvsroot/pgsql/src/include/utils/pg_locale.h,v 1.12 2002/04/03 05:39:33 petere Exp $ * - * $Id: pg_locale.h,v 1.11 2001/11/05 17:46:36 momjian Exp $ + * Copyright (c) 2002, PostgreSQL Global Development Group * - * Portions Copyright (c) 1999-2000, PostgreSQL Global Development Group - * - * Karel Zak - Zakkr - * - * ----------------------------------------------------------------------- + *----------------------------------------------------------------------- */ #ifndef _PG_LOCALE_ #define _PG_LOCALE_ -#ifdef USE_LOCALE +#include "postgres.h" +#include <locale.h> -/*------ - * POSIX locale categories and environment variable LANG - *------ - */ -typedef struct PG_LocaleCategories -{ - char *lang, - *lc_ctype, - *lc_numeric, - *lc_time, - *lc_collate, - *lc_monetary, - *lc_messages; -} PG_LocaleCategories; +extern char * locale_messages; +extern char * locale_monetary; +extern char * locale_numeric; +extern char * locale_time; -/* - * Save locale category settings into PG memory - */ -extern void PGLC_current(PG_LocaleCategories *lc); +bool locale_messages_check(const char *proposed); +bool locale_monetary_check(const char *proposed); +bool locale_numeric_check(const char *proposed); +bool locale_time_check(const char *proposed); + +void locale_messages_assign(const char *value); +void locale_monetary_assign(const char *value); +void locale_numeric_assign(const char *value); +void locale_time_assign(const char *value); + +bool chklocale(int category, const char *proposed); +bool lc_collate_is_c(void); /* - * Free memory allocated in PGLC_current() - */ -extern void PGLC_free_categories(PG_LocaleCategories *lc); - -/*------ - * Return the POSIX lconv struct (contains number/money formatting information) - * with locale information for all categories. Note that returned lconv - * does not depend on currently active category settings, but on external - * environment variables for locale. - *------ + * Return the POSIX lconv struct (contains number/money formatting + * information) with locale information for all categories. */ extern struct lconv *PGLC_localeconv(void); -#endif /* USE_LOCALE */ #endif /* _PG_LOCALE_ */ -- GitLab