From c6ce5f71b08235f9ed8e0206267ae560ea1ebc91 Mon Sep 17 00:00:00 2001
From: Alexander Korotkov <akorotkov@postgresql.org>
Date: Mon, 9 Sep 2019 13:50:12 +0300
Subject: [PATCH] Fix handling of non-key columns get_index_column_opclass()

f2e40380 introduces support of non-key attributes in GiST indexes.  Then if
get_index_column_opclass() is asked by gistproperty() to get an opclass of
non-key column, it returns garbage past oidvector value.  This commit fixes
that by making get_index_column_opclass() return InvalidOid in this case.

Discussion: https://postgr.es/m/20190902231948.GA5343%40alvherre.pgsql
Author: Nikita Glukhov, Alexander Korotkov
Backpatch-through: 12
---
 src/backend/utils/cache/lsyscache.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index c13c08a97b4..27602fa49c6 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -3157,7 +3157,8 @@ get_range_subtype(Oid rangeOid)
  *
  *		Given the index OID and column number,
  *		return opclass of the index column
- *			or InvalidOid if the index was not found.
+ *			or InvalidOid if the index was not found
+ *				or column is non-key one.
  */
 Oid
 get_index_column_opclass(Oid index_oid, int attno)
@@ -3180,11 +3181,20 @@ get_index_column_opclass(Oid index_oid, int attno)
 	/* caller is supposed to guarantee this */
 	Assert(attno > 0 && attno <= rd_index->indnatts);
 
+	/* Non-key attributes don't have an opclass */
+	if (attno > rd_index->indnkeyatts)
+	{
+		ReleaseSysCache(tuple);
+		return InvalidOid;
+	}
+
 	datum = SysCacheGetAttr(INDEXRELID, tuple,
 							Anum_pg_index_indclass, &isnull);
 	Assert(!isnull);
 
 	indclass = ((oidvector *) DatumGetPointer(datum));
+
+	Assert(attno <= indclass->dim1);
 	opclass = indclass->values[attno - 1];
 
 	ReleaseSysCache(tuple);
-- 
GitLab