]> granicus.if.org Git - postgresql/commitdiff
Use libc version as a collation version on glibc systems.
authorThomas Munro <tmunro@postgresql.org>
Wed, 16 Oct 2019 03:51:40 +0000 (16:51 +1300)
committerThomas Munro <tmunro@postgresql.org>
Wed, 16 Oct 2019 04:28:24 +0000 (17:28 +1300)
Using glibc's version string to detect potential collation definition
changes is not 100% reliable, but it's better than nothing.  Currently
this affects only collations explicitly provided by "libc".  More work
will be needed to handle the default collation.

Author: Thomas Munro, based on a suggestion from Christoph Berg
Reviewed-by: Peter Eisentraut
Discussion: https://postgr.es/m/4b76c6d4-ae5e-0dc6-7d0d-b5c796a07e34%402ndquadrant.com

doc/src/sgml/ref/alter_collation.sgml
src/backend/utils/adt/pg_locale.c
src/bin/pg_dump/t/002_pg_dump.pl

index b51b3a25647d9031fde1f9f0b967c58ab3bf4250..4cfcb42251f00d5fd97d7d4bcf1bbe76aaecdd7e 100644 (file)
@@ -129,6 +129,16 @@ HINT:  Rebuild all objects affected by this collation and run ALTER COLLATION pg
    does not actually check whether all affected objects have been rebuilt
    correctly.
   </para>
+  <para>
+   When using collations provided by <literal>libc</literal> and
+   <productname>PostgreSQL</productname> was built with the GNU C library, the
+   C library's version is used as a collation version.  Since collation
+   definitions typically change only with GNU C library releases, this provides
+   some defense against corruption, but it is not completely reliable.
+  </para>
+  <para>
+   Currently, there is no version tracking for the database default collation.
+  </para>
 
   <para>
    The following query can be used to identify all collations in the current
index 2a076a3dfd19522d23c13536cd3f1990524569af..fcdbaae37b9db6d2090aac1196e9b6f2118f2380 100644 (file)
 #include <unicode/ucnv.h>
 #endif
 
+#ifdef __GLIBC__
+#include <gnu/libc-version.h>
+#endif
+
 #ifdef WIN32
 /*
  * This Windows file defines StrNCpy. We don't need it here, so we undefine
@@ -1499,7 +1503,7 @@ pg_newlocale_from_collation(Oid collid)
 char *
 get_collation_actual_version(char collprovider, const char *collcollate)
 {
-       char       *collversion;
+       char       *collversion = NULL;
 
 #ifdef USE_ICU
        if (collprovider == COLLPROVIDER_ICU)
@@ -1523,7 +1527,13 @@ get_collation_actual_version(char collprovider, const char *collcollate)
        }
        else
 #endif
-               collversion = NULL;
+       if (collprovider == COLLPROVIDER_LIBC)
+       {
+#if defined(__GLIBC__)
+               /* Use the glibc version because we don't have anything better. */
+               collversion = pstrdup(gnu_get_libc_version());
+#endif
+       }
 
        return collversion;
 }
index 4712e3a95812c193ca210e57c7f7bfb531c8a118..11634204913d2b9f5b8726bb1bd70975c97f2d4c 100644 (file)
@@ -1376,8 +1376,8 @@ my %tests = (
        'CREATE COLLATION test0 FROM "C"' => {
                create_order => 76,
                create_sql   => 'CREATE COLLATION test0 FROM "C";',
-               regexp       => qr/^
-                 \QCREATE COLLATION public.test0 (provider = libc, locale = 'C');\E/xm,
+               regexp       =>
+                 qr/CREATE COLLATION public.test0 \(provider = libc, locale = 'C'(, version = '[^']*')?\);/m,
                collation => 1,
                like      => { %full_runs, section_pre_data => 1, },
        },