Implement reindex command
authorHiroshi Inoue <inoue@tpf.co.jp>
Fri, 18 Feb 2000 09:30:20 +0000 (09:30 +0000)
committerHiroshi Inoue <inoue@tpf.co.jp>
Fri, 18 Feb 2000 09:30:20 +0000 (09:30 +0000)
29 files changed:
src/backend/access/index/istrat.c
src/backend/access/nbtree/nbtree.c
src/backend/access/transam/xact.c
src/backend/bootstrap/bootstrap.c
src/backend/catalog/heap.c
src/backend/catalog/index.c
src/backend/catalog/indexing.c
src/backend/commands/indexcmds.c
src/backend/commands/trigger.c
src/backend/commands/vacuum.c
src/backend/executor/execUtils.c
src/backend/executor/nodeIndexscan.c
src/backend/optimizer/util/plancat.c
src/backend/parser/gram.y
src/backend/parser/keywords.c
src/backend/postmaster/postmaster.c
src/backend/tcop/postgres.c
src/backend/tcop/utility.c
src/backend/utils/adt/regproc.c
src/backend/utils/cache/catcache.c
src/backend/utils/cache/relcache.c
src/backend/utils/cache/syscache.c
src/backend/utils/init/miscinit.c
src/include/catalog/index.h
src/include/commands/defrem.h
src/include/miscadmin.h
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/include/utils/portal.h

index ef188d0e41257997264bceb9eb19718cdae1ee8c..fe956ead378aa133c6bc8650239103283b4712ce 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.40 2000/01/26 05:55:57 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.41 2000/02/18 09:29:16 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -477,8 +477,9 @@ OperatorRelationFillScanKeyEntry(Relation operatorRelation,
 {
    HeapTuple   tuple;
    HeapScanDesc scan = NULL;
+   bool    cachesearch = (!IsBootstrapProcessingMode()) && IsCacheInitialized();
 
-   if (!IsBootstrapProcessingMode())
+   if (cachesearch)
    {
        tuple = SearchSysCacheTuple(OPEROID,
                                    ObjectIdGetDatum(operatorObjectId),
@@ -501,7 +502,7 @@ OperatorRelationFillScanKeyEntry(Relation operatorRelation,
 
    if (!HeapTupleIsValid(tuple))
    {
-       if (IsBootstrapProcessingMode())
+       if (!cachesearch)
            heap_endscan(scan);
        elog(ERROR, "OperatorObjectIdFillScanKeyEntry: unknown operator %u",
             operatorObjectId);
@@ -512,7 +513,7 @@ OperatorRelationFillScanKeyEntry(Relation operatorRelation,
    fmgr_info(entry->sk_procedure, &entry->sk_func);
    entry->sk_nargs = entry->sk_func.fn_nargs;
 
-   if (IsBootstrapProcessingMode())
+   if (!cachesearch)
        heap_endscan(scan);
 
    if (!RegProcedureIsValid(entry->sk_procedure))
@@ -546,8 +547,9 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
    AttrNumber  attributeNumber;
    int         attributeIndex;
    Oid         operatorClassObjectId[INDEX_MAX_KEYS];
+   bool    cachesearch = (!IsBootstrapProcessingMode()) && IsCacheInitialized();
 
-   if (!IsBootstrapProcessingMode())
+   if (cachesearch)
    {
        tuple = SearchSysCacheTuple(INDEXRELID,
                                    ObjectIdGetDatum(indexObjectId),
@@ -589,7 +591,7 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
        operatorClassObjectId[attributeIndex] = iform->indclass[attributeIndex];
    }
 
-   if (IsBootstrapProcessingMode())
+   if (!cachesearch)
    {
        heap_endscan(scan);
        heap_close(relation, AccessShareLock);
index fa8decce1300fb89596d44413ee9e88e35dcf12e..da5dd70332e5b07a5552b309a98d52828298f684 100644 (file)
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.52 2000/01/26 05:55:58 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.53 2000/02/18 09:29:54 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -310,16 +310,22 @@ btbuild(Relation heap,
    {
        Oid     hrelid = RelationGetRelid(heap);
        Oid     irelid = RelationGetRelid(index);
+       bool        inplace = IsReindexProcessing();
 
        heap_close(heap, NoLock);
        index_close(index);
+       /*
        UpdateStats(hrelid, nhtups, true);
        UpdateStats(irelid, nitups, false);
+       */
+       UpdateStats(hrelid, nhtups, inplace);
+       UpdateStats(irelid, nitups, inplace);
        if (oldPred != NULL)
        {
            if (nitups == nhtups)
                pred = NULL;
-           UpdateIndexPredicate(irelid, oldPred, pred);
+           if (!inplace)
+               UpdateIndexPredicate(irelid, oldPred, pred);
        }
    }
 
index 58e17445586d454ca7bfb77f62180e62f54c3027..e5b521b67cfc158ea1ec3049a863e6dc959f6883 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.60 2000/01/29 16:58:29 petere Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.61 2000/02/18 09:30:20 inoue Exp $
  *
  * NOTES
  *     Transaction aborts can now occur two ways:
 
 #include "access/nbtree.h"
 #include "catalog/heap.h"
+#include "catalog/index.h"
 #include "commands/async.h"
 #include "commands/sequence.h"
 #include "commands/vacuum.h"
@@ -850,6 +851,7 @@ StartTransaction()
     */
    s->state = TRANS_START;
 
+   SetReindexProcessing(false);
    /* ----------------
     *  generate a new transaction id
     * ----------------
@@ -1046,8 +1048,8 @@ AbortTransaction()
    AtAbort_Notify();
    CloseSequences();
    AtEOXact_portals();
-   if (VacuumRunning)
-       vc_abort();
+   if (CommonSpecialPortalIsOpen())
+       CommonSpecialPortalClose();
    RecordTransactionAbort();
    RelationPurgeLocalRelation(false);
    DropNoNameRels();
index e8afa33de2cf7afd5447c0bc1804115034480b6b..8e129a460a9e56cb6b33ba66f5f1d17d98215f39 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.79 2000/01/26 05:56:07 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.80 2000/02/18 09:28:39 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -292,6 +292,7 @@ BootstrapMain(int argc, char *argv[])
        dbName = argv[optind];
 
    SetProcessingMode(BootstrapProcessing);
+   IgnoreSystemIndexes(true);
 
    if (!DataDir)
    {
index 2840e40633f5c63319bc405a6de8161c4e55f281..271dc3ed9789ba2423782ee8dcaadddcbf011769 100644 (file)
@@ -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
index 6040d09f24a09c89b98f69440c1b5f5b06ebb0af..b7d49ed3bc8c6f927cd989bbc17a9b01a5c52514 100644 (file)
@@ -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;
+}
index 2afd6b69097d44a80f13515ac4d6331c974689a1..41337da77f8a469b682fc764b24d857fc97a18fd 100644 (file)
@@ -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++)
index f5de425b2bb95b97237933a468228a7c34157e47..cbd7b26ae8ad2370693b03d1fd624bb7d8972bb2 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.20 2000/01/26 05:56:13 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.21 2000/02/18 09:29:37 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 #include "access/genam.h"
 #include "access/heapam.h"
+#include "catalog/catname.h"
 #include "catalog/heap.h"
 #include "catalog/index.h"
 #include "catalog/pg_index.h"
 #include "catalog/pg_opclass.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_type.h"
+#include "catalog/pg_database.h"
+#include "catalog/pg_shadow.h"
 #include "commands/defrem.h"
 #include "optimizer/clauses.h"
 #include "optimizer/planmain.h"
@@ -30,6 +33,9 @@
 #include "parser/parsetree.h"
 #include "utils/builtins.h"
 #include "utils/syscache.h"
+#include "miscadmin.h" /* ReindexDatabase() */
+#include "utils/portal.h" /* ReindexDatabase() */
+#include "catalog/catalog.h" /* ReindexDatabase() */
 
 #define IsFuncIndex(ATTR_LIST) (((IndexElem*)lfirst(ATTR_LIST))->args!=NULL)
 
@@ -149,6 +155,8 @@ DefineIndex(char *heapRelationName,
        CheckPredicate(cnfPred, rangetable, relationId);
    }
 
+   if (!IsBootstrapProcessingMode() && !IndexesAreActive(relationId, false))
+       elog(ERROR, "existent indexes are inactive. REINDEX first");
    if (IsFuncIndex(attributeList))
    {
        IndexElem  *funcIndex = lfirst(attributeList);
@@ -195,6 +203,7 @@ DefineIndex(char *heapRelationName,
             classObjectId, parameterCount, parameterA, (Node *) cnfPred,
                     lossy, unique, primary);
    }
+   setRelhasindexInplace(relationId, true, false);
 }
 
 
@@ -570,3 +579,163 @@ RemoveIndex(char *name)
 
    index_drop(tuple->t_data->t_oid);
 }
+
+/*
+ * Reindex
+ *     Recreate an index.
+ *
+ * Exceptions:
+ *     "ERROR" if index nonexistent.
+ *     ...
+ */
+void
+ReindexIndex(const char *name, bool force /* currently unused */)
+{
+   HeapTuple   tuple;
+
+   tuple = SearchSysCacheTuple(RELNAME,
+                               PointerGetDatum(name),
+                               0, 0, 0);
+
+   if (!HeapTupleIsValid(tuple))
+       elog(ERROR, "index \"%s\" nonexistent", name);
+
+   if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_INDEX)
+   {
+       elog(ERROR, "relation \"%s\" is of type \"%c\"",
+            name,
+            ((Form_pg_class) GETSTRUCT(tuple))->relkind);
+   }
+
+   reindex_index(tuple->t_data->t_oid, force);
+}
+
+/*
+ * ReindexTable
+ *     Recreate indexes of a table.
+ *
+ * Exceptions:
+ *     "ERROR" if table nonexistent.
+ *     ...
+ */
+void
+ReindexTable(const char *name, bool force)
+{
+   HeapTuple   tuple;
+
+   tuple = SearchSysCacheTuple(RELNAME,
+                               PointerGetDatum(name),
+                               0, 0, 0);
+
+   if (!HeapTupleIsValid(tuple))
+       elog(ERROR, "table \"%s\" nonexistent", name);
+
+   if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_RELATION)
+   {
+       elog(ERROR, "relation \"%s\" is of type \"%c\"",
+            name,
+            ((Form_pg_class) GETSTRUCT(tuple))->relkind);
+   }
+
+   reindex_relation(tuple->t_data->t_oid, force);
+}
+
+/*
+ * ReindexDatabase
+ *     Recreate indexes of a database.
+ *
+ * Exceptions:
+ *     "ERROR" if table nonexistent.
+ *     ...
+ */
+extern Oid MyDatabaseId;
+void
+ReindexDatabase(const char *dbname, bool force, bool all)
+{
+   Relation    relation, relationRelation;
+   HeapTuple   usertuple, dbtuple, tuple;
+   HeapScanDesc    scan;
+   int4        user_id, db_owner;
+   bool        superuser;
+   Oid     db_id;
+   char        *username;
+   ScanKeyData scankey;
+   PortalVariableMemory    pmem;
+   MemoryContext   old;
+   int     relcnt, relalc, i, oncealc = 200;
+   Oid     *relids = (Oid *) NULL;
+
+   AssertArg(dbname);
+
+   username = GetPgUserName();
+   usertuple = SearchSysCacheTuple(SHADOWNAME, PointerGetDatum(username),
+               0, 0, 0);
+   if (!HeapTupleIsValid(usertuple))
+       elog(ERROR, "Current user '%s' is invalid.", username);
+   user_id = ((Form_pg_shadow) GETSTRUCT(usertuple))->usesysid;
+   superuser = ((Form_pg_shadow) GETSTRUCT(usertuple))->usesuper;
+
+   relation = heap_openr(DatabaseRelationName, AccessShareLock);
+   ScanKeyEntryInitialize(&scankey, 0, Anum_pg_database_datname,
+           F_NAMEEQ, NameGetDatum(dbname));
+   scan = heap_beginscan(relation, 0, SnapshotNow, 1, &scankey);
+   dbtuple = heap_getnext(scan, 0);
+   if (!HeapTupleIsValid(dbtuple))
+       elog(ERROR, "Database '%s' doesn't exist", dbname);
+   db_id = dbtuple->t_data->t_oid;
+   db_owner = ((Form_pg_database) GETSTRUCT(dbtuple))->datdba;
+   heap_endscan(scan);
+   if (user_id != db_owner && !superuser)
+       elog(ERROR, "REINDEX DATABASE: Permission denied.");
+
+   if (db_id != MyDatabaseId)
+       elog(ERROR, "REINDEX DATABASE: Can be executed only on the currently open database.");
+
+   heap_close(relation, NoLock);
+   /** reindex_database(db_id, force, !all); **/
+
+   CommonSpecialPortalOpen();
+   pmem = CommonSpecialPortalGetMemory();
+   relationRelation = heap_openr(RelationRelationName, AccessShareLock);
+   scan = heap_beginscan(relationRelation, false, SnapshotNow, 0, NULL);
+   relcnt = relalc = 0;
+   while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
+   {
+       if (!all)
+       {
+           if (!IsSystemRelationName(NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname)))
+               continue;
+           if (((Form_pg_class) GETSTRUCT(tuple))->relhasrules)
+               continue;
+       }
+       if (((Form_pg_class) GETSTRUCT(tuple))->relkind == RELKIND_RELATION)
+       {
+           old = MemoryContextSwitchTo((MemoryContext) pmem);
+           if (relcnt == 0)
+           {
+               relalc = oncealc;
+               relids = palloc(sizeof(Oid) * relalc);
+           }
+           else if (relcnt >= relalc)
+           {
+               relalc *= 2;
+               relids = repalloc(relids, sizeof(Oid) * relalc);
+           }
+           MemoryContextSwitchTo(old);
+           relids[relcnt] = tuple->t_data->t_oid;
+           relcnt++;
+       }
+   }
+   heap_endscan(scan);
+   heap_close(relationRelation, AccessShareLock);
+
+   CommitTransactionCommand();
+   for (i = 0; i < relcnt; i++)
+   {
+       StartTransactionCommand();
+       reindex_relation(relids[i], force);
+       CommitTransactionCommand();
+   }
+   CommonSpecialPortalClose();
+   StartTransactionCommand();
+}
index 0b0b3cf2ece8e25a0b74b9d95eb79d5619076c00..9a4286a500ac4633c03b25f56a34c742d52c88e0 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.60 2000/02/13 13:21:10 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.61 2000/02/18 09:29:37 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -433,15 +433,18 @@ RelationBuildTriggers(Relation relation)
    Trigger    *build;
    Relation    tgrel;
    Form_pg_trigger pg_trigger;
-   Relation    irel;
+   Relation    irel = (Relation) NULL;
    ScanKeyData skey;
    HeapTupleData tuple;
-   IndexScanDesc sd;
+   IndexScanDesc   sd = (IndexScanDesc) NULL;
+   HeapScanDesc    tgscan = (HeapScanDesc) NULL;
+   HeapTuple   htup;
    RetrieveIndexResult indexRes;
    Buffer      buffer;
    struct varlena *val;
    bool        isnull;
    int         found;
+   bool        hasindex;
 
    MemSet(trigdesc, 0, sizeof(TriggerDesc));
 
@@ -452,25 +455,41 @@ RelationBuildTriggers(Relation relation)
                           ObjectIdGetDatum(RelationGetRelid(relation)));
 
    tgrel = heap_openr(TriggerRelationName, AccessShareLock);
-   irel = index_openr(TriggerRelidIndex);
-   sd = index_beginscan(irel, false, 1, &skey);
+   hasindex = (tgrel->rd_rel->relhasindex && !IsIgnoringSystemIndexes());
+   if (hasindex)
+   {
+       irel = index_openr(TriggerRelidIndex);
+       sd = index_beginscan(irel, false, 1, &skey);
+   }
+   else
+       tgscan = heap_beginscan(tgrel, 0, SnapshotNow, 1, &skey);
 
    for (found = 0;;)
    {
-       indexRes = index_getnext(sd, ForwardScanDirection);
-       if (!indexRes)
-           break;
+       if (hasindex)
+       {
+           indexRes = index_getnext(sd, ForwardScanDirection);
+           if (!indexRes)
+               break;
 
-       tuple.t_self = indexRes->heap_iptr;
-       heap_fetch(tgrel, SnapshotNow, &tuple, &buffer);
-       pfree(indexRes);
-       if (!tuple.t_data)
-           continue;
+           tuple.t_self = indexRes->heap_iptr;
+           heap_fetch(tgrel, SnapshotNow, &tuple, &buffer);
+           pfree(indexRes);
+           if (!tuple.t_data)
+               continue;
+           htup = &tuple;
+       }
+       else
+       {
+           htup = heap_getnext(tgscan, 0);
+           if (!HeapTupleIsValid(htup))
+               break;
+       }
        if (found == ntrigs)
            elog(ERROR, "RelationBuildTriggers: unexpected record found for rel %s",
                 RelationGetRelationName(relation));
 
-       pg_trigger = (Form_pg_trigger) GETSTRUCT(&tuple);
+       pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
 
        if (triggers == NULL)
            triggers = (Trigger *) palloc(sizeof(Trigger));
@@ -478,7 +497,7 @@ RelationBuildTriggers(Relation relation)
            triggers = (Trigger *) repalloc(triggers, (found + 1) * sizeof(Trigger));
        build = &(triggers[found]);
 
-       build->tgoid = tuple.t_data->t_oid;
+       build->tgoid = htup->t_data->t_oid;
        build->tgname = nameout(&pg_trigger->tgname);
        build->tgfoid = pg_trigger->tgfoid;
        build->tgfunc.fn_addr = NULL;
@@ -489,7 +508,7 @@ RelationBuildTriggers(Relation relation)
        build->tginitdeferred = pg_trigger->tginitdeferred;
        build->tgnargs = pg_trigger->tgnargs;
        memcpy(build->tgattr, &(pg_trigger->tgattr), FUNC_MAX_ARGS * sizeof(int16));
-       val = (struct varlena *) fastgetattr(&tuple,
+       val = (struct varlena *) fastgetattr(htup,
                                             Anum_pg_trigger_tgargs,
                                             tgrel->rd_att, &isnull);
        if (isnull)
@@ -500,7 +519,7 @@ RelationBuildTriggers(Relation relation)
            char       *p;
            int         i;
 
-           val = (struct varlena *) fastgetattr(&tuple,
+           val = (struct varlena *) fastgetattr(htup,
                                                 Anum_pg_trigger_tgargs,
                                                 tgrel->rd_att, &isnull);
            if (isnull)
@@ -518,7 +537,8 @@ RelationBuildTriggers(Relation relation)
            build->tgargs = NULL;
 
        found++;
-       ReleaseBuffer(buffer);
+       if (hasindex)
+           ReleaseBuffer(buffer);
    }
 
    if (found < ntrigs)
@@ -526,8 +546,13 @@ RelationBuildTriggers(Relation relation)
             ntrigs - found,
             RelationGetRelationName(relation));
 
-   index_endscan(sd);
-   index_close(irel);
+   if (hasindex)
+   {
+       index_endscan(sd);
+       index_close(irel);
+   }
+   else
+       heap_endscan(tgscan);
    heap_close(tgrel, AccessShareLock);
 
    /* Build trigdesc */
@@ -1460,7 +1485,7 @@ void
 DeferredTriggerSetState(ConstraintsSetStmt *stmt)
 {
    Relation                tgrel;
-   Relation                irel;
+   Relation                irel = (Relation) NULL;
    List                    *l;
    List                    *ls;
    List                    *lnext;
@@ -1468,6 +1493,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
    MemoryContext           oldcxt;
    bool                    found;
    DeferredTriggerStatus   state;
+   bool            hasindex;
 
    /* ----------
     * Handle SET CONSTRAINTS ALL ...
@@ -1548,13 +1574,17 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
     * ----------
     */
    tgrel = heap_openr(TriggerRelationName, AccessShareLock);
-   irel = index_openr(TriggerConstrNameIndex);
+   hasindex = (tgrel->rd_rel->relhasindex && !IsIgnoringSystemIndexes());
+   if (hasindex)
+       irel = index_openr(TriggerConstrNameIndex);
 
    foreach (l, stmt->constraints)
    {
        ScanKeyData         skey;
        HeapTupleData       tuple;
-       IndexScanDesc       sd;
+       IndexScanDesc       sd = (IndexScanDesc) NULL;
+       HeapScanDesc        tgscan = (HeapScanDesc) NULL;
+       HeapTuple       htup;
        RetrieveIndexResult indexRes;
        Buffer              buffer;
        Form_pg_trigger     pg_trigger;
@@ -1577,7 +1607,10 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
                               (RegProcedure) F_NAMEEQ,
                               PointerGetDatum((char *)lfirst(l)));
 
-       sd = index_beginscan(irel, false, 1, &skey);
+       if (hasindex)
+           sd = index_beginscan(irel, false, 1, &skey);
+       else
+           tgscan = heap_beginscan(tgrel, 0, SnapshotNow, 1, &skey);
 
        /* ----------
         * ... and search for the constraint trigger row
@@ -1586,33 +1619,43 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
        found = false;
        for (;;)
        {
-           indexRes = index_getnext(sd, ForwardScanDirection);
-           if (!indexRes)
-               break;
+           if (hasindex)
+           {
+               indexRes = index_getnext(sd, ForwardScanDirection);
+               if (!indexRes)
+                   break;
 
-           tuple.t_self = indexRes->heap_iptr;
-           heap_fetch(tgrel, SnapshotNow, &tuple, &buffer);
-           pfree(indexRes);
-           if (!tuple.t_data)
+               tuple.t_self = indexRes->heap_iptr;
+               heap_fetch(tgrel, SnapshotNow, &tuple, &buffer);
+               pfree(indexRes);
+               if (!tuple.t_data)
+               {
+                   continue;
+               }
+               htup = &tuple;
+           }
+           else
            {
-               ReleaseBuffer(buffer);
-               continue;
+               htup = heap_getnext(tgscan, 0);
+               if (!HeapTupleIsValid(htup))
+                   break;
            }
 
            /* ----------
             * If we found some, check that they fit the deferrability
             * ----------
             */
-           pg_trigger = (Form_pg_trigger) GETSTRUCT(&tuple);
+           pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
            if (stmt->deferred & !pg_trigger->tgdeferrable)
                elog(ERROR, "Constraint '%s' is not deferrable",
                                    (char *)lfirst(l));
 
-           constr_oid = tuple.t_data->t_oid;
+           constr_oid = htup->t_data->t_oid;
            loid = lappend(loid, (Node *)constr_oid);
            found = true;
 
-           ReleaseBuffer(buffer);
+           if (hasindex)
+               ReleaseBuffer(buffer);
        }
 
        /* ----------
@@ -1622,9 +1665,13 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
        if (!found)
            elog(ERROR, "Constraint '%s' does not exist", (char *)lfirst(l));
 
-       index_endscan(sd);
+       if (hasindex)
+           index_endscan(sd);
+       else    
+           heap_endscan(tgscan);
    }
-   index_close(irel);
+   if (hasindex)
+       index_close(irel);
    heap_close(tgrel, AccessShareLock);
 
 
index 5274be3bdf3536f1ccd87c238e38534e4c1db15c..ef84459a7145033663f753530a345badb891802b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.138 2000/01/26 05:56:13 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.139 2000/02/18 09:29:37 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -51,7 +51,7 @@
 #endif
 
 
-bool       VacuumRunning = false;
+bool       CommonSpecialPortalInUse = false;
 
 static Portal vc_portal;
 
@@ -99,6 +99,53 @@ static bool vc_enough_space(VPageDescr vpd, Size len);
 static char *vc_show_rusage(struct rusage * ru0);
 
 
+/*
+ * This routines handle a special cross-transaction portal.
+ * However it is automatically closed in case of abort. 
+ */
+void CommonSpecialPortalOpen(void)
+{
+   char       *pname;
+
+   /*
+    * Create a portal for safe memory across transactions. We need to
+    * palloc the name space for it because our hash function expects the
+    * name to be on a longword boundary.  CreatePortal copies the name to
+    * safe storage for us.
+    */
+   pname = pstrdup(VACPNAME);
+   vc_portal = CreatePortal(pname);
+   pfree(pname);
+
+   /*
+    * Set flag to indicate that vc_portal must be removed after an error.
+    * This global variable is checked in the transaction manager on xact
+    * abort, and the routine CommonSpecialPortalClose() is called if
+    * necessary.
+    */
+   CommonSpecialPortalInUse = true;
+}
+
+void CommonSpecialPortalClose(void)
+{
+   /* Clear flag first, to avoid recursion if PortalDrop elog's */
+   CommonSpecialPortalInUse = false;
+
+   /*
+    * Release our portal for cross-transaction memory.
+    */
+   PortalDrop(&vc_portal);
+}
+
+PortalVariableMemory CommonSpecialPortalGetMemory(void)
+{
+   return PortalGetVariableMemory(vc_portal);
+}
+bool CommonSpecialPortalIsOpen(void)
+{
+   return CommonSpecialPortalInUse;
+} 
 void
 vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec)
 {
@@ -136,7 +183,7 @@ vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec)
        strcpy(NameStr(VacRel), vacrel);
 
    /* must also copy the column list, if any, to safe storage */
-   pmem = PortalGetVariableMemory(vc_portal);
+   pmem = CommonSpecialPortalGetMemory();
    old = MemoryContextSwitchTo((MemoryContext) pmem);
    foreach(le, va_spec)
    {
@@ -179,24 +226,7 @@ vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec)
 static void
 vc_init()
 {
-   char       *pname;
-
-   /*
-    * Create a portal for safe memory across transactions. We need to
-    * palloc the name space for it because our hash function expects the
-    * name to be on a longword boundary.  CreatePortal copies the name to
-    * safe storage for us.
-    */
-   pname = pstrdup(VACPNAME);
-   vc_portal = CreatePortal(pname);
-   pfree(pname);
-
-   /*
-    * Set flag to indicate that vc_portal must be removed after an error.
-    * This global variable is checked in the transaction manager on xact
-    * abort, and the routine vc_abort() is called if necessary.
-    */
-   VacuumRunning = true;
+   CommonSpecialPortalOpen();
 
    /* matches the StartTransaction in PostgresMain() */
    CommitTransactionCommand();
@@ -219,30 +249,12 @@ vc_shutdown()
     */
    unlink(RELCACHE_INIT_FILENAME);
 
-   /*
-    * Release our portal for cross-transaction memory.
-    */
-   PortalDrop(&vc_portal);
-
-   /* okay, we're done */
-   VacuumRunning = false;
+   CommonSpecialPortalClose();
 
    /* matches the CommitTransaction in PostgresMain() */
    StartTransactionCommand();
 }
 
-void
-vc_abort()
-{
-   /* Clear flag first, to avoid recursion if PortalDrop elog's */
-   VacuumRunning = false;
-
-   /*
-    * Release our portal for cross-transaction memory.
-    */
-   PortalDrop(&vc_portal);
-}
-
 /*
  * vc_vacuum() -- vacuum the database.
  *
@@ -302,7 +314,7 @@ vc_getrels(NameData *VacRelP)
                               F_CHAREQ, CharGetDatum('r'));
    }
 
-   portalmem = PortalGetVariableMemory(vc_portal);
+   portalmem = CommonSpecialPortalGetMemory();
    vrl = cur = (VRelList) NULL;
 
    rel = heap_openr(RelationRelationName, AccessShareLock);
@@ -379,6 +391,7 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
    int32       nindices,
                i;
    VRelStats  *vacrelstats;
+   bool       reindex = false;
 
    StartTransactionCommand();
 
@@ -552,17 +565,31 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
    GetXmaxRecent(&XmaxRecent);
 
    /* scan it */
+   reindex = false;
    vacuum_pages.vpl_num_pages = fraged_pages.vpl_num_pages = 0;
    vc_scanheap(vacrelstats, onerel, &vacuum_pages, &fraged_pages);
+   if (IsIgnoringSystemIndexes() && IsSystemRelationName(RelationGetRelationName(onerel)))
+       reindex = true;
 
    /* Now open indices */
+   nindices = 0;
    Irel = (Relation *) NULL;
    vc_getindices(vacrelstats->relid, &nindices, &Irel);
-
+   if (!Irel)
+       reindex = false;
+   else if (!RelationGetForm(onerel)->relhasindex)
+       reindex = true;
    if (nindices > 0)
        vacrelstats->hasindex = true;
    else
        vacrelstats->hasindex = false;
+   if (reindex)
+   {
+       for (i = 0; i < nindices; i++)
+           index_close(Irel[i]);
+       Irel = (Relation *) NULL;
+       activate_indexes_of_a_table(relid, false);
+   }
 
    /* Clean/scan index relation(s) */
    if (Irel != (Relation *) NULL)
@@ -590,6 +617,8 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
                                                 * vacuum_pages list */
            vc_vacheap(vacrelstats, onerel, &vacuum_pages);
    }
+   if (reindex)
+       activate_indexes_of_a_table(relid, true);
 
    /* ok - free vacuum_pages list of reaped pages */
    if (vacuum_pages.vpl_num_pages > 0)
index 11cde461b417fed9087fd0997e57b60b6a10dcc9..8f15ac1ed180b18493ecb850d2bf5c9c47fa8a55 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.53 2000/01/26 05:56:22 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.54 2000/02/18 09:29:57 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "catalog/catname.h"
 #include "catalog/index.h"
 #include "catalog/pg_index.h"
+#include "catalog/catalog.h"
 #include "executor/execdebug.h"
 #include "executor/executor.h"
+#include "miscadmin.h"
 
 static void ExecGetIndexKeyInfo(Form_pg_index indexTuple, int *numAttsOutP,
                    AttrNumber **attsOutP, FuncIndexInfoPtr fInfoP);
@@ -770,6 +772,12 @@ ExecOpenIndices(Oid resultRelationOid,
    PredInfo   *predicate;
    int         i;
 
+   resultRelationInfo->ri_NumIndices = 0;
+   if (!RelationGetForm(resultRelationInfo->ri_RelationDesc)->relhasindex)
+       return;
+   if (IsIgnoringSystemIndexes() &&
+       IsSystemRelationName(RelationGetRelationName(resultRelationInfo->ri_RelationDesc)))
+       return;
    /* ----------------
     *  open pg_index
     * ----------------
index e5f7642c85cc6e2de127c0f9673c07557614d9d7..b1d1c578f385503fd110177e57d959da22467ed6 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.46 2000/02/05 23:19:44 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.47 2000/02/18 09:29:57 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1048,6 +1048,10 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
                  &currentRelation,     /* return: rel desc */
                  (Pointer *) &currentScanDesc);        /* return: scan desc */
 
+if (!RelationGetForm(currentRelation)->relhasindex)
+{
+   elog(ERROR, "indexes of the relation %u was inactivated", reloid);
+}
    scanstate->css_currentRelation = currentRelation;
    scanstate->css_currentScanDesc = currentScanDesc;
 
index e3a60c2c7f04be74e8f0949a0882514cd9ea2791..716c31ab0f132b7756457f30ba066a1e41b10a30 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.48 2000/02/17 03:39:40 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.49 2000/02/18 09:30:09 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -29,6 +29,8 @@
 #include "optimizer/plancat.h"
 #include "parser/parsetree.h"
 #include "utils/syscache.h"
+#include "catalog/catalog.h"
+#include "miscadmin.h"
 
 
 /*
@@ -55,7 +57,10 @@ relation_info(Query *root, Index relid,
             relationObjectId);
    relation = (Form_pg_class) GETSTRUCT(relationTuple);
 
-   *hasindex = (relation->relhasindex) ? true : false;
+   if (IsIgnoringSystemIndexes() && IsSystemRelationName(NameStr(relation->relname)))
+       *hasindex = false;
+   else
+       *hasindex = (relation->relhasindex) ? true : false;
    *pages = relation->relpages;
    *tuples = relation->reltuples;
 }
index 4babad9524a12b07ce8f1e3522162d15996b7f8d..b6962f8fad6f4be3f6ee42519f55a9304f167aae 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.143 2000/02/16 17:24:36 thomas Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.144 2000/02/18 09:29:40 inoue Exp $
  *
  * HISTORY
  *   AUTHOR            DATE            MAJOR EVENT
@@ -124,7 +124,7 @@ static Node *doNegate(Node *n);
        ExtendStmt, FetchStmt,  GrantStmt, CreateTrigStmt, DropTrigStmt,
        CreatePLangStmt, DropPLangStmt,
        IndexStmt, ListenStmt, UnlistenStmt, LockStmt, OptimizableStmt,
-       ProcedureStmt, RemoveAggrStmt, RemoveOperStmt,
+       ProcedureStmt, ReindexStmt, RemoveAggrStmt, RemoveOperStmt,
        RemoveFuncStmt, RemoveStmt,
        RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
        CreatedbStmt, DropdbStmt, VacuumStmt, CursorStmt, SubSelect,
@@ -141,7 +141,7 @@ static Node *doNegate(Node *n);
 %type <ival>    createdb_opt_encoding
 
 %type <ival>   opt_lock, lock_type
-%type <boolean>    opt_lmode
+%type <boolean>    opt_lmode, opt_force
 
 %type <ival>    user_createdb_clause, user_createuser_clause
 %type <str>        user_passwd_clause
@@ -211,7 +211,7 @@ static Node *doNegate(Node *n);
                opt_with_copy, index_opt_unique, opt_verbose, opt_analyze
 %type <boolean> opt_cursor
 
-%type <ival>   copy_dirn, def_type, direction, remove_type,
+%type <ival>   copy_dirn, def_type, direction, reindex_type, remove_type,
        opt_column, event, comment_type, comment_cl,
        comment_ag, comment_fn, comment_op, comment_tg
 
@@ -339,13 +339,13 @@ static Node *doNegate(Node *n);
        CACHE, CLUSTER, COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE,
        DATABASE, DELIMITERS, DO,
        EACH, ENCODING, EXCLUSIVE, EXPLAIN, EXTEND,
-       FORWARD, FUNCTION, HANDLER,
+       FORCE, FORWARD, FUNCTION, HANDLER,
        INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
        LANCOMPILER, LIMIT, LISTEN, LOAD, LOCATION, LOCK_P,
        MAXVALUE, MINVALUE, MODE, MOVE,
        NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
        OFFSET, OIDS, OPERATOR, PASSWORD, PROCEDURAL,
-       RENAME, RESET, RETURNS, ROW, RULE,
+       REINDEX, RENAME, RESET, RETURNS, ROW, RULE,
        SEQUENCE, SERIAL, SETOF, SHARE, SHOW, START, STATEMENT, STDIN, STDOUT, SYSID,
        TRUNCATE, TRUSTED, 
        UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
@@ -440,6 +440,7 @@ stmt :  AlterTableStmt
        | UnlistenStmt
        | LockStmt
        | ProcedureStmt
+       | ReindexStmt
        | RemoveAggrStmt
        | RemoveOperStmt
        | RemoveFuncStmt
@@ -2445,6 +2446,35 @@ oper_argtypes:   name
        ;
 
 
+/*****************************************************************************
+ *
+ *     QUERY:
+ *
+ *     REINDEX type <typename> [FORCE] [ALL]
+ *
+ *****************************************************************************/
+
+ReindexStmt:  REINDEX reindex_type name opt_force
+               {
+                   ReindexStmt *n = makeNode(ReindexStmt);
+                   if (IsTransactionBlock())
+                       elog(ERROR,"REINDEX command could only be used outside begin/end transaction blocks");
+                   n->reindexType = $2;
+                   n->name = $3;
+                   n->force = $4;
+                   $$ = (Node *)n;
+               }
+       ;
+
+reindex_type:  INDEX                                   {  $$ = INDEX; }
+       | TABLE                                 {  $$ = TABLE; }
+       | DATABASE                              {  $$ = DATABASE; }
+       ;
+opt_force: FORCE                                   {  $$ = TRUE; }
+       | /* EMPTY */                               {  $$ = FALSE; }
+       ;
+
+
 /*****************************************************************************
  *
  *     QUERY:
index e1c9424e37a358b8dff742b8ca32bfbfc9a9f040..d971e95762dcfd008d5c8681734968068df45e1e 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.66 2000/02/15 03:26:38 thomas Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.67 2000/02/18 09:29:40 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -107,6 +107,7 @@ static ScanKeyword ScanKeywords[] = {
    {"fetch", FETCH},
    {"float", FLOAT},
    {"for", FOR},
+   {"force", FORCE},
    {"foreign", FOREIGN},
    {"forward", FORWARD},
    {"from", FROM},
@@ -196,6 +197,7 @@ static ScanKeyword ScanKeywords[] = {
    {"public", PUBLIC},
    {"read", READ},
    {"references", REFERENCES},
+   {"reindex", REINDEX},
    {"relative", RELATIVE},
    {"rename", RENAME},
    {"reset", RESET},
index 3059e8b8289c4335a2eaf9e60aa091472bec9e64..c455d1cbd2a5004005adbdb26425cada12306518 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.135 2000/01/26 05:56:48 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.136 2000/02/18 09:28:44 inoue Exp $
  *
  * NOTES
  *
@@ -430,6 +430,7 @@ PostmasterMain(int argc, char *argv[])
    DataDir = getenv("PGDATA"); /* default value */
 
    opterr = 0;
+   IgnoreSystemIndexes(false);
    while ((opt = getopt(nonblank_argc, argv, "A:a:B:b:D:d:ilm:MN:no:p:Ss")) != EOF)
    {
        switch (opt)
index 123d70af9b439305e3f54faa667b596fa5b712a3..77422deb386c1c535cbab82f3ab215d771878be5 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.141 2000/01/26 05:57:07 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.142 2000/02/18 09:29:27 inoue Exp $
  *
  * NOTES
  *   this is the "main" module of the postgres backend and
@@ -963,7 +963,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
    optind = 1;                 /* reset after postmaster's usage */
 
    while ((flag = getopt(argc, argv,
-                         "A:B:CD:d:EeFf:iK:LNOo:p:QS:sT:t:v:W:x:"))
+                         "A:B:CD:d:EeFf:iK:LNOPo:p:QS:sT:t:v:W:x:"))
           != EOF)
        switch (flag)
        {
@@ -1116,6 +1116,15 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
                    allowSystemTableMods = true;
                break;
 
+           case 'P':
+               /* --------------------
+                *  ignore system indexes
+                * --------------------
+                */
+               if (secure)     /* XXX safe to allow from client??? */
+                   IgnoreSystemIndexes(true);
+               break;
+
            case 'o':
                /* ----------------
                 *  o - send output (stdout and stderr) to the given file
@@ -1516,7 +1525,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
    if (!IsUnderPostmaster)
    {
        puts("\nPOSTGRES backend interactive interface ");
-       puts("$Revision: 1.141 $ $Date: 2000/01/26 05:57:07 $\n");
+       puts("$Revision: 1.142 $ $Date: 2000/02/18 09:29:27 $\n");
    }
 
    /*
index 66acb230f2e5072395cec1d0bbea4556dfc3f1c3..427bf7b4d41279895c507c6b88ffcb39857d62fb 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.82 2000/01/29 16:58:38 petere Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.83 2000/02/18 09:29:31 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -846,6 +846,61 @@ ProcessUtility(Node *parsetree,
             DropGroup((DropGroupStmt *) parsetree);
             break;
 
+       case T_ReindexStmt:
+           {
+               ReindexStmt *stmt = (ReindexStmt *) parsetree;
+
+               PS_SET_STATUS(commandTag = "REINDEX");
+               CHECK_IF_ABORTED();
+
+               switch (stmt->reindexType)
+               {
+                   case INDEX:
+                       relname = stmt->name;
+                       if (IsSystemRelationName(relname))
+                       {
+                           if (!allowSystemTableMods && IsSystemRelationName(relname))
+                           elog(ERROR, "class \"%s\" is a system catalog index",
+                                relname);
+                           if (!IsIgnoringSystemIndexes())
+                               elog(ERROR, "class \"%s\" is a system catalog index",
+                                relname);
+                       }
+#ifndef NO_SECURITY
+                       if (!pg_ownercheck(userName, relname, RELNAME))
+                           elog(ERROR, "%s: %s", relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
+#endif
+                       ReindexIndex(relname, stmt->force);
+                       break;
+                   case TABLE:
+                       relname = stmt->name;
+                       if (IsSystemRelationName(relname))
+                       {
+                           if (!allowSystemTableMods && IsSystemRelationName(relname))
+                           elog(ERROR, "class \"%s\" is a system catalog index",
+                                relname);
+                           if (!IsIgnoringSystemIndexes())
+                               elog(ERROR, "class \"%s\" is a system catalog index",
+                                relname);
+                       }
+#ifndef NO_SECURITY
+                       if (!pg_ownercheck(userName, relname, RELNAME))
+                           elog(ERROR, "%s: %s", relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
+#endif
+                       ReindexTable(relname, stmt->force);
+                       break;
+                   case DATABASE:
+                       relname = stmt->name;
+                       if (!allowSystemTableMods)
+                           elog(ERROR, "-O option is needed");
+                       if (!IsIgnoringSystemIndexes())
+                           elog(ERROR, "-P option is needed");
+                       ReindexDatabase(relname, stmt->force, false);
+                       break;
+               }
+               break;
+           }
+           break;
            /*
             * ******************************** default ********************************
             *
index 732569fa8f5c7232ac81704b0c60b642982f976f..8094addc7d673f3d8eaa6baca907c408b5f5959e 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.51 2000/01/26 05:57:14 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.52 2000/02/18 09:28:48 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -45,7 +45,7 @@ regprocin(char *pro_name_or_oid)
    if (pro_name_or_oid[0] == '-' && pro_name_or_oid[1] == '\0')
        return InvalidOid;
 
-   if (!IsBootstrapProcessingMode())
+   if (!IsIgnoringSystemIndexes())
    {
 
        /*
index 1f224e56cfedba7714a1c60b848f7b60374e1aaa..c6c8763c706bfc284179cefac681d6baed5cb38a 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.60 2000/02/04 03:16:03 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.61 2000/02/18 09:28:53 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -233,7 +233,7 @@ CatalogCacheInitializeCache(struct catcache * cache,
     */
    if (cache->cc_indname != NULL && cache->indexId == InvalidOid)
    {
-       if (RelationGetForm(relation)->relhasindex)
+       if (!IsIgnoringSystemIndexes() && RelationGetForm(relation)->relhasindex)
        {
 
            /*
@@ -817,14 +817,19 @@ SearchSelfReferences(struct catcache * cache)
 
        if (!OidIsValid(indexSelfOid))
        {
+           ScanKeyData key;
+           HeapScanDesc    sd;
            /* Find oid of pg_index_indexrelid_index */
            rel = heap_openr(RelationRelationName, AccessShareLock);
-           ntp = ClassNameIndexScan(rel, IndexRelidIndex);
+           ScanKeyEntryInitialize(&key, 0, Anum_pg_class_relname,
+                   F_NAMEEQ, PointerGetDatum(IndexRelidIndex));
+           sd = heap_beginscan(rel, false, SnapshotNow, 1, &key);
+           ntp = heap_getnext(sd, 0);
            if (!HeapTupleIsValid(ntp))
                elog(ERROR, "SearchSelfReferences: %s not found in %s",
                    IndexRelidIndex, RelationRelationName);
            indexSelfOid = ntp->t_data->t_oid;
-           heap_freetuple(ntp);
+           heap_endscan(sd);
            heap_close(rel, AccessShareLock);
        }
        /* Looking for something other than pg_index_indexrelid_index? */
@@ -1031,7 +1036,7 @@ SearchSysCache(struct catcache * cache,
    CACHE1_elog(DEBUG, "SearchSysCache: performing scan");
 
    if ((RelationGetForm(relation))->relhasindex
-       && !IsBootstrapProcessingMode())
+       && !IsIgnoringSystemIndexes())
    {
        /* ----------
         *  Switch back to old memory context so memory not freed
index 7c993d3d73f12c6c675ffe608bc55d60c1fbe488..161576291542c6dcb373f1003e8f1b220741e24e 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.89 2000/01/31 04:35:52 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.90 2000/02/18 09:28:55 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -229,6 +229,7 @@ static void IndexedAccessMethodInitialize(Relation relation);
 static void AttrDefaultFetch(Relation relation);
 static void RelCheckFetch(Relation relation);
 
+static bool    criticalRelcacheBuild = false;
 /* ----------------------------------------------------------------
  *     RelationIdGetRelation() and RelationNameGetRelation()
  *                     support functions
@@ -254,7 +255,7 @@ ScanPgRelation(RelationBuildDescInfo buildinfo)
     * can, and do.
     */
 
-   if (IsBootstrapProcessingMode())
+   if (IsIgnoringSystemIndexes() || !criticalRelcacheBuild)
        return scan_pg_rel_seq(buildinfo);
    else
        return scan_pg_rel_ind(buildinfo);
@@ -424,12 +425,50 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
     * can, and do.
     */
 
-   if (IsBootstrapProcessingMode())
+   if (IsIgnoringSystemIndexes() || !criticalRelcacheBuild)
        build_tupdesc_seq(buildinfo, relation, natts);
    else
        build_tupdesc_ind(buildinfo, relation, natts);
 }
 
+static void
+SetConstrOfRelation(Relation relation, TupleConstr *constr, int ndef, AttrDefault *attrdef)
+{
+   if (constr->has_not_null || ndef > 0 || relation->rd_rel->relchecks)
+   {
+       relation->rd_att->constr = constr;
+
+       if (ndef > 0)           /* DEFAULTs */
+       {
+           if (ndef < relation->rd_rel->relnatts)
+               constr->defval = (AttrDefault *)
+                   repalloc(attrdef, ndef * sizeof(AttrDefault));
+           else
+               constr->defval = attrdef;
+           constr->num_defval = ndef;
+           AttrDefaultFetch(relation);
+       }
+       else
+           constr->num_defval = 0;
+
+       if (relation->rd_rel->relchecks > 0)    /* CHECKs */
+       {
+           constr->num_check = relation->rd_rel->relchecks;
+           constr->check = (ConstrCheck *) palloc(constr->num_check *
+                                                  sizeof(ConstrCheck));
+           MemSet(constr->check, 0, constr->num_check * sizeof(ConstrCheck));
+           RelCheckFetch(relation);
+       }
+       else
+           constr->num_check = 0;
+   }
+   else
+   {
+       pfree(constr);
+       relation->rd_att->constr = NULL;
+   }
+}
+
 static void
 build_tupdesc_seq(RelationBuildDescInfo buildinfo,
                  Relation relation,
@@ -441,7 +480,11 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
    Form_pg_attribute attp;
    ScanKeyData key;
    int         need;
+   TupleConstr *constr = (TupleConstr *) palloc(sizeof(TupleConstr));
+   AttrDefault *attrdef = NULL;
+   int     ndef = 0;
 
+   constr->has_not_null = false;
    /* ----------------
     *  form a scan key
     * ----------------
@@ -478,6 +521,23 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
                    (char *) attp,
                    ATTRIBUTE_TUPLE_SIZE);
            need--;
+           /* Update if this attribute have a constraint */
+           if (attp->attnotnull)
+               constr->has_not_null = true;
+
+           if (attp->atthasdef)
+           {
+               if (attrdef == NULL)
+               {
+                   attrdef = (AttrDefault *) palloc(relation->rd_rel->relnatts *
+                                                   sizeof(AttrDefault));
+                   MemSet(attrdef, 0,
+                      relation->rd_rel->relnatts * sizeof(AttrDefault));
+               }
+               attrdef[ndef].adnum = attp->attnum;
+               attrdef[ndef].adbin = NULL;
+               ndef++;
+           }
        }
        pg_attribute_tuple = heap_getnext(pg_attribute_scan, 0);
    }
@@ -492,6 +552,8 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
     */
    heap_endscan(pg_attribute_scan);
    heap_close(pg_attribute_desc, AccessShareLock);
+
+   SetConstrOfRelation(relation, constr, ndef, attrdef);
 }
 
 static void
@@ -549,39 +611,7 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
 
    heap_close(attrel, AccessShareLock);
 
-   if (constr->has_not_null || ndef > 0 || relation->rd_rel->relchecks)
-   {
-       relation->rd_att->constr = constr;
-
-       if (ndef > 0)           /* DEFAULTs */
-       {
-           if (ndef < relation->rd_rel->relnatts)
-               constr->defval = (AttrDefault *)
-                   repalloc(attrdef, ndef * sizeof(AttrDefault));
-           else
-               constr->defval = attrdef;
-           constr->num_defval = ndef;
-           AttrDefaultFetch(relation);
-       }
-       else
-           constr->num_defval = 0;
-
-       if (relation->rd_rel->relchecks > 0)    /* CHECKs */
-       {
-           constr->num_check = relation->rd_rel->relchecks;
-           constr->check = (ConstrCheck *) palloc(constr->num_check *
-                                                  sizeof(ConstrCheck));
-           MemSet(constr->check, 0, constr->num_check * sizeof(ConstrCheck));
-           RelCheckFetch(relation);
-       }
-       else
-           constr->num_check = 0;
-   }
-   else
-   {
-       pfree(constr);
-       relation->rd_att->constr = NULL;
-   }
+   SetConstrOfRelation(relation, constr, ndef, attrdef);
 
 }
 
@@ -1806,16 +1836,19 @@ AttrDefaultFetch(Relation relation)
    AttrDefault *attrdef = relation->rd_att->constr->defval;
    int         ndef = relation->rd_att->constr->num_defval;
    Relation    adrel;
-   Relation    irel;
+   Relation    irel = (Relation) NULL;
    ScanKeyData skey;
    HeapTupleData tuple;
+   HeapTuple   htup;
    Form_pg_attrdef adform;
-   IndexScanDesc sd;
+   IndexScanDesc   sd = (IndexScanDesc) NULL;
+   HeapScanDesc    adscan = (HeapScanDesc) NULL;
    RetrieveIndexResult indexRes;
    struct varlena *val;
    bool        isnull;
    int         found;
    int         i;
+   bool        hasindex;
 
    ScanKeyEntryInitialize(&skey,
                           (bits16) 0x0,
@@ -1824,8 +1857,14 @@ AttrDefaultFetch(Relation relation)
                           ObjectIdGetDatum(RelationGetRelid(relation)));
 
    adrel = heap_openr(AttrDefaultRelationName, AccessShareLock);
-   irel = index_openr(AttrDefaultIndex);
-   sd = index_beginscan(irel, false, 1, &skey);
+   hasindex = (adrel->rd_rel->relhasindex && !IsIgnoringSystemIndexes());
+   if (hasindex)
+   {
+       irel = index_openr(AttrDefaultIndex);
+       sd = index_beginscan(irel, false, 1, &skey);
+   }
+   else
+       adscan = heap_beginscan(adrel, false, SnapshotNow, 1, &skey); 
    tuple.t_datamcxt = NULL;
    tuple.t_data = NULL;
 
@@ -1833,17 +1872,27 @@ AttrDefaultFetch(Relation relation)
    {
        Buffer      buffer;
 
-       indexRes = index_getnext(sd, ForwardScanDirection);
-       if (!indexRes)
-           break;
-
-       tuple.t_self = indexRes->heap_iptr;
-       heap_fetch(adrel, SnapshotNow, &tuple, &buffer);
-       pfree(indexRes);
-       if (tuple.t_data == NULL)
-           continue;
+       if (hasindex)
+       {
+           indexRes = index_getnext(sd, ForwardScanDirection);
+           if (!indexRes)
+               break;
+
+           tuple.t_self = indexRes->heap_iptr;
+           heap_fetch(adrel, SnapshotNow, &tuple, &buffer);
+           pfree(indexRes);
+           if (tuple.t_data == NULL)
+               continue;
+           htup = &tuple;
+       }
+       else
+       {
+           htup = heap_getnext(adscan, 0);
+           if (!HeapTupleIsValid(htup))
+               break;
+       }
        found++;
-       adform = (Form_pg_attrdef) GETSTRUCT(&tuple);
+       adform = (Form_pg_attrdef) GETSTRUCT(htup);
        for (i = 0; i < ndef; i++)
        {
            if (adform->adnum != attrdef[i].adnum)
@@ -1853,7 +1902,7 @@ AttrDefaultFetch(Relation relation)
                NameStr(relation->rd_att->attrs[adform->adnum - 1]->attname),
                     RelationGetRelationName(relation));
 
-           val = (struct varlena *) fastgetattr(&tuple,
+           val = (struct varlena *) fastgetattr(htup,
                                                 Anum_pg_attrdef_adbin,
                                                 adrel->rd_att, &isnull);
            if (isnull)
@@ -1863,7 +1912,8 @@ AttrDefaultFetch(Relation relation)
            attrdef[i].adbin = textout(val);
            break;
        }
-       ReleaseBuffer(buffer);
+       if (hasindex)
+           ReleaseBuffer(buffer);
 
        if (i >= ndef)
            elog(NOTICE, "AttrDefaultFetch: unexpected record found for attr %d in rel %s",
@@ -1875,8 +1925,13 @@ AttrDefaultFetch(Relation relation)
        elog(NOTICE, "AttrDefaultFetch: %d record not found for rel %s",
             ndef - found, RelationGetRelationName(relation));
 
-   index_endscan(sd);
-   index_close(irel);
+   if (hasindex)
+   {
+       index_endscan(sd);
+       index_close(irel);
+   }
+   else
+       heap_endscan(adscan);
    heap_close(adrel, AccessShareLock);
 }
 
@@ -1886,15 +1941,18 @@ RelCheckFetch(Relation relation)
    ConstrCheck *check = relation->rd_att->constr->check;
    int         ncheck = relation->rd_att->constr->num_check;
    Relation    rcrel;
-   Relation    irel;
+   Relation    irel = (Relation)NULL;
    ScanKeyData skey;
    HeapTupleData tuple;
-   IndexScanDesc sd;
+   HeapTuple   htup;
+   IndexScanDesc   sd = (IndexScanDesc)NULL;
+   HeapScanDesc    rcscan = (HeapScanDesc)NULL;
    RetrieveIndexResult indexRes;
    Name        rcname;
    struct varlena *val;
    bool        isnull;
    int         found;
+   bool        hasindex;
 
    ScanKeyEntryInitialize(&skey,
                           (bits16) 0x0,
@@ -1903,8 +1961,14 @@ RelCheckFetch(Relation relation)
                           ObjectIdGetDatum(RelationGetRelid(relation)));
 
    rcrel = heap_openr(RelCheckRelationName, AccessShareLock);
-   irel = index_openr(RelCheckIndex);
-   sd = index_beginscan(irel, false, 1, &skey);
+   hasindex = (rcrel->rd_rel->relhasindex && !IsIgnoringSystemIndexes());
+   if (hasindex)
+   {
+       irel = index_openr(RelCheckIndex);
+       sd = index_beginscan(irel, false, 1, &skey);
+   }
+   else
+       rcscan = heap_beginscan(rcrel, false, SnapshotNow, 1, &skey);
    tuple.t_datamcxt = NULL;
    tuple.t_data = NULL;
 
@@ -1912,27 +1976,37 @@ RelCheckFetch(Relation relation)
    {
        Buffer      buffer;
 
-       indexRes = index_getnext(sd, ForwardScanDirection);
-       if (!indexRes)
-           break;
-
-       tuple.t_self = indexRes->heap_iptr;
-       heap_fetch(rcrel, SnapshotNow, &tuple, &buffer);
-       pfree(indexRes);
-       if (tuple.t_data == NULL)
-           continue;
+       if (hasindex)
+       {
+           indexRes = index_getnext(sd, ForwardScanDirection);
+           if (!indexRes)
+               break;
+
+           tuple.t_self = indexRes->heap_iptr;
+           heap_fetch(rcrel, SnapshotNow, &tuple, &buffer);
+           pfree(indexRes);
+           if (tuple.t_data == NULL)
+               continue;
+           htup = &tuple;
+       }
+       else
+       {
+           htup = heap_getnext(rcscan, 0);
+           if (!HeapTupleIsValid(htup))
+               break;
+       }
        if (found == ncheck)
            elog(ERROR, "RelCheckFetch: unexpected record found for rel %s",
                 RelationGetRelationName(relation));
 
-       rcname = (Name) fastgetattr(&tuple,
+       rcname = (Name) fastgetattr(htup,
                                    Anum_pg_relcheck_rcname,
                                    rcrel->rd_att, &isnull);
        if (isnull)
            elog(ERROR, "RelCheckFetch: rcname IS NULL for rel %s",
                 RelationGetRelationName(relation));
        check[found].ccname = pstrdup(NameStr(*rcname));
-       val = (struct varlena *) fastgetattr(&tuple,
+       val = (struct varlena *) fastgetattr(htup,
                                             Anum_pg_relcheck_rcbin,
                                             rcrel->rd_att, &isnull);
        if (isnull)
@@ -1940,15 +2014,21 @@ RelCheckFetch(Relation relation)
                 RelationGetRelationName(relation));
        check[found].ccbin = textout(val);
        found++;
-       ReleaseBuffer(buffer);
+       if (hasindex)
+           ReleaseBuffer(buffer);
    }
 
    if (found < ncheck)
        elog(ERROR, "RelCheckFetch: %d record not found for rel %s",
             ncheck - found, RelationGetRelationName(relation));
 
-   index_endscan(sd);
-   index_close(irel);
+   if (hasindex)
+   {
+       index_endscan(sd);
+       index_close(irel);
+   }
+   else
+       heap_endscan(rcscan);
    heap_close(rcrel, AccessShareLock);
 }
 
@@ -2148,6 +2228,7 @@ init_irels(void)
 
        RelationCacheInsert(ird);
    }
+   criticalRelcacheBuild = true;
 }
 
 static void
@@ -2162,7 +2243,6 @@ write_irels(void)
    Form_pg_class relform;
    IndexStrategy strat;
    RegProcedure *support;
-   ProcessingMode oldmode;
    int         i;
    int         relno;
    RelationBuildDescInfo bi;
@@ -2186,8 +2266,13 @@ write_irels(void)
     * descriptors, nail them into cache so we never lose them.
     */
 
+   /* Removed the following ProcessingMode change -- inoue
+    * At this point
+    * 1) Catalog Cache isn't initialized
+    * 2) Relation Cache for the following critical indexes aren't built
    oldmode = GetProcessingMode();
    SetProcessingMode(BootstrapProcessing);
+    */
 
    bi.infotype = INFO_RELNAME;
    bi.i.info_name = AttributeRelidNumIndex;
@@ -2202,7 +2287,10 @@ write_irels(void)
    irel[2] = RelationBuildDesc(bi, NULL);
    irel[2]->rd_isnailed = true;
 
+   criticalRelcacheBuild = true;
+   /* Removed the following ProcessingMode -- inoue 
    SetProcessingMode(oldmode);
+    */
 
    /*
     * Write out the index reldescs to the special cache file.
index 3cc75198994bc9f8ff1ac5f1d1a1f92f4b39bb2f..087002ab76fe6a5a24f736aa2e9b5e665f14149f 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.48 2000/01/26 05:57:18 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.49 2000/02/18 09:28:56 inoue Exp $
  *
  * NOTES
  *   These routines allow the parser/planner/executor to perform
@@ -39,6 +39,7 @@
 #include "catalog/pg_type.h"
 #include "utils/catcache.h"
 #include "utils/temprel.h"
+#include "miscadmin.h"
 
 extern bool AMI_OVERRIDE;      /* XXX style */
 
@@ -395,6 +396,11 @@ static struct cachedesc cacheinfo[] = {
 
 static struct catcache *SysCache[lengthof(cacheinfo)];
 static int32 SysCacheSize = lengthof(cacheinfo);
+static bool  CacheInitialized = false;
+extern bool  IsCacheInitialized(void)
+{
+   return CacheInitialized;
+}
 
 
 /*
@@ -442,6 +448,7 @@ InitCatalogCache()
 
        }
    }
+   CacheInitialized = true;
 }
 
 /*
index d5ce83dc6c45762364120513a2843602faf26acd..41b4020c713ce10f71bbeeb11dcfa23e731b6fcf 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.43 2000/01/26 05:57:26 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.44 2000/02/18 09:28:58 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -38,6 +38,33 @@ unsigned char RecodeBackTable[128];
 
 ProcessingMode Mode = InitProcessing;
 
+/* ----------------------------------------------------------------
+ *     ignoring system indexes support stuff
+ * ----------------------------------------------------------------
+ */
+
+static bool    isIgnoringSystemIndexes = false;
+
+/*
+ * IsIgnoringSystemIndexes
+ *     True if ignoring system indexes.
+ */
+bool
+IsIgnoringSystemIndexes()
+{
+   return isIgnoringSystemIndexes;
+}
+
+/*
+ * IgnoreSystemIndexes
+ * Set true or false whether PostgreSQL ignores system indexes.
+ *
+ */
+void
+IgnoreSystemIndexes(bool mode)
+{
+   isIgnoringSystemIndexes = mode;
+}
 
 /* ----------------------------------------------------------------
  *             database path / name support stuff
index b6d90c3a12c47fce25153c8aeb496169f0d1c699..b65e2ad98ebaed593881198add8c5d6a61c1ea56 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: index.h,v 1.21 2000/01/26 05:57:56 momjian Exp $
+ * $Id: index.h,v 1.22 2000/02/18 09:29:19 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -47,7 +47,11 @@ extern void FormIndexDatum(int numberOfAttributes,
               TupleDesc heapDescriptor, Datum *datum,
               char *nullv, FuncIndexInfoPtr fInfo);
 
-extern void UpdateStats(Oid relid, long reltuples, bool hasindex);
+extern void UpdateStats(Oid relid, long reltuples, bool inplace);
+extern bool IndexesAreActive(Oid relid, bool comfirmCommitted);
+extern void setRelhasindexInplace(Oid relid, bool hasindex, bool immediate);
+extern bool SetReindexProcessing(bool processing);
+extern bool IsReindexProcessing(void);
 
 extern void FillDummyExprContext(ExprContext *econtext, TupleTableSlot *slot,
                     TupleDesc tupdesc, Buffer buffer);
@@ -60,4 +64,8 @@ extern void index_build(Relation heapRelation, Relation indexRelation,
 extern bool IndexIsUnique(Oid indexId);
 extern bool IndexIsUniqueNoCache(Oid indexId);
 
+extern bool activate_index(Oid indexId, bool activate);
+extern bool reindex_index(Oid indexId, bool force);
+extern bool activate_indexes_of_a_table(Oid relid, bool activate);
+extern bool reindex_relation(Oid relid, bool force);
 #endif  /* INDEX_H */
index f5d69339e7192238af7044fe9685a0f889699391..f0a1e381e1ae383a8ea686eb92b0fe15981a0dd1 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: defrem.h,v 1.18 2000/01/26 05:58:00 momjian Exp $
+ * $Id: defrem.h,v 1.19 2000/02/18 09:29:49 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -33,6 +33,9 @@ extern void ExtendIndex(char *indexRelationName,
            Expr *predicate,
            List *rangetable);
 extern void RemoveIndex(char *name);
+extern void ReindexIndex(const char *indexRelationName, bool force);
+extern void ReindexTable(const char *relationName, bool force);
+extern void ReindexDatabase(const char *databaseName, bool force, bool all);
 
 /*
  * prototypes in define.c
index 7e47b3a36030b2b1c5561f575506794322008927..df3de38611b0a340124c995380a7e6ad62986c63 100644 (file)
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: miscadmin.h,v 1.50 2000/01/26 05:57:46 momjian Exp $
+ * $Id: miscadmin.h,v 1.51 2000/02/18 09:29:06 inoue Exp $
  *
  * NOTES
  *   some of the information in this file will be moved to
@@ -211,6 +211,9 @@ extern ProcessingMode Mode;
 
 #define GetProcessingMode() Mode
 
+extern void IgnoreSystemIndexes(bool mode);
+extern bool IsIgnoringSystemIndexes(void);
+extern bool IsCacheInitialized(void);
 
 /* 
  * "postmaster.pid" is a file containing postmaster's pid, being
index 161b53c25af97db7ad2d96d18aaccde3f7c75f94..8dd893e3f13cc2ef79b260f6a132d27ca4dec2d1 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: nodes.h,v 1.64 2000/02/15 20:49:24 tgl Exp $
+ * $Id: nodes.h,v 1.65 2000/02/18 09:29:43 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -146,7 +146,7 @@ typedef enum NodeTag
    T_DeleteStmt,
    T_UpdateStmt,
    T_SelectStmt,
-    T_AlterTableStmt,
+   T_AlterTableStmt,
    T_AggregateStmt,
    T_ChangeACLStmt,
    T_ClosePortalStmt,
@@ -191,9 +191,10 @@ typedef enum NodeTag
    T_DropUserStmt,
    T_LockStmt,
    T_ConstraintsSetStmt,
-    T_CreateGroupStmt,
-    T_AlterGroupStmt,
-    T_DropGroupStmt,
+   T_CreateGroupStmt,
+   T_AlterGroupStmt,
+   T_DropGroupStmt,
+   T_ReindexStmt,
 
    T_A_Expr = 700,
    T_Attr,
index df7bec10f0008912ca33a9ec008fbd73a4d4cf1e..d98398aadecd895c55b3856ba015cc6bdac27795 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.99 2000/02/15 20:49:24 tgl Exp $
+ * $Id: parsenodes.h,v 1.100 2000/02/18 09:29:44 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -722,6 +722,19 @@ typedef struct ConstraintsSetStmt
    bool        deferred;
 } ConstraintsSetStmt;
 
+/* ----------------------
+ *     REINDEX Statement
+ * ----------------------
+ */
+typedef struct ReindexStmt
+{
+   NodeTag     type;
+   int     reindexType;        /* INDEX|TABLE|DATABASE */
+   const   char   *name;           /* name to reindex */
+   bool        force;
+   bool        all;
+} ReindexStmt;
+
 
 /*****************************************************************************
  *     Optimizable Statements
index 73a53b2a419042c68fc3517f6b11ed0a4fcbf771..d24fd16f1a59dfe28b5f5cde7d26686fc52b2315 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: portal.h,v 1.21 2000/01/26 05:58:38 momjian Exp $
+ * $Id: portal.h,v 1.22 2000/02/18 09:30:16 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -80,6 +80,10 @@ extern void EndPortalAllocMode(void);
 extern void PortalResetHeapMemory(Portal portal);
 extern PortalVariableMemory PortalGetVariableMemory(Portal portal);
 extern PortalHeapMemory PortalGetHeapMemory(Portal portal);
+extern void CommonSpecialPortalOpen(void);
+extern void CommonSpecialPortalClose(void);
+extern PortalVariableMemory CommonSpecialPortalGetMemory(void);
+extern bool CommonSpecialPortalIsOpen(void);
 
 /* estimate of the maximum number of open portals a user would have,
  * used in initially sizing the PortalHashTable in EnablePortalManager()