LCOV - differential code coverage report
Current view: top level - src/backend/catalog - indexing.c (source / functions) Coverage Total Hit UNC LBC UIC GIC GNC CBC EUB ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 95.5 % 88 84 1 1 2 46 14 24 4 57 2
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 10 10 7 1 2 7 1
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 [..60] days: 93.3 % 15 14 1 14
Legend: Lines: hit not hit (240..) days: 95.9 % 73 70 1 2 46 24 4 54
Function coverage date bins:
[..60] days: 100.0 % 1 1 1
(240..) days: 60.0 % 15 9 7 2 6

 Age         Owner                  TLA  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-2023, 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/genam.h"
                                 19                 : #include "access/heapam.h"
                                 20                 : #include "access/htup_details.h"
                                 21                 : #include "access/xact.h"
                                 22                 : #include "catalog/index.h"
                                 23                 : #include "catalog/indexing.h"
                                 24                 : #include "executor/executor.h"
                                 25                 : #include "utils/rel.h"
                                 26                 : 
                                 27                 : 
                                 28                 : /*
                                 29                 :  * CatalogOpenIndexes - open the indexes on a system catalog.
                                 30                 :  *
                                 31                 :  * When inserting or updating tuples in a system catalog, call this
                                 32                 :  * to prepare to update the indexes for the catalog.
                                 33                 :  *
                                 34                 :  * In the current implementation, we share code for opening/closing the
                                 35                 :  * indexes with execUtils.c.  But we do not use ExecInsertIndexTuples,
                                 36                 :  * because we don't want to create an EState.  This implies that we
                                 37                 :  * do not support partial or expressional indexes on system catalogs,
                                 38                 :  * nor can we support generalized exclusion constraints.
                                 39                 :  * This could be fixed with localized changes here if we wanted to pay
                                 40                 :  * the extra overhead of building an EState.
                                 41                 :  */
                                 42                 : CatalogIndexState
 7552 tgl                        43 CBC     2201807 : CatalogOpenIndexes(Relation heapRel)
                                 44                 : {
                                 45                 :     ResultRelInfo *resultRelInfo;
                                 46                 : 
                                 47         2201807 :     resultRelInfo = makeNode(ResultRelInfo);
 1648                            48         2201807 :     resultRelInfo->ri_RangeTableIndex = 0;   /* dummy */
 7552                            49         2201807 :     resultRelInfo->ri_RelationDesc = heapRel;
 7522 bruce                      50         2201807 :     resultRelInfo->ri_TrigDesc = NULL;   /* we don't fire triggers */
                                 51                 : 
 2893 andres                     52         2201807 :     ExecOpenIndices(resultRelInfo, false);
                                 53                 : 
 7552 tgl                        54         2201807 :     return resultRelInfo;
                                 55                 : }
                                 56                 : 
                                 57                 : /*
                                 58                 :  * CatalogCloseIndexes - clean up resources allocated by CatalogOpenIndexes
                                 59                 :  */
                                 60                 : void
                                 61         2201806 : CatalogCloseIndexes(CatalogIndexState indstate)
                                 62                 : {
                                 63         2201806 :     ExecCloseIndices(indstate);
                                 64         2201806 :     pfree(indstate);
 9770 scrappy                    65         2201806 : }
                                 66                 : 
                                 67                 : /*
                                 68                 :  * CatalogIndexInsert - insert index entries for one catalog tuple
                                 69                 :  *
                                 70                 :  * This should be called for each inserted or updated catalog tuple.
                                 71                 :  *
                                 72                 :  * This is effectively a cut-down version of ExecInsertIndexTuples.
                                 73                 :  */
                                 74                 : static void
   20 tomas.vondra               75 GNC     3684548 : CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple,
                                 76                 :                    TU_UpdateIndexes updateIndexes)
                                 77                 : {
                                 78                 :     int         i;
                                 79                 :     int         numIndexes;
                                 80                 :     RelationPtr relationDescs;
                                 81                 :     Relation    heapRelation;
                                 82                 :     TupleTableSlot *slot;
                                 83                 :     IndexInfo **indexInfoArray;
                                 84                 :     Datum       values[INDEX_MAX_KEYS];
                                 85                 :     bool        isnull[INDEX_MAX_KEYS];
                                 86         3684548 :     bool        onlySummarized = (updateIndexes == TU_Summarizing);
                                 87                 : 
 1441 andres                     88 ECB             :     /*
                                 89                 :      * HOT update does not require index inserts. But with asserts enabled we
                                 90                 :      * want to check that it'd be legal to currently insert into the
                                 91                 :      * table/index.
                                 92                 :      */
                                 93                 : #ifndef USE_ASSERT_CHECKING
                                 94                 :     if (HeapTupleIsHeapOnly(heapTuple) && !onlySummarized)
                                 95                 :         return;
                                 96                 : #endif
                                 97                 : 
                                 98                 :     /* When only updating summarized indexes, the tuple has to be HOT. */
   20 tomas.vondra               99 GNC     3684548 :     Assert((!onlySummarized) || HeapTupleIsHeapOnly(heapTuple));
                                100                 : 
                                101                 :     /*
                                102                 :      * Get information from the state structure.  Fall out if nothing to do.
                                103                 :      */
 7552 tgl                       104 CBC     3684548 :     numIndexes = indstate->ri_NumIndices;
 6598 tgl                       105 GIC     3684548 :     if (numIndexes == 0)
                                106          601765 :         return;
 7552                           107         3082783 :     relationDescs = indstate->ri_IndexRelationDescs;
                                108         3082783 :     indexInfoArray = indstate->ri_IndexRelationInfo;
 7552 tgl                       109 CBC     3082783 :     heapRelation = indstate->ri_RelationDesc;
 6598 tgl                       110 ECB             : 
                                111                 :     /* Need a slot to hold the tuple being examined */
 1606 andres                    112 CBC     3082783 :     slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation),
 1606 andres                    113 ECB             :                                     &TTSOpsHeapTuple);
 1657 andres                    114 CBC     3082783 :     ExecStoreHeapTuple(heapTuple, slot, false);
                                115                 : 
                                116                 :     /*
 7552 tgl                       117 ECB             :      * for each index, form and insert the index tuple
                                118                 :      */
 7552 tgl                       119 CBC     9135002 :     for (i = 0; i < numIndexes; i++)
                                120                 :     {
                                121                 :         IndexInfo  *indexInfo;
                                122                 :         Relation    index;
                                123                 : 
                                124         6052220 :         indexInfo = indexInfoArray[i];
 1441 andres                    125 GIC     6052220 :         index = relationDescs[i];
                                126                 : 
                                127                 :         /* If the index is marked as read-only, ignore it */
 5680 tgl                       128         6052220 :         if (!indexInfo->ii_ReadyForInserts)
 5680 tgl                       129 LBC           0 :             continue;
 5680 tgl                       130 ECB             : 
                                131                 :         /*
                                132                 :          * Expressional and partial indexes on system catalogs are not
 4871                           133                 :          * supported, nor exclusion constraints, nor deferred uniqueness
 7256 tgl                       134 EUB             :          */
 7256 tgl                       135 GIC     6052220 :         Assert(indexInfo->ii_Expressions == NIL);
 7552                           136         6052220 :         Assert(indexInfo->ii_Predicate == NIL);
 4871                           137         6052220 :         Assert(indexInfo->ii_ExclusionOps == NULL);
 1441 andres                    138         6052220 :         Assert(index->rd_index->indimmediate);
 1828 teodor                    139         6052220 :         Assert(indexInfo->ii_NumIndexKeyAttrs != 0);
 7552 tgl                       140 ECB             : 
 1441 andres                    141                 :         /* see earlier check above */
                                142                 : #ifdef USE_ASSERT_CHECKING
   20 tomas.vondra              143 GNC     6052220 :         if (HeapTupleIsHeapOnly(heapTuple) && !onlySummarized)
 1441 andres                    144 ECB             :         {
 1441 andres                    145 GIC      372809 :             Assert(!ReindexIsProcessingIndex(RelationGetRelid(index)));
                                146          372809 :             continue;
                                147                 :         }
 1440 andres                    148 ECB             : #endif                          /* USE_ASSERT_CHECKING */
                                149                 : 
                                150                 :         /*
                                151                 :          * Skip insertions into non-summarizing indexes if we only need
                                152                 :          * to update summarizing indexes.
                                153                 :          */
   20 tomas.vondra              154 GNC     5679411 :         if (onlySummarized && !indexInfo->ii_Summarizing)
   20 tomas.vondra              155 UNC           0 :             continue;
                                156                 : 
 7552 tgl                       157 ECB             :         /*
 6385 bruce                     158                 :          * FormIndexDatum fills in its values and isnull parameters with the
                                159                 :          * appropriate values for the column(s) of the index.
                                160                 :          */
 8304 tgl                       161 GIC     5679411 :         FormIndexDatum(indexInfo,
                                162                 :                        slot,
                                163                 :                        NULL,    /* no expression eval to do */
                                164                 :                        values,
                                165                 :                        isnull);
 9345 bruce                     166 ECB             : 
 7552 tgl                       167 EUB             :         /*
                                168                 :          * The index AM does the rest.
                                169                 :          */
 1440 andres                    170 GIC     5679411 :         index_insert(index,     /* index relation */
                                171                 :                      values,    /* array of index Datums */
                                172                 :                      isnull,    /* is-null flags */
 2118 tgl                       173 ECB             :                      &(heapTuple->t_self),   /* tid of heap tuple */
                                174                 :                      heapRelation,
 1440 andres                    175 GIC     5679411 :                      index->rd_index->indisunique ?
                                176                 :                      UNIQUE_CHECK_YES : UNIQUE_CHECK_NO,
                                177                 :                      false,
                                178                 :                      indexInfo);
                                179                 :     }
                                180                 : 
 6598 tgl                       181         3082782 :     ExecDropSingleTupleTableSlot(slot);
 9770 scrappy                   182 ECB             : }
                                183                 : 
                                184                 : /*
                                185                 :  * Subroutine to verify that catalog constraints are honored.
                                186                 :  *
  992 tgl                       187                 :  * Tuples inserted via CatalogTupleInsert/CatalogTupleUpdate are generally
                                188                 :  * "hand made", so that it's possible that they fail to satisfy constraints
                                189                 :  * that would be checked if they were being inserted by the executor.  That's
                                190                 :  * a coding error, so we only bother to check for it in assert-enabled builds.
                                191                 :  */
                                192                 : #ifdef USE_ASSERT_CHECKING
                                193                 : 
                                194                 : static void
  992 tgl                       195 GIC     1576638 : CatalogTupleCheckConstraints(Relation heapRel, HeapTuple tup)
                                196                 : {
                                197                 :     /*
                                198                 :      * Currently, the only constraints implemented for system catalogs are
                                199                 :      * attnotnull constraints.
                                200                 :      */
                                201         1576638 :     if (HeapTupleHasNulls(tup))
                                202                 :     {
                                203         1227024 :         TupleDesc   tupdesc = RelationGetDescr(heapRel);
                                204         1227024 :         bits8      *bp = tup->t_data->t_bits;
                                205                 : 
                                206        30099598 :         for (int attnum = 0; attnum < tupdesc->natts; attnum++)
  992 tgl                       207 ECB             :         {
  992 tgl                       208 GIC    28872574 :             Form_pg_attribute thisatt = TupleDescAttr(tupdesc, attnum);
                                209                 : 
                                210        28872574 :             Assert(!(thisatt->attnotnull && att_isnull(attnum, bp)));
                                211                 :         }
                                212                 :     }
  992 tgl                       213 CBC     1576638 : }
                                214                 : 
  992 tgl                       215 ECB             : #else                           /* !USE_ASSERT_CHECKING */
                                216                 : 
                                217                 : #define CatalogTupleCheckConstraints(heapRel, tup)  ((void) 0)
                                218                 : 
                                219                 : #endif                          /* USE_ASSERT_CHECKING */
                                220                 : 
                                221                 : /*
 2259 alvherre                  222                 :  * CatalogTupleInsert - do heap and indexing work for a new catalog tuple
                                223                 :  *
                                224                 :  * Insert the tuple data in "tup" into the specified catalog relation.
 2258 tgl                       225                 :  *
                                226                 :  * This is a convenience routine for the common case of inserting a single
                                227                 :  * tuple in a system catalog; it inserts a new heap tuple, keeping indexes
                                228                 :  * current.  Avoid using it for multiple tuples, since opening the indexes
                                229                 :  * and building the index info structures is moderately expensive.
                                230                 :  * (Use CatalogTupleInsertWithInfo in such cases.)
                                231                 :  */
                                232                 : void
 2259 alvherre                  233 GIC     1244023 : CatalogTupleInsert(Relation heapRel, HeapTuple tup)
                                234                 : {
                                235                 :     CatalogIndexState indstate;
                                236                 : 
  992 tgl                       237         1244023 :     CatalogTupleCheckConstraints(heapRel, tup);
                                238                 : 
 2259 alvherre                  239         1244023 :     indstate = CatalogOpenIndexes(heapRel);
                                240                 : 
 1601 andres                    241         1244023 :     simple_heap_insert(heapRel, tup);
                                242                 : 
   20 tomas.vondra              243 GNC     1244023 :     CatalogIndexInsert(indstate, tup, TU_All);
 2259 alvherre                  244 GIC     1244022 :     CatalogCloseIndexes(indstate);
 2259 alvherre                  245 CBC     1244022 : }
                                246                 : 
                                247                 : /*
                                248                 :  * CatalogTupleInsertWithInfo - as above, but with caller-supplied index info
 2258 tgl                       249 ECB             :  *
                                250                 :  * This should be used when it's important to amortize CatalogOpenIndexes/
                                251                 :  * CatalogCloseIndexes work across multiple insertions.  At some point we
                                252                 :  * might cache the CatalogIndexState data somewhere (perhaps in the relcache)
                                253                 :  * so that callers needn't trouble over this ... but we don't do so today.
                                254                 :  */
 1601 andres                    255                 : void
 2258 tgl                       256 CBC      131381 : CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup,
 2258 tgl                       257 ECB             :                            CatalogIndexState indstate)
                                258                 : {
  992 tgl                       259 GIC      131381 :     CatalogTupleCheckConstraints(heapRel, tup);
                                260                 : 
 1601 andres                    261          131381 :     simple_heap_insert(heapRel, tup);
                                262                 : 
   20 tomas.vondra              263 GNC      131381 :     CatalogIndexInsert(indstate, tup, TU_All);
 2258 tgl                       264 GIC      131381 : }
                                265                 : 
                                266                 : /*
                                267                 :  * CatalogTuplesMultiInsertWithInfo - as above, but for multiple tuples
  982 michael                   268 ECB             :  *
                                269                 :  * Insert multiple tuples into the given catalog relation at once, with an
                                270                 :  * amortized cost of CatalogOpenIndexes.
                                271                 :  */
                                272                 : void
  982 michael                   273 CBC      808773 : CatalogTuplesMultiInsertWithInfo(Relation heapRel, TupleTableSlot **slot,
                                274                 :                                  int ntuples, CatalogIndexState indstate)
  982 michael                   275 ECB             : {
                                276                 :     /* Nothing to do */
  982 michael                   277 GIC      808773 :     if (ntuples <= 0)
  982 michael                   278 UIC           0 :         return;
                                279                 : 
  982 michael                   280 GIC      808773 :     heap_multi_insert(heapRel, slot, ntuples,
                                281                 :                       GetCurrentCommandId(true), 0, NULL);
                                282                 : 
                                283                 :     /*
                                284                 :      * There is no equivalent to heap_multi_insert for the catalog indexes, so
  982 michael                   285 ECB             :      * we must loop over and insert individually.
                                286                 :      */
  982 michael                   287 GIC     2916683 :     for (int i = 0; i < ntuples; i++)
                                288                 :     {
  982 michael                   289 ECB             :         bool        should_free;
  982 michael                   290 EUB             :         HeapTuple   tuple;
                                291                 : 
  982 michael                   292 CBC     2107910 :         tuple = ExecFetchSlotHeapTuple(slot[i], true, &should_free);
  982 michael                   293 GIC     2107910 :         tuple->t_tableOid = slot[i]->tts_tableOid;
   20 tomas.vondra              294 GNC     2107910 :         CatalogIndexInsert(indstate, tuple, TU_All);
                                295                 : 
  982 michael                   296 GIC     2107910 :         if (should_free)
  982 michael                   297 UIC           0 :             heap_freetuple(tuple);
                                298                 :     }
  982 michael                   299 ECB             : }
                                300                 : 
                                301                 : /*
                                302                 :  * CatalogTupleUpdate - do heap and indexing work for updating a catalog tuple
                                303                 :  *
 2258 tgl                       304                 :  * Update the tuple identified by "otid", replacing it with the data in "tup".
                                305                 :  *
 2259 alvherre                  306                 :  * This is a convenience routine for the common case of updating a single
                                307                 :  * tuple in a system catalog; it updates one heap tuple, keeping indexes
 2258 tgl                       308                 :  * current.  Avoid using it for multiple tuples, since opening the indexes
 2258 tgl                       309 EUB             :  * and building the index info structures is moderately expensive.
                                310                 :  * (Use CatalogTupleUpdateWithInfo in such cases.)
                                311                 :  */
                                312                 : void
 2259 alvherre                  313 GIC      187858 : CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
                                314                 : {
                                315                 :     CatalogIndexState indstate;
   20 tomas.vondra              316 GNC      187858 :     TU_UpdateIndexes updateIndexes = TU_All;
                                317                 : 
  992 tgl                       318 GIC      187858 :     CatalogTupleCheckConstraints(heapRel, tup);
                                319                 : 
 7552                           320          187858 :     indstate = CatalogOpenIndexes(heapRel);
                                321                 : 
   20 tomas.vondra              322 GNC      187858 :     simple_heap_update(heapRel, otid, tup, &updateIndexes);
                                323                 : 
                                324          187858 :     CatalogIndexInsert(indstate, tup, updateIndexes);
 7552 tgl                       325 GIC      187858 :     CatalogCloseIndexes(indstate);
 7552 tgl                       326 CBC      187858 : }
                                327                 : 
                                328                 : /*
 2258 tgl                       329 ECB             :  * CatalogTupleUpdateWithInfo - as above, but with caller-supplied index info
                                330                 :  *
                                331                 :  * This should be used when it's important to amortize CatalogOpenIndexes/
                                332                 :  * CatalogCloseIndexes work across multiple updates.  At some point we
                                333                 :  * might cache the CatalogIndexState data somewhere (perhaps in the relcache)
                                334                 :  * so that callers needn't trouble over this ... but we don't do so today.
                                335                 :  */
                                336                 : void
 2258 tgl                       337 CBC       13376 : CatalogTupleUpdateWithInfo(Relation heapRel, ItemPointer otid, HeapTuple tup,
 2258 tgl                       338 ECB             :                            CatalogIndexState indstate)
                                339                 : {
   20 tomas.vondra              340 GNC       13376 :     TU_UpdateIndexes updateIndexes = TU_All;
                                341                 : 
  992 tgl                       342 GIC       13376 :     CatalogTupleCheckConstraints(heapRel, tup);
                                343                 : 
   20 tomas.vondra              344 GNC       13376 :     simple_heap_update(heapRel, otid, tup, &updateIndexes);
                                345                 : 
                                346           13376 :     CatalogIndexInsert(indstate, tup, updateIndexes);
 2258 tgl                       347 GIC       13376 : }
                                348                 : 
                                349                 : /*
                                350                 :  * CatalogTupleDelete - do heap and indexing work for deleting a catalog tuple
                                351                 :  *
 2258 tgl                       352 ECB             :  * Delete the tuple identified by "tid" in the specified catalog.
                                353                 :  *
                                354                 :  * With Postgres heaps, there is no index work to do at deletion time;
                                355                 :  * cleanup will be done later by VACUUM.  However, callers of this function
                                356                 :  * shouldn't have to know that; we'd like a uniform abstraction for all
                                357                 :  * catalog tuple changes.  Hence, provide this currently-trivial wrapper.
                                358                 :  *
                                359                 :  * The abstraction is a bit leaky in that we don't provide an optimized
                                360                 :  * CatalogTupleDeleteWithInfo version, because there is currently nothing to
                                361                 :  * optimize.  If we ever need that, rather than touching a lot of call sites,
                                362                 :  * it might be better to do something about caching CatalogIndexState.
                                363                 :  */
                                364                 : void
 2258 tgl                       365 GIC      534713 : CatalogTupleDelete(Relation heapRel, ItemPointer tid)
                                366                 : {
                                367          534713 :     simple_heap_delete(heapRel, tid);
                                368          534713 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a