LCOV - differential code coverage report
Current view: top level - src/backend/catalog - indexing.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 95.5 % 88 84 4 84
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 10 10 10
Baseline: 16@8cea358b128 Branches: 61.4 % 44 27 17 27
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 95.5 % 88 84 4 84
Function coverage date bins:
(240..) days: 100.0 % 10 10 10
Branch coverage date bins:
(240..) days: 61.4 % 44 27 17 27

 Age         Owner                    Branch data    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-2024, 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
 7923 tgl@sss.pgh.pa.us          43                 :CBC      642707 : CatalogOpenIndexes(Relation heapRel)
                                 44                 :                : {
                                 45                 :                :     ResultRelInfo *resultRelInfo;
                                 46                 :                : 
                                 47                 :         642707 :     resultRelInfo = makeNode(ResultRelInfo);
 2019                            48                 :         642707 :     resultRelInfo->ri_RangeTableIndex = 0;   /* dummy */
 7923                            49                 :         642707 :     resultRelInfo->ri_RelationDesc = heapRel;
 7893 bruce@momjian.us           50                 :         642707 :     resultRelInfo->ri_TrigDesc = NULL;   /* we don't fire triggers */
                                 51                 :                : 
 3264 andres@anarazel.de         52                 :         642707 :     ExecOpenIndices(resultRelInfo, false);
                                 53                 :                : 
 7923 tgl@sss.pgh.pa.us          54                 :         642707 :     return resultRelInfo;
                                 55                 :                : }
                                 56                 :                : 
                                 57                 :                : /*
                                 58                 :                :  * CatalogCloseIndexes - clean up resources allocated by CatalogOpenIndexes
                                 59                 :                :  */
                                 60                 :                : void
                                 61                 :         642706 : CatalogCloseIndexes(CatalogIndexState indstate)
                                 62                 :                : {
                                 63                 :         642706 :     ExecCloseIndices(indstate);
                                 64                 :         642706 :     pfree(indstate);
10141 scrappy@hub.org            65                 :         642706 : }
                                 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
  391 tomas.vondra@postgre       75                 :        1163678 : 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                 :        1163678 :     bool        onlySummarized = (updateIndexes == TU_Summarizing);
                                 87                 :                : 
                                 88                 :                :     /*
                                 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. */
                                 99   [ -  +  -  - ]:        1163678 :     Assert((!onlySummarized) || HeapTupleIsHeapOnly(heapTuple));
                                100                 :                : 
                                101                 :                :     /*
                                102                 :                :      * Get information from the state structure.  Fall out if nothing to do.
                                103                 :                :      */
 7923 tgl@sss.pgh.pa.us         104                 :        1163678 :     numIndexes = indstate->ri_NumIndices;
 6969                           105         [ +  + ]:        1163678 :     if (numIndexes == 0)
                                106                 :          77025 :         return;
 7923                           107                 :        1086653 :     relationDescs = indstate->ri_IndexRelationDescs;
                                108                 :        1086653 :     indexInfoArray = indstate->ri_IndexRelationInfo;
                                109                 :        1086653 :     heapRelation = indstate->ri_RelationDesc;
                                110                 :                : 
                                111                 :                :     /* Need a slot to hold the tuple being examined */
 1977 andres@anarazel.de        112                 :        1086653 :     slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation),
                                113                 :                :                                     &TTSOpsHeapTuple);
 2028                           114                 :        1086653 :     ExecStoreHeapTuple(heapTuple, slot, false);
                                115                 :                : 
                                116                 :                :     /*
                                117                 :                :      * for each index, form and insert the index tuple
                                118                 :                :      */
 7923 tgl@sss.pgh.pa.us         119         [ +  + ]:        3443544 :     for (i = 0; i < numIndexes; i++)
                                120                 :                :     {
                                121                 :                :         IndexInfo  *indexInfo;
                                122                 :                :         Relation    index;
                                123                 :                : 
                                124                 :        2356892 :         indexInfo = indexInfoArray[i];
 1812 andres@anarazel.de        125                 :        2356892 :         index = relationDescs[i];
                                126                 :                : 
                                127                 :                :         /* If the index is marked as read-only, ignore it */
 6051 tgl@sss.pgh.pa.us         128         [ -  + ]:        2356892 :         if (!indexInfo->ii_ReadyForInserts)
 6051 tgl@sss.pgh.pa.us         129                 :UBC           0 :             continue;
                                130                 :                : 
                                131                 :                :         /*
                                132                 :                :          * Expressional and partial indexes on system catalogs are not
                                133                 :                :          * supported, nor exclusion constraints, nor deferred uniqueness
                                134                 :                :          */
 7627 tgl@sss.pgh.pa.us         135         [ -  + ]:CBC     2356892 :         Assert(indexInfo->ii_Expressions == NIL);
 7923                           136         [ -  + ]:        2356892 :         Assert(indexInfo->ii_Predicate == NIL);
 5242                           137         [ -  + ]:        2356892 :         Assert(indexInfo->ii_ExclusionOps == NULL);
 1812 andres@anarazel.de        138         [ -  + ]:        2356892 :         Assert(index->rd_index->indimmediate);
 2199 teodor@sigaev.ru          139         [ -  + ]:        2356892 :         Assert(indexInfo->ii_NumIndexKeyAttrs != 0);
                                140                 :                : 
                                141                 :                :         /* see earlier check above */
                                142                 :                : #ifdef USE_ASSERT_CHECKING
  391 tomas.vondra@postgre      143   [ +  +  +  - ]:        2356892 :         if (HeapTupleIsHeapOnly(heapTuple) && !onlySummarized)
                                144                 :                :         {
 1812 andres@anarazel.de        145         [ -  + ]:         148239 :             Assert(!ReindexIsProcessingIndex(RelationGetRelid(index)));
                                146                 :         148239 :             continue;
                                147                 :                :         }
                                148                 :                : #endif                          /* USE_ASSERT_CHECKING */
                                149                 :                : 
                                150                 :                :         /*
                                151                 :                :          * Skip insertions into non-summarizing indexes if we only need to
                                152                 :                :          * update summarizing indexes.
                                153                 :                :          */
  391 tomas.vondra@postgre      154   [ -  +  -  - ]:        2208653 :         if (onlySummarized && !indexInfo->ii_Summarizing)
  391 tomas.vondra@postgre      155                 :UBC           0 :             continue;
                                156                 :                : 
                                157                 :                :         /*
                                158                 :                :          * FormIndexDatum fills in its values and isnull parameters with the
                                159                 :                :          * appropriate values for the column(s) of the index.
                                160                 :                :          */
 8675 tgl@sss.pgh.pa.us         161                 :CBC     2208653 :         FormIndexDatum(indexInfo,
                                162                 :                :                        slot,
                                163                 :                :                        NULL,    /* no expression eval to do */
                                164                 :                :                        values,
                                165                 :                :                        isnull);
                                166                 :                : 
                                167                 :                :         /*
                                168                 :                :          * The index AM does the rest.
                                169                 :                :          */
 1811 andres@anarazel.de        170                 :        2208653 :         index_insert(index,     /* index relation */
                                171                 :                :                      values,    /* array of index Datums */
                                172                 :                :                      isnull,    /* is-null flags */
                                173                 :                :                      &(heapTuple->t_self),   /* tid of heap tuple */
                                174                 :                :                      heapRelation,
                                175                 :        2208653 :                      index->rd_index->indisunique ?
                                176                 :                :                      UNIQUE_CHECK_YES : UNIQUE_CHECK_NO,
                                177                 :                :                      false,
                                178                 :                :                      indexInfo);
                                179                 :                :     }
                                180                 :                : 
 6969 tgl@sss.pgh.pa.us         181                 :        1086652 :     ExecDropSingleTupleTableSlot(slot);
                                182                 :                : }
                                183                 :                : 
                                184                 :                : /*
                                185                 :                :  * Subroutine to verify that catalog constraints are honored.
                                186                 :                :  *
                                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
 1363                           195                 :         403605 : CatalogTupleCheckConstraints(Relation heapRel, HeapTuple tup)
                                196                 :                : {
                                197                 :                :     /*
                                198                 :                :      * Currently, the only constraints implemented for system catalogs are
                                199                 :                :      * attnotnull constraints.
                                200                 :                :      */
                                201         [ +  + ]:         403605 :     if (HeapTupleHasNulls(tup))
                                202                 :                :     {
                                203                 :         333313 :         TupleDesc   tupdesc = RelationGetDescr(heapRel);
                                204                 :         333313 :         bits8      *bp = tup->t_data->t_bits;
                                205                 :                : 
                                206         [ +  + ]:        9222301 :         for (int attnum = 0; attnum < tupdesc->natts; attnum++)
                                207                 :                :         {
                                208                 :        8888988 :             Form_pg_attribute thisatt = TupleDescAttr(tupdesc, attnum);
                                209                 :                : 
                                210   [ +  +  -  + ]:        8888988 :             Assert(!(thisatt->attnotnull && att_isnull(attnum, bp)));
                                211                 :                :         }
                                212                 :                :     }
                                213                 :         403605 : }
                                214                 :                : 
                                215                 :                : #else                           /* !USE_ASSERT_CHECKING */
                                216                 :                : 
                                217                 :                : #define CatalogTupleCheckConstraints(heapRel, tup)  ((void) 0)
                                218                 :                : 
                                219                 :                : #endif                          /* USE_ASSERT_CHECKING */
                                220                 :                : 
                                221                 :                : /*
                                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.
                                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
 2630 alvherre@alvh.no-ip.      233                 :         291587 : CatalogTupleInsert(Relation heapRel, HeapTuple tup)
                                234                 :                : {
                                235                 :                :     CatalogIndexState indstate;
                                236                 :                : 
 1363 tgl@sss.pgh.pa.us         237                 :         291587 :     CatalogTupleCheckConstraints(heapRel, tup);
                                238                 :                : 
 2630 alvherre@alvh.no-ip.      239                 :         291587 :     indstate = CatalogOpenIndexes(heapRel);
                                240                 :                : 
 1972 andres@anarazel.de        241                 :         291587 :     simple_heap_insert(heapRel, tup);
                                242                 :                : 
  391 tomas.vondra@postgre      243                 :         291587 :     CatalogIndexInsert(indstate, tup, TU_All);
 2630 alvherre@alvh.no-ip.      244                 :         291586 :     CatalogCloseIndexes(indstate);
                                245                 :         291586 : }
                                246                 :                : 
                                247                 :                : /*
                                248                 :                :  * CatalogTupleInsertWithInfo - as above, but with caller-supplied index info
                                249                 :                :  *
                                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                 :                :  */
                                255                 :                : void
 2629 tgl@sss.pgh.pa.us         256                 :          23018 : CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup,
                                257                 :                :                            CatalogIndexState indstate)
                                258                 :                : {
 1363                           259                 :          23018 :     CatalogTupleCheckConstraints(heapRel, tup);
                                260                 :                : 
 1972 andres@anarazel.de        261                 :          23018 :     simple_heap_insert(heapRel, tup);
                                262                 :                : 
  391 tomas.vondra@postgre      263                 :          23018 :     CatalogIndexInsert(indstate, tup, TU_All);
 2629 tgl@sss.pgh.pa.us         264                 :          23018 : }
                                265                 :                : 
                                266                 :                : /*
                                267                 :                :  * CatalogTuplesMultiInsertWithInfo - as above, but for multiple tuples
                                268                 :                :  *
                                269                 :                :  * Insert multiple tuples into the given catalog relation at once, with an
                                270                 :                :  * amortized cost of CatalogOpenIndexes.
                                271                 :                :  */
                                272                 :                : void
 1353 michael@paquier.xyz       273                 :         301710 : CatalogTuplesMultiInsertWithInfo(Relation heapRel, TupleTableSlot **slot,
                                274                 :                :                                  int ntuples, CatalogIndexState indstate)
                                275                 :                : {
                                276                 :                :     /* Nothing to do */
                                277         [ -  + ]:         301710 :     if (ntuples <= 0)
 1353 michael@paquier.xyz       278                 :UBC           0 :         return;
                                279                 :                : 
 1353 michael@paquier.xyz       280                 :CBC      301710 :     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
                                285                 :                :      * we must loop over and insert individually.
                                286                 :                :      */
                                287         [ +  + ]:        1061783 :     for (int i = 0; i < ntuples; i++)
                                288                 :                :     {
                                289                 :                :         bool        should_free;
                                290                 :                :         HeapTuple   tuple;
                                291                 :                : 
                                292                 :         760073 :         tuple = ExecFetchSlotHeapTuple(slot[i], true, &should_free);
                                293                 :         760073 :         tuple->t_tableOid = slot[i]->tts_tableOid;
  391 tomas.vondra@postgre      294                 :         760073 :         CatalogIndexInsert(indstate, tuple, TU_All);
                                295                 :                : 
 1353 michael@paquier.xyz       296         [ -  + ]:         760073 :         if (should_free)
 1353 michael@paquier.xyz       297                 :UBC           0 :             heap_freetuple(tuple);
                                298                 :                :     }
                                299                 :                : }
                                300                 :                : 
                                301                 :                : /*
                                302                 :                :  * CatalogTupleUpdate - do heap and indexing work for updating a catalog tuple
                                303                 :                :  *
                                304                 :                :  * Update the tuple identified by "otid", replacing it with the data in "tup".
                                305                 :                :  *
                                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
                                308                 :                :  * current.  Avoid using it for multiple tuples, since opening the indexes
                                309                 :                :  * and building the index info structures is moderately expensive.
                                310                 :                :  * (Use CatalogTupleUpdateWithInfo in such cases.)
                                311                 :                :  */
                                312                 :                : void
 2630 alvherre@alvh.no-ip.      313                 :CBC       73296 : CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
                                314                 :                : {
                                315                 :                :     CatalogIndexState indstate;
  391 tomas.vondra@postgre      316                 :          73296 :     TU_UpdateIndexes updateIndexes = TU_All;
                                317                 :                : 
 1363 tgl@sss.pgh.pa.us         318                 :          73296 :     CatalogTupleCheckConstraints(heapRel, tup);
                                319                 :                : 
 7923                           320                 :          73296 :     indstate = CatalogOpenIndexes(heapRel);
                                321                 :                : 
  391 tomas.vondra@postgre      322                 :          73296 :     simple_heap_update(heapRel, otid, tup, &updateIndexes);
                                323                 :                : 
                                324                 :          73296 :     CatalogIndexInsert(indstate, tup, updateIndexes);
 7923 tgl@sss.pgh.pa.us         325                 :          73296 :     CatalogCloseIndexes(indstate);
                                326                 :          73296 : }
                                327                 :                : 
                                328                 :                : /*
                                329                 :                :  * 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
 2629                           337                 :          15704 : CatalogTupleUpdateWithInfo(Relation heapRel, ItemPointer otid, HeapTuple tup,
                                338                 :                :                            CatalogIndexState indstate)
                                339                 :                : {
  391 tomas.vondra@postgre      340                 :          15704 :     TU_UpdateIndexes updateIndexes = TU_All;
                                341                 :                : 
 1363 tgl@sss.pgh.pa.us         342                 :          15704 :     CatalogTupleCheckConstraints(heapRel, tup);
                                343                 :                : 
  391 tomas.vondra@postgre      344                 :          15704 :     simple_heap_update(heapRel, otid, tup, &updateIndexes);
                                345                 :                : 
                                346                 :          15704 :     CatalogIndexInsert(indstate, tup, updateIndexes);
 2629 tgl@sss.pgh.pa.us         347                 :          15704 : }
                                348                 :                : 
                                349                 :                : /*
                                350                 :                :  * CatalogTupleDelete - do heap and indexing work for deleting a catalog tuple
                                351                 :                :  *
                                352                 :                :  * 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
                                365                 :         570169 : CatalogTupleDelete(Relation heapRel, ItemPointer tid)
                                366                 :                : {
                                367                 :         570169 :     simple_heap_delete(heapRel, tid);
                                368                 :         570169 : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622