diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 5a8d5b226718dac320f8b82069ecfcb1ef42c0cd..6a994aa0cccac8b3b17b5f374b6a9090a03575ea 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.229 2004/05/05 04:48:45 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.230 2004/05/08 00:34:49 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1729,12 +1729,13 @@ reindex_index(Oid indexId)
 
 /*
  * reindex_relation - This routine is used to recreate all indexes
- * of a relation (and its toast relation too, if any).
+ * of a relation (and optionally its toast relation too, if any).
  *
- * Returns true if any indexes were rebuilt.
+ * Returns true if any indexes were rebuilt.  Note that a
+ * CommandCounterIncrement will occur after each index rebuild.
  */
 bool
-reindex_relation(Oid relid)
+reindex_relation(Oid relid, bool toast_too)
 {
 	Relation	rel;
 	Oid			toast_relid;
@@ -1810,8 +1811,8 @@ reindex_relation(Oid relid)
 	 * If the relation has a secondary toast rel, reindex that too while we
 	 * still hold the lock on the master table.
 	 */
-	if (toast_relid != InvalidOid)
-		result |= reindex_relation(toast_relid);
+	if (toast_too && OidIsValid(toast_relid))
+		result |= reindex_relation(toast_relid, false);
 
 	return result;
 }
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index ffd2aff2364543661a65e73d34c51a7355963266..168ae749fa08f748f539625aca7f50851bb583d9 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.122 2004/05/06 16:10:57 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.123 2004/05/08 00:34:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -37,20 +37,6 @@
 #include "utils/relcache.h"
 
 
-/*
- * We need one of these structs for each index in the relation to be
- * clustered.  It's basically the data needed by index_create() so
- * we can rebuild the indexes on the new heap.
- */
-typedef struct
-{
-	Oid			indexOID;
-	char	   *indexName;
-	IndexInfo  *indexInfo;
-	Oid			accessMethodOID;
-	Oid		   *classOID;
-} IndexAttrs;
-
 /*
  * This struct is used to pass around the information on tables to be
  * clustered. We need this so we can make a list of them when invoked without
@@ -64,6 +50,7 @@ typedef struct
 
 
 static void cluster_rel(RelToCluster *rv, bool recheck);
+static void rebuild_relation(Relation OldHeap, Oid indexOid);
 static void copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex);
 static List *get_tables_to_cluster(MemoryContext cluster_context);
 
@@ -411,30 +398,99 @@ check_index_is_clusterable(Relation OldHeap, Oid indexOid)
 }
 
 /*
- * rebuild_relation: rebuild an existing relation
+ * mark_index_clustered: mark the specified index as the one clustered on
  *
- * This is shared code between CLUSTER and TRUNCATE.  In the TRUNCATE
- * case, the new relation is built and left empty.	In the CLUSTER case,
- * it is filled with data read from the old relation in the order specified
- * by the index.
+ * With indexOid == InvalidOid, will mark all indexes of rel not-clustered.
+ */
+void
+mark_index_clustered(Relation rel, Oid indexOid)
+{
+	HeapTuple	indexTuple;
+	Form_pg_index indexForm;
+	Relation	pg_index;
+	List	   *index;
+
+	/*
+	 * If the index is already marked clustered, no need to do anything.
+	 */
+	if (OidIsValid(indexOid))
+	{
+		indexTuple = SearchSysCache(INDEXRELID,
+									ObjectIdGetDatum(indexOid),
+									0, 0, 0);
+		if (!HeapTupleIsValid(indexTuple))
+			elog(ERROR, "cache lookup failed for index %u", indexOid);
+		indexForm = (Form_pg_index) GETSTRUCT(indexTuple);
+
+		if (indexForm->indisclustered)
+		{
+			ReleaseSysCache(indexTuple);
+			return;
+		}
+
+		ReleaseSysCache(indexTuple);
+	}
+
+	/*
+	 * Check each index of the relation and set/clear the bit as needed.
+	 */
+	pg_index = heap_openr(IndexRelationName, RowExclusiveLock);
+
+	foreach(index, RelationGetIndexList(rel))
+	{
+		Oid		thisIndexOid = lfirsto(index);
+
+		indexTuple = SearchSysCacheCopy(INDEXRELID,
+										ObjectIdGetDatum(thisIndexOid),
+										0, 0, 0);
+		if (!HeapTupleIsValid(indexTuple))
+			elog(ERROR, "cache lookup failed for index %u", thisIndexOid);
+		indexForm = (Form_pg_index) GETSTRUCT(indexTuple);
+
+		/*
+		 * Unset the bit if set.  We know it's wrong because we checked
+		 * this earlier.
+		 */
+		if (indexForm->indisclustered)
+		{
+			indexForm->indisclustered = false;
+			simple_heap_update(pg_index, &indexTuple->t_self, indexTuple);
+			CatalogUpdateIndexes(pg_index, indexTuple);
+			/* Ensure we see the update in the index's relcache entry */
+			CacheInvalidateRelcacheByRelid(thisIndexOid);
+		}
+		else if (thisIndexOid == indexOid)
+		{
+			indexForm->indisclustered = true;
+			simple_heap_update(pg_index, &indexTuple->t_self, indexTuple);
+			CatalogUpdateIndexes(pg_index, indexTuple);
+			/* Ensure we see the update in the index's relcache entry */
+			CacheInvalidateRelcacheByRelid(thisIndexOid);
+		}
+		heap_freetuple(indexTuple);
+	}
+
+	heap_close(pg_index, RowExclusiveLock);
+}
+
+/*
+ * rebuild_relation: rebuild an existing relation in index order
  *
  * OldHeap: table to rebuild --- must be opened and exclusive-locked!
- * indexOid: index to cluster by, or InvalidOid in TRUNCATE case
+ * indexOid: index to cluster by
  *
  * NB: this routine closes OldHeap at the right time; caller should not.
  */
-void
+static void
 rebuild_relation(Relation OldHeap, Oid indexOid)
 {
 	Oid			tableOid = RelationGetRelid(OldHeap);
-	Oid			oldClusterIndex;
-	List	   *indexes;
 	Oid			OIDNewHeap;
 	char		NewHeapName[NAMEDATALEN];
 	ObjectAddress object;
 
-	/* Save the information about all indexes on the relation. */
-	indexes = get_indexattr_list(OldHeap, &oldClusterIndex);
+	/* Mark the correct index as clustered */
+	mark_index_clustered(OldHeap, indexOid);
 
 	/* Close relcache entry, but keep lock until transaction commit */
 	heap_close(OldHeap, NoLock);
@@ -459,8 +515,7 @@ rebuild_relation(Relation OldHeap, Oid indexOid)
 	/*
 	 * Copy the heap data into the new table in the desired order.
 	 */
-	if (OidIsValid(indexOid))
-		copy_heap_data(OIDNewHeap, tableOid, indexOid);
+	copy_heap_data(OIDNewHeap, tableOid, indexOid);
 
 	/* To make the new heap's data visible (probably not needed?). */
 	CommandCounterIncrement();
@@ -484,11 +539,11 @@ rebuild_relation(Relation OldHeap, Oid indexOid)
 	/* performDeletion does CommandCounterIncrement at end */
 
 	/*
-	 * Recreate each index on the relation.  We do not need
-	 * CommandCounterIncrement() because rebuild_indexes does it.
+	 * Rebuild each index on the relation (but not the toast table,
+	 * which is all-new at this point).  We do not need
+	 * CommandCounterIncrement() because reindex_relation does it.
 	 */
-	rebuild_indexes(tableOid, indexes,
-					(OidIsValid(indexOid) ? indexOid : oldClusterIndex));
+	reindex_relation(tableOid, false);
 }
 
 /*
@@ -589,138 +644,6 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
 	heap_close(NewHeap, NoLock);
 }
 
-/*
- * Get the necessary info about the indexes of the relation and
- * return a list of IndexAttrs structures.  Also, *OldClusterIndex
- * is set to the OID of the existing clustered index, or InvalidOid
- * if there is none.
- */
-List *
-get_indexattr_list(Relation OldHeap, Oid *OldClusterIndex)
-{
-	List	   *indexes = NIL;
-	List	   *indlist;
-
-	*OldClusterIndex = InvalidOid;
-
-	/* Ask the relcache to produce a list of the indexes of the old rel */
-	foreach(indlist, RelationGetIndexList(OldHeap))
-	{
-		Oid			indexOID = lfirsto(indlist);
-		Relation	oldIndex;
-		IndexAttrs *attrs;
-
-		oldIndex = index_open(indexOID);
-
-		attrs = (IndexAttrs *) palloc(sizeof(IndexAttrs));
-		attrs->indexOID = indexOID;
-		attrs->indexName = pstrdup(NameStr(oldIndex->rd_rel->relname));
-		attrs->accessMethodOID = oldIndex->rd_rel->relam;
-		attrs->indexInfo = BuildIndexInfo(oldIndex);
-		attrs->classOID = (Oid *)
-			palloc(sizeof(Oid) * attrs->indexInfo->ii_NumIndexAttrs);
-		memcpy(attrs->classOID, oldIndex->rd_index->indclass,
-			   sizeof(Oid) * attrs->indexInfo->ii_NumIndexAttrs);
-		if (oldIndex->rd_index->indisclustered)
-			*OldClusterIndex = indexOID;
-
-		index_close(oldIndex);
-
-		indexes = lappend(indexes, attrs);
-	}
-
-	return indexes;
-}
-
-/*
- * Create new indexes and swap the filenodes with old indexes.	Then drop
- * the new index (carrying the old index filenode along).
- *
- * OIDClusterIndex is the OID of the index to be marked as clustered, or
- * InvalidOid if none should be marked clustered.
- */
-void
-rebuild_indexes(Oid OIDOldHeap, List *indexes, Oid OIDClusterIndex)
-{
-	List	   *elem;
-
-	foreach(elem, indexes)
-	{
-		IndexAttrs *attrs = (IndexAttrs *) lfirst(elem);
-		Oid			oldIndexOID = attrs->indexOID;
-		Oid			newIndexOID;
-		char		newIndexName[NAMEDATALEN];
-		bool		isclustered;
-		ObjectAddress object;
-		Form_pg_index index;
-		HeapTuple	tuple;
-		Relation	pg_index;
-
-		/* Create the new index under a temporary name */
-		snprintf(newIndexName, sizeof(newIndexName),
-				 "pg_temp_%u", oldIndexOID);
-
-		/*
-		 * The new index will have primary and constraint status set to
-		 * false, but since we will only use its filenode it doesn't
-		 * matter: after the filenode swap the index will keep the
-		 * constraint status of the old index.
-		 */
-		newIndexOID = index_create(OIDOldHeap,
-								   newIndexName,
-								   attrs->indexInfo,
-								   attrs->accessMethodOID,
-								   attrs->classOID,
-								   false,
-								   false,
-								   allowSystemTableMods,
-								   false);
-		CommandCounterIncrement();
-
-		/* Swap the filenodes. */
-		swap_relfilenodes(oldIndexOID, newIndexOID);
-
-		CommandCounterIncrement();
-
-		/*
-		 * Make sure that indisclustered is correct: it should be set only
-		 * for the index specified by the caller.
-		 */
-		isclustered = (oldIndexOID == OIDClusterIndex);
-
-		pg_index = heap_openr(IndexRelationName, RowExclusiveLock);
-		tuple = SearchSysCacheCopy(INDEXRELID,
-								   ObjectIdGetDatum(oldIndexOID),
-								   0, 0, 0);
-		if (!HeapTupleIsValid(tuple))
-			elog(ERROR, "cache lookup failed for index %u", oldIndexOID);
-		index = (Form_pg_index) GETSTRUCT(tuple);
-		if (index->indisclustered != isclustered)
-		{
-			index->indisclustered = isclustered;
-			simple_heap_update(pg_index, &tuple->t_self, tuple);
-			CatalogUpdateIndexes(pg_index, tuple);
-			/* Ensure we see the update in the index's relcache entry */
-			CacheInvalidateRelcacheByRelid(oldIndexOID);
-		}
-		heap_freetuple(tuple);
-		heap_close(pg_index, RowExclusiveLock);
-
-		/* Destroy new index with old filenode */
-		object.classId = RelOid_pg_class;
-		object.objectId = newIndexOID;
-		object.objectSubId = 0;
-
-		/*
-		 * The relation is local to our transaction and we know nothing
-		 * depends on it, so DROP_RESTRICT should be OK.
-		 */
-		performDeletion(&object, DROP_RESTRICT);
-
-		/* performDeletion does CommandCounterIncrement() at its end */
-	}
-}
-
 /*
  * Swap the relfilenodes for two given relations.
  *
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index efcc70c68560cbabb704feaedd71a29760e17b0c..448f99e1d37f54761b9089f0b360ab425d293b76 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.118 2004/05/05 04:48:45 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.119 2004/05/08 00:34:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -826,7 +826,7 @@ ReindexTable(RangeVar *relation, bool force /* currently unused */ )
 
 	ReleaseSysCache(tuple);
 
-	if (!reindex_relation(heapOid))
+	if (!reindex_relation(heapOid, true))
 		ereport(NOTICE,
 				(errmsg("table \"%s\" has no indexes",
 						relation->relname)));
@@ -936,7 +936,7 @@ ReindexDatabase(const char *dbname, bool force /* currently unused */,
 		StartTransactionCommand();
 		SetQuerySnapshot();		/* might be needed for functions in
 								 * indexes */
-		if (reindex_relation(relid))
+		if (reindex_relation(relid, true))
 			ereport(NOTICE,
 					(errmsg("table \"%s\" was reindexed",
 							get_rel_name(relid))));
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d74e1e7ab310e3a3b1d0ae34372061dd206b6d61..5adafd630ac0f109b5ded5fa98cd868d9bfcbead 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.105 2004/05/07 00:24:57 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.106 2004/05/08 00:34:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -490,14 +490,13 @@ RemoveRelation(const RangeVar *relation, DropBehavior behavior)
 /*
  * TruncateRelation
  *		Removes all the rows from a relation.
- *
- * Note: This routine only does safety and permissions checks;
- * rebuild_relation in cluster.c does the actual work.
  */
 void
 TruncateRelation(const RangeVar *relation)
 {
 	Relation	rel;
+	Oid			heap_relid;
+	Oid			toast_relid;
 
 	/* Grab exclusive lock in preparation for truncate */
 	rel = heap_openrv(relation, AccessExclusiveLock);
@@ -520,6 +519,16 @@ TruncateRelation(const RangeVar *relation)
 				 errmsg("permission denied: \"%s\" is a system catalog",
 						RelationGetRelationName(rel))));
 
+	/*
+	 * We can never allow truncation of shared or nailed-in-cache relations,
+	 * because we can't support changing their relfilenode values.
+	 */
+	if (rel->rd_rel->relisshared || rel->rd_isnailed)
+		ereport(ERROR,
+				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+				 errmsg("cannot truncate system relation \"%s\"",
+						RelationGetRelationName(rel))));
+
 	/*
 	 * Don't allow truncate on temp tables of other backends ... their
 	 * local buffer manager is not going to cope.
@@ -535,17 +544,31 @@ TruncateRelation(const RangeVar *relation)
 	heap_truncate_check_FKs(rel);
 
 	/*
-	 * Do the real work using the same technique as cluster, but without
-	 * the data-copying portion
+	 * Okay, here we go: create a new empty storage file for the relation,
+	 * and assign it as the relfilenode value.  The old storage file is
+	 * scheduled for deletion at commit.
 	 */
-	rebuild_relation(rel, InvalidOid);
+	setNewRelfilenode(rel);
+
+	heap_relid = RelationGetRelid(rel);
+	toast_relid = rel->rd_rel->reltoastrelid;
+
+	heap_close(rel, NoLock);
 
-	/* NB: rebuild_relation does heap_close() */
+	/*
+	 * The same for the toast table, if any.
+	 */
+	if (OidIsValid(toast_relid))
+	{
+		rel = relation_open(toast_relid, AccessExclusiveLock);
+		setNewRelfilenode(rel);
+		heap_close(rel, NoLock);
+	}
 
 	/*
-	 * You might think we need to truncate the rel's toast table here too,
-	 * but actually we don't; it will have been rebuilt in an empty state.
+	 * Reconstruct the indexes to match, and we're done.
 	 */
+	reindex_relation(heap_relid, true);
 }
 
 /*----------
@@ -2098,14 +2121,31 @@ ATRewriteTables(List **wqueue)
 			/* Build a temporary relation and copy data */
 			Oid			OIDNewHeap;
 			char		NewHeapName[NAMEDATALEN];
-			List	   *indexes;
-			Oid			oldClusterIndex;
 			Relation	OldHeap;
 			ObjectAddress	object;
 
-			/* Save the information about all indexes on the relation. */
 			OldHeap = heap_open(tab->relid, NoLock);
-			indexes = get_indexattr_list(OldHeap, &oldClusterIndex);
+
+			/*
+			 * We can never allow rewriting of shared or nailed-in-cache
+			 * relations, because we can't support changing their relfilenode
+			 * values.
+			 */
+			if (OldHeap->rd_rel->relisshared || OldHeap->rd_isnailed)
+				ereport(ERROR,
+						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+						 errmsg("cannot rewrite system relation \"%s\"",
+								RelationGetRelationName(OldHeap))));
+
+			/*
+			 * Don't allow rewrite on temp tables of other backends ... their
+			 * local buffer manager is not going to cope.
+			 */
+			if (isOtherTempNamespace(RelationGetNamespace(OldHeap)))
+				ereport(ERROR,
+						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+						 errmsg("cannot rewrite temporary tables of other sessions")));
+
 			heap_close(OldHeap, NoLock);
 
 			/*
@@ -2146,10 +2186,11 @@ ATRewriteTables(List **wqueue)
 			/* performDeletion does CommandCounterIncrement at end */
 
 			/*
-			 * Rebuild each index on the relation.  We do not need
-			 * CommandCounterIncrement() because rebuild_indexes does it.
+			 * Rebuild each index on the relation (but not the toast table,
+			 * which is all-new anyway).  We do not need
+			 * CommandCounterIncrement() because reindex_relation does it.
 			 */
-			rebuild_indexes(tab->relid, indexes, oldClusterIndex);
+			reindex_relation(tab->relid, false);
 		}
 		else
 		{
@@ -4991,11 +5032,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
 static void
 ATExecClusterOn(Relation rel, const char *indexName)
 {
-	Relation	pg_index;
-	List	   *index;
 	Oid			indexOid;
-	HeapTuple	indexTuple;
-	Form_pg_index indexForm;
 
 	indexOid = get_relname_relid(indexName, rel->rd_rel->relnamespace);
 
@@ -5008,67 +5045,8 @@ ATExecClusterOn(Relation rel, const char *indexName)
 	/* Check index is valid to cluster on */
 	check_index_is_clusterable(rel, indexOid);
 
-	indexTuple = SearchSysCache(INDEXRELID,
-								ObjectIdGetDatum(indexOid),
-								0, 0, 0);
-	if (!HeapTupleIsValid(indexTuple))
-		elog(ERROR, "cache lookup failed for index %u", indexOid);
-	indexForm = (Form_pg_index) GETSTRUCT(indexTuple);
-
-	/*
-	 * If this is the same index the relation was previously clustered on,
-	 * no need to do anything.
-	 */
-	if (indexForm->indisclustered)
-	{
-		ReleaseSysCache(indexTuple);
-		return;
-	}
-
-	ReleaseSysCache(indexTuple);
-
-	pg_index = heap_openr(IndexRelationName, RowExclusiveLock);
-
-	/*
-	 * Now check each index in the relation and set the bit where needed.
-	 */
-	foreach(index, RelationGetIndexList(rel))
-	{
-		HeapTuple	idxtuple;
-		Form_pg_index idxForm;
-
-		indexOid = lfirsto(index);
-		idxtuple = SearchSysCacheCopy(INDEXRELID,
-									  ObjectIdGetDatum(indexOid),
-									  0, 0, 0);
-		if (!HeapTupleIsValid(idxtuple))
-			elog(ERROR, "cache lookup failed for index %u", indexOid);
-		idxForm = (Form_pg_index) GETSTRUCT(idxtuple);
-
-		/*
-		 * Unset the bit if set.  We know it's wrong because we checked
-		 * this earlier.
-		 */
-		if (idxForm->indisclustered)
-		{
-			idxForm->indisclustered = false;
-			simple_heap_update(pg_index, &idxtuple->t_self, idxtuple);
-			CatalogUpdateIndexes(pg_index, idxtuple);
-			/* Ensure we see the update in the index's relcache entry */
-			CacheInvalidateRelcacheByRelid(indexOid);
-		}
-		else if (idxForm->indexrelid == indexForm->indexrelid)
-		{
-			idxForm->indisclustered = true;
-			simple_heap_update(pg_index, &idxtuple->t_self, idxtuple);
-			CatalogUpdateIndexes(pg_index, idxtuple);
-			/* Ensure we see the update in the index's relcache entry */
-			CacheInvalidateRelcacheByRelid(indexOid);
-		}
-		heap_freetuple(idxtuple);
-	}
-
-	heap_close(pg_index, RowExclusiveLock);
+	/* And do the work */
+	mark_index_clustered(rel, indexOid);
 }
 
 /*
diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h
index 13c367c9022845c36ccbfc8d26e6ff32cfc5cb84..841387effcca6d9cbb06a669db87357fd5d00084 100644
--- a/src/include/catalog/index.h
+++ b/src/include/catalog/index.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/index.h,v 1.55 2004/05/05 04:48:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/index.h,v 1.56 2004/05/08 00:34:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -68,6 +68,6 @@ extern double IndexBuildHeapScan(Relation heapRelation,
 				   void *callback_state);
 
 extern void reindex_index(Oid indexId);
-extern bool reindex_relation(Oid relid);
+extern bool reindex_relation(Oid relid, bool toast_too);
 
 #endif   /* INDEX_H */
diff --git a/src/include/commands/cluster.h b/src/include/commands/cluster.h
index d97be66d73a731736ddd2b435045894f2260caad..820c95210805adfbcc60fd469fcb163bd897f00e 100644
--- a/src/include/commands/cluster.h
+++ b/src/include/commands/cluster.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994-5, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/commands/cluster.h,v 1.22 2004/05/06 16:10:57 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/commands/cluster.h,v 1.23 2004/05/08 00:34:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -20,11 +20,8 @@
 extern void cluster(ClusterStmt *stmt);
 
 extern void check_index_is_clusterable(Relation OldHeap, Oid indexOid);
-extern void rebuild_relation(Relation OldHeap, Oid indexOid);
+extern void mark_index_clustered(Relation rel, Oid indexOid);
 extern Oid	make_new_heap(Oid OIDOldHeap, const char *NewName);
-extern List *get_indexattr_list(Relation OldHeap, Oid *OldClusterIndex);
-extern void rebuild_indexes(Oid OIDOldHeap, List *indexes,
-							Oid OIDClusterIndex);
 extern void swap_relfilenodes(Oid r1, Oid r2);
 
 #endif   /* CLUSTER_H */