Logo Search packages:      
Sourcecode: postgresql-8.4 version File versions

indexing.c

/*-------------------------------------------------------------------------
 *
 * indexing.c
 *      This file contains routines to support indexes defined on system
 *      catalogs.
 *
 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *      $PostgreSQL: pgsql/src/backend/catalog/indexing.c,v 1.117 2009/01/01 17:23:37 momjian Exp $
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "access/genam.h"
#include "catalog/index.h"
#include "catalog/indexing.h"
#include "executor/executor.h"


/*
 * CatalogOpenIndexes - open the indexes on a system catalog.
 *
 * When inserting or updating tuples in a system catalog, call this
 * to prepare to update the indexes for the catalog.
 *
 * In the current implementation, we share code for opening/closing the
 * indexes with execUtils.c.  But we do not use ExecInsertIndexTuples,
 * because we don't want to create an EState.  This implies that we
 * do not support partial or expressional indexes on system catalogs.
 * This could be fixed with localized changes here if we wanted to pay
 * the extra overhead of building an EState.
 */
CatalogIndexState
CatalogOpenIndexes(Relation heapRel)
{
      ResultRelInfo *resultRelInfo;

      resultRelInfo = makeNode(ResultRelInfo);
      resultRelInfo->ri_RangeTableIndex = 1;          /* dummy */
      resultRelInfo->ri_RelationDesc = heapRel;
      resultRelInfo->ri_TrigDesc = NULL;  /* we don't fire triggers */

      ExecOpenIndices(resultRelInfo);

      return resultRelInfo;
}

/*
 * CatalogCloseIndexes - clean up resources allocated by CatalogOpenIndexes
 */
void
CatalogCloseIndexes(CatalogIndexState indstate)
{
      ExecCloseIndices(indstate);
      pfree(indstate);
}

/*
 * CatalogIndexInsert - insert index entries for one catalog tuple
 *
 * This should be called for each inserted or updated catalog tuple.
 *
 * This is effectively a cut-down version of ExecInsertIndexTuples.
 */
void
CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
{
      int               i;
      int               numIndexes;
      RelationPtr relationDescs;
      Relation    heapRelation;
      TupleTableSlot *slot;
      IndexInfo **indexInfoArray;
      Datum       values[INDEX_MAX_KEYS];
      bool        isnull[INDEX_MAX_KEYS];

      /* HOT update does not require index inserts */
      if (HeapTupleIsHeapOnly(heapTuple))
            return;

      /*
       * Get information from the state structure.  Fall out if nothing to do.
       */
      numIndexes = indstate->ri_NumIndices;
      if (numIndexes == 0)
            return;
      relationDescs = indstate->ri_IndexRelationDescs;
      indexInfoArray = indstate->ri_IndexRelationInfo;
      heapRelation = indstate->ri_RelationDesc;

      /* Need a slot to hold the tuple being examined */
      slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation));
      ExecStoreTuple(heapTuple, slot, InvalidBuffer, false);

      /*
       * for each index, form and insert the index tuple
       */
      for (i = 0; i < numIndexes; i++)
      {
            IndexInfo  *indexInfo;

            indexInfo = indexInfoArray[i];

            /* If the index is marked as read-only, ignore it */
            if (!indexInfo->ii_ReadyForInserts)
                  continue;

            /*
             * Expressional and partial indexes on system catalogs are not
             * supported
             */
            Assert(indexInfo->ii_Expressions == NIL);
            Assert(indexInfo->ii_Predicate == NIL);

            /*
             * FormIndexDatum fills in its values and isnull parameters with the
             * appropriate values for the column(s) of the index.
             */
            FormIndexDatum(indexInfo,
                                 slot,
                                 NULL,    /* no expression eval to do */
                                 values,
                                 isnull);

            /*
             * The index AM does the rest.
             */
            index_insert(relationDescs[i],      /* index relation */
                               values,    /* array of index Datums */
                               isnull,    /* is-null flags */
                               &(heapTuple->t_self),        /* tid of heap tuple */
                               heapRelation,
                               relationDescs[i]->rd_index->indisunique);
      }

      ExecDropSingleTupleTableSlot(slot);
}

/*
 * CatalogUpdateIndexes - do all the indexing work for a new catalog tuple
 *
 * This is a convenience routine for the common case where we only need
 * to insert or update a single tuple in a system catalog.  Avoid using it for
 * multiple tuples, since opening the indexes and building the index info
 * structures is moderately expensive.
 */
void
CatalogUpdateIndexes(Relation heapRel, HeapTuple heapTuple)
{
      CatalogIndexState indstate;

      indstate = CatalogOpenIndexes(heapRel);
      CatalogIndexInsert(indstate, heapTuple);
      CatalogCloseIndexes(indstate);
}

Generated by  Doxygen 1.6.0   Back to index