From 77a5576306b7c35800dd3fd1c42ddf98ee1e60ee Mon Sep 17 00:00:00 2001
From: Julien Rouhaud <julien.rouhaud@free.fr>
Date: Wed, 11 Dec 2019 13:54:32 +0100
Subject: [PATCH 6/6] Add a new ALTER INDEX name DEPENDS ON COLLATION name
 CURRENT VERSION

This command allows privileged users to specifify that the currently installed
collation library version, for a specific collation, is binary compatible with
the one that was installed when the specified index was built for the last
time.

Author: Julien Rouhaud
Reviewed-by:
Discussion: https://postgr.es/m/CAEepm%3D0uEQCpfq_%2BLYFBdArCe4Ot98t1aR4eYiYTe%3DyavQygiQ%40mail.gmail.com
---
 doc/src/sgml/ref/alter_index.sgml             |  13 ++
 src/backend/commands/tablecmds.c              |  20 ++-
 src/backend/parser/gram.y                     |   9 ++
 src/bin/psql/tab-complete.c                   |  26 +++-
 src/include/nodes/parsenodes.h                |   5 +-
 .../regress/expected/collate.icu.utf8.out     | 147 ++++++++++--------
 src/test/regress/sql/collate.icu.utf8.sql     |  47 +++---
 7 files changed, 175 insertions(+), 92 deletions(-)

diff --git a/doc/src/sgml/ref/alter_index.sgml b/doc/src/sgml/ref/alter_index.sgml
index 6d34dbb74e..f4a4333ab1 100644
--- a/doc/src/sgml/ref/alter_index.sgml
+++ b/doc/src/sgml/ref/alter_index.sgml
@@ -25,6 +25,7 @@ ALTER INDEX [ IF EXISTS ] <replaceable class="parameter">name</replaceable> RENA
 ALTER INDEX [ IF EXISTS ] <replaceable class="parameter">name</replaceable> SET TABLESPACE <replaceable class="parameter">tablespace_name</replaceable>
 ALTER INDEX <replaceable class="parameter">name</replaceable> ATTACH PARTITION <replaceable class="parameter">index_name</replaceable>
 ALTER INDEX <replaceable class="parameter">name</replaceable> DEPENDS ON EXTENSION <replaceable class="parameter">extension_name</replaceable>
+ALTER INDEX <replaceable class="parameter">name</replaceable> DEPENDS ON COLLATION <replaceable class="parameter">collation_name</replaceable> CURRENT VERSION
 ALTER INDEX [ IF EXISTS ] <replaceable class="parameter">name</replaceable> SET ( <replaceable class="parameter">storage_parameter</replaceable> = <replaceable class="parameter">value</replaceable> [, ... ] )
 ALTER INDEX [ IF EXISTS ] <replaceable class="parameter">name</replaceable> RESET ( <replaceable class="parameter">storage_parameter</replaceable> [, ... ] )
 ALTER INDEX [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ALTER [ COLUMN ] <replaceable class="parameter">column_number</replaceable>
@@ -109,6 +110,18 @@ ALTER INDEX ALL IN TABLESPACE <replaceable class="parameter">name</replaceable>
     </listitem>
    </varlistentry>
 
+   <varlistentry>
+    <term><literal>DEPENDS ON COLLATION</literal></term>
+    <listitem>
+     <para>
+      This form update the index existing dependency on a specific collation,
+      to specificy the the currently installed collation version is compatible
+      with the version used the last time the index was built.  Be aware that
+      an incorrect use of this form can hide a corruption on the index.
+     </para>
+    </listitem>
+   </varlistentry>
+
    <varlistentry>
     <term><literal>SET ( <replaceable class="parameter">storage_parameter</replaceable> = <replaceable class="parameter">value</replaceable> [, ... ] )</literal></term>
     <listitem>
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index b3cf5641fd..31ab4f5ad4 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -93,6 +93,7 @@
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
 #include "utils/partcache.h"
+#include "utils/pg_locale.h"
 #include "utils/relcache.h"
 #include "utils/ruleutils.h"
 #include "utils/snapmgr.h"
@@ -4054,7 +4055,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
 			break;
 		case AT_DependsOnCollationVersion:	/* DEPENDS ON COLLATION ...
 											 * [UNKNOWN VERSION | VERSION ...] */
-			if (!IsBinaryUpgrade)
+			if (!IsBinaryUpgrade && cmd->version)
 				ereport(ERROR,
 						(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
 						 (errmsg("command can only be called when server is in binary upgrade mode"))));
@@ -17319,8 +17320,9 @@ index_force_collation_version(const ObjectAddress *otherObject,
 
 /* Execute an ALTER INDEX ... ALTER COLLATION DEPENDS ON ...
  *
- * A version has to be provided.  If the caller wants to notify that the
- * collation version to depend on is unknown, an empty string is passed.
+ * If the caller wants to notify that the collation version to depend on is
+ * unknown, an empty string is passed.  If the collation's current version has
+ * to be used, then NULL is passed.
  */
 static void
 ATExecDependsOnCollationVersion(Relation rel, List *coll, char *version)
@@ -17328,14 +17330,20 @@ ATExecDependsOnCollationVersion(Relation rel, List *coll, char *version)
 	ObjectAddress object;
 	NewCollationVersionDependency forced_dependency;
 
-	Assert(version);
-
 	if (coll == NIL)
 		forced_dependency.oid = InvalidOid;
 	else
 		forced_dependency.oid = get_collation_oid(coll, false);
 
-	forced_dependency.version = version;
+	if (version)
+		forced_dependency.version = version;
+	else
+	{
+		/* Retrieve the current version for the CURRENT VERSION case. */
+		Assert(OidIsValid(forced_dependency.oid));
+		forced_dependency.version =
+			get_collation_version_for_oid(forced_dependency.oid);
+	}
 
 	object.classId = RelationRelationId;
 	object.objectId = rel->rd_id;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 1437123540..cb8c4f6b05 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -2596,6 +2596,15 @@ alter_table_cmd:
 					n->version = "";
 					$$ = (Node *)n;
 				}
+			/* ALTER INDEX <name> DEPENDS ON COLLATION ... CURRENT VERSION */
+			| DEPENDS ON COLLATION any_name CURRENT_P VERSION_P
+				{
+					AlterTableCmd *n = makeNode(AlterTableCmd);
+					n->subtype = AT_DependsOnCollationVersion;
+					n->object = $4;
+					n->version = NULL;
+					$$ = (Node *)n;
+				}
 			| alter_generic_options
 				{
 					AlterTableCmd *n = makeNode(AlterTableCmd);
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index dc03fbde13..e1b56b8fed 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -45,6 +45,7 @@
 
 #include "catalog/pg_am_d.h"
 #include "catalog/pg_class_d.h"
+#include "catalog/pg_collation_d.h"
 #include "common.h"
 #include "libpq-fe.h"
 #include "pqexpbuffer.h"
@@ -807,6 +808,20 @@ static const SchemaQuery Query_for_list_of_statistics = {
 "       (SELECT tgrelid FROM pg_catalog.pg_trigger "\
 "         WHERE pg_catalog.quote_ident(tgname)='%s')"
 
+/* the silly-looking length condition is just to eat up the current word */
+#define Query_for_list_of_colls_for_one_index \
+" SELECT DISTINCT pg_catalog.quote_ident(coll.collname) " \
+"   FROM pg_catalog.pg_depend d, pg_catalog.pg_collation coll, " \
+"     pg_catalog.pg_class c" \
+" WHERE (%d = pg_catalog.length('%s'))" \
+"   AND d.refclassid = " CppAsString2(CollationRelationId) \
+"   AND d.refobjid = coll.oid " \
+"   AND d.classid = " CppAsString2(RelationRelationId) \
+"   AND d.objid = c.oid " \
+"   AND c.relkind = " CppAsString2(RELKIND_INDEX) \
+"   AND pg_catalog.pg_table_is_visible(c.oid) " \
+"   AND c.relname = '%s'"
+
 #define Query_for_list_of_ts_configurations \
 "SELECT pg_catalog.quote_ident(cfgname) FROM pg_catalog.pg_ts_config "\
 " WHERE substring(pg_catalog.quote_ident(cfgname),1,%d)='%s'"
@@ -1697,7 +1712,7 @@ psql_completion(const char *text, int start, int end)
 	/* ALTER INDEX <name> */
 	else if (Matches("ALTER", "INDEX", MatchAny))
 		COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO", "SET",
-					  "RESET", "ATTACH PARTITION");
+					  "RESET", "ATTACH PARTITION", "DEPENDS ON COLLATION");
 	else if (Matches("ALTER", "INDEX", MatchAny, "ATTACH"))
 		COMPLETE_WITH("PARTITION");
 	else if (Matches("ALTER", "INDEX", MatchAny, "ATTACH", "PARTITION"))
@@ -1743,6 +1758,15 @@ psql_completion(const char *text, int start, int end)
 					  "buffering =",	/* GiST */
 					  "pages_per_range =", "autosummarize ="	/* BRIN */
 			);
+	/* ALTER INDEX <name> DEPENDS ON COLLATION */
+	else if (Matches("ALTER", "INDEX", MatchAny, "DEPENDS", "ON", "COLLATION"))
+	{
+		completion_info_charp = prev4_wd;
+		COMPLETE_WITH_QUERY(Query_for_list_of_colls_for_one_index);
+	}
+	/* ALTER INDEX <name> DEPENDS ON COLLATION <name> */
+	else if (Matches("ALTER", "INDEX", MatchAny, "DEPENDS", "ON", "COLLATION", MatchAny))
+		COMPLETE_WITH("CURRENT VERSION");
 
 	/* ALTER LANGUAGE <name> */
 	else if (Matches("ALTER", "LANGUAGE", MatchAny))
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index b36824ddfe..a418d43352 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1864,7 +1864,10 @@ typedef struct AlterTableCmd	/* one subcommand of an ALTER TABLE */
 	List	   *object;			/* collation to act on if it's a collation */
 	int16		num;			/* attribute number for columns referenced by
 								 * number */
-	char	   *version;		/* version reference for collation dependency */
+	char	   *version;		/* version reference for collation dependency.
+								 * An empty string is used to represent an
+								 * unknown version, and a NULL pointer is used
+								 * to represent the current version */
 	RoleSpec   *newowner;
 	Node	   *def;			/* definition of new column, index,
 								 * constraint, or parent table */
diff --git a/src/test/regress/expected/collate.icu.utf8.out b/src/test/regress/expected/collate.icu.utf8.out
index 6a218d7954..b35c200b24 100644
--- a/src/test/regress/expected/collate.icu.utf8.out
+++ b/src/test/regress/expected/collate.icu.utf8.out
@@ -1923,26 +1923,26 @@ CREATE TABLE collate_test (
     myrange_en_fr_ga myrange_en_fr_ga,
     mood mood
 );
-CREATE INDEX idx01_t_en_fr__d_es ON collate_test (t_en_fr, d_es);
-CREATE INDEX idx02_d_en_fr ON collate_test (d_en_fr);
-CREATE INDEX idx03_t_en_fr_ga ON collate_test (t_en_fr_ga);
-CREATE INDEX idx04_d_en_fr_ga ON collate_test (d_en_fr_ga);
-CREATE INDEX idx05_d_en_fr_ga_arr ON collate_test (d_en_fr_ga_arr);
-CREATE INDEX idx06_d_en_fr_ga ON collate_test(id) WHERE (d_en_fr_ga).en_fr.fr = 'foo';
-CREATE INDEX idx07_d_en_fr_ga ON collate_test(id) WHERE (d_en_fr_ga).ga = 'foo';
-CREATE INDEX idx08_d_en_fr_ga ON collate_test(id) WHERE (t_en_fr_ga) = ('foo', 'bar', 'baz');
-CREATE INDEX idx09_d_en_fr_ga ON collate_test(id) WHERE (d_en_fr_ga) = ('foo', 'bar', 'baz');
-CREATE INDEX idx10_d_en_fr_ga_es ON collate_test(id) WHERE (d_en_fr_ga) = ('foo', 'bar', 'baz' COLLATE "es-x-icu");
-CREATE INDEX idx11_d_es ON collate_test(id) WHERE (d_es) = ('foo');
-CREATE INDEX idx12_custom ON collate_test(id) WHERE ('foo', 'bar')::d_custom = ('foo', 'bar' collate custom)::d_custom;
-CREATE INDEX idx13_custom ON collate_test(id) WHERE ('foo' collate custom, 'bar')::d_custom = ('foo', 'bar')::d_custom;
-CREATE INDEX idx14_myrange ON collate_test(myrange);
-CREATE INDEX idx15_myrange_en_fr_ga ON collate_test USING gist (myrange_en_fr_ga);
-CREATE INDEX idx16_mood ON collate_test(id) WHERE mood > 'ok' collate "fr-x-icu";
+CREATE INDEX icuidx01_t_en_fr__d_es ON collate_test (t_en_fr, d_es);
+CREATE INDEX icuidx02_d_en_fr ON collate_test (d_en_fr);
+CREATE INDEX icuidx03_t_en_fr_ga ON collate_test (t_en_fr_ga);
+CREATE INDEX icuidx04_d_en_fr_ga ON collate_test (d_en_fr_ga);
+CREATE INDEX icuidx05_d_en_fr_ga_arr ON collate_test (d_en_fr_ga_arr);
+CREATE INDEX icuidx06_d_en_fr_ga ON collate_test(id) WHERE (d_en_fr_ga).en_fr.fr = 'foo';
+CREATE INDEX icuidx07_d_en_fr_ga ON collate_test(id) WHERE (d_en_fr_ga).ga = 'foo';
+CREATE INDEX icuidx08_d_en_fr_ga ON collate_test(id) WHERE (t_en_fr_ga) = ('foo', 'bar', 'baz');
+CREATE INDEX icuidx09_d_en_fr_ga ON collate_test(id) WHERE (d_en_fr_ga) = ('foo', 'bar', 'baz');
+CREATE INDEX icuidx10_d_en_fr_ga_es ON collate_test(id) WHERE (d_en_fr_ga) = ('foo', 'bar', 'baz' COLLATE "es-x-icu");
+CREATE INDEX icuidx11_d_es ON collate_test(id) WHERE (d_es) = ('foo');
+CREATE INDEX icuidx12_custom ON collate_test(id) WHERE ('foo', 'bar')::d_custom = ('foo', 'bar' collate custom)::d_custom;
+CREATE INDEX icuidx13_custom ON collate_test(id) WHERE ('foo' collate custom, 'bar')::d_custom = ('foo', 'bar')::d_custom;
+CREATE INDEX icuidx14_myrange ON collate_test(myrange);
+CREATE INDEX icuidx15_myrange_en_fr_ga ON collate_test USING gist (myrange_en_fr_ga);
+CREATE INDEX icuidx16_mood ON collate_test(id) WHERE mood > 'ok' collate "fr-x-icu";
 CREATE TABLE collate_part(id integer, val text COLLATE "en-x-icu") PARTITION BY range(id);
 CREATE TABLE collate_part_0 PARTITION OF collate_part FOR VALUES FROM (0) TO (1);
 CREATE TABLE collate_part_1 PARTITION OF collate_part FOR VALUES FROM (1) TO (1000000);
-CREATE INDEX idx16_part ON collate_part_1 (val);
+CREATE INDEX icuidx17_part ON collate_part_1 (val);
 -- version of default (and libc) collation is only tracked on glibc systems
 SELECT objid::regclass, refobjid::regcollation,
 CASE
@@ -1953,59 +1953,59 @@ FROM pg_depend d
 LEFT JOIN pg_class c ON c.oid = d.objid
 WHERE refclassid = 'pg_collation'::regclass
 AND coalesce(relkind, 'i') = 'i'
-AND relname LIKE 'idx%'
+AND relname LIKE 'icuidx%'
 ORDER BY 1, 2;
-         objid          |  refobjid  |   version    
-------------------------+------------+--------------
- idx01_t_en_fr__d_es    | "en-x-icu" | some version
- idx01_t_en_fr__d_es    | "es-x-icu" | some version
- idx01_t_en_fr__d_es    | "fr-x-icu" | some version
- idx02_d_en_fr          | "en-x-icu" | some version
- idx02_d_en_fr          | "fr-x-icu" | some version
- idx03_t_en_fr_ga       | "en-x-icu" | some version
- idx03_t_en_fr_ga       | "fr-x-icu" | some version
- idx03_t_en_fr_ga       | "ga-x-icu" | some version
- idx04_d_en_fr_ga       | "en-x-icu" | some version
- idx04_d_en_fr_ga       | "fr-x-icu" | some version
- idx04_d_en_fr_ga       | "ga-x-icu" | some version
- idx05_d_en_fr_ga_arr   | "en-x-icu" | some version
- idx05_d_en_fr_ga_arr   | "fr-x-icu" | some version
- idx05_d_en_fr_ga_arr   | "ga-x-icu" | some version
- idx06_d_en_fr_ga       | "default"  | no version
- idx06_d_en_fr_ga       | "en-x-icu" | some version
- idx06_d_en_fr_ga       | "fr-x-icu" | some version
- idx06_d_en_fr_ga       | "ga-x-icu" | some version
- idx07_d_en_fr_ga       | "default"  | no version
- idx07_d_en_fr_ga       | "en-x-icu" | some version
- idx07_d_en_fr_ga       | "fr-x-icu" | some version
- idx07_d_en_fr_ga       | "ga-x-icu" | some version
- idx08_d_en_fr_ga       | "en-x-icu" | some version
- idx08_d_en_fr_ga       | "fr-x-icu" | some version
- idx08_d_en_fr_ga       | "ga-x-icu" | some version
- idx09_d_en_fr_ga       | "en-x-icu" | some version
- idx09_d_en_fr_ga       | "fr-x-icu" | some version
- idx09_d_en_fr_ga       | "ga-x-icu" | some version
- idx10_d_en_fr_ga_es    | "en-x-icu" | some version
- idx10_d_en_fr_ga_es    | "es-x-icu" | some version
- idx10_d_en_fr_ga_es    | "fr-x-icu" | some version
- idx10_d_en_fr_ga_es    | "ga-x-icu" | some version
- idx11_d_es             | "default"  | no version
- idx11_d_es             | "es-x-icu" | some version
- idx12_custom           | "default"  | no version
- idx12_custom           | custom     | some version
- idx13_custom           | "default"  | no version
- idx13_custom           | custom     | some version
- idx14_myrange          | "default"  | no version
- idx15_myrange_en_fr_ga | "en-x-icu" | some version
- idx15_myrange_en_fr_ga | "fr-x-icu" | some version
- idx15_myrange_en_fr_ga | "ga-x-icu" | some version
- idx16_mood             | "fr-x-icu" | some version
- idx16_part             | "en-x-icu" | some version
+           objid           |  refobjid  |   version    
+---------------------------+------------+--------------
+ icuidx01_t_en_fr__d_es    | "en-x-icu" | some version
+ icuidx01_t_en_fr__d_es    | "es-x-icu" | some version
+ icuidx01_t_en_fr__d_es    | "fr-x-icu" | some version
+ icuidx02_d_en_fr          | "en-x-icu" | some version
+ icuidx02_d_en_fr          | "fr-x-icu" | some version
+ icuidx03_t_en_fr_ga       | "en-x-icu" | some version
+ icuidx03_t_en_fr_ga       | "fr-x-icu" | some version
+ icuidx03_t_en_fr_ga       | "ga-x-icu" | some version
+ icuidx04_d_en_fr_ga       | "en-x-icu" | some version
+ icuidx04_d_en_fr_ga       | "fr-x-icu" | some version
+ icuidx04_d_en_fr_ga       | "ga-x-icu" | some version
+ icuidx05_d_en_fr_ga_arr   | "en-x-icu" | some version
+ icuidx05_d_en_fr_ga_arr   | "fr-x-icu" | some version
+ icuidx05_d_en_fr_ga_arr   | "ga-x-icu" | some version
+ icuidx06_d_en_fr_ga       | "default"  | no version
+ icuidx06_d_en_fr_ga       | "en-x-icu" | some version
+ icuidx06_d_en_fr_ga       | "fr-x-icu" | some version
+ icuidx06_d_en_fr_ga       | "ga-x-icu" | some version
+ icuidx07_d_en_fr_ga       | "default"  | no version
+ icuidx07_d_en_fr_ga       | "en-x-icu" | some version
+ icuidx07_d_en_fr_ga       | "fr-x-icu" | some version
+ icuidx07_d_en_fr_ga       | "ga-x-icu" | some version
+ icuidx08_d_en_fr_ga       | "en-x-icu" | some version
+ icuidx08_d_en_fr_ga       | "fr-x-icu" | some version
+ icuidx08_d_en_fr_ga       | "ga-x-icu" | some version
+ icuidx09_d_en_fr_ga       | "en-x-icu" | some version
+ icuidx09_d_en_fr_ga       | "fr-x-icu" | some version
+ icuidx09_d_en_fr_ga       | "ga-x-icu" | some version
+ icuidx10_d_en_fr_ga_es    | "en-x-icu" | some version
+ icuidx10_d_en_fr_ga_es    | "es-x-icu" | some version
+ icuidx10_d_en_fr_ga_es    | "fr-x-icu" | some version
+ icuidx10_d_en_fr_ga_es    | "ga-x-icu" | some version
+ icuidx11_d_es             | "default"  | no version
+ icuidx11_d_es             | "es-x-icu" | some version
+ icuidx12_custom           | "default"  | no version
+ icuidx12_custom           | custom     | some version
+ icuidx13_custom           | "default"  | no version
+ icuidx13_custom           | custom     | some version
+ icuidx14_myrange          | "default"  | no version
+ icuidx15_myrange_en_fr_ga | "en-x-icu" | some version
+ icuidx15_myrange_en_fr_ga | "fr-x-icu" | some version
+ icuidx15_myrange_en_fr_ga | "ga-x-icu" | some version
+ icuidx16_mood             | "fr-x-icu" | some version
+ icuidx17_part             | "en-x-icu" | some version
 (44 rows)
 
 UPDATE pg_depend SET refobjversion = 'not a version'
 WHERE refclassid = 'pg_collation'::regclass
-AND objid::regclass::text LIKE 'idx%'
+AND objid::regclass::text LIKE 'icuidx%'
 AND refobjversion IS NOT NULL;
 REINDEX TABLE collate_test;
 REINDEX TABLE collate_part_0;
@@ -2015,6 +2015,23 @@ SELECT objid::regclass FROM pg_depend WHERE refobjversion = 'not a version';
 -------
 (0 rows)
 
+-- Test ALTER INDEX name DEPENDS ON COLLATION name CURRENT VERSION
+UPDATE pg_depend SET refobjversion = 'not a version'
+WHERE refclassid = 'pg_collation'::regclass
+AND objid::regclass::text = 'icuidx17_part'
+AND refobjversion IS NOT NULL;
+SELECT objid::regclass FROM pg_depend WHERE refobjversion = 'not a version';
+     objid     
+---------------
+ icuidx17_part
+(1 row)
+
+ALTER INDEX icuidx17_part DEPENDS ON COLLATION "en-x-icu" CURRENT VERSION;
+SELECT objid::regclass FROM pg_depend WHERE refobjversion = 'not a version';
+ objid 
+-------
+(0 rows)
+
 -- cleanup
 RESET search_path;
 SET client_min_messages TO warning;
diff --git a/src/test/regress/sql/collate.icu.utf8.sql b/src/test/regress/sql/collate.icu.utf8.sql
index e870594b5b..885470c7ba 100644
--- a/src/test/regress/sql/collate.icu.utf8.sql
+++ b/src/test/regress/sql/collate.icu.utf8.sql
@@ -747,27 +747,27 @@ CREATE TABLE collate_test (
     mood mood
 );
 
-CREATE INDEX idx01_t_en_fr__d_es ON collate_test (t_en_fr, d_es);
-CREATE INDEX idx02_d_en_fr ON collate_test (d_en_fr);
-CREATE INDEX idx03_t_en_fr_ga ON collate_test (t_en_fr_ga);
-CREATE INDEX idx04_d_en_fr_ga ON collate_test (d_en_fr_ga);
-CREATE INDEX idx05_d_en_fr_ga_arr ON collate_test (d_en_fr_ga_arr);
-CREATE INDEX idx06_d_en_fr_ga ON collate_test(id) WHERE (d_en_fr_ga).en_fr.fr = 'foo';
-CREATE INDEX idx07_d_en_fr_ga ON collate_test(id) WHERE (d_en_fr_ga).ga = 'foo';
-CREATE INDEX idx08_d_en_fr_ga ON collate_test(id) WHERE (t_en_fr_ga) = ('foo', 'bar', 'baz');
-CREATE INDEX idx09_d_en_fr_ga ON collate_test(id) WHERE (d_en_fr_ga) = ('foo', 'bar', 'baz');
-CREATE INDEX idx10_d_en_fr_ga_es ON collate_test(id) WHERE (d_en_fr_ga) = ('foo', 'bar', 'baz' COLLATE "es-x-icu");
-CREATE INDEX idx11_d_es ON collate_test(id) WHERE (d_es) = ('foo');
-CREATE INDEX idx12_custom ON collate_test(id) WHERE ('foo', 'bar')::d_custom = ('foo', 'bar' collate custom)::d_custom;
-CREATE INDEX idx13_custom ON collate_test(id) WHERE ('foo' collate custom, 'bar')::d_custom = ('foo', 'bar')::d_custom;
-CREATE INDEX idx14_myrange ON collate_test(myrange);
-CREATE INDEX idx15_myrange_en_fr_ga ON collate_test USING gist (myrange_en_fr_ga);
-CREATE INDEX idx16_mood ON collate_test(id) WHERE mood > 'ok' collate "fr-x-icu";
+CREATE INDEX icuidx01_t_en_fr__d_es ON collate_test (t_en_fr, d_es);
+CREATE INDEX icuidx02_d_en_fr ON collate_test (d_en_fr);
+CREATE INDEX icuidx03_t_en_fr_ga ON collate_test (t_en_fr_ga);
+CREATE INDEX icuidx04_d_en_fr_ga ON collate_test (d_en_fr_ga);
+CREATE INDEX icuidx05_d_en_fr_ga_arr ON collate_test (d_en_fr_ga_arr);
+CREATE INDEX icuidx06_d_en_fr_ga ON collate_test(id) WHERE (d_en_fr_ga).en_fr.fr = 'foo';
+CREATE INDEX icuidx07_d_en_fr_ga ON collate_test(id) WHERE (d_en_fr_ga).ga = 'foo';
+CREATE INDEX icuidx08_d_en_fr_ga ON collate_test(id) WHERE (t_en_fr_ga) = ('foo', 'bar', 'baz');
+CREATE INDEX icuidx09_d_en_fr_ga ON collate_test(id) WHERE (d_en_fr_ga) = ('foo', 'bar', 'baz');
+CREATE INDEX icuidx10_d_en_fr_ga_es ON collate_test(id) WHERE (d_en_fr_ga) = ('foo', 'bar', 'baz' COLLATE "es-x-icu");
+CREATE INDEX icuidx11_d_es ON collate_test(id) WHERE (d_es) = ('foo');
+CREATE INDEX icuidx12_custom ON collate_test(id) WHERE ('foo', 'bar')::d_custom = ('foo', 'bar' collate custom)::d_custom;
+CREATE INDEX icuidx13_custom ON collate_test(id) WHERE ('foo' collate custom, 'bar')::d_custom = ('foo', 'bar')::d_custom;
+CREATE INDEX icuidx14_myrange ON collate_test(myrange);
+CREATE INDEX icuidx15_myrange_en_fr_ga ON collate_test USING gist (myrange_en_fr_ga);
+CREATE INDEX icuidx16_mood ON collate_test(id) WHERE mood > 'ok' collate "fr-x-icu";
 
 CREATE TABLE collate_part(id integer, val text COLLATE "en-x-icu") PARTITION BY range(id);
 CREATE TABLE collate_part_0 PARTITION OF collate_part FOR VALUES FROM (0) TO (1);
 CREATE TABLE collate_part_1 PARTITION OF collate_part FOR VALUES FROM (1) TO (1000000);
-CREATE INDEX idx16_part ON collate_part_1 (val);
+CREATE INDEX icuidx17_part ON collate_part_1 (val);
 
 -- version of default (and libc) collation is only tracked on glibc systems
 SELECT objid::regclass, refobjid::regcollation,
@@ -779,12 +779,12 @@ FROM pg_depend d
 LEFT JOIN pg_class c ON c.oid = d.objid
 WHERE refclassid = 'pg_collation'::regclass
 AND coalesce(relkind, 'i') = 'i'
-AND relname LIKE 'idx%'
+AND relname LIKE 'icuidx%'
 ORDER BY 1, 2;
 
 UPDATE pg_depend SET refobjversion = 'not a version'
 WHERE refclassid = 'pg_collation'::regclass
-AND objid::regclass::text LIKE 'idx%'
+AND objid::regclass::text LIKE 'icuidx%'
 AND refobjversion IS NOT NULL;
 
 REINDEX TABLE collate_test;
@@ -793,6 +793,15 @@ REINDEX TABLE collate_part_1;
 
 SELECT objid::regclass FROM pg_depend WHERE refobjversion = 'not a version';
 
+-- Test ALTER INDEX name DEPENDS ON COLLATION name CURRENT VERSION
+UPDATE pg_depend SET refobjversion = 'not a version'
+WHERE refclassid = 'pg_collation'::regclass
+AND objid::regclass::text = 'icuidx17_part'
+AND refobjversion IS NOT NULL;
+SELECT objid::regclass FROM pg_depend WHERE refobjversion = 'not a version';
+ALTER INDEX icuidx17_part DEPENDS ON COLLATION "en-x-icu" CURRENT VERSION;
+SELECT objid::regclass FROM pg_depend WHERE refobjversion = 'not a version';
+
 -- cleanup
 RESET search_path;
 SET client_min_messages TO warning;
-- 
2.20.1

