From a4dde3bff36dac1ac0b699becad6f103d861a874 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Tue, 10 May 2005 13:16:26 +0000
Subject: [PATCH] Report index name on CLUSTER failure.  Also, suggest ALTER
 TABLE WITHOUT CLUSTER for cluster failure of a single table in a full db
 cluster.

---
 src/backend/commands/cluster.c   | 26 ++++++++++++++++----------
 src/backend/commands/tablecmds.c |  4 ++--
 src/include/commands/cluster.h   |  5 +++--
 3 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 5d3382a375e..aab03ea4b33 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.137 2005/05/06 17:24:53 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.138 2005/05/10 13:16:26 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -292,7 +292,7 @@ cluster_rel(RelToCluster *rvtc, bool recheck)
 	OldHeap = heap_open(rvtc->tableOid, AccessExclusiveLock);
 
 	/* Check index is valid to cluster on */
-	check_index_is_clusterable(OldHeap, rvtc->indexOid);
+	check_index_is_clusterable(OldHeap, rvtc->indexOid, recheck);
 
 	/* rebuild_relation does all the dirty work */
 	rebuild_relation(OldHeap, rvtc->indexOid);
@@ -309,7 +309,7 @@ cluster_rel(RelToCluster *rvtc, bool recheck)
  * definition can't change under us.
  */
 void
-check_index_is_clusterable(Relation OldHeap, Oid indexOid)
+check_index_is_clusterable(Relation OldHeap, Oid indexOid, bool recheck)
 {
 	Relation	OldIndex;
 
@@ -336,7 +336,9 @@ check_index_is_clusterable(Relation OldHeap, Oid indexOid)
 	if (!heap_attisnull(OldIndex->rd_indextuple, Anum_pg_index_indpred))
 		ereport(ERROR,
 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-				 errmsg("cannot cluster on partial index")));
+				 errmsg("cannot cluster on partial index \"%s\"",
+						RelationGetRelationName(OldIndex))));
+	
 	if (!OldIndex->rd_am->amindexnulls)
 	{
 		AttrNumber	colno;
@@ -354,21 +356,25 @@ check_index_is_clusterable(Relation OldHeap, Oid indexOid)
 			if (!OldHeap->rd_att->attrs[colno - 1]->attnotnull)
 				ereport(ERROR,
 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-						 errmsg("cannot cluster when index access method does not handle null values"),
-						 errhint("You may be able to work around this by marking column \"%s\" NOT NULL.",
-				  NameStr(OldHeap->rd_att->attrs[colno - 1]->attname))));
+						 errmsg("cannot cluster on index \"%s\" because access method\n"
+								"does not handle null values",
+							  RelationGetRelationName(OldIndex)),
+						 errhint("You may be able to work around this by marking column \"%s\" NOT NULL%s",
+							NameStr(OldHeap->rd_att->attrs[colno - 1]->attname),
+							recheck ? ",\nor use ALTER TABLE ... SET WITHOUT CLUSTER to remove the cluster\n"
+									"specification from the table." : ".")));
 		}
 		else if (colno < 0)
 		{
 			/* system column --- okay, always non-null */
 		}
 		else
-		{
 			/* index expression, lose... */
 			ereport(ERROR,
 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-					 errmsg("cannot cluster on expressional index when index access method does not handle null values")));
-		}
+					 errmsg("cannot cluster on expressional index \"%s\" because its index access\n"
+							"method does not handle null values",
+						RelationGetRelationName(OldIndex))));
 	}
 
 	/*
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 279222ca1d7..187fb5db8e6 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.156 2005/05/06 17:24:53 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.157 2005/05/10 13:16:26 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -5464,7 +5464,7 @@ ATExecClusterOn(Relation rel, const char *indexName)
 						indexName, RelationGetRelationName(rel))));
 
 	/* Check index is valid to cluster on */
-	check_index_is_clusterable(rel, indexOid);
+	check_index_is_clusterable(rel, indexOid, false);
 
 	/* And do the work */
 	mark_index_clustered(rel, indexOid);
diff --git a/src/include/commands/cluster.h b/src/include/commands/cluster.h
index 7a72ee6dcbb..382e2bcadfe 100644
--- a/src/include/commands/cluster.h
+++ b/src/include/commands/cluster.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994-5, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/commands/cluster.h,v 1.27 2004/12/31 22:03:28 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/commands/cluster.h,v 1.28 2005/05/10 13:16:26 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -19,7 +19,8 @@
 
 extern void cluster(ClusterStmt *stmt);
 
-extern void check_index_is_clusterable(Relation OldHeap, Oid indexOid);
+extern void check_index_is_clusterable(Relation OldHeap, Oid indexOid,
+			  bool recheck);
 extern void mark_index_clustered(Relation rel, Oid indexOid);
 extern Oid make_new_heap(Oid OIDOldHeap, const char *NewName,
 			  Oid NewTableSpace);
-- 
GitLab