summaryrefslogtreecommitdiff
path: root/src/backend/catalog
diff options
context:
space:
mode:
authorHiroshi Inoue <inoue@tpf.co.jp>2000-02-18 09:30:20 +0000
committerHiroshi Inoue <inoue@tpf.co.jp>2000-02-18 09:30:20 +0000
commite3a97b370c2671c05ad95d6a21914c225a0cf32d (patch)
treee20b8bdc9dfedef71dfe1367c3b957cbf16c42c1 /src/backend/catalog
parente3befe4a66c68fea03300eadb9d9b2f1c2534dc6 (diff)
downloadpostgresql-e3a97b370c2671c05ad95d6a21914c225a0cf32d.tar.gz
Implement reindex command
Diffstat (limited to 'src/backend/catalog')
-rw-r--r--src/backend/catalog/heap.c11
-rw-r--r--src/backend/catalog/index.c487
-rw-r--r--src/backend/catalog/indexing.c8
3 files changed, 478 insertions, 28 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 2840e40633..271dc3ed97 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.121 2000/02/15 03:36:34 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.122 2000/02/18 09:28:40 inoue Exp $
*
*
* INTERFACE ROUTINES
@@ -713,7 +713,7 @@ AddNewRelationTuple(Relation pg_class_desc,
if (temp_relname)
create_temp_relation(temp_relname, tup);
- if (!IsBootstrapProcessingMode())
+ if (!IsIgnoringSystemIndexes())
{
/*
* First, open the catalog indices and insert index tuples for the
@@ -1263,8 +1263,7 @@ heap_truncate(char *relname)
rel->rd_nblocks = 0;
/* If this relation has indexes, truncate the indexes too */
- if (rel->rd_rel->relhasindex)
- RelationTruncateIndexes(rel);
+ RelationTruncateIndexes(rel);
/*
* Close the relation, but keep exclusive lock on it until commit.
@@ -1491,8 +1490,8 @@ heap_drop_with_catalog(const char *relname)
* remove indexes if necessary
* ----------------
*/
- if (rel->rd_rel->relhasindex)
- RelationRemoveIndexes(rel);
+ /* should ignore relhasindex */
+ RelationRemoveIndexes(rel);
/* ----------------
* remove rules if necessary
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 6040d09f24..b7d49ed3bc 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.104 2000/01/26 05:56:10 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.105 2000/02/18 09:28:41 inoue Exp $
*
*
* INTERFACE ROUTINES
@@ -44,6 +44,7 @@
#include "utils/relcache.h"
#include "utils/syscache.h"
#include "utils/temprel.h"
+#include "utils/inval.h"
/*
* macros used in guessing how many tuples are on a page.
@@ -75,6 +76,17 @@ static void DefaultBuild(Relation heapRelation, Relation indexRelation,
Datum *parameter, FuncIndexInfoPtr funcInfo, PredInfo *predInfo);
static Oid IndexGetRelation(Oid indexId);
+static bool reindexing = false;
+extern bool SetReindexProcessing(bool reindexmode)
+{
+ bool old = reindexing;
+ reindexing = reindexmode;
+ return old;
+}
+extern bool IsReindexProcessing(void)
+{
+ return reindexing;
+}
/* ----------------------------------------------------------------
* sysatts is a structure containing attribute tuple forms
* for system attributes (numbered -1, -2, ...). This really
@@ -484,7 +496,7 @@ UpdateRelationRelation(Relation indexRelation, char *temp_relname)
* just before exiting.
*/
- if (!IsBootstrapProcessingMode())
+ if (!IsIgnoringSystemIndexes())
{
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class, tuple);
@@ -569,7 +581,7 @@ AppendAttributeTuples(Relation indexRelation, int numatts)
(char *) (indexRelation->rd_att->attrs[0]));
hasind = false;
- if (!IsBootstrapProcessingMode() && pg_attribute->rd_rel->relhasindex)
+ if (!IsIgnoringSystemIndexes() && pg_attribute->rd_rel->relhasindex)
{
hasind = true;
CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
@@ -758,7 +770,7 @@ UpdateIndexRelation(Oid indexoid,
* insert the index tuple into the pg_index
* ----------------
*/
- if (!IsBootstrapProcessingMode())
+ if (!IsIgnoringSystemIndexes())
{
CatalogOpenIndices(Num_pg_index_indices, Name_pg_index_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_index_indices, pg_index, tuple);
@@ -956,6 +968,7 @@ index_create(char *heapRelationName,
* check parameters
* ----------------
*/
+ SetReindexProcessing(false);
if (numatts < 1)
elog(ERROR, "must index at least one attribute");
@@ -1271,12 +1284,217 @@ FormIndexDatum(int numberOfAttributes,
}
+/* --------------------------------------------
+ * Lock class info for update
+ * --------------------------------------------
+ */
+static
+bool LockClassinfoForUpdate(Oid relid, HeapTuple rtup, Buffer *buffer, bool confirmCommitted)
+{
+ HeapTuple classTuple;
+ Form_pg_class pgcform;
+ bool test;
+ Relation relationRelation;
+
+ classTuple = SearchSysCacheTuple(RELOID, PointerGetDatum(relid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(classTuple))
+ return false;
+ rtup->t_self = classTuple->t_self;
+ pgcform = (Form_pg_class) GETSTRUCT(classTuple);
+ relationRelation = heap_openr(RelationRelationName, RowShareLock);
+ test = heap_mark4update(relationRelation, rtup, buffer);
+ switch (test)
+ {
+ case HeapTupleSelfUpdated:
+ case HeapTupleMayBeUpdated:
+ break;
+ default:
+ elog(ERROR, "LockStatsForUpdate couldn't lock relid %u", relid);
+ return false;
+ }
+ RelationInvalidateHeapTuple(relationRelation, rtup);
+ if (confirmCommitted)
+ {
+ HeapTupleHeader th = rtup->t_data;
+ if (!(th->t_infomask & HEAP_XMIN_COMMITTED))
+ elog(ERROR, "The tuple isn't committed");
+ if (th->t_infomask & HEAP_XMAX_COMMITTED)
+ if (!(th->t_infomask & HEAP_MARKED_FOR_UPDATE))
+ elog(ERROR, "The tuple is already deleted");
+ }
+ heap_close(relationRelation, NoLock);
+ return true;
+}
+
+/* ---------------------------------------------
+ * Indexes of the relation active ?
+ * ---------------------------------------------
+ */
+bool IndexesAreActive(Oid relid, bool confirmCommitted)
+{
+ HeapTupleData tuple;
+ Relation indexRelation;
+ Buffer buffer;
+ HeapScanDesc scan;
+ ScanKeyData entry;
+ bool isactive;
+
+ if (!LockClassinfoForUpdate(relid, &tuple, &buffer, confirmCommitted))
+ elog(ERROR, "IndexesAreActive couldn't lock %u", relid);
+ if (((Form_pg_class) GETSTRUCT(&tuple))->relkind != RELKIND_RELATION)
+ elog(ERROR, "relation %u isn't an relation", relid);
+ isactive = ((Form_pg_class) GETSTRUCT(&tuple))->relhasindex;
+ ReleaseBuffer(buffer);
+ if (isactive)
+ return isactive;
+ indexRelation = heap_openr(IndexRelationName, AccessShareLock);
+ ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indrelid,
+ F_OIDEQ, ObjectIdGetDatum(relid));
+ scan = heap_beginscan(indexRelation, false, SnapshotNow,
+ 1, &entry);
+ if (!heap_getnext(scan, 0))
+ isactive = true;
+ heap_endscan(scan);
+ heap_close(indexRelation, NoLock);
+ return isactive;
+}
+
+/* ----------------
+ * set relhasindex of pg_class in place
+ * ----------------
+ */
+void
+setRelhasindexInplace(Oid relid, bool hasindex, bool immediate)
+{
+ Relation whichRel;
+ Relation pg_class;
+ HeapTuple tuple;
+ Form_pg_class rd_rel;
+ HeapScanDesc pg_class_scan = NULL;
+
+ /* ----------------
+ * This routine handles updates for only the heap relation
+ * hasindex. In order to guarantee that we're able to *see* the index
+ * relation tuple, we bump the command counter id here.
+ * ----------------
+ */
+ CommandCounterIncrement();
+
+ /* ----------------
+ * CommandCounterIncrement() flushes invalid cache entries, including
+ * those for the heap and index relations for which we're updating
+ * statistics. Now that the cache is flushed, it's safe to open the
+ * relation again. We need the relation open in order to figure out
+ * how many blocks it contains.
+ * ----------------
+ */
+
+ whichRel = heap_open(relid, ShareLock);
+
+ if (!RelationIsValid(whichRel))
+ elog(ERROR, "setRelhasindexInplace: cannot open relation id %u", relid);
+
+ /* ----------------
+ * Find the RELATION relation tuple for the given relation.
+ * ----------------
+ */
+ pg_class = heap_openr(RelationRelationName, RowExclusiveLock);
+ if (!RelationIsValid(pg_class))
+ elog(ERROR, "setRelhasindexInplace: could not open RELATION relation");
+
+ if (!IsIgnoringSystemIndexes())
+ {
+ tuple = SearchSysCacheTupleCopy(RELOID,
+ ObjectIdGetDatum(relid), 0, 0, 0);
+ }
+ else
+ {
+ ScanKeyData key[1];
+
+ ScanKeyEntryInitialize(&key[0], 0,
+ ObjectIdAttributeNumber,
+ F_OIDEQ,
+ ObjectIdGetDatum(relid));
+
+ pg_class_scan = heap_beginscan(pg_class, 0, SnapshotNow, 1, key);
+ tuple = heap_getnext(pg_class_scan, 0);
+ }
+
+ if (!HeapTupleIsValid(tuple))
+ {
+ if (pg_class_scan)
+ heap_endscan(pg_class_scan);
+ heap_close(pg_class, RowExclusiveLock);
+ elog(ERROR, "setRelhasindexInplace: cannot scan RELATION relation");
+ }
+ /*
+ * Confirm that target tuple is locked by this transaction
+ * in case of immedaite updation.
+ */
+ if (immediate)
+ {
+ HeapTupleHeader th = tuple->t_data;
+ if (!(th->t_infomask & HEAP_XMIN_COMMITTED))
+ elog(ERROR, "Immediate hasindex updation can be done only for committed tuples %x", th->t_infomask);
+ if (th->t_infomask & HEAP_XMAX_INVALID)
+ elog(ERROR, "Immediate hasindex updation can be done only for locked tuples %x", th->t_infomask);
+ if (th->t_infomask & HEAP_XMAX_COMMITTED)
+ elog(ERROR, "Immediate hasindex updation can be done only for locked tuples %x", th->t_infomask);
+ if (!(th->t_infomask & HEAP_MARKED_FOR_UPDATE))
+ elog(ERROR, "Immediate hasindex updation can be done only for locked tuples %x", th->t_infomask);
+ if (!(TransactionIdIsCurrentTransactionId(th->t_xmax)))
+ elog(ERROR, "The updating tuple is already locked by another backend");
+ }
+
+ /*
+ * We shouldn't have to do this, but we do... Modify the reldesc in
+ * place with the new values so that the cache contains the latest
+ * copy.
+ */
+ whichRel->rd_rel->relhasindex = hasindex;
+
+ /* ----------------
+ * Update hasindex in pg_class.
+ * ----------------
+ */
+ if (pg_class_scan)
+ {
+
+ if (!IsBootstrapProcessingMode())
+ ImmediateInvalidateSharedHeapTuple(pg_class, tuple);
+ rd_rel = (Form_pg_class) GETSTRUCT(tuple);
+ rd_rel->relhasindex = hasindex;
+ WriteNoReleaseBuffer(pg_class_scan->rs_cbuf);
+ }
+ else
+ {
+ HeapTupleData htup;
+ Buffer buffer;
+
+ htup.t_self = tuple->t_self;
+ heap_fetch(pg_class, SnapshotNow, &htup, &buffer);
+ ImmediateInvalidateSharedHeapTuple(pg_class, tuple);
+ rd_rel = (Form_pg_class) GETSTRUCT(&htup);
+ rd_rel->relhasindex = hasindex;
+ WriteBuffer(buffer);
+ }
+
+ if (!pg_class_scan)
+ heap_freetuple(tuple);
+ else
+ heap_endscan(pg_class_scan);
+
+ heap_close(pg_class, NoLock);
+ heap_close(whichRel, NoLock);
+}
+
/* ----------------
* UpdateStats
* ----------------
*/
void
-UpdateStats(Oid relid, long reltuples, bool hasindex)
+UpdateStats(Oid relid, long reltuples, bool inplace)
{
Relation whichRel;
Relation pg_class;
@@ -1289,7 +1507,8 @@ UpdateStats(Oid relid, long reltuples, bool hasindex)
Datum values[Natts_pg_class];
char nulls[Natts_pg_class];
char replace[Natts_pg_class];
- HeapScanDesc pg_class_scan = NULL;
+ HeapScanDesc pg_class_scan = NULL;
+ bool in_place_upd;
/* ----------------
* This routine handles updates for both the heap and index relation
@@ -1327,7 +1546,8 @@ UpdateStats(Oid relid, long reltuples, bool hasindex)
if (!RelationIsValid(pg_class))
elog(ERROR, "UpdateStats: could not open RELATION relation");
- if (!IsBootstrapProcessingMode())
+ in_place_upd = (inplace || IsBootstrapProcessingMode());
+ if (!in_place_upd)
{
tuple = SearchSysCacheTupleCopy(RELOID,
ObjectIdGetDatum(relid),
@@ -1348,7 +1568,7 @@ UpdateStats(Oid relid, long reltuples, bool hasindex)
if (!HeapTupleIsValid(tuple))
{
- if (IsBootstrapProcessingMode())
+ if (pg_class_scan)
heap_endscan(pg_class_scan);
heap_close(pg_class, RowExclusiveLock);
elog(ERROR, "UpdateStats: cannot scan RELATION relation");
@@ -1389,7 +1609,6 @@ UpdateStats(Oid relid, long reltuples, bool hasindex)
* place with the new values so that the cache contains the latest
* copy.
*/
- whichRel->rd_rel->relhasindex = hasindex;
whichRel->rd_rel->relpages = relpages;
whichRel->rd_rel->reltuples = reltuples;
@@ -1397,17 +1616,18 @@ UpdateStats(Oid relid, long reltuples, bool hasindex)
* Update statistics in pg_class.
* ----------------
*/
- if (IsBootstrapProcessingMode())
+ if (in_place_upd)
{
/*
* At bootstrap time, we don't need to worry about concurrency or
* visibility of changes, so we cheat.
*/
+ if (!IsBootstrapProcessingMode())
+ ImmediateInvalidateSharedHeapTuple(pg_class, tuple);
rd_rel = (Form_pg_class) GETSTRUCT(tuple);
rd_rel->relpages = relpages;
rd_rel->reltuples = reltuples;
- rd_rel->relhasindex = hasindex;
WriteNoReleaseBuffer(pg_class_scan->rs_cbuf);
}
else
@@ -1425,18 +1645,18 @@ UpdateStats(Oid relid, long reltuples, bool hasindex)
values[Anum_pg_class_relpages - 1] = (Datum) relpages;
replace[Anum_pg_class_reltuples - 1] = 'r';
values[Anum_pg_class_reltuples - 1] = (Datum) reltuples;
- replace[Anum_pg_class_relhasindex - 1] = 'r';
- values[Anum_pg_class_relhasindex - 1] = CharGetDatum(hasindex);
-
newtup = heap_modifytuple(tuple, pg_class, values, nulls, replace);
heap_update(pg_class, &tuple->t_self, newtup, NULL);
- CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
- CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class, newtup);
- CatalogCloseIndices(Num_pg_class_indices, idescs);
+ if (!IsIgnoringSystemIndexes())
+ {
+ CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class, newtup);
+ CatalogCloseIndices(Num_pg_class_indices, idescs);
+ }
heap_freetuple(newtup);
}
- if (!IsBootstrapProcessingMode())
+ if (!pg_class_scan)
heap_freetuple(tuple);
else
heap_endscan(pg_class_scan);
@@ -1668,16 +1888,18 @@ DefaultBuild(Relation heapRelation,
{
Oid hrelid = RelationGetRelid(heapRelation);
Oid irelid = RelationGetRelid(indexRelation);
+ bool inplace = IsReindexProcessing();
heap_close(heapRelation, NoLock);
index_close(indexRelation);
- UpdateStats(hrelid, reltuples, true);
- UpdateStats(irelid, indtuples, false);
+ UpdateStats(hrelid, reltuples, inplace);
+ UpdateStats(irelid, indtuples, inplace);
if (oldPred != NULL)
{
if (indtuples == reltuples)
predicate = NULL;
- UpdateIndexPredicate(irelid, oldPred, predicate);
+ if (!inplace)
+ UpdateIndexPredicate(irelid, oldPred, predicate);
}
}
}
@@ -1826,3 +2048,226 @@ IndexIsUniqueNoCache(Oid indexId)
heap_close(pg_index, AccessShareLock);
return isunique;
}
+
+
+/* ---------------------------------
+ * activate_index -- activate/deactivate the specified index.
+ * Note that currelntly PostgreSQL doesn't hold the
+ * status per index
+ * ---------------------------------
+ */
+bool
+activate_index(Oid indexId, bool activate)
+{
+ if (!activate) /* Currently does nothing */
+ return true;
+ return reindex_index(indexId, false);
+}
+
+/* --------------------------------
+ * reindex_index - This routine is used to recreate an index
+ * --------------------------------
+ */
+bool
+reindex_index(Oid indexId, bool force)
+{
+ Relation iRel, indexRelation, heapRelation;
+ ScanKeyData entry;
+ HeapScanDesc scan;
+ HeapTuple indexTuple, procTuple, classTuple;
+ Form_pg_index index;
+ Oid heapId, procId, accessMethodId;
+ Node *oldPred = NULL;
+ PredInfo *predInfo;
+ List *cnfPred = NULL;
+ AttrNumber *attributeNumberA;
+ FuncIndexInfo fInfo, *funcInfo = NULL;
+ int i, numberOfAttributes;
+ char *predString;
+ bool old;
+
+ old = SetReindexProcessing(true);
+ /* Scan pg_index to find indexes on heapRelation */
+ indexRelation = heap_openr(IndexRelationName, AccessShareLock);
+ ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indexrelid, F_OIDEQ,
+ ObjectIdGetDatum(indexId));
+ scan = heap_beginscan(indexRelation, false, SnapshotNow, 1, &entry);
+ indexTuple = heap_getnext(scan, 0);
+ if (!HeapTupleIsValid(indexTuple))
+ elog(ERROR, "reindex_index index %d tuple is invalid", indexId);
+
+ /*
+ * For the index, fetch index attributes so we can apply index_build
+ */
+ index = (Form_pg_index) GETSTRUCT(indexTuple);
+ heapId = index->indrelid;
+ procId = index->indproc;
+
+ for (i = 0; i < INDEX_MAX_KEYS; i++)
+ {
+ if (index->indkey[i] == InvalidAttrNumber)
+ break;
+ }
+ numberOfAttributes = i;
+
+ /* If a valid where predicate, compute predicate Node */
+ if (VARSIZE(&index->indpred) != 0)
+ {
+ predString = fmgr(F_TEXTOUT, &index->indpred);
+ oldPred = stringToNode(predString);
+ pfree(predString);
+ }
+ predInfo = (PredInfo *) palloc(sizeof(PredInfo));
+ predInfo->pred = (Node *) cnfPred;
+ predInfo->oldPred = oldPred;
+
+ /* Assign Index keys to attributes array */
+ attributeNumberA = (AttrNumber *) palloc(numberOfAttributes * sizeof(AttrNumber));
+ for (i = 0; i < numberOfAttributes; i++)
+ attributeNumberA[i] = index->indkey[i];
+
+ /* If this is a procedural index, initialize our FuncIndexInfo */
+ if (procId != InvalidOid)
+ {
+ funcInfo = &fInfo;
+ FIsetnArgs(funcInfo, numberOfAttributes);
+ procTuple = SearchSysCacheTuple(PROCOID, ObjectIdGetDatum(procId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(procTuple))
+ elog(ERROR, "RelationTruncateIndexes: index procedure not found");
+ namecpy(&(funcInfo->funcName),
+ &(((Form_pg_proc) GETSTRUCT(procTuple))->proname));
+ FIsetProcOid(funcInfo, procTuple->t_data->t_oid);
+ }
+
+ /* Fetch the classTuple associated with this index */
+ classTuple = SearchSysCacheTupleCopy(RELOID, ObjectIdGetDatum(indexId), 0, 0, 0);
+ if (!HeapTupleIsValid(classTuple))
+ elog(ERROR, "RelationTruncateIndexes: index access method not found");
+ accessMethodId = ((Form_pg_class) GETSTRUCT(classTuple))->relam;
+
+ /* Open our index relation */
+ iRel = index_open(indexId);
+ if (iRel == NULL)
+ elog(ERROR, "reindex_index: can't open index relation");
+ heapRelation = heap_open(heapId, ExclusiveLock);
+ if (heapRelation == NULL)
+ elog(ERROR, "reindex_index: can't open heap relation");
+
+ /* Obtain exclusive lock on it, just to be sure */
+ LockRelation(iRel, AccessExclusiveLock);
+
+ /*
+ * Release any buffers associated with this index. If they're dirty,
+ * they're just dropped without bothering to flush to disk.
+ */
+ ReleaseRelationBuffers(iRel);
+ if (FlushRelationBuffers(iRel, (BlockNumber) 0, false) < 0)
+ elog(ERROR, "reindex_index: unable to flush index from buffer pool");
+
+ /* Now truncate the actual data and set blocks to zero */
+ smgrtruncate(DEFAULT_SMGR, iRel, 0);
+ iRel->rd_nblocks = 0;
+
+ /* Initialize the index and rebuild */
+ InitIndexStrategy(numberOfAttributes, iRel, accessMethodId);
+ index_build(heapRelation, iRel, numberOfAttributes,
+ attributeNumberA, 0, NULL, funcInfo, predInfo);
+
+ /*
+ * index_build will close both the heap and index relations
+ * (but not give up the locks we hold on them). That's fine
+ * for the index, but we need to open the heap again. We need
+ * no new lock, since this backend still has the exclusive lock
+ * grabbed by heap_truncate.
+ */
+ iRel = index_open(indexId);
+ Assert(iRel != NULL);
+
+ /* Complete the scan and close pg_index */
+ heap_endscan(scan);
+ heap_close(indexRelation, AccessShareLock);
+ SetReindexProcessing(old);
+ return true;
+}
+
+/*
+ * ----------------------------
+ * activate_indexes_of_a_table
+ * activate/deactivate indexes of the specified table.
+ * ----------------------------
+ */
+bool
+activate_indexes_of_a_table(Oid relid, bool activate)
+{
+ if (IndexesAreActive(relid, true))
+ {
+ if (!activate)
+ setRelhasindexInplace(relid, false, true);
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (activate)
+ reindex_relation(relid, false);
+ else
+ {
+ return false;
+ }
+ }
+ return true;
+}
+/* --------------------------------
+ * reindex_relation - This routine is used to recreate indexes
+ * of a relation.
+ * --------------------------------
+ */
+bool
+reindex_relation(Oid relid, bool force)
+{
+ Relation indexRelation;
+ ScanKeyData entry;
+ HeapScanDesc scan;
+ HeapTuple indexTuple;
+ bool old, reindexed;
+
+ old = SetReindexProcessing(true);
+ if (IndexesAreActive(relid, true))
+ {
+ if (!force)
+ {
+ SetReindexProcessing(old);
+ return false;
+ }
+ activate_indexes_of_a_table(relid, false);
+ }
+
+ indexRelation = heap_openr(IndexRelationName, AccessShareLock);
+ ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indrelid,
+ F_OIDEQ, ObjectIdGetDatum(relid));
+ scan = heap_beginscan(indexRelation, false, SnapshotNow,
+ 1, &entry);
+ reindexed = false;
+ while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0)))
+ {
+ Form_pg_index index = (Form_pg_index) GETSTRUCT(indexTuple);
+ if (activate_index(index->indexrelid, true))
+ reindexed = true;
+ else
+ {
+ reindexed = false;
+ break;
+ }
+ }
+ heap_endscan(scan);
+ heap_close(indexRelation, AccessShareLock);
+ if (reindexed)
+ {
+ setRelhasindexInplace(relid, true, false);
+ }
+ SetReindexProcessing(old);
+ return true;
+}
diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c
index 2afd6b6909..41337da77f 100644
--- a/src/backend/catalog/indexing.c
+++ b/src/backend/catalog/indexing.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.58 2000/01/26 05:56:10 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.59 2000/02/18 09:28:41 inoue Exp $
*
*-------------------------------------------------------------------------
*/
@@ -92,6 +92,8 @@ CatalogOpenIndices(int nIndices, char **names, Relation *idescs)
{
int i;
+ if (IsIgnoringSystemIndexes())
+ return;
for (i = 0; i < nIndices; i++)
idescs[i] = index_openr(names[i]);
}
@@ -104,6 +106,8 @@ CatalogCloseIndices(int nIndices, Relation *idescs)
{
int i;
+ if (IsIgnoringSystemIndexes())
+ return;
for (i = 0; i < nIndices; i++)
index_close(idescs[i]);
}
@@ -131,6 +135,8 @@ CatalogIndexInsert(Relation *idescs,
*finfoP;
int i;
+ if (IsIgnoringSystemIndexes())
+ return;
heapDescriptor = RelationGetDescr(heapRelation);
for (i = 0; i < nIndices; i++)