From d14d5408008e675c10d0b85cad8d5e7be1c4b114 Mon Sep 17 00:00:00 2001
From: Julien Rouhaud <julien.rouhaud@free.fr>
Date: Fri, 1 Nov 2019 14:05:44 +0100
Subject: [PATCH 4/5] Also track default collation version.

---
 src/backend/catalog/dependency.c           | 12 +++++---
 src/backend/catalog/index.c                | 23 ++++++++++++----
 src/backend/catalog/pg_depend.c            | 13 +++++----
 src/backend/utils/adt/pg_locale.c          | 32 +++++++++++++++++-----
 src/include/catalog/dependency.h           |  6 ++--
 src/test/regress/expected/create_index.out |  8 ++++--
 6 files changed, 68 insertions(+), 26 deletions(-)

diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 6287a4017a..518b53094f 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -1661,7 +1661,8 @@ recordDependencyOnExpr(const ObjectAddress *depender,
 	recordMultipleDependencies(depender,
 							   context.addrs->refs, NULL,
 							   context.addrs->numrefs,
-							   behavior);
+							   behavior,
+							   false);
 
 	free_object_addresses(context.addrs);
 }
@@ -1749,7 +1750,8 @@ recordDependencyOnSingleRelExpr(const ObjectAddress *depender,
 			recordMultipleDependencies(depender,
 									   self_addrs->refs, NULL,
 									   self_addrs->numrefs,
-									   self_behavior);
+									   self_behavior,
+									   false);
 		else
 		{
 			/* Can't use recordMultipleDependencies, so do it the hard way */
@@ -1770,7 +1772,8 @@ recordDependencyOnSingleRelExpr(const ObjectAddress *depender,
 	recordMultipleDependencies(depender,
 							   context.addrs->refs, NULL,
 							   context.addrs->numrefs,
-							   behavior);
+							   behavior,
+							   false);
 
 	free_object_addresses(context.addrs);
 }
@@ -2708,7 +2711,8 @@ record_object_address_dependencies(const ObjectAddress *depender,
 	eliminate_duplicate_dependencies(referenced);
 	recordMultipleDependencies(depender,
 							   referenced->refs, NULL, referenced->numrefs,
-							   behavior);
+							   behavior,
+							   false);
 }
 
 /*
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index ee841a9a36..2e9b28fe11 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1118,14 +1118,25 @@ index_create(Relation heapRelation,
 			recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_SEC);
 		}
 
-		/* Store dependency on collations */
-		/* The default collation is pinned, so don't bother recording it */
+		/*
+		 * Store dependency on collations The C and posix collations are
+		 * pinned, so don't bother recording them
+		 */
 		for (i = 0; i < indexInfo->ii_NumIndexKeyAttrs; i++)
 		{
-			if (OidIsValid(collationObjectId[i]) &&
-				collationObjectId[i] != DEFAULT_COLLATION_OID)
+			if (OidIsValid(collationObjectId[i])
+				&& collationObjectId[i] != C_COLLATION_OID
+				&& collationObjectId[i] != POSIX_COLLATION_OID
+				)
 			{
-				NameData version;
+				NameData	version;
+				bool		force;
+
+				/*
+				 * We need to force the recording for the default collation as
+				 * it's pinned
+				 */
+				force = (collationObjectId[i] == DEFAULT_COLLATION_OID);
 
 				referenced.classId = CollationRelationId;
 				referenced.objectId = collationObjectId[i];
@@ -1133,7 +1144,7 @@ index_create(Relation heapRelation,
 				get_collation_version_for_oid(referenced.objectId, &version);
 
 				recordDependencyOnVersion(&myself, &referenced, &version,
-										  DEPENDENCY_NORMAL);
+										  DEPENDENCY_NORMAL, force);
 			}
 		}
 
diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c
index f1dc1143a7..db83658cf6 100644
--- a/src/backend/catalog/pg_depend.c
+++ b/src/backend/catalog/pg_depend.c
@@ -44,7 +44,7 @@ recordDependencyOn(const ObjectAddress *depender,
 				   const ObjectAddress *referenced,
 				   DependencyType behavior)
 {
-	recordMultipleDependencies(depender, referenced, NULL, 1, behavior);
+	recordMultipleDependencies(depender, referenced, NULL, 1, behavior, false);
 }
 
 /*
@@ -57,9 +57,11 @@ void
 recordDependencyOnVersion(const ObjectAddress *depender,
 						  const ObjectAddress *referenced,
 						  const NameData *version,
-						  DependencyType behavior)
+						  DependencyType behavior,
+						  bool ignore_systempin)
 {
-	recordMultipleDependencies(depender, referenced, version, 1, behavior);
+	recordMultipleDependencies(depender, referenced, version, 1, behavior,
+							   ignore_systempin);
 }
 
 /*
@@ -71,7 +73,8 @@ recordMultipleDependencies(const ObjectAddress *depender,
 						   const ObjectAddress *referenced,
 						   const NameData *version,
 						   int nreferenced,
-						   DependencyType behavior)
+						   DependencyType behavior,
+						   bool ignore_systempin)
 {
 	Relation	dependDesc;
 	CatalogIndexState indstate;
@@ -104,7 +107,7 @@ recordMultipleDependencies(const ObjectAddress *depender,
 		 * need to record dependencies on it.  This saves lots of space in
 		 * pg_depend, so it's worth the time taken to check.
 		 */
-		if (!isObjectPinned(referenced, dependDesc))
+		if (ignore_systempin || !isObjectPinned(referenced, dependDesc))
 		{
 			/*
 			 * Record the Dependency.  Note we don't bother to check for
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index f7aa3a3672..19a1a6573a 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -57,7 +57,9 @@
 #include "access/htup_details.h"
 #include "catalog/pg_collation.h"
 #include "catalog/pg_control.h"
+#include "catalog/pg_database.h"
 #include "mb/pg_wchar.h"
+#include "miscadmin.h"
 #include "utils/builtins.h"
 #include "utils/formatting.h"
 #include "utils/hsearch.h"
@@ -1508,15 +1510,31 @@ void
 get_collation_version_for_oid(Oid oid, NameData *output)
 {
 	HeapTuple	tp;
-	Form_pg_collation collform;
 	const char *version;
 
-	tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(oid));
-	if (!HeapTupleIsValid(tp))
-		elog(ERROR, "cache lookup failed for collation %u", oid);
-	collform = (Form_pg_collation) GETSTRUCT(tp);
-	version = get_collation_actual_version(collform->collprovider,
-										   NameStr(collform->collcollate));
+	if (oid == DEFAULT_COLLATION_OID)
+	{
+		Form_pg_database dbform;
+
+		tp = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
+		if (!HeapTupleIsValid(tp))
+			elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
+		dbform = (Form_pg_database) GETSTRUCT(tp);
+		version = get_collation_actual_version(COLLPROVIDER_LIBC,
+											   NameStr(dbform->datcollate));
+	}
+	else
+	{
+		Form_pg_collation collform;
+
+		tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(oid));
+		if (!HeapTupleIsValid(tp))
+			elog(ERROR, "cache lookup failed for collation %u", oid);
+		collform = (Form_pg_collation) GETSTRUCT(tp);
+		version = get_collation_actual_version(collform->collprovider,
+											   NameStr(collform->collcollate));
+	}
+
 	memset(output, 0, sizeof(NameData));
 	if (version)
 		strncpy(NameStr(*output), version, sizeof(NameData));
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
index 6ba9e634a5..83ea8c9458 100644
--- a/src/include/catalog/dependency.h
+++ b/src/include/catalog/dependency.h
@@ -193,13 +193,15 @@ extern void recordDependencyOn(const ObjectAddress *depender,
 extern void recordDependencyOnVersion(const ObjectAddress *depender,
 									  const ObjectAddress *referenced,
 									  const NameData *version,
-									  DependencyType behavior);
+									  DependencyType behavior,
+									  bool ignore_systempin);
 
 extern void recordMultipleDependencies(const ObjectAddress *depender,
 									   const ObjectAddress *referenced,
 									   const NameData *version,
 									   int nreferenced,
-									   DependencyType behavior);
+									   DependencyType behavior,
+									   bool ignore_systempin);
 
 extern void recordDependencyOnCurrentExtension(const ObjectAddress *object,
 											   bool isReplace);
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 1cdb7a9663..2f30d66935 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -1990,15 +1990,17 @@ WHERE classid = 'pg_class'::regclass AND
                    obj                    |                           objref                           | deptype 
 ------------------------------------------+------------------------------------------------------------+---------
  index concur_reindex_ind1                | constraint concur_reindex_ind1 on table concur_reindex_tab | i
+ index concur_reindex_ind2                | collation "default"                                        | n
  index concur_reindex_ind2                | column c2 of table concur_reindex_tab                      | a
  index concur_reindex_ind3                | column c1 of table concur_reindex_tab                      | a
  index concur_reindex_ind3                | table concur_reindex_tab                                   | a
+ index concur_reindex_ind4                | collation "default"                                        | n
  index concur_reindex_ind4                | column c1 of table concur_reindex_tab                      | a
  index concur_reindex_ind4                | column c1 of table concur_reindex_tab                      | a
  index concur_reindex_ind4                | column c2 of table concur_reindex_tab                      | a
  materialized view concur_reindex_matview | schema public                                              | n
  table concur_reindex_tab                 | schema public                                              | n
-(9 rows)
+(11 rows)
 
 REINDEX INDEX CONCURRENTLY concur_reindex_ind1;
 REINDEX TABLE CONCURRENTLY concur_reindex_tab;
@@ -2018,15 +2020,17 @@ WHERE classid = 'pg_class'::regclass AND
                    obj                    |                           objref                           | deptype 
 ------------------------------------------+------------------------------------------------------------+---------
  index concur_reindex_ind1                | constraint concur_reindex_ind1 on table concur_reindex_tab | i
+ index concur_reindex_ind2                | collation "default"                                        | n
  index concur_reindex_ind2                | column c2 of table concur_reindex_tab                      | a
  index concur_reindex_ind3                | column c1 of table concur_reindex_tab                      | a
  index concur_reindex_ind3                | table concur_reindex_tab                                   | a
+ index concur_reindex_ind4                | collation "default"                                        | n
  index concur_reindex_ind4                | column c1 of table concur_reindex_tab                      | a
  index concur_reindex_ind4                | column c1 of table concur_reindex_tab                      | a
  index concur_reindex_ind4                | column c2 of table concur_reindex_tab                      | a
  materialized view concur_reindex_matview | schema public                                              | n
  table concur_reindex_tab                 | schema public                                              | n
-(9 rows)
+(11 rows)
 
 -- Check that comments are preserved
 CREATE TABLE testcomment (i int);
-- 
2.20.1

