mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Massive commit to run PGINDENT on all *.c and *.h files.
This commit is contained in:
@ -1,20 +1,20 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* cluster.c--
|
||||
* Paul Brown's implementation of cluster index.
|
||||
* 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]
|
||||
* 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]
|
||||
*
|
||||
* Copyright (c) 1994-5, Regents of the University of California
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.13 1997/08/19 21:30:45 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.14 1997/09/07 04:40:36 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -47,307 +47,323 @@
|
||||
#include <optimizer/internal.h>
|
||||
#ifndef NO_SECURITY
|
||||
#include <utils/acl.h>
|
||||
#endif /* !NO_SECURITY */
|
||||
#endif /* !NO_SECURITY */
|
||||
|
||||
static Relation copy_heap(Oid OIDOldHeap);
|
||||
static void copy_index(Oid OIDOldIndex, Oid OIDNewHeap);
|
||||
static void rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex);
|
||||
static void copy_index(Oid OIDOldIndex, Oid OIDNewHeap);
|
||||
static void rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex);
|
||||
|
||||
/*
|
||||
* cluster
|
||||
*
|
||||
* Check that the relation is a relation in the appropriate user
|
||||
* ACL. I will use the same security that limits users on the
|
||||
* renamerel() function.
|
||||
* Check that the relation is a relation in the appropriate user
|
||||
* ACL. I will use the same security that limits users on the
|
||||
* renamerel() function.
|
||||
*
|
||||
* Check that the index specified is appropriate for the task
|
||||
* ( ie it's an index over this relation ). This is trickier.
|
||||
* Check that the index specified is appropriate for the task
|
||||
* ( ie it's an index over this relation ). This is trickier.
|
||||
*
|
||||
* Create a list of all the other indicies on this relation. Because
|
||||
* the cluster will wreck all the tids, I'll need to destroy bogus
|
||||
* indicies. 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 indicies may blow out the space.
|
||||
* Create a list of all the other indicies on this relation. Because
|
||||
* the cluster will wreck all the tids, I'll need to destroy bogus
|
||||
* indicies. 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 indicies may blow out the space.
|
||||
*
|
||||
* Create new (temporary) relations for the base heap and the new
|
||||
* index.
|
||||
*
|
||||
* Exclusively lock the relations.
|
||||
*
|
||||
* Create new clustered index and base heap relation.
|
||||
* Create new (temporary) relations for the base heap and the new
|
||||
* index.
|
||||
*
|
||||
* Exclusively lock the relations.
|
||||
*
|
||||
* Create new clustered index and base heap relation.
|
||||
*
|
||||
*/
|
||||
void
|
||||
cluster(char oldrelname[], char oldindexname[])
|
||||
{
|
||||
Oid OIDOldHeap, OIDOldIndex, OIDNewHeap;
|
||||
|
||||
Relation OldHeap, OldIndex;
|
||||
Relation NewHeap;
|
||||
|
||||
char NewIndexName[NAMEDATALEN];
|
||||
char NewHeapName[NAMEDATALEN];
|
||||
char saveoldrelname[NAMEDATALEN];
|
||||
char saveoldindexname[NAMEDATALEN];
|
||||
Oid OIDOldHeap,
|
||||
OIDOldIndex,
|
||||
OIDNewHeap;
|
||||
|
||||
Relation OldHeap,
|
||||
OldIndex;
|
||||
Relation NewHeap;
|
||||
|
||||
char NewIndexName[NAMEDATALEN];
|
||||
char NewHeapName[NAMEDATALEN];
|
||||
char saveoldrelname[NAMEDATALEN];
|
||||
char saveoldindexname[NAMEDATALEN];
|
||||
|
||||
|
||||
/* Save the old names because they will get lost when the old relations
|
||||
* are destroyed.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
|
||||
/* matches the StartTransaction in PostgresMain() */
|
||||
|
||||
OldHeap = heap_openr(oldrelname);
|
||||
if (!RelationIsValid(OldHeap)) {
|
||||
elog(WARN, "cluster: unknown relation: \"%s\"",
|
||||
oldrelname);
|
||||
}
|
||||
OIDOldHeap = OldHeap->rd_id; /* Get OID for the index scan */
|
||||
|
||||
OldIndex=index_openr(oldindexname);/* Open old index relation */
|
||||
if (!RelationIsValid(OldIndex)) {
|
||||
elog(WARN, "cluster: unknown index: \"%s\"",
|
||||
oldindexname);
|
||||
}
|
||||
OIDOldIndex = OldIndex->rd_id; /* OID for the index scan */
|
||||
|
||||
heap_close(OldHeap);
|
||||
index_close(OldIndex);
|
||||
|
||||
/*
|
||||
* I need to build the copies of the heap and the index. The Commit()
|
||||
* between here is *very* bogus. If someone is appending stuff, they will
|
||||
* get the lock after being blocked and add rows which won't be present in
|
||||
* the new table. Bleagh! I'd be best to try and ensure that no-one's
|
||||
* in the tables for the entire duration of this process with a pg_vlock.
|
||||
*/
|
||||
NewHeap = copy_heap(OIDOldHeap);
|
||||
OIDNewHeap = NewHeap->rd_id;
|
||||
strcpy(NewHeapName,NewHeap->rd_rel->relname.data);
|
||||
/*
|
||||
* Save the old names because they will get lost when the old
|
||||
* relations are destroyed.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
|
||||
/* matches the StartTransaction in PostgresMain() */
|
||||
|
||||
OldHeap = heap_openr(oldrelname);
|
||||
if (!RelationIsValid(OldHeap))
|
||||
{
|
||||
elog(WARN, "cluster: unknown relation: \"%s\"",
|
||||
oldrelname);
|
||||
}
|
||||
OIDOldHeap = OldHeap->rd_id;/* Get OID for the index scan */
|
||||
|
||||
OldIndex = index_openr(oldindexname); /* Open old index relation */
|
||||
if (!RelationIsValid(OldIndex))
|
||||
{
|
||||
elog(WARN, "cluster: unknown index: \"%s\"",
|
||||
oldindexname);
|
||||
}
|
||||
OIDOldIndex = OldIndex->rd_id; /* OID for the index scan */
|
||||
|
||||
heap_close(OldHeap);
|
||||
index_close(OldIndex);
|
||||
|
||||
/*
|
||||
* I need to build the copies of the heap and the index. The Commit()
|
||||
* between here is *very* bogus. If someone is appending stuff, they
|
||||
* will get the lock after being blocked and add rows which won't be
|
||||
* present in the new table. Bleagh! I'd be best to try and ensure
|
||||
* that no-one's in the tables for the entire duration of this process
|
||||
* with a pg_vlock.
|
||||
*/
|
||||
NewHeap = copy_heap(OIDOldHeap);
|
||||
OIDNewHeap = NewHeap->rd_id;
|
||||
strcpy(NewHeapName, NewHeap->rd_rel->relname.data);
|
||||
|
||||
|
||||
/* To make the new heap visible (which is until now empty). */
|
||||
CommandCounterIncrement();
|
||||
|
||||
rebuildheap(OIDNewHeap, OIDOldHeap, OIDOldIndex);
|
||||
|
||||
/* To flush the filled new heap (and the statistics about it). */
|
||||
CommandCounterIncrement();
|
||||
/* To make the new heap visible (which is until now empty). */
|
||||
CommandCounterIncrement();
|
||||
|
||||
/* Create new index over the tuples of the new heap. */
|
||||
copy_index(OIDOldIndex, OIDNewHeap);
|
||||
sprintf(NewIndexName, "temp_%x", OIDOldIndex);
|
||||
|
||||
/*
|
||||
* make this really happen. Flush all the buffers.
|
||||
* (Believe me, it is necessary ... ended up in a mess without it.)
|
||||
*/
|
||||
CommitTransactionCommand();
|
||||
StartTransactionCommand();
|
||||
rebuildheap(OIDNewHeap, OIDOldHeap, OIDOldIndex);
|
||||
|
||||
/* To flush the filled new heap (and the statistics about it). */
|
||||
CommandCounterIncrement();
|
||||
|
||||
/* Create new index over the tuples of the new heap. */
|
||||
copy_index(OIDOldIndex, OIDNewHeap);
|
||||
sprintf(NewIndexName, "temp_%x", OIDOldIndex);
|
||||
|
||||
/*
|
||||
* make this really happen. Flush all the buffers. (Believe me, it is
|
||||
* necessary ... ended up in a mess without it.)
|
||||
*/
|
||||
CommitTransactionCommand();
|
||||
StartTransactionCommand();
|
||||
|
||||
|
||||
/* Destroy old heap (along with its index) and rename new. */
|
||||
heap_destroy(oldrelname);
|
||||
|
||||
renamerel(NewHeapName, saveoldrelname);
|
||||
TypeRename(NewHeapName, saveoldrelname);
|
||||
/* Destroy old heap (along with its index) and rename new. */
|
||||
heap_destroy(oldrelname);
|
||||
|
||||
renamerel(NewIndexName, saveoldindexname);
|
||||
renamerel(NewHeapName, saveoldrelname);
|
||||
TypeRename(NewHeapName, saveoldrelname);
|
||||
|
||||
/*
|
||||
* Again flush all the buffers.
|
||||
*/
|
||||
CommitTransactionCommand();
|
||||
StartTransactionCommand();
|
||||
renamerel(NewIndexName, saveoldindexname);
|
||||
|
||||
/*
|
||||
* Again flush all the buffers.
|
||||
*/
|
||||
CommitTransactionCommand();
|
||||
StartTransactionCommand();
|
||||
}
|
||||
|
||||
static Relation
|
||||
static Relation
|
||||
copy_heap(Oid OIDOldHeap)
|
||||
{
|
||||
char NewName[NAMEDATALEN];
|
||||
TupleDesc OldHeapDesc, tupdesc;
|
||||
Oid OIDNewHeap;
|
||||
Relation NewHeap, OldHeap;
|
||||
char NewName[NAMEDATALEN];
|
||||
TupleDesc OldHeapDesc,
|
||||
tupdesc;
|
||||
Oid OIDNewHeap;
|
||||
Relation NewHeap,
|
||||
OldHeap;
|
||||
|
||||
/*
|
||||
* Create a new heap relation with a temporary name, which has the
|
||||
* same tuple description as the old one.
|
||||
*/
|
||||
sprintf(NewName,"temp_%x", OIDOldHeap);
|
||||
/*
|
||||
* Create a new heap relation with a temporary name, which has the
|
||||
* same tuple description as the old one.
|
||||
*/
|
||||
sprintf(NewName, "temp_%x", OIDOldHeap);
|
||||
|
||||
OldHeap= heap_open(OIDOldHeap);
|
||||
OldHeapDesc= RelationGetTupleDescriptor(OldHeap);
|
||||
OldHeap = heap_open(OIDOldHeap);
|
||||
OldHeapDesc = RelationGetTupleDescriptor(OldHeap);
|
||||
|
||||
/*
|
||||
* Need to make a copy of the tuple descriptor, heap_create modifies
|
||||
* it.
|
||||
*/
|
||||
/*
|
||||
* Need to make a copy of the tuple descriptor, heap_create modifies
|
||||
* it.
|
||||
*/
|
||||
|
||||
tupdesc = CreateTupleDescCopy(OldHeapDesc);
|
||||
|
||||
OIDNewHeap=heap_create(NewName,
|
||||
NULL,
|
||||
OldHeap->rd_rel->relarch,
|
||||
OldHeap->rd_rel->relsmgr,
|
||||
tupdesc);
|
||||
tupdesc = CreateTupleDescCopy(OldHeapDesc);
|
||||
|
||||
if (!OidIsValid(OIDNewHeap))
|
||||
elog(WARN,"clusterheap: cannot create temporary heap relation\n");
|
||||
OIDNewHeap = heap_create(NewName,
|
||||
NULL,
|
||||
OldHeap->rd_rel->relarch,
|
||||
OldHeap->rd_rel->relsmgr,
|
||||
tupdesc);
|
||||
|
||||
NewHeap=heap_open(OIDNewHeap);
|
||||
if (!OidIsValid(OIDNewHeap))
|
||||
elog(WARN, "clusterheap: cannot create temporary heap relation\n");
|
||||
|
||||
heap_close(NewHeap);
|
||||
heap_close(OldHeap);
|
||||
NewHeap = heap_open(OIDNewHeap);
|
||||
|
||||
return NewHeap;
|
||||
heap_close(NewHeap);
|
||||
heap_close(OldHeap);
|
||||
|
||||
return NewHeap;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_index(Oid OIDOldIndex, Oid OIDNewHeap)
|
||||
{
|
||||
Relation OldIndex, NewHeap;
|
||||
HeapTuple Old_pg_index_Tuple, Old_pg_index_relation_Tuple, pg_proc_Tuple;
|
||||
IndexTupleForm Old_pg_index_Form;
|
||||
Form_pg_class Old_pg_index_relation_Form;
|
||||
Form_pg_proc pg_proc_Form;
|
||||
char *NewIndexName;
|
||||
AttrNumber *attnumP;
|
||||
int natts;
|
||||
FuncIndexInfo * finfo;
|
||||
Relation OldIndex,
|
||||
NewHeap;
|
||||
HeapTuple Old_pg_index_Tuple,
|
||||
Old_pg_index_relation_Tuple,
|
||||
pg_proc_Tuple;
|
||||
IndexTupleForm Old_pg_index_Form;
|
||||
Form_pg_class Old_pg_index_relation_Form;
|
||||
Form_pg_proc pg_proc_Form;
|
||||
char *NewIndexName;
|
||||
AttrNumber *attnumP;
|
||||
int natts;
|
||||
FuncIndexInfo *finfo;
|
||||
|
||||
NewHeap = heap_open(OIDNewHeap);
|
||||
OldIndex = index_open(OIDOldIndex);
|
||||
NewHeap = heap_open(OIDNewHeap);
|
||||
OldIndex = index_open(OIDOldIndex);
|
||||
|
||||
/*
|
||||
* OK. Create a new (temporary) index for the one that's already
|
||||
* here. To do this I get the info from pg_index, re-build the
|
||||
* FunctInfo if I have to, and add a new index with a temporary
|
||||
* name.
|
||||
*/
|
||||
Old_pg_index_Tuple =
|
||||
SearchSysCacheTuple(INDEXRELID,
|
||||
ObjectIdGetDatum(OldIndex->rd_id),
|
||||
0,0,0);
|
||||
/*
|
||||
* OK. Create a new (temporary) index for the one that's already here.
|
||||
* To do this I get the info from pg_index, re-build the FunctInfo if
|
||||
* I have to, and add a new index with a temporary name.
|
||||
*/
|
||||
Old_pg_index_Tuple =
|
||||
SearchSysCacheTuple(INDEXRELID,
|
||||
ObjectIdGetDatum(OldIndex->rd_id),
|
||||
0, 0, 0);
|
||||
|
||||
Assert(Old_pg_index_Tuple);
|
||||
Old_pg_index_Form = (IndexTupleForm)GETSTRUCT(Old_pg_index_Tuple);
|
||||
Assert(Old_pg_index_Tuple);
|
||||
Old_pg_index_Form = (IndexTupleForm) GETSTRUCT(Old_pg_index_Tuple);
|
||||
|
||||
Old_pg_index_relation_Tuple =
|
||||
SearchSysCacheTuple(RELOID,
|
||||
ObjectIdGetDatum(OldIndex->rd_id),
|
||||
0,0,0);
|
||||
Old_pg_index_relation_Tuple =
|
||||
SearchSysCacheTuple(RELOID,
|
||||
ObjectIdGetDatum(OldIndex->rd_id),
|
||||
0, 0, 0);
|
||||
|
||||
Assert(Old_pg_index_relation_Tuple);
|
||||
Old_pg_index_relation_Form =
|
||||
(Form_pg_class)GETSTRUCT(Old_pg_index_relation_Tuple);
|
||||
Assert(Old_pg_index_relation_Tuple);
|
||||
Old_pg_index_relation_Form =
|
||||
(Form_pg_class) GETSTRUCT(Old_pg_index_relation_Tuple);
|
||||
|
||||
NewIndexName = palloc(NAMEDATALEN); /* XXX */
|
||||
sprintf(NewIndexName, "temp_%x", OIDOldIndex); /* Set the name. */
|
||||
NewIndexName = palloc(NAMEDATALEN); /* XXX */
|
||||
sprintf(NewIndexName, "temp_%x", OIDOldIndex); /* Set the name. */
|
||||
|
||||
/*
|
||||
* Ugly as it is, the only way I have of working out the number of
|
||||
* attribues is to count them. Mostly there'll be just one but
|
||||
* I've got to be sure.
|
||||
*/
|
||||
for (attnumP = &(Old_pg_index_Form->indkey[0]), natts = 0;
|
||||
*attnumP != InvalidAttrNumber;
|
||||
attnumP++, natts++);
|
||||
/*
|
||||
* Ugly as it is, the only way I have of working out the number of
|
||||
* attribues is to count them. Mostly there'll be just one but I've
|
||||
* got to be sure.
|
||||
*/
|
||||
for (attnumP = &(Old_pg_index_Form->indkey[0]), natts = 0;
|
||||
*attnumP != InvalidAttrNumber;
|
||||
attnumP++, natts++);
|
||||
|
||||
/*
|
||||
* If this is a functional index, I need to rebuild the functional
|
||||
* component to pass it to the defining procedure.
|
||||
*/
|
||||
if (Old_pg_index_Form->indproc != InvalidOid) {
|
||||
finfo = (FuncIndexInfo *) palloc(sizeof(FuncIndexInfo));
|
||||
FIgetnArgs(finfo) = natts;
|
||||
FIgetProcOid(finfo) = Old_pg_index_Form->indproc;
|
||||
/*
|
||||
* If this is a functional index, I need to rebuild the functional
|
||||
* component to pass it to the defining procedure.
|
||||
*/
|
||||
if (Old_pg_index_Form->indproc != InvalidOid)
|
||||
{
|
||||
finfo = (FuncIndexInfo *) palloc(sizeof(FuncIndexInfo));
|
||||
FIgetnArgs(finfo) = natts;
|
||||
FIgetProcOid(finfo) = Old_pg_index_Form->indproc;
|
||||
|
||||
pg_proc_Tuple =
|
||||
SearchSysCacheTuple(PROOID,
|
||||
ObjectIdGetDatum(Old_pg_index_Form->indproc),
|
||||
0,0,0);
|
||||
pg_proc_Tuple =
|
||||
SearchSysCacheTuple(PROOID,
|
||||
ObjectIdGetDatum(Old_pg_index_Form->indproc),
|
||||
0, 0, 0);
|
||||
|
||||
Assert(pg_proc_Tuple);
|
||||
pg_proc_Form = (Form_pg_proc)GETSTRUCT(pg_proc_Tuple);
|
||||
namecpy(&(finfo->funcName), &(pg_proc_Form->proname));
|
||||
} else {
|
||||
finfo = (FuncIndexInfo *) NULL;
|
||||
natts = 1;
|
||||
}
|
||||
Assert(pg_proc_Tuple);
|
||||
pg_proc_Form = (Form_pg_proc) GETSTRUCT(pg_proc_Tuple);
|
||||
namecpy(&(finfo->funcName), &(pg_proc_Form->proname));
|
||||
}
|
||||
else
|
||||
{
|
||||
finfo = (FuncIndexInfo *) NULL;
|
||||
natts = 1;
|
||||
}
|
||||
|
||||
index_create((NewHeap->rd_rel->relname).data,
|
||||
NewIndexName,
|
||||
finfo,
|
||||
NULL, /* type info is in the old index */
|
||||
Old_pg_index_relation_Form->relam,
|
||||
natts,
|
||||
Old_pg_index_Form->indkey,
|
||||
Old_pg_index_Form->indclass,
|
||||
(uint16)0, (Datum) NULL, NULL,
|
||||
Old_pg_index_Form->indislossy,
|
||||
Old_pg_index_Form->indisunique);
|
||||
index_create((NewHeap->rd_rel->relname).data,
|
||||
NewIndexName,
|
||||
finfo,
|
||||
NULL, /* type info is in the old index */
|
||||
Old_pg_index_relation_Form->relam,
|
||||
natts,
|
||||
Old_pg_index_Form->indkey,
|
||||
Old_pg_index_Form->indclass,
|
||||
(uint16) 0, (Datum) NULL, NULL,
|
||||
Old_pg_index_Form->indislossy,
|
||||
Old_pg_index_Form->indisunique);
|
||||
|
||||
heap_close(OldIndex);
|
||||
heap_close(NewHeap);
|
||||
heap_close(OldIndex);
|
||||
heap_close(NewHeap);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
|
||||
{
|
||||
Relation LocalNewHeap, LocalOldHeap, LocalOldIndex;
|
||||
IndexScanDesc ScanDesc;
|
||||
RetrieveIndexResult ScanResult;
|
||||
ItemPointer HeapTid;
|
||||
HeapTuple LocalHeapTuple;
|
||||
Buffer LocalBuffer;
|
||||
Oid OIDNewHeapInsert;
|
||||
Relation LocalNewHeap,
|
||||
LocalOldHeap,
|
||||
LocalOldIndex;
|
||||
IndexScanDesc ScanDesc;
|
||||
RetrieveIndexResult ScanResult;
|
||||
ItemPointer HeapTid;
|
||||
HeapTuple LocalHeapTuple;
|
||||
Buffer LocalBuffer;
|
||||
Oid OIDNewHeapInsert;
|
||||
|
||||
/*
|
||||
* Open the relations I need. Scan through the OldHeap on the OldIndex and
|
||||
* insert each tuple into the NewHeap.
|
||||
*/
|
||||
LocalNewHeap=(Relation)heap_open(OIDNewHeap);
|
||||
LocalOldHeap=(Relation)heap_open(OIDOldHeap);
|
||||
LocalOldIndex=(Relation)index_open(OIDOldIndex);
|
||||
/*
|
||||
* Open the relations I need. Scan through the OldHeap on the OldIndex
|
||||
* and insert each tuple into the NewHeap.
|
||||
*/
|
||||
LocalNewHeap = (Relation) heap_open(OIDNewHeap);
|
||||
LocalOldHeap = (Relation) heap_open(OIDOldHeap);
|
||||
LocalOldIndex = (Relation) index_open(OIDOldIndex);
|
||||
|
||||
ScanDesc=index_beginscan(LocalOldIndex, false, 0, (ScanKey) NULL);
|
||||
ScanDesc = index_beginscan(LocalOldIndex, false, 0, (ScanKey) NULL);
|
||||
|
||||
while ((ScanResult =
|
||||
index_getnext(ScanDesc, ForwardScanDirection)) != NULL) {
|
||||
while ((ScanResult =
|
||||
index_getnext(ScanDesc, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
|
||||
HeapTid = &ScanResult->heap_iptr;
|
||||
LocalHeapTuple = heap_fetch(LocalOldHeap, 0, HeapTid, &LocalBuffer);
|
||||
OIDNewHeapInsert =
|
||||
heap_insert(LocalNewHeap, LocalHeapTuple);
|
||||
pfree(ScanResult);
|
||||
ReleaseBuffer(LocalBuffer);
|
||||
}
|
||||
index_endscan(ScanDesc);
|
||||
HeapTid = &ScanResult->heap_iptr;
|
||||
LocalHeapTuple = heap_fetch(LocalOldHeap, 0, HeapTid, &LocalBuffer);
|
||||
OIDNewHeapInsert =
|
||||
heap_insert(LocalNewHeap, LocalHeapTuple);
|
||||
pfree(ScanResult);
|
||||
ReleaseBuffer(LocalBuffer);
|
||||
}
|
||||
index_endscan(ScanDesc);
|
||||
|
||||
index_close(LocalOldIndex);
|
||||
heap_close(LocalOldHeap);
|
||||
heap_close(LocalNewHeap);
|
||||
index_close(LocalOldIndex);
|
||||
heap_close(LocalOldHeap);
|
||||
heap_close(LocalNewHeap);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user