*** src/backend/commands/cluster.c Mon Sep 24 16:01:31 2001 --- src/backend/commands/cluster.c.orig Sun Sep 23 16:37:35 2001 *************** *** 24,33 **** #include "access/genam.h" #include "access/heapam.h" - #include "catalog/catname.h" #include "catalog/heap.h" #include "catalog/index.h" - #include "catalog/indexing.h" #include "catalog/pg_index.h" #include "catalog/pg_proc.h" #include "commands/cluster.h" --- 24,31 ---- *************** *** 37,46 **** #include "utils/builtins.h" #include "utils/syscache.h" #include "utils/temprel.h" ! #include "utils/relcache.h" // for RelationGetIndexList() static Oid copy_heap(Oid OIDOldHeap, char *NewName, bool istemp); ! static void new_index(Oid OIDOldIndex, Oid OIDHeap, char *NewIndexName); static void rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex); /* --- 35,44 ---- #include "utils/builtins.h" #include "utils/syscache.h" #include "utils/temprel.h" ! static Oid copy_heap(Oid OIDOldHeap, char *NewName, bool istemp); ! static void copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName); static void rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex); /* *************** *** 62,93 **** OIDOldIndex, OIDNewHeap; Relation OldHeap, ! OldIndex, ! NewHeap, ! relrelation; HeapTuple tuple; - TupleDesc tupdesc; - bool istemp; char NewHeapName[NAMEDATALEN]; char NewIndexName[NAMEDATALEN]; char saveoldrelname[NAMEDATALEN]; char saveoldindexname[NAMEDATALEN]; - List *OldIndexOids; - - Relation irelations[Num_pg_class_indices]; - - /* put the details of index name/oid of the OldHeap - * in here to speed things up and make it all cleaner - */ - - struct OldIndexData { - char oldindname[NAMEDATALEN]; - char newindname[NAMEDATALEN]; - }; - - List *OldIndices = NULL; - List *ltmp; /* * Copy the arguments into local storage, just to be safe. --- 60,72 ---- OIDOldIndex, OIDNewHeap; Relation OldHeap, ! OldIndex; HeapTuple tuple; bool istemp; char NewHeapName[NAMEDATALEN]; char NewIndexName[NAMEDATALEN]; char saveoldrelname[NAMEDATALEN]; char saveoldindexname[NAMEDATALEN]; /* * Copy the arguments into local storage, just to be safe. *************** *** 100,109 **** * duration of the transaction. */ OldHeap = heap_openr(saveoldrelname, AccessExclusiveLock); - - /* Preserve all indices. - gavin */ - OldIndexOids = RelationGetIndexList(OldHeap); - OIDOldHeap = RelationGetRelid(OldHeap); OldIndex = index_openr(saveoldindexname); --- 79,84 ---- *************** *** 135,213 **** */ snprintf(NewHeapName, NAMEDATALEN, "temp_%u", OIDOldHeap); /* ! * heap_create needs this. Unsure if I can just give it a ! * zero'd structure. Lets use the current one instead */ ! tupdesc = CreateTupleDescCopyConstr(RelationGetDescr(OldHeap)); - - NewHeap = heap_create(NewHeapName,tupdesc,istemp,true, - allowSystemTableMods); - - /* Is this required here ? */ CommandCounterIncrement(); ! OIDNewHeap = RelationGetRelid(NewHeap); /* ! * Copy the heap data into the new table in the desired order. */ ! rebuildheap(OIDNewHeap, OIDOldHeap, OIDOldIndex); ! heap_close(NewHeap,NoLock); ! /* To make the new heap's data visible. */ CommandCounterIncrement(); ! /* Update OldHeap to have new relfilenode */ ! relrelation = heap_openr(RelationRelationName,RowExclusiveLock); ! tuple = SearchSysCacheCopy(RELOID, ! ObjectIdGetDatum(OIDOldHeap), ! 0, 0, 0); ! Assert(HeapTupleIsValid(tuple)); ! ! ((Form_pg_class) GETSTRUCT(tuple))->relfilenode = ! NewHeap->rd_rel->relfilenode; ! ! simple_heap_update(relrelation,&tuple->t_self,tuple); ! ! /* update catalogue indices */ ! CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, irelations); ! CatalogIndexInsert(irelations, Num_pg_class_indices, relrelation, tuple); ! CatalogCloseIndices(Num_pg_class_indices, irelations); ! ! heap_close(relrelation,NoLock); ! ! /* Reindex */ ! /* copy to a new index, drop the old and rename */ ! ! foreach(ltmp,OldIndexOids) { ! Relation rel; ! char OldIndexName[NAMEDATALEN]; ! ! rel = RelationIdGetRelation((Oid)lfirst(ltmp)); ! StrNCpy(OldIndexName,RelationGetRelationName(rel),NAMEDATALEN); ! ! snprintf(NewIndexName,NAMEDATALEN,"temp_%u",(Oid)lfirst(ltmp)); ! ! new_index((Oid)lfirst(ltmp),OIDOldHeap,NewIndexName); ! ! index_drop((Oid)lfirst(ltmp)); ! CommandCounterIncrement(); ! ! renamerel(NewIndexName,OldIndexName); ! /* decrement the count to keep everyone happy */ ! RelationClose(rel); ! } ! FreeTupleDesc(tupdesc); ! heap_freetuple(tuple); } static void ! new_index(Oid OIDOldIndex, Oid OIDHeap, char *NewIndexName) { Relation OldIndex, NewHeap; --- 110,188 ---- */ snprintf(NewHeapName, NAMEDATALEN, "temp_%u", OIDOldHeap); + OIDNewHeap = copy_heap(OIDOldHeap, NewHeapName, istemp); + + /* 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); + + copy_index(OIDOldIndex, OIDNewHeap, NewIndexName); + + CommandCounterIncrement(); ! /* Destroy old heap (along with its index) and rename new. */ ! heap_drop_with_catalog(saveoldrelname, allowSystemTableMods); CommandCounterIncrement(); ! renamerel(NewHeapName, saveoldrelname); ! ! /* This one might be unnecessary, but let's be safe. */ ! CommandCounterIncrement(); ! ! renamerel(NewIndexName, saveoldindexname); ! } ! ! static Oid ! copy_heap(Oid OIDOldHeap, char *NewName, bool istemp) ! { ! 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, tupdesc, + RELKIND_RELATION, istemp, + 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(NewName, true); ! heap_close(OldHeap, NoLock); ! return OIDNewHeap; } static void ! copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName) { Relation OldIndex, NewHeap; *************** *** 217,223 **** Form_pg_class Old_pg_index_relation_Form; IndexInfo *indexInfo; ! NewHeap = heap_open(OIDHeap, AccessExclusiveLock); OldIndex = index_open(OIDOldIndex); /* --- 192,198 ---- Form_pg_class Old_pg_index_relation_Form; IndexInfo *indexInfo; ! NewHeap = heap_open(OIDNewHeap, AccessExclusiveLock); OldIndex = index_open(OIDOldIndex); /* *************** *** 242,247 **** --- 217,223 ---- 0, 0, 0); Assert(Old_pg_index_relation_Tuple); Old_pg_index_relation_Form = (Form_pg_class) GETSTRUCT(Old_pg_index_relation_Tuple); + index_create(RelationGetRelationName(NewHeap), NewIndexName, indexInfo, *************** *** 251,259 **** Old_pg_index_Form->indisprimary, allowSystemTableMods); ! /* handled by index_drop */ ! ! // setRelhasindex(OIDHeap, true); ReleaseSysCache(Old_pg_index_Tuple); ReleaseSysCache(Old_pg_index_relation_Tuple); --- 227,233 ---- Old_pg_index_Form->indisprimary, allowSystemTableMods); ! setRelhasindex(OIDNewHeap, true); ReleaseSysCache(Old_pg_index_Tuple); ReleaseSysCache(Old_pg_index_relation_Tuple);