LCOV - differential code coverage report
Current view: top level - contrib/hstore - hstore.h (source / functions) Coverage Total Hit GNC
Current: ba12a202ce1b5581dc0ed149cf3f637d7897ad5d vs 2866d8c7dbfc9d882a7d80fef93fbbe763709932 Lines: 100.0 % 4 4 4
Current Date: 2026-08-27 14:31:44 +0300 Functions: 100.0 % 1 1 1
Baseline: lcov-20260827-baseline Line coverage date bins:
Baseline Date: 2026-08-27 14:31:58 +0300 (7,30] days: 100.0 % 4 4 4
Legend: Lines:     hit not hit Function coverage date bins:
(7,30] days: 100.0 % 1 1 1

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*
                                  2                 :  * contrib/hstore/hstore.h
                                  3                 :  */
                                  4                 : #ifndef __HSTORE_H__
                                  5                 : #define __HSTORE_H__
                                  6                 : 
                                  7                 : #include "fmgr.h"
                                  8                 : #include "utils/array.h"
                                  9                 : 
                                 10                 : 
                                 11                 : /*
                                 12                 :  * HEntry: there is one of these for each key _and_ value in an hstore
                                 13                 :  *
                                 14                 :  * the position offset points to the _end_ so that we can get the length
                                 15                 :  * by subtraction from the previous entry.  the ISFIRST flag lets us tell
                                 16                 :  * whether there is a previous entry.
                                 17                 :  */
                                 18                 : typedef struct
                                 19                 : {
                                 20                 :     uint32      entry;
                                 21                 : } HEntry;
                                 22                 : 
                                 23                 : #define HENTRY_ISFIRST 0x80000000
                                 24                 : #define HENTRY_ISNULL  0x40000000
                                 25                 : #define HENTRY_POSMASK 0x3FFFFFFF
                                 26                 : 
                                 27                 : /* note possible multiple evaluations, also access to prior array element */
                                 28                 : #define HSE_ISFIRST(he_) (((he_).entry & HENTRY_ISFIRST) != 0)
                                 29                 : #define HSE_ISNULL(he_) (((he_).entry & HENTRY_ISNULL) != 0)
                                 30                 : #define HSE_ENDPOS(he_) ((he_).entry & HENTRY_POSMASK)
                                 31                 : #define HSE_OFF(he_) (HSE_ISFIRST(he_) ? 0 : HSE_ENDPOS((&(he_))[-1]))
                                 32                 : #define HSE_LEN(he_) (HSE_ISFIRST(he_)  \
                                 33                 :                       ? HSE_ENDPOS(he_) \
                                 34                 :                       : HSE_ENDPOS(he_) - HSE_ENDPOS((&(he_))[-1]))
                                 35                 : 
                                 36                 : /*
                                 37                 :  * determined by the size of "endpos" (ie HENTRY_POSMASK), though this is a
                                 38                 :  * bit academic since currently varlenas (and hence both the input and the
                                 39                 :  * whole hstore) have the same limit
                                 40                 :  */
                                 41                 : #define HSTORE_MAX_KEY_LEN 0x3FFFFFFF
                                 42                 : #define HSTORE_MAX_VALUE_LEN 0x3FFFFFFF
                                 43                 : 
                                 44                 : typedef struct
                                 45                 : {
                                 46                 :     int32       vl_len_;        /* varlena header (do not touch directly!) */
                                 47                 :     uint32      size_;          /* flags and number of items in hstore */
                                 48                 :     /* array of HEntry follows */
                                 49                 : } HStore;
                                 50                 : 
                                 51                 : /*
                                 52                 :  * It's not possible to get more than 2^28 items into an hstore, so we reserve
                                 53                 :  * the top few bits of the size field.  See hstore_compat.c for one reason
                                 54                 :  * why.  Some bits are left for future use here.  MaxAllocSize makes the
                                 55                 :  * practical count limit slightly more than 2^28 / 3, or INT_MAX / 24, the
                                 56                 :  * limit for an hstore full of 4-byte keys and null values.  Therefore, we
                                 57                 :  * don't explicitly check the format-imposed limit.
                                 58                 :  */
                                 59                 : #define HS_FLAG_NEWVERSION 0x80000000
                                 60                 : 
                                 61                 : #define HS_COUNT(hsp_) ((hsp_)->size_ & 0x0FFFFFFF)
                                 62                 : #define HS_SETCOUNT(hsp_,c_) ((hsp_)->size_ = (c_) | HS_FLAG_NEWVERSION)
                                 63                 : 
                                 64                 : 
                                 65                 : #define HSHRDSIZE   (sizeof(HStore))
                                 66                 : 
                                 67                 : /*
                                 68                 :  * "x" is a pair count, coming from an existing HS_COUNT() (as discussed, <=
                                 69                 :  * INT_MAX/24) or a Pairs array length (due to MaxAllocSize, <= INT_MAX/40).
                                 70                 :  * "lenstr" is no more than INT_MAX, that extreme case arising in
                                 71                 :  * hstore_from_arrays().  Therefore, this calculation should be limited to
                                 72                 :  * about INT_MAX / 5 + INT_MAX.
                                 73                 :  */
                                 74                 : static inline Size
    9 michael@paquier.xyz        75 GNC        4432 : hstoreCalcDataSize(Size x, Size lenstr)
                                 76                 : {
                                 77            4432 :     Size        entrysize = mul_size(x, 2 * sizeof(HEntry));
                                 78            4432 :     Size        total = add_size(HSHRDSIZE, lenstr);
                                 79                 : 
                                 80            4432 :     return add_size(entrysize, total);
                                 81                 : }
                                 82                 : 
                                 83                 : /* note multiple evaluations of x */
                                 84                 : #define ARRPTR(x)       ( (HEntry*) ( (HStore*)(x) + 1 ) )
                                 85                 : #define STRPTR(x)       ( (char*)(ARRPTR(x) + HS_COUNT((HStore*)(x)) * 2) )
                                 86                 : 
                                 87                 : /* note multiple/non evaluations */
                                 88                 : #define HSTORE_KEY(arr_,str_,i_)    ((str_) + HSE_OFF((arr_)[2*(i_)]))
                                 89                 : #define HSTORE_VAL(arr_,str_,i_)    ((str_) + HSE_OFF((arr_)[2*(i_)+1]))
                                 90                 : #define HSTORE_KEYLEN(arr_,i_)      (HSE_LEN((arr_)[2*(i_)]))
                                 91                 : #define HSTORE_VALLEN(arr_,i_)      (HSE_LEN((arr_)[2*(i_)+1]))
                                 92                 : #define HSTORE_VALISNULL(arr_,i_)   (HSE_ISNULL((arr_)[2*(i_)+1]))
                                 93                 : 
                                 94                 : /*
                                 95                 :  * currently, these following macros are the _only_ places that rely
                                 96                 :  * on internal knowledge of HEntry. Everything else should be using
                                 97                 :  * the above macros. Exception: the in-place upgrade in hstore_compat.c
                                 98                 :  * messes with entries directly.
                                 99                 :  */
                                100                 : 
                                101                 : /*
                                102                 :  * copy one key/value pair (which must be contiguous starting at
                                103                 :  * sptr_) into an under-construction hstore; dent_ is an HEntry*,
                                104                 :  * dbuf_ is the destination's string buffer, dptr_ is the current
                                105                 :  * position in the destination. lots of modification and multiple
                                106                 :  * evaluation here.
                                107                 :  */
                                108                 : #define HS_COPYITEM(dent_,dbuf_,dptr_,sptr_,klen_,vlen_,vnull_)         \
                                109                 :     do {                                                                \
                                110                 :         memcpy((dptr_), (sptr_), (klen_)+(vlen_));                      \
                                111                 :         (dptr_) += (klen_)+(vlen_);                                     \
                                112                 :         (dent_)++->entry = ((dptr_) - (dbuf_) - (vlen_)) & HENTRY_POSMASK; \
                                113                 :         (dent_)++->entry = ((((dptr_) - (dbuf_)) & HENTRY_POSMASK)       \
                                114                 :                              | ((vnull_) ? HENTRY_ISNULL : 0));         \
                                115                 :     } while(0)
                                116                 : 
                                117                 : /*
                                118                 :  * add one key/item pair, from a Pairs structure, into an
                                119                 :  * under-construction hstore
                                120                 :  */
                                121                 : #define HS_ADDITEM(dent_,dbuf_,dptr_,pair_)                             \
                                122                 :     do {                                                                \
                                123                 :         memcpy((dptr_), (pair_).key, (pair_).keylen);                   \
                                124                 :         (dptr_) += (pair_).keylen;                                      \
                                125                 :         (dent_)++->entry = ((dptr_) - (dbuf_)) & HENTRY_POSMASK;     \
                                126                 :         if ((pair_).isnull)                                             \
                                127                 :             (dent_)++->entry = ((((dptr_) - (dbuf_)) & HENTRY_POSMASK)   \
                                128                 :                                  | HENTRY_ISNULL);                      \
                                129                 :         else                                                            \
                                130                 :         {                                                               \
                                131                 :             memcpy((dptr_), (pair_).val, (pair_).vallen);               \
                                132                 :             (dptr_) += (pair_).vallen;                                  \
                                133                 :             (dent_)++->entry = ((dptr_) - (dbuf_)) & HENTRY_POSMASK; \
                                134                 :         }                                                               \
                                135                 :     } while (0)
                                136                 : 
                                137                 : /* finalize a newly-constructed hstore */
                                138                 : #define HS_FINALIZE(hsp_,count_,buf_,ptr_)                          \
                                139                 :     do {                                                            \
                                140                 :         Size _buflen = (ptr_) - (buf_);                             \
                                141                 :         if ((count_))                                               \
                                142                 :             ARRPTR(hsp_)[0].entry |= HENTRY_ISFIRST;                \
                                143                 :         if ((count_) != HS_COUNT((hsp_)))                           \
                                144                 :         {                                                           \
                                145                 :             HS_SETCOUNT((hsp_),(count_));                           \
                                146                 :             memmove(STRPTR(hsp_), (buf_), _buflen);                 \
                                147                 :         }                                                           \
                                148                 :         SET_VARSIZE((hsp_), hstoreCalcDataSize((count_), _buflen)); \
                                149                 :     } while (0)
                                150                 : 
                                151                 : /* ensure the varlena size of an existing hstore is correct */
                                152                 : #define HS_FIXSIZE(hsp_,count_)                                         \
                                153                 :     do {                                                                \
                                154                 :         Size bl = (count_) ? HSE_ENDPOS(ARRPTR(hsp_)[2*(count_)-1]) : 0; \
                                155                 :         SET_VARSIZE((hsp_), hstoreCalcDataSize((count_),bl));               \
                                156                 :     } while (0)
                                157                 : 
                                158                 : /* DatumGetHStoreP includes support for reading old-format hstore values */
                                159                 : extern PGDLLEXPORT HStore *hstoreUpgrade(Datum orig);
                                160                 : 
                                161                 : #define DatumGetHStoreP(d) hstoreUpgrade(d)
                                162                 : 
                                163                 : #define PG_GETARG_HSTORE_P(x) DatumGetHStoreP(PG_GETARG_DATUM(x))
                                164                 : 
                                165                 : 
                                166                 : /*
                                167                 :  * Pairs is a "decompressed" representation of one key/value pair.
                                168                 :  * The two strings are not necessarily null-terminated.
                                169                 :  */
                                170                 : typedef struct
                                171                 : {
                                172                 :     char       *key;
                                173                 :     char       *val;
                                174                 :     size_t      keylen;
                                175                 :     size_t      vallen;
                                176                 :     bool        isnull;         /* value is null? */
                                177                 :     bool        needfree;       /* need to pfree the value? */
                                178                 : } Pairs;
                                179                 : 
                                180                 : extern PGDLLEXPORT int hstoreUniquePairs(Pairs *a, int32 l, Size *buflen);
                                181                 : extern PGDLLEXPORT HStore *hstorePairs(Pairs *pairs, int32 pcount, Size buflen);
                                182                 : 
                                183                 : extern PGDLLEXPORT size_t hstoreCheckKeyLen(size_t len);
                                184                 : extern PGDLLEXPORT size_t hstoreCheckValLen(size_t len);
                                185                 : 
                                186                 : extern PGDLLEXPORT int hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen);
                                187                 : extern PGDLLEXPORT Pairs *hstoreArrayToPairs(ArrayType *a, int *npairs);
                                188                 : 
                                189                 : #define HStoreContainsStrategyNumber    7
                                190                 : #define HStoreExistsStrategyNumber      9
                                191                 : #define HStoreExistsAnyStrategyNumber   10
                                192                 : #define HStoreExistsAllStrategyNumber   11
                                193                 : #define HStoreOldContainsStrategyNumber 13  /* backwards compatibility */
                                194                 : 
                                195                 : /*
                                196                 :  * defining HSTORE_POLLUTE_NAMESPACE=0 will prevent use of old function names;
                                197                 :  * for now, we default to on for the benefit of people restoring old dumps
                                198                 :  */
                                199                 : #ifndef HSTORE_POLLUTE_NAMESPACE
                                200                 : #define HSTORE_POLLUTE_NAMESPACE 1
                                201                 : #endif
                                202                 : 
                                203                 : #if HSTORE_POLLUTE_NAMESPACE
                                204                 : #define HSTORE_POLLUTE(newname_,oldname_) \
                                205                 :     PG_FUNCTION_INFO_V1(oldname_);        \
                                206                 :     extern PGDLLEXPORT Datum newname_(PG_FUNCTION_ARGS);      \
                                207                 :     Datum oldname_(PG_FUNCTION_ARGS) { return newname_(fcinfo); } \
                                208                 :     extern int no_such_variable
                                209                 : #else
                                210                 : #define HSTORE_POLLUTE(newname_,oldname_) \
                                211                 :     extern int no_such_variable
                                212                 : #endif
                                213                 : 
                                214                 : #endif                          /* __HSTORE_H__ */
        

Generated by: LCOV version 2.0-1