summaryrefslogtreecommitdiff
path: root/src/backend/commands/cluster.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/cluster.c')
-rw-r--r--src/backend/commands/cluster.c255
1 files changed, 0 insertions, 255 deletions
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
deleted file mode 100644
index 3306943fb04..00000000000
--- a/src/backend/commands/cluster.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * cluster.c
- * Paul Brown's implementation of cluster index.
- *
- * I am going to use the rename function as a model for this in the
- * parser and executor, and the vacuum code as an example in this
- * file. As I go - in contrast to the rest of postgres - there will
- * be BUCKETS of comments. This is to allow reviewers to understand
- * my (probably bogus) assumptions about the way this works.
- * [pbrown '94]
- *
- * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994-5, Regents of the University of California
- *
- *
- * IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.82 2002/06/20 20:29:26 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-
-#include "postgres.h"
-
-#include "access/genam.h"
-#include "access/heapam.h"
-#include "catalog/heap.h"
-#include "catalog/index.h"
-#include "catalog/pg_index.h"
-#include "catalog/pg_proc.h"
-#include "commands/cluster.h"
-#include "commands/tablecmds.h"
-#include "miscadmin.h"
-#include "utils/builtins.h"
-#include "utils/lsyscache.h"
-#include "utils/syscache.h"
-
-
-static Oid copy_heap(Oid OIDOldHeap, const char *NewName);
-static Oid copy_index(Oid OIDOldIndex, Oid OIDNewHeap,
- const char *NewIndexName);
-static void rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex);
-
-/*
- * cluster
- *
- * STILL TO DO:
- * Create a list of all the other indexes on this relation. Because
- * the cluster will wreck all the tids, I'll need to destroy bogus
- * indexes. The user will have to re-create them. Not nice, but
- * I'm not a nice guy. The alternative is to try some kind of post
- * destroy re-build. This may be possible. I'll check out what the
- * index create functiond want in the way of paramaters. On the other
- * hand, re-creating n indexes may blow out the space.
- */
-void
-cluster(RangeVar *oldrelation, char *oldindexname)
-{
- Oid OIDOldHeap,
- OIDOldIndex,
- OIDNewHeap,
- OIDNewIndex;
- Relation OldHeap,
- OldIndex;
- char NewHeapName[NAMEDATALEN];
- char NewIndexName[NAMEDATALEN];
-
- /*
- * We grab exclusive access to the target rel and index for the
- * duration of the transaction.
- */
- OldHeap = heap_openrv(oldrelation, AccessExclusiveLock);
- OIDOldHeap = RelationGetRelid(OldHeap);
-
- /*
- * The index is expected to be in the same namespace as the relation.
- */
- OIDOldIndex = get_relname_relid(oldindexname,
- RelationGetNamespace(OldHeap));
- if (!OidIsValid(OIDOldIndex))
- elog(ERROR, "CLUSTER: cannot find index \"%s\" for table \"%s\"",
- oldindexname, oldrelation->relname);
- OldIndex = index_open(OIDOldIndex);
- LockRelation(OldIndex, AccessExclusiveLock);
-
- /*
- * Check that index is in fact an index on the given relation
- */
- if (OldIndex->rd_index->indrelid != OIDOldHeap)
- elog(ERROR, "CLUSTER: \"%s\" is not an index for table \"%s\"",
- oldindexname, oldrelation->relname);
-
- /* Drop relcache refcnts, but do NOT give up the locks */
- heap_close(OldHeap, NoLock);
- index_close(OldIndex);
-
- /*
- * Create the new heap with a temporary name.
- */
- snprintf(NewHeapName, NAMEDATALEN, "temp_%u", OIDOldHeap);
-
- OIDNewHeap = copy_heap(OIDOldHeap, NewHeapName);
-
- /* We do not need CommandCounterIncrement() because copy_heap did it. */
-
- /*
- * Copy the heap data into the new table in the desired order.
- */
- rebuildheap(OIDNewHeap, OIDOldHeap, OIDOldIndex);
-
- /* To make the new heap's data visible. */
- CommandCounterIncrement();
-
- /* Create new index over the tuples of the new heap. */
- snprintf(NewIndexName, NAMEDATALEN, "temp_%u", OIDOldIndex);
-
- OIDNewIndex = copy_index(OIDOldIndex, OIDNewHeap, NewIndexName);
-
- CommandCounterIncrement();
-
- /* Destroy old heap (along with its index) and rename new. */
- heap_drop_with_catalog(OIDOldHeap, allowSystemTableMods);
-
- CommandCounterIncrement();
-
- renamerel(OIDNewHeap, oldrelation->relname);
-
- /* This one might be unnecessary, but let's be safe. */
- CommandCounterIncrement();
-
- renamerel(OIDNewIndex, oldindexname);
-}
-
-static Oid
-copy_heap(Oid OIDOldHeap, const char *NewName)
-{
- TupleDesc OldHeapDesc,
- tupdesc;
- Oid OIDNewHeap;
- Relation OldHeap;
-
- OldHeap = heap_open(OIDOldHeap, AccessExclusiveLock);
- OldHeapDesc = RelationGetDescr(OldHeap);
-
- /*
- * Need to make a copy of the tuple descriptor, since
- * heap_create_with_catalog modifies it.
- */
- tupdesc = CreateTupleDescCopyConstr(OldHeapDesc);
-
- OIDNewHeap = heap_create_with_catalog(NewName,
- RelationGetNamespace(OldHeap),
- tupdesc,
- OldHeap->rd_rel->relkind,
- OldHeap->rd_rel->relisshared,
- OldHeap->rd_rel->relhasoids,
- allowSystemTableMods);
-
- /*
- * Advance command counter so that the newly-created relation's
- * catalog tuples will be visible to heap_open.
- */
- CommandCounterIncrement();
-
- /*
- * If necessary, create a TOAST table for the new relation. Note that
- * AlterTableCreateToastTable ends with CommandCounterIncrement(), so
- * that the TOAST table will be visible for insertion.
- */
- AlterTableCreateToastTable(OIDNewHeap, true);
-
- heap_close(OldHeap, NoLock);
-
- return OIDNewHeap;
-}
-
-static Oid
-copy_index(Oid OIDOldIndex, Oid OIDNewHeap, const char *NewIndexName)
-{
- Oid OIDNewIndex;
- Relation OldIndex,
- NewHeap;
- IndexInfo *indexInfo;
-
- NewHeap = heap_open(OIDNewHeap, AccessExclusiveLock);
- OldIndex = index_open(OIDOldIndex);
-
- /*
- * Create a new index like the old one. To do this I get the info
- * from pg_index, and add a new index with a temporary name (that will
- * be changed later).
- */
- indexInfo = BuildIndexInfo(OldIndex->rd_index);
-
- OIDNewIndex = index_create(OIDNewHeap,
- NewIndexName,
- indexInfo,
- OldIndex->rd_rel->relam,
- OldIndex->rd_index->indclass,
- OldIndex->rd_index->indisprimary,
- allowSystemTableMods);
-
- setRelhasindex(OIDNewHeap, true,
- OldIndex->rd_index->indisprimary, InvalidOid);
-
- index_close(OldIndex);
- heap_close(NewHeap, NoLock);
-
- return OIDNewIndex;
-}
-
-
-static void
-rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
-{
- Relation LocalNewHeap,
- LocalOldHeap,
- LocalOldIndex;
- IndexScanDesc ScanDesc;
- HeapTuple LocalHeapTuple;
-
- /*
- * Open the relations I need. Scan through the OldHeap on the OldIndex
- * and insert each tuple into the NewHeap.
- */
- LocalNewHeap = heap_open(OIDNewHeap, AccessExclusiveLock);
- LocalOldHeap = heap_open(OIDOldHeap, AccessExclusiveLock);
- LocalOldIndex = index_open(OIDOldIndex);
-
- ScanDesc = index_beginscan(LocalOldHeap, LocalOldIndex,
- SnapshotNow, 0, (ScanKey) NULL);
-
- while ((LocalHeapTuple = index_getnext(ScanDesc, ForwardScanDirection)) != NULL)
- {
- /*
- * We must copy the tuple because heap_insert() will overwrite
- * the commit-status fields of the tuple it's handed, and the
- * retrieved tuple will actually be in a disk buffer! Thus,
- * the source relation would get trashed, which is bad news if
- * we abort later on. (This was a bug in releases thru 7.0)
- */
- HeapTuple copiedTuple = heap_copytuple(LocalHeapTuple);
-
- simple_heap_insert(LocalNewHeap, copiedTuple);
- heap_freetuple(copiedTuple);
-
- CHECK_FOR_INTERRUPTS();
- }
-
- index_endscan(ScanDesc);
-
- index_close(LocalOldIndex);
- heap_close(LocalOldHeap, NoLock);
- heap_close(LocalNewHeap, NoLock);
-}