LCOV - differential code coverage report
Current view: top level - contrib/hstore - hstore_gin.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 94.1 % 85 80 5 80
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 7 7 7
Baseline: 16@8cea358b128 Branches: 66.2 % 68 45 23 45
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: 94.1 % 85 80 5 80
Function coverage date bins:
(240..) days: 100.0 % 7 7 7
Branch coverage date bins:
(240..) days: 66.2 % 68 45 23 45

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*
                                  2                 :                :  * contrib/hstore/hstore_gin.c
                                  3                 :                :  */
                                  4                 :                : #include "postgres.h"
                                  5                 :                : 
                                  6                 :                : #include "access/gin.h"
                                  7                 :                : #include "access/stratnum.h"
                                  8                 :                : #include "catalog/pg_type.h"
                                  9                 :                : 
                                 10                 :                : #include "hstore.h"
                                 11                 :                : 
                                 12                 :                : 
                                 13                 :                : /*
                                 14                 :                :  * When using a GIN index for hstore, we choose to index both keys and values.
                                 15                 :                :  * The storage format is "text" values, with K, V, or N prepended to the string
                                 16                 :                :  * to indicate key, value, or null values.  (As of 9.1 it might be better to
                                 17                 :                :  * store null values as nulls, but we'll keep it this way for on-disk
                                 18                 :                :  * compatibility.)
                                 19                 :                :  */
                                 20                 :                : #define KEYFLAG     'K'
                                 21                 :                : #define VALFLAG     'V'
                                 22                 :                : #define NULLFLAG    'N'
                                 23                 :                : 
 6241 teodor@sigaev.ru           24                 :CBC           8 : PG_FUNCTION_INFO_V1(gin_extract_hstore);
                                 25                 :                : 
                                 26                 :                : /* Build an indexable text value */
                                 27                 :                : static text *
 4844 tgl@sss.pgh.pa.us          28                 :           9588 : makeitem(char *str, int len, char flag)
                                 29                 :                : {
                                 30                 :                :     text       *item;
                                 31                 :                : 
 5995 bruce@momjian.us           32                 :           9588 :     item = (text *) palloc(VARHDRSZ + len + 1);
 6241 teodor@sigaev.ru           33                 :           9588 :     SET_VARSIZE(item, VARHDRSZ + len + 1);
                                 34                 :                : 
 4844 tgl@sss.pgh.pa.us          35                 :           9588 :     *VARDATA(item) = flag;
                                 36                 :                : 
 5995 bruce@momjian.us           37   [ +  +  +  - ]:           9588 :     if (str && len > 0)
                                 38                 :           9585 :         memcpy(VARDATA(item) + 1, str, len);
                                 39                 :                : 
 6241 teodor@sigaev.ru           40                 :           9588 :     return item;
                                 41                 :                : }
                                 42                 :                : 
                                 43                 :                : Datum
                                 44                 :           1007 : gin_extract_hstore(PG_FUNCTION_ARGS)
                                 45                 :                : {
 2400 tgl@sss.pgh.pa.us          46                 :           1007 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 5995 bruce@momjian.us           47                 :           1007 :     int32      *nentries = (int32 *) PG_GETARG_POINTER(1);
                                 48                 :           1007 :     Datum      *entries = NULL;
 5161                            49                 :           1007 :     HEntry     *hsent = ARRPTR(hs);
                                 50                 :           1007 :     char       *ptr = STRPTR(hs);
                                 51                 :           1007 :     int         count = HS_COUNT(hs);
                                 52                 :                :     int         i;
                                 53                 :                : 
 5310 tgl@sss.pgh.pa.us          54                 :           1007 :     *nentries = 2 * count;
                                 55         [ +  + ]:           1007 :     if (count)
                                 56                 :            890 :         entries = (Datum *) palloc(sizeof(Datum) * 2 * count);
                                 57                 :                : 
                                 58         [ +  + ]:           5796 :     for (i = 0; i < count; ++i)
                                 59                 :                :     {
                                 60                 :                :         text       *item;
                                 61                 :                : 
 3069                            62         [ +  + ]:           4789 :         item = makeitem(HSTORE_KEY(hsent, ptr, i),
                                 63         [ +  + ]:           4789 :                         HSTORE_KEYLEN(hsent, i),
                                 64                 :                :                         KEYFLAG);
 5161 bruce@momjian.us           65                 :           4789 :         entries[2 * i] = PointerGetDatum(item);
                                 66                 :                : 
 3069 tgl@sss.pgh.pa.us          67         [ +  + ]:           4789 :         if (HSTORE_VALISNULL(hsent, i))
 4844                            68                 :              3 :             item = makeitem(NULL, 0, NULLFLAG);
                                 69                 :                :         else
 3069                            70         [ +  - ]:           4786 :             item = makeitem(HSTORE_VAL(hsent, ptr, i),
                                 71         [ -  + ]:           4786 :                             HSTORE_VALLEN(hsent, i),
                                 72                 :                :                             VALFLAG);
 5161 bruce@momjian.us           73                 :           4789 :         entries[2 * i + 1] = PointerGetDatum(item);
                                 74                 :                :     }
                                 75                 :                : 
 6241 teodor@sigaev.ru           76                 :           1007 :     PG_RETURN_POINTER(entries);
                                 77                 :                : }
                                 78                 :                : 
                                 79                 :              8 : PG_FUNCTION_INFO_V1(gin_extract_hstore_query);
                                 80                 :                : 
                                 81                 :                : Datum
                                 82                 :             12 : gin_extract_hstore_query(PG_FUNCTION_ARGS)
                                 83                 :                : {
 4844 tgl@sss.pgh.pa.us          84                 :             12 :     int32      *nentries = (int32 *) PG_GETARG_POINTER(1);
 6241 teodor@sigaev.ru           85                 :             12 :     StrategyNumber strategy = PG_GETARG_UINT16(2);
 4844 tgl@sss.pgh.pa.us          86                 :             12 :     int32      *searchMode = (int32 *) PG_GETARG_POINTER(6);
                                 87                 :                :     Datum      *entries;
                                 88                 :                : 
 5995 bruce@momjian.us           89         [ +  + ]:             12 :     if (strategy == HStoreContainsStrategyNumber)
                                 90                 :                :     {
                                 91                 :                :         /* Query is an hstore, so just apply gin_extract_hstore... */
                                 92                 :                :         entries = (Datum *)
 4844 tgl@sss.pgh.pa.us          93                 :              6 :             DatumGetPointer(DirectFunctionCall2(gin_extract_hstore,
                                 94                 :                :                                                 PG_GETARG_DATUM(0),
                                 95                 :                :                                                 PointerGetDatum(nentries)));
                                 96                 :                :         /* ... except that "contains {}" requires a full index scan */
                                 97         [ -  + ]:              6 :         if (entries == NULL)
 4844 tgl@sss.pgh.pa.us          98                 :UBC           0 :             *searchMode = GIN_SEARCH_MODE_ALL;
                                 99                 :                :     }
 5995 bruce@momjian.us          100         [ +  + ]:CBC           6 :     else if (strategy == HStoreExistsStrategyNumber)
                                101                 :                :     {
 4844 tgl@sss.pgh.pa.us         102                 :              2 :         text       *query = PG_GETARG_TEXT_PP(0);
                                103                 :                :         text       *item;
                                104                 :                : 
 6241 teodor@sigaev.ru          105                 :              2 :         *nentries = 1;
 5995 bruce@momjian.us          106                 :              2 :         entries = (Datum *) palloc(sizeof(Datum));
 4844 tgl@sss.pgh.pa.us         107   [ -  +  -  -  :              2 :         item = makeitem(VARDATA_ANY(query), VARSIZE_ANY_EXHDR(query), KEYFLAG);
                                     -  -  -  -  -  
                                           +  -  + ]
 6241 teodor@sigaev.ru          108                 :              2 :         entries[0] = PointerGetDatum(item);
                                109                 :                :     }
 5310 tgl@sss.pgh.pa.us         110   [ +  +  +  - ]:              4 :     else if (strategy == HStoreExistsAnyStrategyNumber ||
                                111                 :                :              strategy == HStoreExistsAllStrategyNumber)
                                112                 :              4 :     {
 5161 bruce@momjian.us          113                 :              4 :         ArrayType  *query = PG_GETARG_ARRAYTYPE_P(0);
                                114                 :                :         Datum      *key_datums;
                                115                 :                :         bool       *key_nulls;
                                116                 :                :         int         key_count;
                                117                 :                :         int         i,
                                118                 :                :                     j;
                                119                 :                :         text       *item;
                                120                 :                : 
  653 peter@eisentraut.org      121                 :              4 :         deconstruct_array_builtin(query, TEXTOID, &key_datums, &key_nulls, &key_count);
                                122                 :                : 
 5310 tgl@sss.pgh.pa.us         123                 :              4 :         entries = (Datum *) palloc(sizeof(Datum) * key_count);
                                124                 :                : 
                                125         [ +  + ]:             12 :         for (i = 0, j = 0; i < key_count; ++i)
                                126                 :                :         {
                                127                 :                :             /* Nulls in the array are ignored, cf hstoreArrayToPairs */
                                128         [ -  + ]:              8 :             if (key_nulls[i])
 5310 tgl@sss.pgh.pa.us         129                 :UBC           0 :                 continue;
 4844 tgl@sss.pgh.pa.us         130                 :CBC           8 :             item = makeitem(VARDATA(key_datums[i]), VARSIZE(key_datums[i]) - VARHDRSZ, KEYFLAG);
 5310                           131                 :              8 :             entries[j++] = PointerGetDatum(item);
                                132                 :                :         }
                                133                 :                : 
 4844                           134                 :              4 :         *nentries = j;
                                135                 :                :         /* ExistsAll with no keys should match everything */
                                136   [ -  +  -  - ]:              4 :         if (j == 0 && strategy == HStoreExistsAllStrategyNumber)
 4844 tgl@sss.pgh.pa.us         137                 :UBC           0 :             *searchMode = GIN_SEARCH_MODE_ALL;
                                138                 :                :     }
                                139                 :                :     else
                                140                 :                :     {
                                141         [ #  # ]:              0 :         elog(ERROR, "unrecognized strategy number: %d", strategy);
                                142                 :                :         entries = NULL;         /* keep compiler quiet */
                                143                 :                :     }
                                144                 :                : 
 4844 tgl@sss.pgh.pa.us         145                 :CBC          12 :     PG_RETURN_POINTER(entries);
                                146                 :                : }
                                147                 :                : 
 6241 teodor@sigaev.ru          148                 :              8 : PG_FUNCTION_INFO_V1(gin_consistent_hstore);
                                149                 :                : 
                                150                 :                : Datum
                                151                 :            955 : gin_consistent_hstore(PG_FUNCTION_ARGS)
                                152                 :                : {
 5844 tgl@sss.pgh.pa.us         153                 :            955 :     bool       *check = (bool *) PG_GETARG_POINTER(0);
 6241 teodor@sigaev.ru          154                 :            955 :     StrategyNumber strategy = PG_GETARG_UINT16(1);
                                155                 :                : 
                                156                 :                :     /* HStore      *query = PG_GETARG_HSTORE_P(2); */
 5310 tgl@sss.pgh.pa.us         157                 :            955 :     int32       nkeys = PG_GETARG_INT32(3);
                                158                 :                : 
                                159                 :                :     /* Pointer     *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
 5499                           160                 :            955 :     bool       *recheck = (bool *) PG_GETARG_POINTER(5);
 5995 bruce@momjian.us          161                 :            955 :     bool        res = true;
                                162                 :                :     int32       i;
                                163                 :                : 
                                164         [ +  + ]:            955 :     if (strategy == HStoreContainsStrategyNumber)
                                165                 :                :     {
                                166                 :                :         /*
                                167                 :                :          * Index doesn't have information about correspondence of keys and
                                168                 :                :          * values, so we need recheck.  However, if not all the keys are
                                169                 :                :          * present, we can fail at once.
                                170                 :                :          */
 5844 tgl@sss.pgh.pa.us         171                 :            235 :         *recheck = true;
 4844                           172         [ +  + ]:            375 :         for (i = 0; i < nkeys; i++)
                                173                 :                :         {
                                174         [ +  + ]:            339 :             if (!check[i])
                                175                 :                :             {
 6241 teodor@sigaev.ru          176                 :            199 :                 res = false;
 4844 tgl@sss.pgh.pa.us         177                 :            199 :                 break;
                                178                 :                :             }
                                179                 :                :         }
                                180                 :                :     }
 5995 bruce@momjian.us          181         [ +  + ]:            720 :     else if (strategy == HStoreExistsStrategyNumber)
                                182                 :                :     {
                                183                 :                :         /* Existence of key is guaranteed in default search mode */
 4844 tgl@sss.pgh.pa.us         184                 :            194 :         *recheck = false;
 6241 teodor@sigaev.ru          185                 :            194 :         res = true;
                                186                 :                :     }
 5310 tgl@sss.pgh.pa.us         187         [ +  + ]:            526 :     else if (strategy == HStoreExistsAnyStrategyNumber)
                                188                 :                :     {
                                189                 :                :         /* Existence of key is guaranteed in default search mode */
 4844                           190                 :            339 :         *recheck = false;
 5310                           191                 :            339 :         res = true;
                                192                 :                :     }
                                193         [ +  - ]:            187 :     else if (strategy == HStoreExistsAllStrategyNumber)
                                194                 :                :     {
                                195                 :                :         /* Testing for all the keys being present gives an exact result */
 4844                           196                 :            187 :         *recheck = false;
                                197         [ +  + ]:            272 :         for (i = 0; i < nkeys; i++)
                                198                 :                :         {
 5310                           199         [ +  + ]:            230 :             if (!check[i])
                                200                 :                :             {
                                201                 :            145 :                 res = false;
 4844                           202                 :            145 :                 break;
                                203                 :                :             }
                                204                 :                :         }
                                205                 :                :     }
                                206                 :                :     else
 4844 tgl@sss.pgh.pa.us         207         [ #  # ]:UBC           0 :         elog(ERROR, "unrecognized strategy number: %d", strategy);
                                208                 :                : 
 6241 teodor@sigaev.ru          209                 :CBC         955 :     PG_RETURN_BOOL(res);
                                210                 :                : }
        

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