LCOV - code coverage report
Current view: top level - src/backend/catalog - indexing.c (source / functions) Hit Total Coverage
Test: PostgreSQL Lines: 56 57 98.2 %
Date: 2017-09-29 13:40:31 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * indexing.c
       4             :  *    This file contains routines to support indexes defined on system
       5             :  *    catalogs.
       6             :  *
       7             :  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
       8             :  * Portions Copyright (c) 1994, Regents of the University of California
       9             :  *
      10             :  *
      11             :  * IDENTIFICATION
      12             :  *    src/backend/catalog/indexing.c
      13             :  *
      14             :  *-------------------------------------------------------------------------
      15             :  */
      16             : #include "postgres.h"
      17             : 
      18             : #include "access/htup_details.h"
      19             : #include "catalog/index.h"
      20             : #include "catalog/indexing.h"
      21             : #include "executor/executor.h"
      22             : #include "utils/rel.h"
      23             : 
      24             : 
      25             : /*
      26             :  * CatalogOpenIndexes - open the indexes on a system catalog.
      27             :  *
      28             :  * When inserting or updating tuples in a system catalog, call this
      29             :  * to prepare to update the indexes for the catalog.
      30             :  *
      31             :  * In the current implementation, we share code for opening/closing the
      32             :  * indexes with execUtils.c.  But we do not use ExecInsertIndexTuples,
      33             :  * because we don't want to create an EState.  This implies that we
      34             :  * do not support partial or expressional indexes on system catalogs,
      35             :  * nor can we support generalized exclusion constraints.
      36             :  * This could be fixed with localized changes here if we wanted to pay
      37             :  * the extra overhead of building an EState.
      38             :  */
      39             : CatalogIndexState
      40       44280 : CatalogOpenIndexes(Relation heapRel)
      41             : {
      42             :     ResultRelInfo *resultRelInfo;
      43             : 
      44       44280 :     resultRelInfo = makeNode(ResultRelInfo);
      45       44280 :     resultRelInfo->ri_RangeTableIndex = 1;   /* dummy */
      46       44280 :     resultRelInfo->ri_RelationDesc = heapRel;
      47       44280 :     resultRelInfo->ri_TrigDesc = NULL;   /* we don't fire triggers */
      48             : 
      49       44280 :     ExecOpenIndices(resultRelInfo, false);
      50             : 
      51       44280 :     return resultRelInfo;
      52             : }
      53             : 
      54             : /*
      55             :  * CatalogCloseIndexes - clean up resources allocated by CatalogOpenIndexes
      56             :  */
      57             : void
      58       44280 : CatalogCloseIndexes(CatalogIndexState indstate)
      59             : {
      60       44280 :     ExecCloseIndices(indstate);
      61       44280 :     pfree(indstate);
      62       44280 : }
      63             : 
      64             : /*
      65             :  * CatalogIndexInsert - insert index entries for one catalog tuple
      66             :  *
      67             :  * This should be called for each inserted or updated catalog tuple.
      68             :  *
      69             :  * This is effectively a cut-down version of ExecInsertIndexTuples.
      70             :  */
      71             : static void
      72       68860 : CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
      73             : {
      74             :     int         i;
      75             :     int         numIndexes;
      76             :     RelationPtr relationDescs;
      77             :     Relation    heapRelation;
      78             :     TupleTableSlot *slot;
      79             :     IndexInfo **indexInfoArray;
      80             :     Datum       values[INDEX_MAX_KEYS];
      81             :     bool        isnull[INDEX_MAX_KEYS];
      82             : 
      83             :     /* HOT update does not require index inserts */
      84       68860 :     if (HeapTupleIsHeapOnly(heapTuple))
      85       10110 :         return;
      86             : 
      87             :     /*
      88             :      * Get information from the state structure.  Fall out if nothing to do.
      89             :      */
      90       64556 :     numIndexes = indstate->ri_NumIndices;
      91       64556 :     if (numIndexes == 0)
      92        1502 :         return;
      93       63054 :     relationDescs = indstate->ri_IndexRelationDescs;
      94       63054 :     indexInfoArray = indstate->ri_IndexRelationInfo;
      95       63054 :     heapRelation = indstate->ri_RelationDesc;
      96             : 
      97             :     /* Need a slot to hold the tuple being examined */
      98       63054 :     slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation));
      99       63054 :     ExecStoreTuple(heapTuple, slot, InvalidBuffer, false);
     100             : 
     101             :     /*
     102             :      * for each index, form and insert the index tuple
     103             :      */
     104      192780 :     for (i = 0; i < numIndexes; i++)
     105             :     {
     106             :         IndexInfo  *indexInfo;
     107             : 
     108      129726 :         indexInfo = indexInfoArray[i];
     109             : 
     110             :         /* If the index is marked as read-only, ignore it */
     111      129726 :         if (!indexInfo->ii_ReadyForInserts)
     112           0 :             continue;
     113             : 
     114             :         /*
     115             :          * Expressional and partial indexes on system catalogs are not
     116             :          * supported, nor exclusion constraints, nor deferred uniqueness
     117             :          */
     118      129726 :         Assert(indexInfo->ii_Expressions == NIL);
     119      129726 :         Assert(indexInfo->ii_Predicate == NIL);
     120      129726 :         Assert(indexInfo->ii_ExclusionOps == NULL);
     121      129726 :         Assert(relationDescs[i]->rd_index->indimmediate);
     122             : 
     123             :         /*
     124             :          * FormIndexDatum fills in its values and isnull parameters with the
     125             :          * appropriate values for the column(s) of the index.
     126             :          */
     127      129726 :         FormIndexDatum(indexInfo,
     128             :                        slot,
     129             :                        NULL,    /* no expression eval to do */
     130             :                        values,
     131             :                        isnull);
     132             : 
     133             :         /*
     134             :          * The index AM does the rest.
     135             :          */
     136      129726 :         index_insert(relationDescs[i],  /* index relation */
     137             :                      values,    /* array of index Datums */
     138             :                      isnull,    /* is-null flags */
     139             :                      &(heapTuple->t_self),   /* tid of heap tuple */
     140             :                      heapRelation,
     141      129726 :                      relationDescs[i]->rd_index->indisunique ?
     142             :                      UNIQUE_CHECK_YES : UNIQUE_CHECK_NO,
     143             :                      indexInfo);
     144             :     }
     145             : 
     146       63054 :     ExecDropSingleTupleTableSlot(slot);
     147             : }
     148             : 
     149             : /*
     150             :  * CatalogTupleInsert - do heap and indexing work for a new catalog tuple
     151             :  *
     152             :  * Insert the tuple data in "tup" into the specified catalog relation.
     153             :  * The Oid of the inserted tuple is returned.
     154             :  *
     155             :  * This is a convenience routine for the common case of inserting a single
     156             :  * tuple in a system catalog; it inserts a new heap tuple, keeping indexes
     157             :  * current.  Avoid using it for multiple tuples, since opening the indexes
     158             :  * and building the index info structures is moderately expensive.
     159             :  * (Use CatalogTupleInsertWithInfo in such cases.)
     160             :  */
     161             : Oid
     162       17218 : CatalogTupleInsert(Relation heapRel, HeapTuple tup)
     163             : {
     164             :     CatalogIndexState indstate;
     165             :     Oid         oid;
     166             : 
     167       17218 :     indstate = CatalogOpenIndexes(heapRel);
     168             : 
     169       17218 :     oid = simple_heap_insert(heapRel, tup);
     170             : 
     171       17218 :     CatalogIndexInsert(indstate, tup);
     172       17218 :     CatalogCloseIndexes(indstate);
     173             : 
     174       17218 :     return oid;
     175             : }
     176             : 
     177             : /*
     178             :  * CatalogTupleInsertWithInfo - as above, but with caller-supplied index info
     179             :  *
     180             :  * This should be used when it's important to amortize CatalogOpenIndexes/
     181             :  * CatalogCloseIndexes work across multiple insertions.  At some point we
     182             :  * might cache the CatalogIndexState data somewhere (perhaps in the relcache)
     183             :  * so that callers needn't trouble over this ... but we don't do so today.
     184             :  */
     185             : Oid
     186       45759 : CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup,
     187             :                            CatalogIndexState indstate)
     188             : {
     189             :     Oid         oid;
     190             : 
     191       45759 :     oid = simple_heap_insert(heapRel, tup);
     192             : 
     193       45759 :     CatalogIndexInsert(indstate, tup);
     194             : 
     195       45759 :     return oid;
     196             : }
     197             : 
     198             : /*
     199             :  * CatalogTupleUpdate - do heap and indexing work for updating a catalog tuple
     200             :  *
     201             :  * Update the tuple identified by "otid", replacing it with the data in "tup".
     202             :  *
     203             :  * This is a convenience routine for the common case of updating a single
     204             :  * tuple in a system catalog; it updates one heap tuple, keeping indexes
     205             :  * current.  Avoid using it for multiple tuples, since opening the indexes
     206             :  * and building the index info structures is moderately expensive.
     207             :  * (Use CatalogTupleUpdateWithInfo in such cases.)
     208             :  */
     209             : void
     210        5653 : CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
     211             : {
     212             :     CatalogIndexState indstate;
     213             : 
     214        5653 :     indstate = CatalogOpenIndexes(heapRel);
     215             : 
     216        5653 :     simple_heap_update(heapRel, otid, tup);
     217             : 
     218        5653 :     CatalogIndexInsert(indstate, tup);
     219        5653 :     CatalogCloseIndexes(indstate);
     220        5653 : }
     221             : 
     222             : /*
     223             :  * CatalogTupleUpdateWithInfo - as above, but with caller-supplied index info
     224             :  *
     225             :  * This should be used when it's important to amortize CatalogOpenIndexes/
     226             :  * CatalogCloseIndexes work across multiple updates.  At some point we
     227             :  * might cache the CatalogIndexState data somewhere (perhaps in the relcache)
     228             :  * so that callers needn't trouble over this ... but we don't do so today.
     229             :  */
     230             : void
     231         230 : CatalogTupleUpdateWithInfo(Relation heapRel, ItemPointer otid, HeapTuple tup,
     232             :                            CatalogIndexState indstate)
     233             : {
     234         230 :     simple_heap_update(heapRel, otid, tup);
     235             : 
     236         230 :     CatalogIndexInsert(indstate, tup);
     237         230 : }
     238             : 
     239             : /*
     240             :  * CatalogTupleDelete - do heap and indexing work for deleting a catalog tuple
     241             :  *
     242             :  * Delete the tuple identified by "tid" in the specified catalog.
     243             :  *
     244             :  * With Postgres heaps, there is no index work to do at deletion time;
     245             :  * cleanup will be done later by VACUUM.  However, callers of this function
     246             :  * shouldn't have to know that; we'd like a uniform abstraction for all
     247             :  * catalog tuple changes.  Hence, provide this currently-trivial wrapper.
     248             :  *
     249             :  * The abstraction is a bit leaky in that we don't provide an optimized
     250             :  * CatalogTupleDeleteWithInfo version, because there is currently nothing to
     251             :  * optimize.  If we ever need that, rather than touching a lot of call sites,
     252             :  * it might be better to do something about caching CatalogIndexState.
     253             :  */
     254             : void
     255       43260 : CatalogTupleDelete(Relation heapRel, ItemPointer tid)
     256             : {
     257       43260 :     simple_heap_delete(heapRel, tid);
     258       43260 : }

Generated by: LCOV version 1.11