*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.51 2000/04/12 17:14:57 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.52 2000/05/11 03:54:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "catalog/heap.h"
#include "catalog/index.h"
#include "catalog/pg_proc.h"
-#include "catalog/pg_type.h"
#include "commands/cluster.h"
#include "commands/rename.h"
#include "optimizer/internal.h"
char saveoldrelname[NAMEDATALEN];
char saveoldindexname[NAMEDATALEN];
-
/*
- * Save the old names because they will get lost when the old
- * relations are destroyed.
+ * Copy the arguments into local storage, because they are probably
+ * in palloc'd storage that will go away when we commit a transaction.
*/
strcpy(saveoldrelname, oldrelname);
strcpy(saveoldindexname, oldindexname);
- /*
- * I'm going to force all checking back into the commands.c function.
- *
- * Get the list if indicies for this relation. If the index we want is
- * among them, do not add it to the 'kill' list, as it will be handled
- * by the 'clean up' code which commits this transaction.
- *
- * I'm not using the SysCache, because this will happen but once, and the
- * slow way is the sure way in this case.
- *
- */
-
/*
* Like vacuum, cluster spans transactions, so I'm going to handle it
* in the same way: commit and restart transactions where needed.
* of the initial transaction.
*/
- OldHeap = heap_openr(oldrelname, AccessExclusiveLock);
+ OldHeap = heap_openr(saveoldrelname, AccessExclusiveLock);
OIDOldHeap = RelationGetRelid(OldHeap);
- OldIndex = index_openr(oldindexname); /* Open old index relation */
+ OldIndex = index_openr(saveoldindexname); /* Open old index relation */
LockRelation(OldIndex, AccessExclusiveLock);
OIDOldIndex = RelationGetRelid(OldIndex);
+ /*
+ * XXX Should check that index is in fact an index on this relation?
+ */
+
heap_close(OldHeap, NoLock);/* do NOT give up the locks */
index_close(OldIndex);
OIDNewHeap = RelationGetRelid(NewHeap);
strcpy(NewHeapName, RelationGetRelationName(NewHeap));
-
/* To make the new heap visible (which is until now empty). */
CommandCounterIncrement();
CommitTransactionCommand();
StartTransactionCommand();
-
/* Destroy old heap (along with its index) and rename new. */
- heap_drop_with_catalog(oldrelname);
+ heap_drop_with_catalog(saveoldrelname);
CommitTransactionCommand();
StartTransactionCommand();
renamerel(NewHeapName, saveoldrelname);
- TypeRename(NewHeapName, saveoldrelname);
-
renamerel(NewIndexName, saveoldindexname);
-
- /*
- * Again flush all the buffers. XXX perhaps not needed?
- */
- CommitTransactionCommand();
- StartTransactionCommand();
}
static Relation
Old_pg_index_Form->indisunique,
Old_pg_index_Form->indisprimary);
+ setRelhasindexInplace(OIDNewHeap, true, false);
+
index_close(OldIndex);
heap_close(NewHeap, AccessExclusiveLock);
}
LocalOldIndex;
IndexScanDesc ScanDesc;
RetrieveIndexResult ScanResult;
- HeapTupleData LocalHeapTuple;
- Buffer LocalBuffer;
- Oid OIDNewHeapInsert;
/*
* Open the relations I need. Scan through the OldHeap on the OldIndex
*/
LocalNewHeap = heap_open(OIDNewHeap, AccessExclusiveLock);
LocalOldHeap = heap_open(OIDOldHeap, AccessExclusiveLock);
- LocalOldIndex = (Relation) index_open(OIDOldIndex);
+ LocalOldIndex = index_open(OIDOldIndex);
ScanDesc = index_beginscan(LocalOldIndex, false, 0, (ScanKey) NULL);
while ((ScanResult = index_getnext(ScanDesc, ForwardScanDirection)) != NULL)
{
+ HeapTupleData LocalHeapTuple;
+ Buffer LocalBuffer;
LocalHeapTuple.t_self = ScanResult->heap_iptr;
LocalHeapTuple.t_datamcxt = NULL;
LocalHeapTuple.t_data = NULL;
heap_fetch(LocalOldHeap, SnapshotNow, &LocalHeapTuple, &LocalBuffer);
- OIDNewHeapInsert = heap_insert(LocalNewHeap, &LocalHeapTuple);
- pfree(ScanResult);
+ heap_insert(LocalNewHeap, &LocalHeapTuple);
ReleaseBuffer(LocalBuffer);
+ pfree(ScanResult);
}
+
index_endscan(ScanDesc);
index_close(LocalOldIndex);
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.42 2000/04/12 17:14:59 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.43 2000/05/11 03:54:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "access/heapam.h"
#include "catalog/catname.h"
+#include "catalog/pg_type.h"
#include "utils/syscache.h"
#include "catalog/heap.h"
#include "catalog/indexing.h"
#include "storage/smgr.h"
#include "optimizer/prep.h"
#include "utils/acl.h"
+#include "utils/relcache.h"
+
/*
* renameatt - changes the name of a attribute in a relation
Relation targetrelation;
Relation relrelation; /* for RELATION relation */
HeapTuple oldreltup;
+ char relkind;
char oldpath[MAXPGPATH],
newpath[MAXPGPATH],
toldpath[MAXPGPATH + 10],
elog(ERROR, "renamerel: Illegal class name: \"%s\" -- pg_ is reserved for system catalogs",
newrelname);
+ /*
+ * Instead of using heap_openr(), do it the hard way, so that we
+ * can rename indexes as well as regular relations.
+ */
+ targetrelation = RelationNameGetRelation(oldrelname);
+
+ if (!RelationIsValid(targetrelation))
+ elog(ERROR, "Relation '%s' does not exist", oldrelname);
+
/*
* Grab an exclusive lock on the target table, which we will NOT
* release until end of transaction.
*/
- targetrelation = heap_openr(oldrelname, AccessExclusiveLock);
+ LockRelation(targetrelation, AccessExclusiveLock);
/* ----------------
* RENAME TABLE within a transaction block is dangerous, because
if (IsTransactionBlock() && !targetrelation->rd_myxactonly)
elog(NOTICE, "Caution: RENAME TABLE cannot be rolled back, so don't abort now");
+ relkind = targetrelation->rd_rel->relkind;
+
/*
* Flush all blocks of the relation out of the buffer pool. We need
* this because the blocks are marked with the relation's name as well
CatalogCloseIndices(Num_pg_class_indices, irelations);
heap_close(relrelation, RowExclusiveLock);
+
+ /*
+ * Also rename the associated type, if any.
+ */
+ if (relkind != RELKIND_INDEX)
+ TypeRename(oldrelname, newrelname);
}