On Thu, Oct 3, 2019 at 7:53 AM Peter Eisentraut
<peter.eisentr...@2ndquadrant.com> wrote:
> On 2018-09-05 23:18, Thomas Munro wrote:
> > On Wed, Sep 5, 2018 at 12:10 PM Christoph Berg <m...@debian.org> wrote:
> >>> So, it's not ideal but perhaps worth considering on the grounds that
> >>> it's better than nothing?
> >>
> >> Ack.
> >
> > Ok, here's a little patch like that.
> >
> > postgres=# select collname, collcollate, collversion from pg_collation
> > where collname = 'en_NZ';
> >  collname | collcollate | collversion
> > ----------+-------------+-------------
> >  en_NZ    | en_NZ.utf8  | 2.24
> > (1 row)
>
> After, um, briefly sleeping on this, I would like to go ahead with this.
>
> There is ongoing work to make ICU available globally, and as part of
> that I've also proposed a way to make the collation version tracking
> work on a database level.
>
> This here would be a useful piece on the overall picture.  Independent
> of what becomes of the ICU effort, we could have glibc collation version
> tracking completely working for PG13.

+1

Also, better ideas about which objects to attach versions to can come
along independently of this.

> The only open question on this patch was whether it's a good version to
> use.  I think based on subsequent discussions, there was the realization
> that this is the best we can do and better than nothing.
>
> In the patch, I would skip the configure test and just do
>
> #ifdef __GLIBC__
>
> directly.

Ok.  Here's one like that.  Also, a WIP patch for FreeBSD.

Thanks,
Thomas
From 79ec43cd69e82867f479e4df7e87789f89525826 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.mu...@gmail.com>
Date: Fri, 4 Oct 2019 00:03:04 +1300
Subject: [PATCH 1/2] Use libc version as a collation version on glibc systems.

Using glibc's version number to detect potential collation definition
changes is not 100% reliable, but it's better than nothing.

Author: Thomas Munro
Reviewed-by: Peter Eisentraut
Discussion: https://postgr.es/m/4b76c6d4-ae5e-0dc6-7d0d-b5c796a07e34%402ndquadrant.com
---
 src/backend/utils/adt/pg_locale.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index b2f08ead45..694ff7626e 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -70,6 +70,10 @@
 #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
@@ -1518,7 +1522,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)
@@ -1542,7 +1546,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;
 }
-- 
2.20.1

From 81f5cf0283541874f6c9d2c2339e9326ff1ebee4 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.mu...@gmail.com>
Date: Fri, 4 Oct 2019 00:19:49 +1300
Subject: [PATCH 2/2] WIP: Use querylocale() for collation versions on FreeBSD.

Requires a WIP FreeBSD patch: https://reviews.freebsd.org/D17166
---
 src/backend/utils/adt/pg_locale.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 694ff7626e..a66f1c1fbe 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1551,6 +1551,18 @@ get_collation_actual_version(char collprovider, const char *collcollate)
 #if defined(__GLIBC__)
 		/* Use the glibc version because we don't have anything better. */
 		collversion = pstrdup(gnu_get_libc_version());
+#elif defined(LC_VERSION_MASK)
+		/* FreeBSD exposes the CLDR version. */
+		locale_t loc = newlocale(LC_COLLATE, collcollate, NULL);
+		if (loc)
+		{
+			collversion =
+				pstrdup(querylocale(LC_COLLATE_MASK | LC_VERSION_MASK, loc));
+			freelocale(loc);
+		}
+		else
+			ereport(ERROR,
+					(errmsg("could not load locale \"%s\"", collcollate)));
 #endif
 	}
 
-- 
2.20.1

Reply via email to