1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-31 22:04:40 +03:00

Use libc version as a collation version on glibc systems.

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
This commit is contained in:
Thomas Munro
2019-10-16 16:51:40 +13:00
parent 4351142e58
commit d5ac14f9cc
3 changed files with 24 additions and 4 deletions

View 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 does not actually check whether all affected objects have been rebuilt
correctly. correctly.
</para> </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> <para>
The following query can be used to identify all collations in the current The following query can be used to identify all collations in the current

View File

@ -70,6 +70,10 @@
#include <unicode/ucnv.h> #include <unicode/ucnv.h>
#endif #endif
#ifdef __GLIBC__
#include <gnu/libc-version.h>
#endif
#ifdef WIN32 #ifdef WIN32
/* /*
* This Windows file defines StrNCpy. We don't need it here, so we undefine * 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 * char *
get_collation_actual_version(char collprovider, const char *collcollate) get_collation_actual_version(char collprovider, const char *collcollate)
{ {
char *collversion; char *collversion = NULL;
#ifdef USE_ICU #ifdef USE_ICU
if (collprovider == COLLPROVIDER_ICU) if (collprovider == COLLPROVIDER_ICU)
@ -1523,7 +1527,13 @@ get_collation_actual_version(char collprovider, const char *collcollate)
} }
else else
#endif #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; return collversion;
} }

View File

@ -1376,8 +1376,8 @@ my %tests = (
'CREATE COLLATION test0 FROM "C"' => { 'CREATE COLLATION test0 FROM "C"' => {
create_order => 76, create_order => 76,
create_sql => 'CREATE COLLATION test0 FROM "C";', create_sql => 'CREATE COLLATION test0 FROM "C";',
regexp => qr/^ regexp =>
\QCREATE COLLATION public.test0 (provider = libc, locale = 'C');\E/xm, qr/CREATE COLLATION public.test0 \(provider = libc, locale = 'C'(, version = '[^']*')?\);/m,
collation => 1, collation => 1,
like => { %full_runs, section_pre_data => 1, }, like => { %full_runs, section_pre_data => 1, },
}, },