Header And Logo

PostgreSQL
| The world's most advanced open source database.

indexing.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * indexing.c
00004  *    This file contains routines to support indexes defined on system
00005  *    catalogs.
00006  *
00007  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00008  * Portions Copyright (c) 1994, Regents of the University of California
00009  *
00010  *
00011  * IDENTIFICATION
00012  *    src/backend/catalog/indexing.c
00013  *
00014  *-------------------------------------------------------------------------
00015  */
00016 #include "postgres.h"
00017 
00018 #include "access/htup_details.h"
00019 #include "catalog/index.h"
00020 #include "catalog/indexing.h"
00021 #include "executor/executor.h"
00022 #include "utils/rel.h"
00023 
00024 
00025 /*
00026  * CatalogOpenIndexes - open the indexes on a system catalog.
00027  *
00028  * When inserting or updating tuples in a system catalog, call this
00029  * to prepare to update the indexes for the catalog.
00030  *
00031  * In the current implementation, we share code for opening/closing the
00032  * indexes with execUtils.c.  But we do not use ExecInsertIndexTuples,
00033  * because we don't want to create an EState.  This implies that we
00034  * do not support partial or expressional indexes on system catalogs,
00035  * nor can we support generalized exclusion constraints.
00036  * This could be fixed with localized changes here if we wanted to pay
00037  * the extra overhead of building an EState.
00038  */
00039 CatalogIndexState
00040 CatalogOpenIndexes(Relation heapRel)
00041 {
00042     ResultRelInfo *resultRelInfo;
00043 
00044     resultRelInfo = makeNode(ResultRelInfo);
00045     resultRelInfo->ri_RangeTableIndex = 1;      /* dummy */
00046     resultRelInfo->ri_RelationDesc = heapRel;
00047     resultRelInfo->ri_TrigDesc = NULL;  /* we don't fire triggers */
00048 
00049     ExecOpenIndices(resultRelInfo);
00050 
00051     return resultRelInfo;
00052 }
00053 
00054 /*
00055  * CatalogCloseIndexes - clean up resources allocated by CatalogOpenIndexes
00056  */
00057 void
00058 CatalogCloseIndexes(CatalogIndexState indstate)
00059 {
00060     ExecCloseIndices(indstate);
00061     pfree(indstate);
00062 }
00063 
00064 /*
00065  * CatalogIndexInsert - insert index entries for one catalog tuple
00066  *
00067  * This should be called for each inserted or updated catalog tuple.
00068  *
00069  * This is effectively a cut-down version of ExecInsertIndexTuples.
00070  */
00071 void
00072 CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
00073 {
00074     int         i;
00075     int         numIndexes;
00076     RelationPtr relationDescs;
00077     Relation    heapRelation;
00078     TupleTableSlot *slot;
00079     IndexInfo **indexInfoArray;
00080     Datum       values[INDEX_MAX_KEYS];
00081     bool        isnull[INDEX_MAX_KEYS];
00082 
00083     /* HOT update does not require index inserts */
00084     if (HeapTupleIsHeapOnly(heapTuple))
00085         return;
00086 
00087     /*
00088      * Get information from the state structure.  Fall out if nothing to do.
00089      */
00090     numIndexes = indstate->ri_NumIndices;
00091     if (numIndexes == 0)
00092         return;
00093     relationDescs = indstate->ri_IndexRelationDescs;
00094     indexInfoArray = indstate->ri_IndexRelationInfo;
00095     heapRelation = indstate->ri_RelationDesc;
00096 
00097     /* Need a slot to hold the tuple being examined */
00098     slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation));
00099     ExecStoreTuple(heapTuple, slot, InvalidBuffer, false);
00100 
00101     /*
00102      * for each index, form and insert the index tuple
00103      */
00104     for (i = 0; i < numIndexes; i++)
00105     {
00106         IndexInfo  *indexInfo;
00107 
00108         indexInfo = indexInfoArray[i];
00109 
00110         /* If the index is marked as read-only, ignore it */
00111         if (!indexInfo->ii_ReadyForInserts)
00112             continue;
00113 
00114         /*
00115          * Expressional and partial indexes on system catalogs are not
00116          * supported, nor exclusion constraints, nor deferred uniqueness
00117          */
00118         Assert(indexInfo->ii_Expressions == NIL);
00119         Assert(indexInfo->ii_Predicate == NIL);
00120         Assert(indexInfo->ii_ExclusionOps == NULL);
00121         Assert(relationDescs[i]->rd_index->indimmediate);
00122 
00123         /*
00124          * FormIndexDatum fills in its values and isnull parameters with the
00125          * appropriate values for the column(s) of the index.
00126          */
00127         FormIndexDatum(indexInfo,
00128                        slot,
00129                        NULL,    /* no expression eval to do */
00130                        values,
00131                        isnull);
00132 
00133         /*
00134          * The index AM does the rest.
00135          */
00136         index_insert(relationDescs[i],  /* index relation */
00137                      values,    /* array of index Datums */
00138                      isnull,    /* is-null flags */
00139                      &(heapTuple->t_self),      /* tid of heap tuple */
00140                      heapRelation,
00141                      relationDescs[i]->rd_index->indisunique ?
00142                      UNIQUE_CHECK_YES : UNIQUE_CHECK_NO);
00143     }
00144 
00145     ExecDropSingleTupleTableSlot(slot);
00146 }
00147 
00148 /*
00149  * CatalogUpdateIndexes - do all the indexing work for a new catalog tuple
00150  *
00151  * This is a convenience routine for the common case where we only need
00152  * to insert or update a single tuple in a system catalog.  Avoid using it for
00153  * multiple tuples, since opening the indexes and building the index info
00154  * structures is moderately expensive.
00155  */
00156 void
00157 CatalogUpdateIndexes(Relation heapRel, HeapTuple heapTuple)
00158 {
00159     CatalogIndexState indstate;
00160 
00161     indstate = CatalogOpenIndexes(heapRel);
00162     CatalogIndexInsert(indstate, heapTuple);
00163     CatalogCloseIndexes(indstate);
00164 }