LCOV - differential code coverage report
Current view: top level - src/backend/utils/cache - attoptcache.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 95.5 % 44 42 2 42
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 3 3 3
Baseline: 16@8cea358b128 Branches: 80.0 % 20 16 4 16
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 % 44 42 2 42
Function coverage date bins:
(240..) days: 100.0 % 3 3 3
Branch coverage date bins:
(240..) days: 80.0 % 20 16 4 16

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * attoptcache.c
                                  4                 :                :  *    Attribute options cache management.
                                  5                 :                :  *
                                  6                 :                :  * Attribute options are cached separately from the fixed-size portion of
                                  7                 :                :  * pg_attribute entries, which are handled by the relcache.
                                  8                 :                :  *
                                  9                 :                :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
                                 10                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                 11                 :                :  *
                                 12                 :                :  * IDENTIFICATION
                                 13                 :                :  *    src/backend/utils/cache/attoptcache.c
                                 14                 :                :  *
                                 15                 :                :  *-------------------------------------------------------------------------
                                 16                 :                :  */
                                 17                 :                : #include "postgres.h"
                                 18                 :                : 
                                 19                 :                : #include "access/reloptions.h"
                                 20                 :                : #include "utils/attoptcache.h"
                                 21                 :                : #include "utils/catcache.h"
                                 22                 :                : #include "utils/hsearch.h"
                                 23                 :                : #include "utils/inval.h"
                                 24                 :                : #include "utils/syscache.h"
                                 25                 :                : #include "varatt.h"
                                 26                 :                : 
                                 27                 :                : 
                                 28                 :                : /* Hash table for information about each attribute's options */
                                 29                 :                : static HTAB *AttoptCacheHash = NULL;
                                 30                 :                : 
                                 31                 :                : /* attrelid and attnum form the lookup key, and must appear first */
                                 32                 :                : typedef struct
                                 33                 :                : {
                                 34                 :                :     Oid         attrelid;
                                 35                 :                :     int         attnum;
                                 36                 :                : } AttoptCacheKey;
                                 37                 :                : 
                                 38                 :                : typedef struct
                                 39                 :                : {
                                 40                 :                :     AttoptCacheKey key;         /* lookup key - must be first */
                                 41                 :                :     AttributeOpts *opts;        /* options, or NULL if none */
                                 42                 :                : } AttoptCacheEntry;
                                 43                 :                : 
                                 44                 :                : 
                                 45                 :                : /*
                                 46                 :                :  * InvalidateAttoptCacheCallback
                                 47                 :                :  *      Flush all cache entries when pg_attribute is updated.
                                 48                 :                :  *
                                 49                 :                :  * When pg_attribute is updated, we must flush the cache entry at least
                                 50                 :                :  * for that attribute.  Currently, we just flush them all.  Since attribute
                                 51                 :                :  * options are not currently used in performance-critical paths (such as
                                 52                 :                :  * query execution), this seems OK.
                                 53                 :                :  */
                                 54                 :                : static void
 4625 tgl@sss.pgh.pa.us          55                 :CBC      451472 : InvalidateAttoptCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
                                 56                 :                : {
                                 57                 :                :     HASH_SEQ_STATUS status;
                                 58                 :                :     AttoptCacheEntry *attopt;
                                 59                 :                : 
 5196 rhaas@postgresql.org       60                 :         451472 :     hash_seq_init(&status, AttoptCacheHash);
                                 61         [ +  + ]:         457760 :     while ((attopt = (AttoptCacheEntry *) hash_seq_search(&status)) != NULL)
                                 62                 :                :     {
                                 63         [ +  + ]:           6288 :         if (attopt->opts)
                                 64                 :              3 :             pfree(attopt->opts);
                                 65         [ -  + ]:           6288 :         if (hash_search(AttoptCacheHash,
  433 peter@eisentraut.org       66                 :           6288 :                         &attopt->key,
                                 67                 :                :                         HASH_REMOVE,
                                 68                 :                :                         NULL) == NULL)
 5196 rhaas@postgresql.org       69         [ #  # ]:UBC           0 :             elog(ERROR, "hash table corrupted");
                                 70                 :                :     }
 5196 rhaas@postgresql.org       71                 :CBC      451472 : }
                                 72                 :                : 
                                 73                 :                : /*
                                 74                 :                :  * InitializeAttoptCache
                                 75                 :                :  *      Initialize the attribute options cache.
                                 76                 :                :  */
                                 77                 :                : static void
                                 78                 :            239 : InitializeAttoptCache(void)
                                 79                 :                : {
                                 80                 :                :     HASHCTL     ctl;
                                 81                 :                : 
                                 82                 :                :     /* Initialize the hash table. */
                                 83                 :            239 :     ctl.keysize = sizeof(AttoptCacheKey);
                                 84                 :            239 :     ctl.entrysize = sizeof(AttoptCacheEntry);
                                 85                 :            239 :     AttoptCacheHash =
                                 86                 :            239 :         hash_create("Attopt cache", 256, &ctl,
                                 87                 :                :                     HASH_ELEM | HASH_BLOBS);
                                 88                 :                : 
                                 89                 :                :     /* Make sure we've initialized CacheMemoryContext. */
                                 90         [ -  + ]:            239 :     if (!CacheMemoryContext)
 5196 rhaas@postgresql.org       91                 :UBC           0 :         CreateCacheMemoryContext();
                                 92                 :                : 
                                 93                 :                :     /* Watch for invalidation events. */
 5196 rhaas@postgresql.org       94                 :CBC         239 :     CacheRegisterSyscacheCallback(ATTNUM,
                                 95                 :                :                                   InvalidateAttoptCacheCallback,
                                 96                 :                :                                   (Datum) 0);
                                 97                 :            239 : }
                                 98                 :                : 
                                 99                 :                : /*
                                100                 :                :  * get_attribute_options
                                101                 :                :  *      Fetch attribute options for a specified table OID.
                                102                 :                :  */
                                103                 :                : AttributeOpts *
                                104                 :          32919 : get_attribute_options(Oid attrelid, int attnum)
                                105                 :                : {
                                106                 :                :     AttoptCacheKey key;
                                107                 :                :     AttoptCacheEntry *attopt;
                                108                 :                :     AttributeOpts *result;
                                109                 :                :     HeapTuple   tp;
                                110                 :                : 
                                111                 :                :     /* Find existing cache entry, if any. */
                                112         [ +  + ]:          32919 :     if (!AttoptCacheHash)
                                113                 :            239 :         InitializeAttoptCache();
 2489 tgl@sss.pgh.pa.us         114                 :          32919 :     memset(&key, 0, sizeof(key));   /* make sure any padding bits are unset */
 5196 rhaas@postgresql.org      115                 :          32919 :     key.attrelid = attrelid;
                                116                 :          32919 :     key.attnum = attnum;
                                117                 :                :     attopt =
                                118                 :          32919 :         (AttoptCacheEntry *) hash_search(AttoptCacheHash,
                                119                 :                :                                          &key,
                                120                 :                :                                          HASH_FIND,
                                121                 :                :                                          NULL);
                                122                 :                : 
                                123                 :                :     /* Not found in Attopt cache.  Construct new cache entry. */
                                124         [ +  + ]:          32919 :     if (!attopt)
                                125                 :                :     {
                                126                 :                :         AttributeOpts *opts;
                                127                 :                : 
 5173                           128                 :          32248 :         tp = SearchSysCache2(ATTNUM,
                                129                 :                :                              ObjectIdGetDatum(attrelid),
                                130                 :                :                              Int16GetDatum(attnum));
                                131                 :                : 
                                132                 :                :         /*
                                133                 :                :          * If we don't find a valid HeapTuple, it must mean someone has
                                134                 :                :          * managed to request attribute details for a non-existent attribute.
                                135                 :                :          * We treat that case as if no options were specified.
                                136                 :                :          */
 5196                           137         [ +  + ]:          32248 :         if (!HeapTupleIsValid(tp))
                                138                 :             50 :             opts = NULL;
                                139                 :                :         else
                                140                 :                :         {
                                141                 :                :             Datum       datum;
                                142                 :                :             bool        isNull;
                                143                 :                : 
                                144                 :          32198 :             datum = SysCacheGetAttr(ATTNUM,
                                145                 :                :                                     tp,
                                146                 :                :                                     Anum_pg_attribute_attoptions,
                                147                 :                :                                     &isNull);
                                148         [ +  + ]:          32198 :             if (isNull)
                                149                 :          32195 :                 opts = NULL;
                                150                 :                :             else
                                151                 :                :             {
 5161 bruce@momjian.us          152                 :              3 :                 bytea      *bytea_opts = attribute_reloptions(datum, false);
                                153                 :                : 
 5196 rhaas@postgresql.org      154                 :              3 :                 opts = MemoryContextAlloc(CacheMemoryContext,
                                155                 :              3 :                                           VARSIZE(bytea_opts));
                                156                 :              3 :                 memcpy(opts, bytea_opts, VARSIZE(bytea_opts));
                                157                 :                :             }
                                158                 :          32198 :             ReleaseSysCache(tp);
                                159                 :                :         }
                                160                 :                : 
                                161                 :                :         /*
                                162                 :                :          * It's important to create the actual cache entry only after reading
                                163                 :                :          * pg_attribute, since the read could cause a cache flush.
                                164                 :                :          */
                                165                 :          32248 :         attopt = (AttoptCacheEntry *) hash_search(AttoptCacheHash,
                                166                 :                :                                                   &key,
                                167                 :                :                                                   HASH_ENTER,
                                168                 :                :                                                   NULL);
                                169                 :          32248 :         attopt->opts = opts;
                                170                 :                :     }
                                171                 :                : 
                                172                 :                :     /* Return results in caller's memory context. */
                                173         [ +  + ]:          32919 :     if (attopt->opts == NULL)
                                174                 :          32916 :         return NULL;
                                175                 :              3 :     result = palloc(VARSIZE(attopt->opts));
                                176                 :              3 :     memcpy(result, attopt->opts, VARSIZE(attopt->opts));
                                177                 :              3 :     return result;
                                178                 :                : }
        

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