On Fri, Oct 4, 2019 at 1:25 AM Thomas Munro <thomas.mu...@gmail.com> wrote:
> Ok.  Here's one like that.  Also, a WIP patch for FreeBSD.

Here's an updated patch for FreeBSD, which I'll sit on for a bit
longer.  It needs bleeding edge 13-CURRENT (due out Q1ish).
From b9cb5562457c214c48c0a6334b8ed3264f50e3d6 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.mu...@gmail.com>
Date: Sun, 8 Nov 2020 21:12:12 +1300
Subject: [PATCH] Add collation versions for FreeBSD.

On FreeBSD 13, use querylocale() to read the current version of libc
collations.
---
 doc/src/sgml/charset.sgml         |  3 ++-
 src/backend/utils/adt/pg_locale.c | 20 ++++++++++++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 832a701523..e151987eff 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -973,7 +973,8 @@ CREATE COLLATION ignore_accents (provider = icu, locale = 'und-u-ks-level1-kc-tr
     Version information is available from the
     <literal>icu</literal> provider on all operating systems.  For the
     <literal>libc</literal> provider, versions are currently only available
-    on systems using the GNU C library (most Linux systems) and Windows.
+    on systems using the GNU C library (most Linux systems), FreeBSD and
+    Windows.
    </para>
 
    <note>
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 1dfe343b79..b1a8eb9a4e 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1684,6 +1684,26 @@ get_collation_actual_version(char collprovider, const char *collcollate)
 
 		/* Use the glibc version because we don't have anything better. */
 		collversion = pstrdup(gnu_get_libc_version());
+#elif defined(LC_VERSION_MASK)
+		locale_t    loc;
+
+		/* C[.encoding] and POSIX never change. */
+		if (strcmp("C", collcollate) == 0 ||
+			strncmp("C.", collcollate, 2) == 0 ||
+			strcmp("POSIX", collcollate) == 0)
+			return NULL;
+
+		/* Look up FreeBSD collation version. */
+		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)));
 #elif defined(WIN32) && _WIN32_WINNT >= 0x0600
 		/*
 		 * If we are targeting Windows Vista and above, we can ask for a name
-- 
2.28.0

Reply via email to