From: PostgreSQL relcache v3 Linux review
Subject: [PATCH 1/4] Use relkind to classify relations in predicate locking

RelationData overlays table rewrite rules with index metadata.  Testing the
overlaid pointer therefore misclassifies rule-bearing tables as indexes and
can dereference a RuleLock as Form_pg_index.  Classify ordinary and
partitioned indexes by relkind instead.

Applies after David Geier's v3 patches 0001 through 0006, based on
9dbc53591a2de03e0cfdab61a78726f8b2c29eef.
---
diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c
index 0ae85b7d5b4..5c539306e77 100644
--- a/src/backend/storage/lmgr/predicate.c
+++ b/src/backend/storage/lmgr/predicate.c
@@ -2558,7 +2558,7 @@ PredicateLockTID(Relation relation, const ItemPointerData *tid, Snapshot snapsho
 	/*
 	 * Return if this xact wrote it.
 	 */
-	if (relation->rd_index == NULL)
+	if (!RelationIsIndex(relation))
 	{
 		/* If we wrote it; we already have a write lock. */
 		if (TransactionIdIsCurrentTransactionId(tuple_xid))
@@ -2890,7 +2890,7 @@ DropAllPredicateLocksFromTable(Relation relation, bool transfer)
 
 	dbId = relation->rd_locator.dbOid;
 	relId = relation->rd_id;
-	if (relation->rd_index == NULL)
+	if (!RelationIsIndex(relation))
 	{
 		isIndex = false;
 		heapId = relId;
@@ -4371,7 +4371,7 @@ CheckTableForSerializableConflictIn(Relation relation)
 	 */
 	MyXactDidWrite = true;
 
-	Assert(relation->rd_index == NULL); /* not an index relation */
+	Assert(!RelationIsIndex(relation));
 
 	dbId = relation->rd_locator.dbOid;
 	heapId = relation->rd_id;
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 33a3921f5cf..60db9fd8753 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -309,6 +309,11 @@ typedef struct ViewOptions
  */
 #define RelationGetRelid(relation) ((relation)->rd_id)
 
+/* True for both ordinary and partitioned index relations. */
+#define RelationIsIndex(relation) \
+	((relation)->rd_rel->relkind == RELKIND_INDEX || \
+	 (relation)->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
+
 /*
  * RelationGetLockRelId
  *		Returns the LockRelId to use for locking the relation.
