]> granicus.if.org Git - postgresql/commitdiff
Make LC_COLLATE and LC_CTYPE database-level settings. Collation and
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Tue, 23 Sep 2008 09:20:39 +0000 (09:20 +0000)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Tue, 23 Sep 2008 09:20:39 +0000 (09:20 +0000)
ctype are now more like encoding, stored in new datcollate and datctype
columns in pg_database.

This is a stripped-down version of Radek Strnad's patch, with further
changes by me.

30 files changed:
doc/src/sgml/catalogs.sgml
doc/src/sgml/charset.sgml
doc/src/sgml/indices.sgml
doc/src/sgml/ref/create_database.sgml
doc/src/sgml/ref/initdb.sgml
doc/src/sgml/ref/pg_controldata.sgml
doc/src/sgml/ref/pg_resetxlog.sgml
doc/src/sgml/ref/select.sgml
doc/src/sgml/ref/show.sgml
doc/src/sgml/runtime.sgml
doc/src/sgml/textsearch.sgml
src/backend/access/transam/xlog.c
src/backend/commands/dbcommands.c
src/backend/parser/gram.y
src/backend/parser/keywords.c
src/backend/postmaster/postmaster.c
src/backend/utils/adt/pg_locale.c
src/backend/utils/init/postinit.c
src/bin/initdb/initdb.c
src/bin/pg_controldata/pg_controldata.c
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dumpall.c
src/bin/pg_resetxlog/pg_resetxlog.c
src/bin/psql/describe.c
src/bin/scripts/createdb.c
src/include/catalog/catversion.h
src/include/catalog/pg_control.h
src/include/catalog/pg_database.h
src/include/utils/pg_locale.h
src/interfaces/ecpg/preproc/preproc.y

index 40f1ce568ed47495d3cf4c4ce9b20253a457019d..bf1ac314f73c299cb7cd3dd5f214f80818b4ca6b 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.175 2008/09/19 19:03:40 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.176 2008/09/23 09:20:33 heikki Exp $ -->
 <!--
  Documentation of the system catalogs, directed toward PostgreSQL developers
  -->
            this number to the encoding name)</entry>
      </row>
 
+     <row>
+      <entry><structfield>datcollate</structfield></entry>
+      <entry><type>name</type></entry>
+      <entry></entry>
+      <entry>LC_COLLATE for this database</entry>
+     </row>
+
+     <row>
+      <entry><structfield>datctype</structfield></entry>
+      <entry><type>name</type></entry>
+      <entry></entry>
+      <entry>LC_CTYPE for this database</entry>
+     </row>
+
      <row>
       <entry><structfield>datistemplate</structfield></entry>
       <entry><type>bool</type></entry>
index 1f4866b203c9609751b9d276f1c053f3337cbde7..c012294ef81f1ccdbdd4a99152accd9a80050474 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/charset.sgml,v 2.87 2008/07/15 17:45:03 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/charset.sgml,v 2.88 2008/09/23 09:20:34 heikki Exp $ -->
 
 <chapter id="charset">
  <title>Localization</>
@@ -130,23 +130,23 @@ initdb --locale=sv_SE
 
    <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.
+    fixed when the database is created.  You can use different settings
+    for different databases, but once a database is created, you cannot
+    change them for that database 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.  The default values for these
+    categories are defined when <command>initdb</command> is run, and
+    those values are used when new databases are created, unless
+    specified otherwise in the <command>CREATE DATABASE</command> command.
    </para>
 
    <para>
     The other locale categories can be changed as desired whenever the
     server is running by setting the run-time configuration variables
     that have the same name as the locale categories (see <xref
-    linkend="runtime-config-client-format"> for details).  The defaults that are
-    chosen by <command>initdb</command> are actually only written into
+    linkend="runtime-config-client-format"> 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 these
     assignments from <filename>postgresql.conf</filename> then the
@@ -261,7 +261,7 @@ initdb --locale=sv_SE
 
    <para>
     Check that <productname>PostgreSQL</> is actually using the locale
-    that you think it is.  <envar>LC_COLLATE</> and <envar>LC_CTYPE</>
+    that you think it is.  The default <envar>LC_COLLATE</> and <envar>LC_CTYPE</>
     settings are determined at <command>initdb</> time and cannot be
     changed without repeating <command>initdb</>.  Other locale
     settings including <envar>LC_MESSAGES</> and <envar>LC_MONETARY</>
@@ -319,17 +319,11 @@ initdb --locale=sv_SE
   </para>
 
   <para>
-   An important restriction, however, is that each database character set
-   must be compatible with the server's <envar>LC_CTYPE</> setting.
+   An important restriction, however, is that each database's character set
+   must be compatible with the database's <envar>LC_CTYPE</> setting.
    When <envar>LC_CTYPE</> is <literal>C</> or <literal>POSIX</>, any
    character set is allowed, but for other settings of <envar>LC_CTYPE</>
    there is only one character set that will work correctly.
-   Since the <envar>LC_CTYPE</> setting is frozen by <command>initdb</>, the
-   apparent flexibility to use different encodings in different databases
-   of a cluster is more theoretical than real, except when you select
-   <literal>C</> or <literal>POSIX</> locale (thus disabling any real locale
-   awareness).  It is likely that these mechanisms will be revisited in future
-   versions of <productname>PostgreSQL</productname>.
   </para>
 
    <sect2 id="multibyte-charset-supported">
@@ -734,19 +728,19 @@ initdb -E EUC_JP
     </para>
 
     <para>
-     If you have selected <literal>C</> or <literal>POSIX</> locale,
-     you can create a database with a different character set:
+     You can specify a non-default encoding at database creation time,
+     provided that the encoding is compatible with the selected locale:
 
 <screen>
-createdb -E EUC_KR korean
+createdb -E EUC_KR -T template0 --lc-collate=ko_KR.euckr --lc-ctype=ko_KR.euckr korean
 </screen>
 
      This will create a database named <literal>korean</literal> that
-     uses the character set <literal>EUC_KR</literal>.  Another way to
-     accomplish this is to use this SQL command:
+     uses the character set <literal>EUC_KR</literal>, and locale <literal>ko_KR</literal>.
+     Another way to accomplish this is to use this SQL command:
 
 <programlisting>
-CREATE DATABASE korean WITH ENCODING 'EUC_KR';
+CREATE DATABASE korean WITH ENCODING 'EUC_KR' COLLATE='ko_KR.euckr' CTYPE='ko_KR.euckr' TEMPLATE=template0;
 </programlisting>
 
      The encoding for a database is stored in the system catalog
@@ -756,20 +750,17 @@ CREATE DATABASE korean WITH ENCODING 'EUC_KR';
 
 <screen>
 $ <userinput>psql -l</userinput>
-            List of databases
-   Database    |  Owner  |   Encoding    
----------------+---------+---------------
- euc_cn        | t-ishii | EUC_CN
- euc_jp        | t-ishii | EUC_JP
- euc_kr        | t-ishii | EUC_KR
- euc_tw        | t-ishii | EUC_TW
- mule_internal | t-ishii | MULE_INTERNAL
- postgres      | t-ishii | EUC_JP
- regression    | t-ishii | SQL_ASCII
- template1     | t-ishii | EUC_JP
- test          | t-ishii | EUC_JP
- utf8          | t-ishii | UTF8
-(9 rows)
+                                         List of databases
+   Name    |  Owner   | Encoding  |  Collation  |    Ctype    |          Access Privileges          
+-----------+----------+-----------+-------------+-------------+-------------------------------------
+ clocaledb | hlinnaka | SQL_ASCII | C           | C           | 
+ englishdb | hlinnaka | UTF8      | en_GB.UTF8  | en_GB.UTF8  | 
+ japanese  | hlinnaka | UTF8      | ja_JP.UTF8  | ja_JP.UTF8  | 
+ korean    | hlinnaka | EUC_KR    | ko_KR.euckr | ko_KR.euckr | 
+ postgres  | hlinnaka | UTF8      | fi_FI.UTF8  | fi_FI.UTF8  | 
+ template0 | hlinnaka | UTF8      | fi_FI.UTF8  | fi_FI.UTF8  | {=c/hlinnaka,hlinnaka=CTc/hlinnaka}
+ template1 | hlinnaka | UTF8      | fi_FI.UTF8  | fi_FI.UTF8  | {=c/hlinnaka,hlinnaka=CTc/hlinnaka}
+(7 rows)
 </screen>
     </para>
 
index 2ab713c39becbe9f99e642199e351fe2878f5aa6..0993a8be03f28ece627a7294e4b3876ae4c1b2bd 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/indices.sgml,v 1.74 2008/07/11 21:06:28 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/indices.sgml,v 1.75 2008/09/23 09:20:34 heikki Exp $ -->
 
 <chapter id="indexes">
  <title id="indexes-title">Indexes</title>
@@ -157,7 +157,7 @@ CREATE INDEX test1_id_index ON test1 (id);
    <emphasis>if</emphasis> the pattern is a constant and is anchored to
    the beginning of the string &mdash; for example, <literal>col LIKE
    'foo%'</literal> or <literal>col ~ '^foo'</literal>, but not
-   <literal>col LIKE '%bar'</literal>. However, if your server does not
+   <literal>col LIKE '%bar'</literal>. However, if your database does not
    use the C locale you will need to create the index with a special
    operator class to support indexing of pattern-matching queries. See
    <xref linkend="indexes-opclass"> below. It is also possible to use
@@ -922,7 +922,7 @@ CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable>
       according to the locale-specific collation rules.  This makes
       these operator classes suitable for use by queries involving
       pattern matching expressions (<literal>LIKE</literal> or POSIX
-      regular expressions) when the server does not use the standard
+      regular expressions) when the database does not use the standard
       <quote>C</quote> locale.  As an example, you might index a
       <type>varchar</type> column like this:
 <programlisting>
index b1b133324560e72301e72845ceca98dbd9c2a5ac..5e72768981c29ef15135e39ac378b5b211ded47e 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_database.sgml,v 1.48 2007/09/28 22:25:49 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_database.sgml,v 1.49 2008/09/23 09:20:34 heikki Exp $
 PostgreSQL documentation
 -->
 
@@ -24,6 +24,8 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
     [ [ WITH ] [ OWNER [=] <replaceable class="parameter">dbowner</replaceable> ]
            [ TEMPLATE [=] <replaceable class="parameter">template</replaceable> ]
            [ ENCODING [=] <replaceable class="parameter">encoding</replaceable> ]
+           [ COLLATE [=] <replaceable class="parameter">collate</replaceable> ]
+           [ CTYPE [=] <replaceable class="parameter">ctype</replaceable> ]
            [ TABLESPACE [=] <replaceable class="parameter">tablespace</replaceable> ]
            [ CONNECTION LIMIT [=] <replaceable class="parameter">connlimit</replaceable> ] ]
 </synopsis>
@@ -112,6 +114,29 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
        </para>
       </listitem>
      </varlistentry>
+     <varlistentry>
+      <term><replaceable class="parameter">collate</replaceable></term>
+      <listitem>
+       <para>
+        Collation order (<literal>LC_COLLATE</>) to use in the new database.
+        This affects the sort order applied to strings, e.g in queries with
+        ORDER BY, as well as the order used in indexes on text columns.
+        The default is to use the collation order of the template database.
+        See below for additional restrictions.
+       </para>
+      </listitem>
+     </varlistentry>
+     <varlistentry>
+      <term><replaceable class="parameter">ctype</replaceable></term>
+      <listitem>
+       <para>
+        Character classification (<literal>LC_CTYPE</>) to use in the new
+        database. This affects the categorization of characters, e.g. lower,
+        upper and digit. The default is to use the character classification of
+        the template database. See below for additional restrictions.
+       </para>
+      </listitem>
+     </varlistentry>
      <varlistentry>
       <term><replaceable class="parameter">tablespace</replaceable></term>
       <listitem>
@@ -180,13 +205,11 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
   </para>
 
   <para>
-   Any character set encoding specified for the new database must be
-   compatible with the server's <envar>LC_CTYPE</> locale setting.
+   The character set encoding specified for the new database must be
+   compatible with the chosen COLLATE and CTYPE settings.
    If <envar>LC_CTYPE</> is <literal>C</> (or equivalently
    <literal>POSIX</>), then all encodings are allowed, but for other
-   locale settings there is only one encoding that will work properly,
-   and so the apparent freedom to specify an encoding is illusory if
-   you didn't initialize the database cluster in <literal>C</> locale.
+   locale settings there is only one encoding that will work properly.
    <command>CREATE DATABASE</> will allow superusers to specify
    <literal>SQL_ASCII</> encoding regardless of the locale setting,
    but this choice is deprecated and may result in misbehavior of
@@ -194,6 +217,16 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
    with the locale is stored in the database.
   </para>
 
+  <para>
+   The <literal>COLLATE</> and <literal>CTYPE</> settings must match
+   those of the template database, except when template0 is used as
+   template. This is because <literal>COLLATE</> and <literal>CTYPE</>
+   affects the ordering in indexes, so that any indexes copied from the
+   template database would be invalid in the new database with different
+   settings. <literal>template0</literal>, however, is known to not
+   contain any indexes that would be affected.
+  </para>
+
   <para>
    The <literal>CONNECTION LIMIT</> option is only enforced approximately;
    if two new sessions start at about the same time when just one
index 312da7085a9706a45890da609158f3698e5d8774..110c21eb8c5f0e277a0c130b0bc954916cc8202a 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/initdb.sgml,v 1.43 2007/03/26 17:23:36 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/initdb.sgml,v 1.44 2008/09/23 09:20:34 heikki Exp $
 PostgreSQL documentation
 -->
 
@@ -76,25 +76,34 @@ PostgreSQL documentation
 
   <para>
    <command>initdb</command> initializes the database cluster's default
-   locale and character set encoding. The collation order
-   (<literal>LC_COLLATE</>) and character set classes
-   (<literal>LC_CTYPE</>, e.g. upper, lower, digit) are fixed for all
-   databases and cannot be changed. Collation orders other than
-   <literal>C</> or <literal>POSIX</> also have a performance penalty.
-   For these reasons it is important to choose the right locale when
-   running <command>initdb</command>. The remaining locale categories
-   can be changed later when the server is started. All server locale
-   values (<literal>lc_*</>) can be displayed via <command>SHOW ALL</>.
+   locale and character set encoding. The character set encoding,
+   collation order (<literal>LC_COLLATE</>) and character set classes
+   (<literal>LC_CTYPE</>, e.g. upper, lower, digit) can be set separately
+   for a database when it is created. <command>initdb</command> determines
+   those settings for the <literal>template1</literal> database, which will
+   serve as the default for all other databases.
+  </para>
+
+  <para>
+   To alter the default collation order or character set classes, use the
+   <option>--lc-collate</option> and <option>--lc-ctype</option> options.
+   Collation orders other than <literal>C</> or <literal>POSIX</> also have
+   a performance penalty.  For these reasons it is important to choose the
+   right locale when running <command>initdb</command>. 
+  </para>
+
+  <para>
+   The remaining locale categories can be changed later when the server
+   is started.  You can also use <option>--locale</option> to set the
+   default for all locale categories, including collation order and
+   character set classes. All server locale values (<literal>lc_*</>) can
+   be displayed via <command>SHOW ALL</>.
    More details can be found in <xref linkend="locale">.
   </para>
 
   <para>
-   The character set encoding can be set separately for a database when
-   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. More details can be found in
-   <xref linkend="multibyte">.
+   To alter the default encoding, use the <option>--encoding</option>.
+   More details can be found in <xref linkend="multibyte">.
   </para>
 
  </refsect1>
index 466c03e224448c8500fac061608d8e46563c6701..62695963e2b5b4b2d8c837855ab9dbd19eb96378 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/pg_controldata.sgml,v 1.10 2007/02/20 18:10:58 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/pg_controldata.sgml,v 1.11 2008/09/23 09:20:35 heikki Exp $
 PostgreSQL documentation
 -->
 
@@ -30,7 +30,7 @@ PostgreSQL documentation
   <title>Description</title>
   <para>
    <command>pg_controldata</command> prints information initialized during
-   <command>initdb</>, such as the catalog version and server locale.
+   <command>initdb</>, such as the catalog version.
    It also shows information about write-ahead logging and checkpoint 
    processing.  This information is cluster-wide, and not specific to any one
    database.
index 588ff38c1bb2553ff4175760ba698422dcd8bd51..a9d34298e4c17bcec95441a6c8253524467c10ce 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/pg_resetxlog.sgml,v 1.20 2007/01/31 23:26:04 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/pg_resetxlog.sgml,v 1.21 2008/09/23 09:20:35 heikki Exp $
 PostgreSQL documentation
 -->
 
@@ -62,14 +62,10 @@ PostgreSQL documentation
    by specifying the <literal>-f</> (force) switch.  In this case plausible
    values will be substituted for the missing data.  Most of the fields can be
    expected to match, but manual assistance might be needed for the next OID,
-   next transaction ID and epoch, next multitransaction ID and offset,
-   WAL starting address, and database locale fields.
-   The first six of these can be set using the switches discussed below.
-   <command>pg_resetxlog</command>'s own environment is the source for its
-   guess at the locale fields; take care that <envar>LANG</> and so forth
-   match the environment that <command>initdb</> was run in.
-   If you are not able to determine correct values for all these fields,
-   <literal>-f</> can still be used, but
+   next transaction ID and epoch, next multitransaction ID and offset, and
+   WAL starting address fields. These fields can be set using the switches
+   discussed below. If you are not able to determine correct values for all
+   these fields, <literal>-f</> can still be used, but
    the recovered database must be treated with even more suspicion than
    usual: an immediate dump and reload is imperative.  <emphasis>Do not</>
    execute any data-modifying operations in the database before you dump,
index 000b5614dd2854431bb57e5af2312ae98b8dd491..d8ed7aef9c6c66befece74bcab494b1239529f59 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/select.sgml,v 1.103 2008/02/15 22:17:06 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/select.sgml,v 1.104 2008/09/23 09:20:35 heikki Exp $
 PostgreSQL documentation
 -->
 
@@ -747,8 +747,7 @@ SELECT name FROM distributors ORDER BY code;
 
    <para>
     Character-string data is sorted according to the locale-specific
-    collation order that was established when the database cluster
-    was initialized.
+    collation order that was established when the database was created.
    </para>
   </refsect2>
 
index ebd1acee35aff39cd53c2c8ad6d255d39610137e..fdc348053ea542e2d4bbcc064f692c551f02326c 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/show.sgml,v 1.45 2008/01/03 21:23:15 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/show.sgml,v 1.46 2008/09/23 09:20:35 heikki Exp $
 PostgreSQL documentation
 -->
 
@@ -82,8 +82,8 @@ SHOW ALL
          <para>
           Shows the database's locale setting for collation (text
           ordering).  At present, this parameter can be shown but not
-          set, because the setting is determined at
-          <command>initdb</> time.
+          set, because the setting is determined at database creation
+          time.
          </para>
         </listitem>
        </varlistentry>
@@ -94,8 +94,8 @@ SHOW ALL
          <para>
           Shows the database's locale setting for character
           classification.  At present, this parameter can be shown but
-          not set, because the setting is determined at
-          <command>initdb</> time.
+          not set, because the setting is determined at database creation
+          time.
          </para>
         </listitem>
        </varlistentry>
index 75c6d266e9d11153fe90e5042a634183f4ab8055..adde49e1a3970d3681787930c414230ef20ea717 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.416 2008/04/26 22:47:40 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.417 2008/09/23 09:20:34 heikki Exp $ -->
 
 <chapter Id="runtime">
  <title>Operating System Environment</title>
@@ -145,11 +145,12 @@ postgres$ <userinput>initdb -D /usr/local/pgsql/data</userinput>
    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">.  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. There is also a performance impact for using locales
+   that can be found in <xref linkend="locale">.  The default sort order used
+   within the particular database cluster is set by
+   <command>initdb</command>, and while you can create new databases using
+   different sort order, the order used in the template databases that initdb
+   creates cannot be changed without dropping and recreating them.
+   There is also a performance impact for using locales
    other than <literal>C</> or <literal>POSIX</>. Therefore, it is
    important to make this choice correctly the first time.
   </para>
index 41db566b6cc48614b9d4ec44f756194f68943a16..45a9f5a389fef64ea3151a019d1d9b3094e28edd 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/textsearch.sgml,v 1.44 2008/05/16 16:31:01 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/textsearch.sgml,v 1.45 2008/09/23 09:20:34 heikki Exp $ -->
 
 <chapter id="textsearch">
  <title id="textsearch-title">Full Text Search</title>
@@ -1896,7 +1896,7 @@ LIMIT 10;
 
   <note>
    <para>
-    The parser's notion of a <quote>letter</> is determined by the server's
+    The parser's notion of a <quote>letter</> is determined by the database's
     locale setting, specifically <varname>lc_ctype</>.  Words containing
     only the basic ASCII letters are reported as a separate token type,
     since it is sometimes useful to distinguish them.  In most European
index a776be2badb943c7e7b503ef204047bddaacea69..e8c230466d328bcfaa24bce5ff6e5ab3b6401e49 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.318 2008/09/08 16:42:15 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.319 2008/09/23 09:20:35 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -46,7 +46,7 @@
 #include "storage/smgr.h"
 #include "storage/spin.h"
 #include "utils/builtins.h"
-#include "utils/pg_locale.h"
+#include "utils/guc.h"
 #include "utils/ps_status.h"
 
 
@@ -3847,7 +3847,6 @@ WriteControlFile(void)
 {
        int                     fd;
        char            buffer[PG_CONTROL_SIZE];                /* need not be aligned */
-       char       *localeptr;
 
        /*
         * Initialize version and compatibility-check fields
@@ -3876,18 +3875,6 @@ WriteControlFile(void)
        ControlFile->float4ByVal = FLOAT4PASSBYVAL;
        ControlFile->float8ByVal = FLOAT8PASSBYVAL;
 
-       ControlFile->localeBuflen = LOCALE_NAME_BUFLEN;
-       localeptr = setlocale(LC_COLLATE, NULL);
-       if (!localeptr)
-               ereport(PANIC,
-                               (errmsg("invalid LC_COLLATE setting")));
-       StrNCpy(ControlFile->lc_collate, localeptr, LOCALE_NAME_BUFLEN);
-       localeptr = setlocale(LC_CTYPE, NULL);
-       if (!localeptr)
-               ereport(PANIC,
-                               (errmsg("invalid LC_CTYPE setting")));
-       StrNCpy(ControlFile->lc_ctype, localeptr, LOCALE_NAME_BUFLEN);
-
        /* Contents are protected with a CRC */
        INIT_CRC32(ControlFile->crc);
        COMP_CRC32(ControlFile->crc,
@@ -4126,34 +4113,6 @@ ReadControlFile(void)
                                                   " but the server was compiled without USE_FLOAT8_BYVAL."),
                                 errhint("It looks like you need to recompile or initdb.")));
 #endif
-
-       if (ControlFile->localeBuflen != LOCALE_NAME_BUFLEN)
-               ereport(FATAL,
-                               (errmsg("database files are incompatible with server"),
-                                errdetail("The database cluster was initialized with LOCALE_NAME_BUFLEN %d,"
-                                 " but the server was compiled with LOCALE_NAME_BUFLEN %d.",
-                                                  ControlFile->localeBuflen, LOCALE_NAME_BUFLEN),
-                                errhint("It looks like you need to recompile or initdb.")));
-       if (pg_perm_setlocale(LC_COLLATE, ControlFile->lc_collate) == NULL)
-               ereport(FATAL,
-                       (errmsg("database files are incompatible with operating system"),
-                        errdetail("The database cluster was initialized with LC_COLLATE \"%s\","
-                                          " which is not recognized by setlocale().",
-                                          ControlFile->lc_collate),
-                        errhint("It looks like you need to initdb or install locale support.")));
-       if (pg_perm_setlocale(LC_CTYPE, ControlFile->lc_ctype) == NULL)
-               ereport(FATAL,
-                       (errmsg("database files are incompatible with operating system"),
-               errdetail("The database cluster was initialized with LC_CTYPE \"%s\","
-                                 " which is not recognized by setlocale().",
-                                 ControlFile->lc_ctype),
-                        errhint("It looks like you need to initdb or install locale support.")));
-
-       /* Make the fixed locale settings visible as GUC variables, too */
-       SetConfigOption("lc_collate", ControlFile->lc_collate,
-                                       PGC_INTERNAL, PGC_S_OVERRIDE);
-       SetConfigOption("lc_ctype", ControlFile->lc_ctype,
-                                       PGC_INTERNAL, PGC_S_OVERRIDE);
 }
 
 void
index f4bfa5cf6dbe77597a12f9245325fecbcef2cbe1..ce3754f5928269e436d754520647c1c5b552e2d1 100644 (file)
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.210 2008/08/04 18:03:46 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.211 2008/09/23 09:20:35 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,7 @@
 #include "utils/fmgroids.h"
 #include "utils/guc.h"
 #include "utils/lsyscache.h"
+#include "utils/pg_locale.h"
 #include "utils/syscache.h"
 #include "utils/tqual.h"
 
@@ -69,7 +70,7 @@ static bool get_db_info(const char *name, LOCKMODE lockmode,
                        Oid *dbIdP, Oid *ownerIdP,
                        int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
                        Oid *dbLastSysOidP, TransactionId *dbFrozenXidP,
-                       Oid *dbTablespace);
+                       Oid *dbTablespace, char **dbCollate, char **dbCtype);
 static bool have_createdb_privilege(void);
 static void remove_dbtablespaces(Oid db_id);
 static bool check_db_file_conflict(Oid db_id);
@@ -87,6 +88,8 @@ createdb(const CreatedbStmt *stmt)
        Oid                     src_dboid;
        Oid                     src_owner;
        int                     src_encoding;
+       char       *src_collate;
+       char       *src_ctype;
        bool            src_istemplate;
        bool            src_allowconn;
        Oid                     src_lastsysoid;
@@ -104,10 +107,14 @@ createdb(const CreatedbStmt *stmt)
        DefElem    *downer = NULL;
        DefElem    *dtemplate = NULL;
        DefElem    *dencoding = NULL;
+       DefElem    *dcollate = NULL;
+       DefElem    *dctype = NULL;
        DefElem    *dconnlimit = NULL;
        char       *dbname = stmt->dbname;
        char       *dbowner = NULL;
        const char *dbtemplate = NULL;
+       char       *dbcollate = NULL;
+       char       *dbctype = NULL;
        int                     encoding = -1;
        int                     dbconnlimit = -1;
        int                     ctype_encoding;
@@ -152,6 +159,22 @@ createdb(const CreatedbStmt *stmt)
                                                 errmsg("conflicting or redundant options")));
                        dencoding = defel;
                }
+               else if (strcmp(defel->defname, "collate") == 0)
+               {
+                       if (dcollate)
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_SYNTAX_ERROR),
+                                                errmsg("conflicting or redundant options")));
+                       dcollate = defel;
+               }
+               else if (strcmp(defel->defname, "ctype") == 0)
+               {
+                       if (dctype)
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_SYNTAX_ERROR),
+                                                errmsg("conflicting or redundant options")));
+                       dctype = defel;
+               }
                else if (strcmp(defel->defname, "connectionlimit") == 0)
                {
                        if (dconnlimit)
@@ -205,6 +228,11 @@ createdb(const CreatedbStmt *stmt)
                        elog(ERROR, "unrecognized node type: %d",
                                 nodeTag(dencoding->arg));
        }
+       if (dcollate && dcollate->arg)
+               dbcollate = strVal(dcollate->arg);
+       if (dctype && dctype->arg)
+               dbctype = strVal(dctype->arg);
+
        if (dconnlimit && dconnlimit->arg)
                dbconnlimit = intVal(dconnlimit->arg);
 
@@ -243,7 +271,8 @@ createdb(const CreatedbStmt *stmt)
        if (!get_db_info(dbtemplate, ShareLock,
                                         &src_dboid, &src_owner, &src_encoding,
                                         &src_istemplate, &src_allowconn, &src_lastsysoid,
-                                        &src_frozenxid, &src_deftablespace))
+                                        &src_frozenxid, &src_deftablespace,
+                                        &src_collate, &src_ctype))
                ereport(ERROR,
                                (errcode(ERRCODE_UNDEFINED_DATABASE),
                                 errmsg("template database \"%s\" does not exist",
@@ -262,9 +291,13 @@ createdb(const CreatedbStmt *stmt)
                                                        dbtemplate)));
        }
 
-       /* If encoding is defaulted, use source's encoding */
+       /* If encoding or locales are defaulted, use source's setting */
        if (encoding < 0)
                encoding = src_encoding;
+       if (dbcollate == NULL)
+               dbcollate = src_collate;
+       if (dbctype == NULL)
+               dbctype = src_ctype;
 
        /* Some encodings are client only */
        if (!PG_VALID_BE_ENCODING(encoding))
@@ -272,6 +305,16 @@ createdb(const CreatedbStmt *stmt)
                                (errcode(ERRCODE_WRONG_OBJECT_TYPE),
                                 errmsg("invalid server encoding %d", encoding)));
 
+       /* Check that the chosen locales are valid */
+       if (!check_locale(LC_COLLATE, dbcollate))
+               ereport(ERROR,
+                               (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+                                errmsg("invalid locale name %s", dbcollate)));
+       if (!check_locale(LC_CTYPE, dbctype))
+               ereport(ERROR,
+                               (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+                                errmsg("invalid locale name %s", dbctype)));
+
        /*
         * Check whether encoding matches server locale settings.  We allow
         * mismatch in three cases:
@@ -290,7 +333,7 @@ createdb(const CreatedbStmt *stmt)
         *
         * Note: if you change this policy, fix initdb to match.
         */
-       ctype_encoding = pg_get_encoding_from_locale(NULL);
+       ctype_encoding = pg_get_encoding_from_locale(dbctype);
 
        if (!(ctype_encoding == encoding ||
                  ctype_encoding == PG_SQL_ASCII ||
@@ -299,12 +342,32 @@ createdb(const CreatedbStmt *stmt)
 #endif
                  (encoding == PG_SQL_ASCII && superuser())))
                ereport(ERROR,
-                               (errmsg("encoding %s does not match server's locale %s",
+                               (errmsg("encoding %s does not match locale %s",
                                                pg_encoding_to_char(encoding),
-                                               setlocale(LC_CTYPE, NULL)),
-                        errdetail("The server's LC_CTYPE setting requires encoding %s.",
+                                               dbctype),
+                        errdetail("The chosen LC_CTYPE setting requires encoding %s.",
                                           pg_encoding_to_char(ctype_encoding))));
 
+       /*
+        * Check that the new locale is compatible with the source database.
+        *
+        * We know that template0 doesn't contain any indexes that depend on
+        * collation or ctype, so template0 can be used as template for
+        * any locale.
+        */
+       if (strcmp(dbtemplate, "template0") != 0)
+       {
+               if (strcmp(dbcollate, src_collate))
+                       ereport(ERROR,
+                                       (errmsg("new collation is incompatible with the collation of the template database (%s)", src_collate),
+                                        errhint("Use the same collation as in the template database, or use template0 as template")));
+
+               if (strcmp(dbctype, src_ctype))
+                       ereport(ERROR,
+                                       (errmsg("new ctype is incompatible with the ctype of the template database (%s)", src_ctype),
+                                        errhint("Use the same ctype as in the template database, or use template0 as template")));
+       }
+
        /* Resolve default tablespace for new database */
        if (dtablespacename && dtablespacename->arg)
        {
@@ -421,6 +484,10 @@ createdb(const CreatedbStmt *stmt)
                DirectFunctionCall1(namein, CStringGetDatum(dbname));
        new_record[Anum_pg_database_datdba - 1] = ObjectIdGetDatum(datdba);
        new_record[Anum_pg_database_encoding - 1] = Int32GetDatum(encoding);
+       new_record[Anum_pg_database_datcollate - 1] =
+               DirectFunctionCall1(namein, CStringGetDatum(dbcollate));
+       new_record[Anum_pg_database_datctype - 1] =
+               DirectFunctionCall1(namein, CStringGetDatum(dbctype));
        new_record[Anum_pg_database_datistemplate - 1] = BoolGetDatum(false);
        new_record[Anum_pg_database_datallowconn - 1] = BoolGetDatum(true);
        new_record[Anum_pg_database_datconnlimit - 1] = Int32GetDatum(dbconnlimit);
@@ -629,7 +696,7 @@ dropdb(const char *dbname, bool missing_ok)
        pgdbrel = heap_open(DatabaseRelationId, RowExclusiveLock);
 
        if (!get_db_info(dbname, AccessExclusiveLock, &db_id, NULL, NULL,
-                                        &db_istemplate, NULL, NULL, NULL, NULL))
+                                        &db_istemplate, NULL, NULL, NULL, NULL, NULL, NULL))
        {
                if (!missing_ok)
                {
@@ -781,7 +848,7 @@ RenameDatabase(const char *oldname, const char *newname)
        rel = heap_open(DatabaseRelationId, RowExclusiveLock);
 
        if (!get_db_info(oldname, AccessExclusiveLock, &db_id, NULL, NULL,
-                                        NULL, NULL, NULL, NULL, NULL))
+                                        NULL, NULL, NULL, NULL, NULL, NULL, NULL))
                ereport(ERROR,
                                (errcode(ERRCODE_UNDEFINED_DATABASE),
                                 errmsg("database \"%s\" does not exist", oldname)));
@@ -1168,7 +1235,7 @@ get_db_info(const char *name, LOCKMODE lockmode,
                        Oid *dbIdP, Oid *ownerIdP,
                        int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
                        Oid *dbLastSysOidP, TransactionId *dbFrozenXidP,
-                       Oid *dbTablespace)
+                       Oid *dbTablespace, char **dbCollate, char **dbCtype)
 {
        bool            result = false;
        Relation        relation;
@@ -1259,6 +1326,11 @@ get_db_info(const char *name, LOCKMODE lockmode,
                                /* default tablespace for this database */
                                if (dbTablespace)
                                        *dbTablespace = dbform->dattablespace;
+                               /* default locale settings for this database */
+                               if (dbCollate)
+                                       *dbCollate = pstrdup(NameStr(dbform->datcollate));
+                               if (dbCtype)
+                                       *dbCtype = pstrdup(NameStr(dbform->datctype));
                                ReleaseSysCache(tuple);
                                result = true;
                                break;
index ecbd55d13020b4095a6cc4481d53b706b3d86f27..d487e59fd72654305d3b1120d6a2aba0117c6c75 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.623 2008/09/11 15:27:30 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.624 2008/09/23 09:20:35 heikki Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -398,7 +398,7 @@ static TypeName *TableFuncTypeName(List *columns);
        CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
        COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
        CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
-       CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
+       CREATEROLE CREATEUSER CROSS CSV CTYPE CURRENT_P CURRENT_DATE CURRENT_ROLE
        CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
 
        DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
@@ -5458,6 +5458,22 @@ createdb_opt_item:
                                {
                                        $$ = makeDefElem("encoding", NULL);
                                }
+                       | COLLATE opt_equal Sconst
+                               {
+                                       $$ = makeDefElem("collate", (Node *)makeString($3));
+                               }
+                       | COLLATE opt_equal DEFAULT
+                               {
+                                       $$ = makeDefElem("collate", NULL);
+                               }
+                       | CTYPE opt_equal Sconst
+                               {
+                                       $$ = makeDefElem("ctype", (Node *)makeString($3));
+                               }
+                       | CTYPE opt_equal DEFAULT
+                               {
+                                       $$ = makeDefElem("ctype", NULL);
+                               }
                        | CONNECTION LIMIT opt_equal SignedIconst
                                {
                                        $$ = makeDefElem("connectionlimit", (Node *)makeInteger($4));
@@ -9216,6 +9232,7 @@ unreserved_keyword:
                        | CREATEROLE
                        | CREATEUSER
                        | CSV
+                       | CTYPE
                        | CURRENT_P
                        | CURSOR
                        | CYCLE
index 2b7a56bccd2d10b483a870c75a9a223708b38f81..0f17aa131ebc702ca1bc39c1a563e09473fabda4 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.200 2008/08/29 13:02:32 petere Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.201 2008/09/23 09:20:36 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -114,6 +114,7 @@ const ScanKeyword ScanKeywords[] = {
        {"createuser", CREATEUSER, UNRESERVED_KEYWORD},
        {"cross", CROSS, TYPE_FUNC_NAME_KEYWORD},
        {"csv", CSV, UNRESERVED_KEYWORD},
+       {"ctype", CTYPE, UNRESERVED_KEYWORD},
        {"current", CURRENT_P, UNRESERVED_KEYWORD},
        {"current_date", CURRENT_DATE, RESERVED_KEYWORD},
        {"current_role", CURRENT_ROLE, RESERVED_KEYWORD},
index 72b9387767a6e412dbf3d0c43af6fe7dd552f27f..51f766275bbe1dacc09cd5c11f093e173c3e32c7 100644 (file)
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.563 2008/09/15 12:32:57 mha Exp $
+ *       $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.564 2008/09/23 09:20:36 heikki Exp $
  *
  * NOTES
  *
@@ -403,8 +403,8 @@ typedef struct
        char            my_exec_path[MAXPGPATH];
        char            pkglib_path[MAXPGPATH];
        char            ExtraOptions[MAXPGPATH];
-       char            lc_collate[LOCALE_NAME_BUFLEN];
-       char            lc_ctype[LOCALE_NAME_BUFLEN];
+       char            lc_collate[NAMEDATALEN];
+       char            lc_ctype[NAMEDATALEN];
 }      BackendParameters;
 
 static void read_backend_variables(char *id, Port *port);
@@ -4294,8 +4294,8 @@ save_backend_variables(BackendParameters * param, Port *port,
 
        strlcpy(param->ExtraOptions, ExtraOptions, MAXPGPATH);
 
-       strlcpy(param->lc_collate, setlocale(LC_COLLATE, NULL), LOCALE_NAME_BUFLEN);
-       strlcpy(param->lc_ctype, setlocale(LC_CTYPE, NULL), LOCALE_NAME_BUFLEN);
+       strlcpy(param->lc_collate, setlocale(LC_COLLATE, NULL), NAMEDATALEN);
+       strlcpy(param->lc_ctype, setlocale(LC_CTYPE, NULL), NAMEDATALEN);
 
        return true;
 }
index dfc6c886a52125702ea716a1ec1c202c765679b4..4b57d5791e0c42aa510bc985b44ce8850a67497f 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Portions Copyright (c) 2002-2008, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.41 2008/05/19 18:08:16 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.42 2008/09/23 09:20:36 heikki Exp $
  *
  *-----------------------------------------------------------------------
  */
@@ -76,7 +76,7 @@ static bool CurrentLCTimeValid = false;
 
 /* Environment variable storage area */
 
-#define LC_ENV_BUFSIZE (LOCALE_NAME_BUFLEN + 20)
+#define LC_ENV_BUFSIZE (NAMEDATALEN + 20)
 
 static char lc_collate_envbuf[LC_ENV_BUFSIZE];
 static char lc_ctype_envbuf[LC_ENV_BUFSIZE];
@@ -189,6 +189,31 @@ pg_perm_setlocale(int category, const char *locale)
 }
 
 
+/*
+ * Is the locale name valid for the locale category?
+ */
+bool
+check_locale(int category, const char *value)
+{
+       char       *save;
+       bool            ret;
+
+       save = setlocale(category, NULL);
+       if (!save)
+               return false;                   /* won't happen, we hope */
+
+       /* save may be pointing at a modifiable scratch variable, see above */
+       save = pstrdup(save);
+
+       /* set the locale with setlocale, to see if it accepts it. */
+       ret = (setlocale(category, value) != NULL);
+
+       setlocale(category, save);      /* assume this won't fail */
+       pfree(save);
+
+       return ret;
+}
+
 /* GUC assign hooks */
 
 /*
@@ -203,21 +228,9 @@ pg_perm_setlocale(int category, const char *locale)
 static const char *
 locale_xxx_assign(int category, const char *value, bool doit, GucSource source)
 {
-       char       *save;
-
-       save = setlocale(category, NULL);
-       if (!save)
-               return NULL;                    /* won't happen, we hope */
-
-       /* save may be pointing at a modifiable scratch variable, see above */
-       save = pstrdup(save);
-
-       if (!setlocale(category, value))
+       if (!check_locale(category, value))
                value = NULL;                   /* set failure return marker */
 
-       setlocale(category, save);      /* assume this won't fail */
-       pfree(save);
-
        /* need to reload cache next time? */
        if (doit && value != NULL)
        {
index 6b66b2e3926440bf3215afb73f0d5908d70afa77..b6f9718b7aa23e230eff0cd4be6e46ce7ac82e07 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.185 2008/09/11 14:01:09 alvherre Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.186 2008/09/23 09:20:36 heikki Exp $
  *
  *
  *-------------------------------------------------------------------------
@@ -159,6 +159,8 @@ CheckMyDatabase(const char *name, bool am_superuser)
 {
        HeapTuple       tup;
        Form_pg_database dbform;
+       char       *collate;
+       char       *ctype;
 
        /* Fetch our real pg_database row */
        tup = SearchSysCache(DATABASEOID,
@@ -240,6 +242,28 @@ CheckMyDatabase(const char *name, bool am_superuser)
        /* If we have no other source of client_encoding, use server encoding */
        SetConfigOption("client_encoding", GetDatabaseEncodingName(),
                                        PGC_BACKEND, PGC_S_DEFAULT);
+       
+       /* assign locale variables */ 
+       collate = NameStr(dbform->datcollate);
+       ctype = NameStr(dbform->datctype);
+                                       
+       if (setlocale(LC_COLLATE, collate) == NULL)
+               ereport(FATAL, 
+                       (errmsg("database locale is incompatible with operating system"),
+                       errdetail("The database was initialized with LC_COLLATE \"%s\", "
+                                               " which is not recognized by setlocale().", collate),
+                       errhint("Recreate the database with another locale or install the missing locale.")));
+                       
+       if (setlocale(LC_CTYPE, ctype) == NULL)
+               ereport(FATAL, 
+                       (errmsg("database locale is incompatible with operating system"),
+                       errdetail("The database was initialized with LC_CTYPE \"%s\", "
+                                               " which is not recognized by setlocale().", ctype),
+                       errhint("Recreate the database with another locale or install the missing locale.")));
+                       
+       /* Make the locale settings visible as GUC variables, too */
+       SetConfigOption("lc_collate", collate, PGC_INTERNAL, PGC_S_OVERRIDE);
+       SetConfigOption("lc_ctype", ctype, PGC_INTERNAL, PGC_S_OVERRIDE);
 
        /*
         * Lastly, set up any database-specific configuration variables.
index e305c69fa3c47bd01be892c9823561554dece264..a4bd34cb685ce1392569e30eb969e2ecfec518fd 100644 (file)
@@ -42,7 +42,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  * Portions taken from FreeBSD.
  *
- * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.159 2008/08/05 12:09:30 mha Exp $
+ * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.160 2008/09/23 09:20:37 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1353,6 +1353,10 @@ bootstrap_template1(char *short_version)
 
        bki_lines = replace_token(bki_lines, "ENCODING", encodingid);
 
+       bki_lines = replace_token(bki_lines, "LC_COLLATE", lc_collate);
+       
+       bki_lines = replace_token(bki_lines, "LC_CTYPE", lc_ctype);
+       
        /*
         * Pass correct LC_xxx environment to bootstrap.
         *
@@ -2179,6 +2183,8 @@ locale_date_order(const char *locale)
 
 /*
  * check if given string is a valid locale specifier
+ *
+ * this should match the backend check_locale() function
  */
 static bool
 chklocale(const char *locale)
@@ -2378,12 +2384,12 @@ usage(const char *progname)
        printf(_("\nOptions:\n"));
        printf(_(" [-D, --pgdata=]DATADIR     location for this database cluster\n"));
        printf(_("  -E, --encoding=ENCODING   set default encoding for new databases\n"));
-       printf(_("  --locale=LOCALE           initialize database cluster with given locale\n"));
+       printf(_("  --locale=LOCALE           set default locale for new databases\n"));
        printf(_("  --lc-collate, --lc-ctype, --lc-messages=LOCALE\n"
                         "  --lc-monetary, --lc-numeric, --lc-time=LOCALE\n"
-                        "                            initialize database cluster with given locale\n"
-                        "                            in the respective category (default taken from\n"
-                        "                            environment)\n"));
+                        "                            set default locale in the respective\n"
+                        "                            category for new databases (default\n"
+                        "                            taken from environment)\n"));
        printf(_("  --no-locale               equivalent to --locale=C\n"));
        printf(_("  -T, --text-search-config=CFG\n"
                 "                            default text search configuration\n"));
index 122ef37996a04ab42d5172672a4ef101645a35db..50a4754cd5d93f51efc0b1a7569130c06cecd121 100644 (file)
@@ -6,7 +6,7 @@
  * copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001;
  * licence: BSD
  *
- * $PostgreSQL: pgsql/src/bin/pg_controldata/pg_controldata.c,v 1.39 2008/04/21 00:26:46 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_controldata/pg_controldata.c,v 1.40 2008/09/23 09:20:37 heikki Exp $
  */
 #include "postgres_fe.h"
 
@@ -220,12 +220,5 @@ main(int argc, char *argv[])
                   (ControlFile.float4ByVal ? _("by value") : _("by reference")));
        printf(_("Float8 argument passing:              %s\n"),
                   (ControlFile.float8ByVal ? _("by value") : _("by reference")));
-       printf(_("Maximum length of locale name:        %u\n"),
-                  ControlFile.localeBuflen);
-       printf(_("LC_COLLATE:                           %s\n"),
-                  ControlFile.lc_collate);
-       printf(_("LC_CTYPE:                             %s\n"),
-                  ControlFile.lc_ctype);
-
        return 0;
 }
index 25b0f58e7d4a5e05df979f17888d7f84c53e4ecf..55b944ae948ce9b25c97152070edbb4230da0ad0 100644 (file)
@@ -12,7 +12,7 @@
  *     by PostgreSQL
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.500 2008/09/08 15:26:23 tgl Exp $
+ *       $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.501 2008/09/23 09:20:37 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1542,12 +1542,16 @@ dumpDatabase(Archive *AH)
                                i_oid,
                                i_dba,
                                i_encoding,
+                               i_collate,
+                               i_ctype,
                                i_tablespace;
        CatalogId       dbCatId;
        DumpId          dbDumpId;
        const char *datname,
                           *dba,
                           *encoding,
+                          *collate,
+                          *ctype,
                           *tablespace;
 
        datname = PQdb(g_conn);
@@ -1559,11 +1563,26 @@ dumpDatabase(Archive *AH)
        selectSourceSchema("pg_catalog");
 
        /* Get the database owner and parameters from pg_database */
-       if (g_fout->remoteVersion >= 80200)
+       if (g_fout->remoteVersion >= 80400)
+       {
+               appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
+                                                 "(%s datdba) as dba, "
+                                                 "pg_encoding_to_char(encoding) as encoding, "
+                                                 "datcollate, datctype, "
+                                                 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) as tablespace, "
+                                         "shobj_description(oid, 'pg_database') as description "
+
+                                                 "FROM pg_database "
+                                                 "WHERE datname = ",
+                                                 username_subquery);
+               appendStringLiteralAH(dbQry, datname, AH);
+       }
+       else if (g_fout->remoteVersion >= 80200)
        {
                appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
                                                  "(%s datdba) as dba, "
                                                  "pg_encoding_to_char(encoding) as encoding, "
+                                                 "NULL as datcollate, NULL as datctype, "
                                                  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) as tablespace, "
                                          "shobj_description(oid, 'pg_database') as description "
 
@@ -1577,6 +1596,7 @@ dumpDatabase(Archive *AH)
                appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
                                                  "(%s datdba) as dba, "
                                                  "pg_encoding_to_char(encoding) as encoding, "
+                                                 "NULL as datcollate, NULL as datctype, "
                                                  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) as tablespace "
                                                  "FROM pg_database "
                                                  "WHERE datname = ",
@@ -1588,6 +1608,7 @@ dumpDatabase(Archive *AH)
                appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
                                                  "(%s datdba) as dba, "
                                                  "pg_encoding_to_char(encoding) as encoding, "
+                                                 "NULL as datcollate, NULL as datctype, "
                                                  "NULL as tablespace "
                                                  "FROM pg_database "
                                                  "WHERE datname = ",
@@ -1601,6 +1622,7 @@ dumpDatabase(Archive *AH)
                                                  "oid, "
                                                  "(%s datdba) as dba, "
                                                  "pg_encoding_to_char(encoding) as encoding, "
+                                                 "NULL as datcollate, NULL as datctype, "
                                                  "NULL as tablespace "
                                                  "FROM pg_database "
                                                  "WHERE datname = ",
@@ -1631,12 +1653,16 @@ dumpDatabase(Archive *AH)
        i_oid = PQfnumber(res, "oid");
        i_dba = PQfnumber(res, "dba");
        i_encoding = PQfnumber(res, "encoding");
+       i_collate = PQfnumber(res, "collate");
+       i_ctype = PQfnumber(res, "ctype");
        i_tablespace = PQfnumber(res, "tablespace");
 
        dbCatId.tableoid = atooid(PQgetvalue(res, 0, i_tableoid));
        dbCatId.oid = atooid(PQgetvalue(res, 0, i_oid));
        dba = PQgetvalue(res, 0, i_dba);
        encoding = PQgetvalue(res, 0, i_encoding);
+       collate = PQgetvalue(res, 0, i_collate);
+       ctype = PQgetvalue(res, 0, i_ctype);
        tablespace = PQgetvalue(res, 0, i_tablespace);
 
        appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
@@ -1646,6 +1672,16 @@ dumpDatabase(Archive *AH)
                appendPQExpBuffer(creaQry, " ENCODING = ");
                appendStringLiteralAH(creaQry, encoding, AH);
        }
+       if (strlen(collate) > 0)
+       {
+               appendPQExpBuffer(creaQry, " COLLATE = ");
+               appendStringLiteralAH(creaQry, collate, AH);
+       }
+       if (strlen(ctype) > 0)
+       {
+               appendPQExpBuffer(creaQry, " CTYPE = ");
+               appendStringLiteralAH(creaQry, ctype, AH);
+       }
        if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0)
                appendPQExpBuffer(creaQry, " TABLESPACE = %s",
                                                  fmtId(tablespace));
index 3bac1a38cefeea138e4e0fd770b0e33c60fb30fc..ceb8cd48a0854c947492568d2ac7c8ad1eb3f9f6 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.106 2008/08/29 17:28:43 alvherre Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.107 2008/09/23 09:20:38 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -925,11 +925,22 @@ dumpCreateDB(PGconn *conn)
 
        fprintf(OPF, "--\n-- Database creation\n--\n\n");
 
-       if (server_version >= 80100)
+       if (server_version >= 80400)
                res = executeQuery(conn,
                                                   "SELECT datname, "
                                                   "coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
                                                   "pg_encoding_to_char(d.encoding), "
+                                                  "datcollate, datctype, "
+                                                  "datistemplate, datacl, datconnlimit, "
+                                                  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
+                         "FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
+                                                  "WHERE datallowconn ORDER BY 1");
+       else if (server_version >= 80100)
+               res = executeQuery(conn,
+                                                  "SELECT datname, "
+                                                  "coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
+                                                  "pg_encoding_to_char(d.encoding), "
+                                                  "null::text AS datcollate, null::text AS datctype, "
                                                   "datistemplate, datacl, datconnlimit, "
                                                   "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
                          "FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
@@ -939,6 +950,7 @@ dumpCreateDB(PGconn *conn)
                                                   "SELECT datname, "
                                                   "coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
                                                   "pg_encoding_to_char(d.encoding), "
+                                                  "null::text AS datcollate, null::text AS datctype, "
                                                   "datistemplate, datacl, -1 as datconnlimit, "
                                                   "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
                   "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
@@ -948,6 +960,7 @@ dumpCreateDB(PGconn *conn)
                                                   "SELECT datname, "
                                                   "coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
                                                   "pg_encoding_to_char(d.encoding), "
+                                                  "null::text AS datcollate, null::text AS datctype, "
                                                   "datistemplate, datacl, -1 as datconnlimit, "
                                                   "'pg_default' AS dattablespace "
                   "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
@@ -959,6 +972,7 @@ dumpCreateDB(PGconn *conn)
                                        "(select usename from pg_shadow where usesysid=datdba), "
                                                   "(select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
                                                   "pg_encoding_to_char(d.encoding), "
+                                                  "null::text AS datcollate, null::text AS datctype, "
                                                   "datistemplate, '' as datacl, -1 as datconnlimit, "
                                                   "'pg_default' AS dattablespace "
                                                   "FROM pg_database d "
@@ -973,6 +987,7 @@ dumpCreateDB(PGconn *conn)
                                                   "SELECT datname, "
                                        "(select usename from pg_shadow where usesysid=datdba), "
                                                   "pg_encoding_to_char(d.encoding), "
+                                                  "null::text AS datcollate, null::text AS datctype, "
                                                   "'f' as datistemplate, "
                                                   "'' as datacl, -1 as datconnlimit, "
                                                   "'pg_default' AS dattablespace "
@@ -985,10 +1000,12 @@ dumpCreateDB(PGconn *conn)
                char       *dbname = PQgetvalue(res, i, 0);
                char       *dbowner = PQgetvalue(res, i, 1);
                char       *dbencoding = PQgetvalue(res, i, 2);
-               char       *dbistemplate = PQgetvalue(res, i, 3);
-               char       *dbacl = PQgetvalue(res, i, 4);
-               char       *dbconnlimit = PQgetvalue(res, i, 5);
-               char       *dbtablespace = PQgetvalue(res, i, 6);
+               char       *dbcollate = PQgetvalue(res, i, 3);
+               char       *dbctype = PQgetvalue(res, i, 4);
+               char       *dbistemplate = PQgetvalue(res, i, 5);
+               char       *dbacl = PQgetvalue(res, i, 6);
+               char       *dbconnlimit = PQgetvalue(res, i, 7);
+               char       *dbtablespace = PQgetvalue(res, i, 8);
                char       *fdbname;
 
                fdbname = strdup(fmtId(dbname));
@@ -1016,6 +1033,18 @@ dumpCreateDB(PGconn *conn)
                        appendPQExpBuffer(buf, " ENCODING = ");
                        appendStringLiteralConn(buf, dbencoding, conn);
 
+                       if (strlen(dbcollate) != 0)
+                       {
+                               appendPQExpBuffer(buf, " COLLATE = ");
+                               appendStringLiteralConn(buf, dbcollate, conn);
+                       }
+
+                       if (strlen(dbctype) != 0)
+                       {
+                               appendPQExpBuffer(buf, " CTYPE = ");
+                               appendStringLiteralConn(buf, dbctype, conn);
+                       }
+
                        /*
                         * Output tablespace if it isn't the default.  For default, it
                         * uses the default from the template database.  If tablespace is
index 109fec7facfb950900dafa2cc9d902c71f9b4ab2..c3cfafea7ae234ff1051d436e48a3c020445dbcb 100644 (file)
@@ -23,7 +23,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.65 2008/04/21 00:26:46 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.66 2008/09/23 09:20:38 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -493,22 +493,6 @@ GuessControlValues(void)
 #endif
        ControlFile.float4ByVal = FLOAT4PASSBYVAL;
        ControlFile.float8ByVal = FLOAT8PASSBYVAL;
-       ControlFile.localeBuflen = LOCALE_NAME_BUFLEN;
-
-       localeptr = setlocale(LC_COLLATE, "");
-       if (!localeptr)
-       {
-               fprintf(stderr, _("%s: invalid LC_COLLATE setting\n"), progname);
-               exit(1);
-       }
-       strlcpy(ControlFile.lc_collate, localeptr, sizeof(ControlFile.lc_collate));
-       localeptr = setlocale(LC_CTYPE, "");
-       if (!localeptr)
-       {
-               fprintf(stderr, _("%s: invalid LC_CTYPE setting\n"), progname);
-               exit(1);
-       }
-       strlcpy(ControlFile.lc_ctype, localeptr, sizeof(ControlFile.lc_ctype));
 
        /*
         * XXX eventually, should try to grovel through old XLOG to develop more
@@ -584,12 +568,6 @@ PrintControlValues(bool guessed)
                   (ControlFile.float4ByVal ? _("by value") : _("by reference")));
        printf(_("Float8 argument passing:              %s\n"),
                   (ControlFile.float8ByVal ? _("by value") : _("by reference")));
-       printf(_("Maximum length of locale name:        %u\n"),
-                  ControlFile.localeBuflen);
-       printf(_("LC_COLLATE:                           %s\n"),
-                  ControlFile.lc_collate);
-       printf(_("LC_CTYPE:                             %s\n"),
-                  ControlFile.lc_ctype);
 }
 
 
index 137ea6c2d4454fb5297c624e9aa8d382500529ee..c801fe7c52ff48228720aa22df8485eb5b42aee7 100644 (file)
@@ -8,7 +8,7 @@
  *
  * Copyright (c) 2000-2008, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.184 2008/07/18 04:20:24 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.185 2008/09/23 09:20:38 heikki Exp $
  */
 #include "postgres_fe.h"
 
@@ -454,11 +454,18 @@ listAllDbs(bool verbose)
        printfPQExpBuffer(&buf,
                                          "SELECT d.datname as \"%s\",\n"
                                          "       pg_catalog.pg_get_userbyid(d.datdba) as \"%s\",\n"
-                                         "       pg_catalog.pg_encoding_to_char(d.encoding) as \"%s\",\n"
-                                         "       d.datacl as \"%s\"",
+                                         "       pg_catalog.pg_encoding_to_char(d.encoding) as \"%s\",\n",
                                          gettext_noop("Name"),
                                          gettext_noop("Owner"),
-                                         gettext_noop("Encoding"),
+                                         gettext_noop("Encoding"));
+       if (pset.sversion >= 80400)
+               appendPQExpBuffer(&buf,
+                                                 "       d.datcollate as \"%s\",\n"
+                                                 "       d.datctype as \"%s\",\n",
+                                                 gettext_noop("Collation"),
+                                                 gettext_noop("Ctype"));
+       appendPQExpBuffer(&buf,
+                                         "       d.datacl as \"%s\"",
                                          gettext_noop("Access Privileges"));
        if (verbose && pset.sversion >= 80200)
                appendPQExpBuffer(&buf,
index d42eea93d1afcddac1b82be7b05b7d84560addf8..da216819b63b67387f19dca397f54f030b2c5b06 100644 (file)
@@ -5,7 +5,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/bin/scripts/createdb.c,v 1.26 2008/01/01 19:45:56 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/scripts/createdb.c,v 1.27 2008/09/23 09:20:38 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -32,6 +32,8 @@ main(int argc, char *argv[])
                {"tablespace", required_argument, NULL, 'D'},
                {"template", required_argument, NULL, 'T'},
                {"encoding", required_argument, NULL, 'E'},
+               {"lc-collate", required_argument, NULL, 1},
+               {"lc-ctype", required_argument, NULL, 2},
                {NULL, 0, NULL, 0}
        };
 
@@ -50,6 +52,8 @@ main(int argc, char *argv[])
        char       *tablespace = NULL;
        char       *template = NULL;
        char       *encoding = NULL;
+       char       *lc_collate = NULL;
+       char       *lc_ctype = NULL;
 
        PQExpBufferData sql;
 
@@ -95,6 +99,12 @@ main(int argc, char *argv[])
                        case 'E':
                                encoding = optarg;
                                break;
+                       case 1:
+                               lc_collate = optarg;
+                               break;
+                       case 2:
+                               lc_ctype = optarg;
+                               break;
                        default:
                                fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
                                exit(1);
@@ -152,6 +162,11 @@ main(int argc, char *argv[])
                appendPQExpBuffer(&sql, " ENCODING '%s'", encoding);
        if (template)
                appendPQExpBuffer(&sql, " TEMPLATE %s", fmtId(template));
+       if (lc_collate)
+               appendPQExpBuffer(&sql, " COLLATE '%s'", lc_collate);
+       if (lc_ctype)
+               appendPQExpBuffer(&sql, " CTYPE '%s'", lc_ctype);
+
        appendPQExpBuffer(&sql, ";\n");
 
        conn = connectDatabase(strcmp(dbname, "postgres") == 0 ? "template1" : "postgres",
@@ -209,6 +224,8 @@ help(const char *progname)
        printf(_("\nOptions:\n"));
        printf(_("  -D, --tablespace=TABLESPACE  default tablespace for the database\n"));
        printf(_("  -E, --encoding=ENCODING      encoding for the database\n"));
+       printf(_("  --lc-collate=LOCALE          LC_COLLATE setting for the database\n"));
+       printf(_("  --lc-ctype=LOCALE            LC_CTYPE setting for the database\n"));
        printf(_("  -O, --owner=OWNER            database user to own the new database\n"));
        printf(_("  -T, --template=TEMPLATE      template database to copy\n"));
        printf(_("  -e, --echo                   show the commands being sent to the server\n"));
index f13412c576a4da82578c0fe1f56a6a41e016ae46..e7f96f78c14e7b6cc3b80e38d3fbf6593dc03d73 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.487 2008/09/19 19:03:40 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.488 2008/09/23 09:20:38 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     200809191
+#define CATALOG_VERSION_NO     200809231
 
 #endif
index 4f789e9af97a6b58a0b7899547d85aad1b9c1370..621f7594576755fe67151677a9d21fbd8207c945 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.41 2008/04/21 00:26:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.42 2008/09/23 09:20:39 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -21,7 +21,7 @@
 
 
 /* Version identifier for this pg_control format */
-#define PG_CONTROL_VERSION     842
+#define PG_CONTROL_VERSION     843
 
 /*
  * Body of CheckPoint XLOG records.  This is declared here because we keep
@@ -59,15 +59,12 @@ typedef enum DBState
        DB_IN_PRODUCTION
 } DBState;
 
-#define LOCALE_NAME_BUFLEN     128
-
 /*
  * Contents of pg_control.
  *
  * NOTE: try to keep this under 512 bytes so that it will fit on one physical
  * sector of typical disk drives.  This reduces the odds of corruption due to
- * power failure midway through a write.  Currently it fits comfortably,
- * but we could probably reduce LOCALE_NAME_BUFLEN if things get tight.
+ * power failure midway through a write.
  */
 
 typedef struct ControlFileData
@@ -144,11 +141,6 @@ typedef struct ControlFileData
        bool            float4ByVal;    /* float4 pass-by-value? */
        bool            float8ByVal;    /* float8, int8, etc pass-by-value? */
 
-       /* active locales */
-       uint32          localeBuflen;
-       char            lc_collate[LOCALE_NAME_BUFLEN];
-       char            lc_ctype[LOCALE_NAME_BUFLEN];
-
        /* CRC of all above ... MUST BE LAST! */
        pg_crc32        crc;
 } ControlFileData;
index ae7edefdafca11b1d07d6f7ddad930236808814b..4a93b8464f4391d700afb5650b2eb056c8978daf 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_database.h,v 1.47 2008/03/27 03:57:34 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_database.h,v 1.48 2008/09/23 09:20:39 heikki Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -33,6 +33,8 @@ CATALOG(pg_database,1262) BKI_SHARED_RELATION
        NameData        datname;                /* database name */
        Oid                     datdba;                 /* owner of database */
        int4            encoding;               /* character encoding */
+       NameData        datcollate;             /* LC_COLLATE setting */
+       NameData        datctype;               /* LC_CTYPE setting */
        bool            datistemplate;  /* allowed as CREATE DATABASE template? */
        bool            datallowconn;   /* new connections allowed? */
        int4            datconnlimit;   /* max connections allowed (-1=no limit) */
@@ -54,20 +56,22 @@ typedef FormData_pg_database *Form_pg_database;
  *             compiler constants for pg_database
  * ----------------
  */
-#define Natts_pg_database                              11
+#define Natts_pg_database                              13
 #define Anum_pg_database_datname               1
 #define Anum_pg_database_datdba                        2
 #define Anum_pg_database_encoding              3
-#define Anum_pg_database_datistemplate 4
-#define Anum_pg_database_datallowconn  5
-#define Anum_pg_database_datconnlimit  6
-#define Anum_pg_database_datlastsysoid 7
-#define Anum_pg_database_datfrozenxid  8
-#define Anum_pg_database_dattablespace 9
-#define Anum_pg_database_datconfig             10
-#define Anum_pg_database_datacl                        11
+#define Anum_pg_database_datcollate            4
+#define Anum_pg_database_datctype              5
+#define Anum_pg_database_datistemplate 6
+#define Anum_pg_database_datallowconn  7
+#define Anum_pg_database_datconnlimit  8
+#define Anum_pg_database_datlastsysoid 9
+#define Anum_pg_database_datfrozenxid  10
+#define Anum_pg_database_dattablespace 11
+#define Anum_pg_database_datconfig             12
+#define Anum_pg_database_datacl                        13
 
-DATA(insert OID = 1 (  template1 PGUID ENCODING t t -1 0 0 1663 _null_ _null_ ));
+DATA(insert OID = 1 (  template1 PGUID ENCODING "LC_COLLATE" "LC_CTYPE" t t -1 0 0 1663 _null_ _null_));
 SHDESCR("default template database");
 #define TemplateDbOid                  1
 
index 2dee75524cabf07d56edf1fd354e97edf655baab..e67ea73b036023c4bf99a6d3610324ad09071708 100644 (file)
@@ -2,7 +2,7 @@
  *
  * PostgreSQL locale utilities
  *
- * $PostgreSQL: pgsql/src/include/utils/pg_locale.h,v 1.25 2008/05/19 18:08:16 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/pg_locale.h,v 1.26 2008/09/23 09:20:39 heikki Exp $
  *
  * Copyright (c) 2002-2008, PostgreSQL Global Development Group
  *
@@ -39,6 +39,7 @@ extern const char *locale_numeric_assign(const char *value,
 extern const char *locale_time_assign(const char *value,
                                   bool doit, GucSource source);
 
+extern bool check_locale(int category, const char *locale);
 extern char *pg_perm_setlocale(int category, const char *locale);
 
 extern bool lc_collate_is_c(void);
index d651852049b38169ccc1fd8451b92e64ce03b7d5..5b69d8b306e4c231bfb481b2aa13ff7d363053e8 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.371 2008/08/20 14:09:16 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.372 2008/09/23 09:20:39 heikki Exp $ */
 
 /* Copyright comment */
 %{
@@ -428,7 +428,7 @@ add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enu
        CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
        COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS 
        CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
-       CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
+       CREATEROLE CREATEUSER CROSS CSV CTYPE CURRENT_P CURRENT_DATE CURRENT_ROLE
        CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
 
        DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS