From 95f35fcbc61354c984193293f70e8ee8a944df91 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Mon, 23 Mar 2020 12:48:59 +1300
Subject: [PATCH v3 1/2] Allow NULL version for individual collations.

Remove the documented restriction that collation providers must either
return NULL for all collations or non-NULL for all collations.

Use NULL for glibc collations like "C.UTF-8", which might otherwise lead
future proposed commits to force unnecessary index rebuilds.

Reviewed-by: Peter Eisentraut <peter.eisentraut@2ndquadrant.com>
Discussion: https://postgr.es/m/CA%2BhUKGJvqup3s%2BJowVTcacZADO6dOhfdBmvOPHLS3KXUJu41Jw%40mail.gmail.com
---
 src/backend/utils/adt/pg_locale.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 64fd3ae18a..b42122f9ce 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1505,10 +1505,6 @@ pg_newlocale_from_collation(Oid collid)
 /*
  * Get provider-specific collation version string for the given collation from
  * the operating system/library.
- *
- * A particular provider must always either return a non-NULL string or return
- * NULL (if it doesn't support versions).  It must not return NULL for some
- * collcollate and not NULL for others.
  */
 char *
 get_collation_actual_version(char collprovider, const char *collcollate)
@@ -1540,6 +1536,23 @@ get_collation_actual_version(char collprovider, const char *collcollate)
 	if (collprovider == COLLPROVIDER_LIBC)
 	{
 #if defined(__GLIBC__)
+		char	   *copy = pstrdup(collcollate);
+		char	   *copy_suffix = strstr(copy, ".");
+		bool		need_version = true;
+
+		/*
+		 * Check for names like C.UTF-8 by chopping off the encoding suffix on
+		 * our temporary copy, so we can skip the version.
+		 */
+		if (copy_suffix)
+			*copy_suffix = '\0';
+		if (pg_strcasecmp("c", copy) == 0 ||
+			pg_strcasecmp("posix", copy) == 0)
+			need_version = false;
+		pfree(copy);
+		if (!need_version)
+			return NULL;
+
 		/* Use the glibc version because we don't have anything better. */
 		collversion = pstrdup(gnu_get_libc_version());
 #endif
-- 
2.20.1

