OSDN Git Service

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 ef188d0..fe956ea 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 fa8decc..da5dd70 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 58e1744..e5b521b 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 e8afa33..8e129a4 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 2840e40..271dc3e 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 6040d09..b7d49ed 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 2afd6b6..41337da 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 f5de425..cbd7b26 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 0b0b3cf..9a4286a 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 5274be3..ef84459 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 11cde46..8f15ac1 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 e5f7642..b1d1c57 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 e3a60c2..716c31a 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 4babad9..b6962f8 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
@@ -2448,6 +2449,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:
  *                             rename <attrname1> in <relname> [*] to <attrname2>
  *                             rename <relname1> to <relname2>
  *
index e1c9424..d971e95 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 3059e8b..c455d1c 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 123d70a..77422de 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 66acb23..427bf7b 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 732569f..8094add 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 1f224e5..c6c8763 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 7c993d3..1615762 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,13 +425,51 @@ 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,
                                  u_int natts)
@@ -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 3cc7519..087002a 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 d5ce83d..41b4020 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 b6d90c3..b65e2ad 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 f5d6933..f0a1e38 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 7e47b3a..df3de38 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 161b53c..8dd893e 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 df7bec1..d98398a 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 73a53b2..d24fd16 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()