LCOV - differential code coverage report
Current view: top level - contrib/hstore - hstore_op.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 90.9 % 574 522 52 522
Current Date: 2024-04-14 14:21:10 Functions: 66.3 % 86 57 29 57
Baseline: 16@8cea358b128 Branches: 73.2 % 452 331 121 331
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: 90.9 % 574 522 52 522
Function coverage date bins:
(240..) days: 66.3 % 86 57 29 57
Branch coverage date bins:
(240..) days: 73.2 % 452 331 121 331

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*
                                  2                 :                :  * contrib/hstore/hstore_op.c
                                  3                 :                :  */
                                  4                 :                : #include "postgres.h"
                                  5                 :                : 
                                  6                 :                : #include "access/htup_details.h"
                                  7                 :                : #include "catalog/pg_type.h"
                                  8                 :                : #include "common/hashfn.h"
                                  9                 :                : #include "funcapi.h"
                                 10                 :                : #include "hstore.h"
                                 11                 :                : #include "utils/builtins.h"
                                 12                 :                : #include "utils/memutils.h"
                                 13                 :                : 
                                 14                 :                : /* old names for C functions */
 5161 bruce@momjian.us           15                 :UBC           0 : HSTORE_POLLUTE(hstore_fetchval, fetchval);
                                 16                 :              0 : HSTORE_POLLUTE(hstore_exists, exists);
                                 17                 :              0 : HSTORE_POLLUTE(hstore_defined, defined);
                                 18                 :              0 : HSTORE_POLLUTE(hstore_delete, delete);
                                 19                 :              0 : HSTORE_POLLUTE(hstore_concat, hs_concat);
                                 20                 :              0 : HSTORE_POLLUTE(hstore_contains, hs_contains);
                                 21                 :              0 : HSTORE_POLLUTE(hstore_contained, hs_contained);
                                 22                 :              0 : HSTORE_POLLUTE(hstore_akeys, akeys);
                                 23                 :              0 : HSTORE_POLLUTE(hstore_avals, avals);
                                 24                 :              0 : HSTORE_POLLUTE(hstore_skeys, skeys);
                                 25                 :              0 : HSTORE_POLLUTE(hstore_svals, svals);
                                 26                 :              0 : HSTORE_POLLUTE(hstore_each, each);
                                 27                 :                : 
                                 28                 :                : 
                                 29                 :                : /*
                                 30                 :                :  * We're often finding a sequence of keys in ascending order. The
                                 31                 :                :  * "lowbound" parameter is used to cache lower bounds of searches
                                 32                 :                :  * between calls, based on this assumption. Pass NULL for it for
                                 33                 :                :  * one-off or unordered searches.
                                 34                 :                :  */
                                 35                 :                : int
 5161 bruce@momjian.us           36                 :CBC        9456 : hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen)
                                 37                 :                : {
 5310 tgl@sss.pgh.pa.us          38                 :           9456 :     HEntry     *entries = ARRPTR(hs);
 5161 bruce@momjian.us           39         [ +  + ]:           9456 :     int         stopLow = lowbound ? *lowbound : 0;
                                 40                 :           9456 :     int         stopHigh = HS_COUNT(hs);
                                 41                 :                :     int         stopMiddle;
 6402                            42                 :           9456 :     char       *base = STRPTR(hs);
                                 43                 :                : 
 5310 tgl@sss.pgh.pa.us          44         [ +  + ]:          24849 :     while (stopLow < stopHigh)
                                 45                 :                :     {
                                 46                 :                :         int         difference;
                                 47                 :                : 
                                 48                 :          18556 :         stopMiddle = stopLow + (stopHigh - stopLow) / 2;
                                 49                 :                : 
 3069                            50   [ +  +  +  + ]:          18556 :         if (HSTORE_KEYLEN(entries, stopMiddle) == keylen)
                                 51         [ +  + ]:           7413 :             difference = memcmp(HSTORE_KEY(entries, base, stopMiddle), key, keylen);
                                 52                 :                :         else
                                 53   [ +  +  +  + ]:          11143 :             difference = (HSTORE_KEYLEN(entries, stopMiddle) > keylen) ? 1 : -1;
                                 54                 :                : 
 6431 teodor@sigaev.ru           55         [ +  + ]:          18556 :         if (difference == 0)
                                 56                 :                :         {
 5310 tgl@sss.pgh.pa.us          57         [ +  + ]:           3163 :             if (lowbound)
                                 58                 :           2519 :                 *lowbound = stopMiddle + 1;
                                 59                 :           3163 :             return stopMiddle;
                                 60                 :                :         }
 6431 teodor@sigaev.ru           61         [ +  + ]:          15393 :         else if (difference < 0)
 5310 tgl@sss.pgh.pa.us          62                 :           8228 :             stopLow = stopMiddle + 1;
                                 63                 :                :         else
                                 64                 :           7165 :             stopHigh = stopMiddle;
                                 65                 :                :     }
                                 66                 :                : 
                                 67         [ +  + ]:           6293 :     if (lowbound)
                                 68                 :           5329 :         *lowbound = stopLow;
                                 69                 :           6293 :     return -1;
                                 70                 :                : }
                                 71                 :                : 
                                 72                 :                : Pairs *
                                 73                 :           2842 : hstoreArrayToPairs(ArrayType *a, int *npairs)
                                 74                 :                : {
                                 75                 :                :     Datum      *key_datums;
                                 76                 :                :     bool       *key_nulls;
                                 77                 :                :     int         key_count;
                                 78                 :                :     Pairs      *key_pairs;
                                 79                 :                :     int         bufsiz;
                                 80                 :                :     int         i,
                                 81                 :                :                 j;
                                 82                 :                : 
  653 peter@eisentraut.org       83                 :           2842 :     deconstruct_array_builtin(a, TEXTOID, &key_datums, &key_nulls, &key_count);
                                 84                 :                : 
 5310 tgl@sss.pgh.pa.us          85         [ +  + ]:           2842 :     if (key_count == 0)
                                 86                 :                :     {
                                 87                 :              5 :         *npairs = 0;
                                 88                 :              5 :         return NULL;
                                 89                 :                :     }
                                 90                 :                : 
                                 91                 :                :     /*
                                 92                 :                :      * A text array uses at least eight bytes per element, so any overflow in
                                 93                 :                :      * "key_count * sizeof(Pairs)" is small enough for palloc() to catch.
                                 94                 :                :      * However, credible improvements to the array format could invalidate
                                 95                 :                :      * that assumption.  Therefore, use an explicit check rather than relying
                                 96                 :                :      * on palloc() to complain.
                                 97                 :                :      */
 3709 noah@leadboat.com          98         [ -  + ]:           2837 :     if (key_count > MaxAllocSize / sizeof(Pairs))
 3709 noah@leadboat.com          99         [ #  # ]:UBC           0 :         ereport(ERROR,
                                100                 :                :                 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                                101                 :                :                  errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
                                102                 :                :                         key_count, (int) (MaxAllocSize / sizeof(Pairs)))));
                                103                 :                : 
 5310 tgl@sss.pgh.pa.us         104                 :CBC        2837 :     key_pairs = palloc(sizeof(Pairs) * key_count);
                                105                 :                : 
                                106         [ +  + ]:           8516 :     for (i = 0, j = 0; i < key_count; i++)
                                107                 :                :     {
                                108         [ +  - ]:           5679 :         if (!key_nulls[i])
                                109                 :                :         {
                                110                 :           5679 :             key_pairs[j].key = VARDATA(key_datums[i]);
                                111                 :           5679 :             key_pairs[j].keylen = VARSIZE(key_datums[i]) - VARHDRSZ;
                                112                 :           5679 :             key_pairs[j].val = NULL;
                                113                 :           5679 :             key_pairs[j].vallen = 0;
                                114                 :           5679 :             key_pairs[j].needfree = 0;
                                115                 :           5679 :             key_pairs[j].isnull = 1;
                                116                 :           5679 :             j++;
                                117                 :                :         }
                                118                 :                :     }
                                119                 :                : 
                                120                 :           2837 :     *npairs = hstoreUniquePairs(key_pairs, j, &bufsiz);
                                121                 :                : 
                                122                 :           2837 :     return key_pairs;
                                123                 :                : }
                                124                 :                : 
                                125                 :                : 
                                126                 :              8 : PG_FUNCTION_INFO_V1(hstore_fetchval);
                                127                 :                : Datum
                                128                 :              6 : hstore_fetchval(PG_FUNCTION_ARGS)
                                129                 :                : {
 2400                           130                 :              6 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 5310                           131                 :              6 :     text       *key = PG_GETARG_TEXT_PP(1);
                                132                 :              6 :     HEntry     *entries = ARRPTR(hs);
                                133                 :                :     text       *out;
 5161 bruce@momjian.us          134                 :UBC           0 :     int         idx = hstoreFindKey(hs, NULL,
 5310 tgl@sss.pgh.pa.us         135   [ -  +  -  -  :CBC          12 :                                     VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key));
                                     -  -  -  -  -  
                                           +  -  + ]
                                136                 :                : 
 3069                           137   [ +  +  +  + ]:              6 :     if (idx < 0 || HSTORE_VALISNULL(entries, idx))
 6431 teodor@sigaev.ru          138                 :              2 :         PG_RETURN_NULL();
                                139                 :                : 
 3069 tgl@sss.pgh.pa.us         140         [ +  - ]:              4 :     out = cstring_to_text_with_len(HSTORE_VAL(entries, STRPTR(hs), idx),
                                141         [ -  + ]:              4 :                                    HSTORE_VALLEN(entries, idx));
                                142                 :                : 
 5864                           143                 :              4 :     PG_RETURN_TEXT_P(out);
                                144                 :                : }
                                145                 :                : 
                                146                 :                : 
 5310                           147                 :             16 : PG_FUNCTION_INFO_V1(hstore_exists);
                                148                 :                : Datum
                                149                 :           1440 : hstore_exists(PG_FUNCTION_ARGS)
                                150                 :                : {
 2400                           151                 :           1440 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 5310                           152                 :           1440 :     text       *key = PG_GETARG_TEXT_PP(1);
 5161 bruce@momjian.us          153                 :UBC           0 :     int         idx = hstoreFindKey(hs, NULL,
 5310 tgl@sss.pgh.pa.us         154   [ -  +  -  -  :CBC        2880 :                                     VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key));
                                     -  -  -  -  -  
                                           +  -  + ]
                                155                 :                : 
                                156                 :           1440 :     PG_RETURN_BOOL(idx >= 0);
                                157                 :                : }
                                158                 :                : 
                                159                 :                : 
                                160                 :              8 : PG_FUNCTION_INFO_V1(hstore_exists_any);
                                161                 :                : Datum
                                162                 :           1727 : hstore_exists_any(PG_FUNCTION_ARGS)
                                163                 :                : {
 2400                           164                 :           1727 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 5310                           165                 :           1727 :     ArrayType  *keys = PG_GETARG_ARRAYTYPE_P(1);
                                166                 :                :     int         nkeys;
 5161 bruce@momjian.us          167                 :           1727 :     Pairs      *key_pairs = hstoreArrayToPairs(keys, &nkeys);
                                168                 :                :     int         i;
                                169                 :           1727 :     int         lowbound = 0;
                                170                 :           1727 :     bool        res = false;
                                171                 :                : 
                                172                 :                :     /*
                                173                 :                :      * we exploit the fact that the pairs list is already sorted into strictly
                                174                 :                :      * increasing order to narrow the hstoreFindKey search; each search can
                                175                 :                :      * start one entry past the previous "found" entry, or at the lower bound
                                176                 :                :      * of the last search.
                                177                 :                :      */
 4844 tgl@sss.pgh.pa.us         178         [ +  + ]:           3580 :     for (i = 0; i < nkeys; i++)
                                179                 :                :     {
 5161 bruce@momjian.us          180                 :           2867 :         int         idx = hstoreFindKey(hs, &lowbound,
 2489 tgl@sss.pgh.pa.us         181                 :           2867 :                                         key_pairs[i].key, key_pairs[i].keylen);
                                182                 :                : 
 5310                           183         [ +  + ]:           2867 :         if (idx >= 0)
                                184                 :                :         {
                                185                 :           1014 :             res = true;
 4844                           186                 :           1014 :             break;
                                187                 :                :         }
                                188                 :                :     }
                                189                 :                : 
 5310                           190                 :           1727 :     PG_RETURN_BOOL(res);
                                191                 :                : }
                                192                 :                : 
                                193                 :                : 
                                194                 :              8 : PG_FUNCTION_INFO_V1(hstore_exists_all);
                                195                 :                : Datum
                                196                 :           1097 : hstore_exists_all(PG_FUNCTION_ARGS)
                                197                 :                : {
 2400                           198                 :           1097 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 5310                           199                 :           1097 :     ArrayType  *keys = PG_GETARG_ARRAYTYPE_P(1);
                                200                 :                :     int         nkeys;
 5161 bruce@momjian.us          201                 :           1097 :     Pairs      *key_pairs = hstoreArrayToPairs(keys, &nkeys);
                                202                 :                :     int         i;
                                203                 :           1097 :     int         lowbound = 0;
 4844 tgl@sss.pgh.pa.us         204                 :           1097 :     bool        res = true;
                                205                 :                : 
                                206                 :                :     /*
                                207                 :                :      * we exploit the fact that the pairs list is already sorted into strictly
                                208                 :                :      * increasing order to narrow the hstoreFindKey search; each search can
                                209                 :                :      * start one entry past the previous "found" entry, or at the lower bound
                                210                 :                :      * of the last search.
                                211                 :                :      */
                                212         [ +  + ]:           1507 :     for (i = 0; i < nkeys; i++)
                                213                 :                :     {
 5161 bruce@momjian.us          214                 :           1378 :         int         idx = hstoreFindKey(hs, &lowbound,
 2489 tgl@sss.pgh.pa.us         215                 :           1378 :                                         key_pairs[i].key, key_pairs[i].keylen);
                                216                 :                : 
 5310                           217         [ +  + ]:           1378 :         if (idx < 0)
                                218                 :                :         {
                                219                 :            968 :             res = false;
 4844                           220                 :            968 :             break;
                                221                 :                :         }
                                222                 :                :     }
                                223                 :                : 
 5310                           224                 :           1097 :     PG_RETURN_BOOL(res);
                                225                 :                : }
                                226                 :                : 
                                227                 :                : 
                                228                 :             15 : PG_FUNCTION_INFO_V1(hstore_defined);
                                229                 :                : Datum
                                230                 :              4 : hstore_defined(PG_FUNCTION_ARGS)
                                231                 :                : {
 2400                           232                 :              4 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 5310                           233                 :              4 :     text       *key = PG_GETARG_TEXT_PP(1);
                                234                 :              4 :     HEntry     *entries = ARRPTR(hs);
 5161 bruce@momjian.us          235                 :UBC           0 :     int         idx = hstoreFindKey(hs, NULL,
 5310 tgl@sss.pgh.pa.us         236   [ -  +  -  -  :CBC           8 :                                     VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key));
                                     -  -  -  -  -  
                                           +  -  + ]
 3069                           237   [ +  +  +  + ]:              4 :     bool        res = (idx >= 0 && !HSTORE_VALISNULL(entries, idx));
                                238                 :                : 
 6431 teodor@sigaev.ru          239                 :              4 :     PG_RETURN_BOOL(res);
                                240                 :                : }
                                241                 :                : 
                                242                 :                : 
 5310 tgl@sss.pgh.pa.us         243                 :              8 : PG_FUNCTION_INFO_V1(hstore_delete);
                                244                 :                : Datum
                                245                 :             11 : hstore_delete(PG_FUNCTION_ARGS)
                                246                 :                : {
 2400                           247                 :             11 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 5310                           248                 :             11 :     text       *key = PG_GETARG_TEXT_PP(1);
 5161 bruce@momjian.us          249         [ -  + ]:             11 :     char       *keyptr = VARDATA_ANY(key);
                                250   [ -  +  -  -  :             11 :     int         keylen = VARSIZE_ANY_EXHDR(key);
                                     -  -  -  -  -  
                                                 + ]
 6255 tgl@sss.pgh.pa.us         251                 :             11 :     HStore     *out = palloc(VARSIZE(hs));
                                252                 :                :     char       *bufs,
                                253                 :                :                *bufd,
                                254                 :                :                *ptrd;
                                255                 :                :     HEntry     *es,
                                256                 :                :                *ed;
                                257                 :                :     int         i;
 5161 bruce@momjian.us          258                 :             11 :     int         count = HS_COUNT(hs);
                                259                 :             11 :     int         outcount = 0;
                                260                 :                : 
 6255 tgl@sss.pgh.pa.us         261                 :             11 :     SET_VARSIZE(out, VARSIZE(hs));
 5161 bruce@momjian.us          262                 :             11 :     HS_SETCOUNT(out, count);    /* temporary! */
                                263                 :                : 
 5310 tgl@sss.pgh.pa.us         264                 :             11 :     bufs = STRPTR(hs);
 6402 bruce@momjian.us          265                 :             11 :     es = ARRPTR(hs);
 5310 tgl@sss.pgh.pa.us         266                 :             11 :     bufd = ptrd = STRPTR(out);
 6402 bruce@momjian.us          267                 :             11 :     ed = ARRPTR(out);
                                268                 :                : 
 5310 tgl@sss.pgh.pa.us         269         [ +  + ]:             44 :     for (i = 0; i < count; ++i)
                                270                 :                :     {
 3069                           271         [ +  + ]:             33 :         int         len = HSTORE_KEYLEN(es, i);
                                272         [ +  + ]:             33 :         char       *ptrs = HSTORE_KEY(es, bufs, i);
                                273                 :                : 
 4863 rhaas@postgresql.org      274   [ +  -  +  + ]:             33 :         if (!(len == keylen && memcmp(ptrs, keyptr, keylen) == 0))
                                275                 :                :         {
 3069 tgl@sss.pgh.pa.us         276         [ -  + ]:             24 :             int         vallen = HSTORE_VALLEN(es, i);
                                277                 :                : 
                                278                 :             24 :             HS_COPYITEM(ed, bufd, ptrd, ptrs, len, vallen,
                                279                 :                :                         HSTORE_VALISNULL(es, i));
 5310                           280                 :             24 :             ++outcount;
                                281                 :                :         }
                                282                 :                :     }
                                283                 :                : 
 5161 bruce@momjian.us          284   [ +  -  +  + ]:             11 :     HS_FINALIZE(out, outcount, bufd, ptrd);
                                285                 :                : 
 5310 tgl@sss.pgh.pa.us         286                 :             11 :     PG_RETURN_POINTER(out);
                                287                 :                : }
                                288                 :                : 
                                289                 :                : 
                                290                 :              8 : PG_FUNCTION_INFO_V1(hstore_delete_array);
                                291                 :                : Datum
                                292                 :             12 : hstore_delete_array(PG_FUNCTION_ARGS)
                                293                 :                : {
 2400                           294                 :             12 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 5310                           295                 :             12 :     HStore     *out = palloc(VARSIZE(hs));
 5161 bruce@momjian.us          296                 :             12 :     int         hs_count = HS_COUNT(hs);
                                297                 :                :     char       *ps,
                                298                 :                :                *bufd,
                                299                 :                :                *pd;
                                300                 :                :     HEntry     *es,
                                301                 :                :                *ed;
                                302                 :                :     int         i,
                                303                 :                :                 j;
                                304                 :             12 :     int         outcount = 0;
 5310 tgl@sss.pgh.pa.us         305                 :             12 :     ArrayType  *key_array = PG_GETARG_ARRAYTYPE_P(1);
                                306                 :                :     int         nkeys;
 5161 bruce@momjian.us          307                 :             12 :     Pairs      *key_pairs = hstoreArrayToPairs(key_array, &nkeys);
                                308                 :                : 
 5310 tgl@sss.pgh.pa.us         309                 :             12 :     SET_VARSIZE(out, VARSIZE(hs));
 5161 bruce@momjian.us          310                 :             12 :     HS_SETCOUNT(out, hs_count); /* temporary! */
                                311                 :                : 
 5310 tgl@sss.pgh.pa.us         312                 :             12 :     ps = STRPTR(hs);
                                313                 :             12 :     es = ARRPTR(hs);
                                314                 :             12 :     bufd = pd = STRPTR(out);
                                315                 :             12 :     ed = ARRPTR(out);
                                316                 :                : 
                                317         [ +  + ]:             12 :     if (nkeys == 0)
                                318                 :                :     {
                                319                 :                :         /* return a copy of the input, unchanged */
                                320                 :              3 :         memcpy(out, hs, VARSIZE(hs));
                                321         [ +  - ]:              3 :         HS_FIXSIZE(out, hs_count);
                                322                 :              3 :         HS_SETCOUNT(out, hs_count);
                                323                 :              3 :         PG_RETURN_POINTER(out);
                                324                 :                :     }
                                325                 :                : 
                                326                 :                :     /*
                                327                 :                :      * this is in effect a merge between hs and key_pairs, both of which are
                                328                 :                :      * already sorted by (keylen,key); we take keys from hs only
                                329                 :                :      */
                                330                 :                : 
 5161 bruce@momjian.us          331         [ +  + ]:             36 :     for (i = j = 0; i < hs_count;)
                                332                 :                :     {
                                333                 :                :         int         difference;
                                334                 :                : 
 5310 tgl@sss.pgh.pa.us         335         [ -  + ]:             27 :         if (j >= nkeys)
 5310 tgl@sss.pgh.pa.us         336                 :UBC           0 :             difference = -1;
                                337                 :                :         else
                                338                 :                :         {
 3069 tgl@sss.pgh.pa.us         339         [ +  + ]:CBC          27 :             int         skeylen = HSTORE_KEYLEN(es, i);
                                340                 :                : 
 5310                           341         [ +  - ]:             27 :             if (skeylen == key_pairs[j].keylen)
 3069                           342                 :             27 :                 difference = memcmp(HSTORE_KEY(es, ps, i),
 4863 rhaas@postgresql.org      343                 :             27 :                                     key_pairs[j].key,
                                344         [ +  + ]:             27 :                                     key_pairs[j].keylen);
                                345                 :                :             else
 5310 tgl@sss.pgh.pa.us         346         [ #  # ]:UBC           0 :                 difference = (skeylen > key_pairs[j].keylen) ? 1 : -1;
                                347                 :                :         }
                                348                 :                : 
 5310 tgl@sss.pgh.pa.us         349         [ -  + ]:CBC          27 :         if (difference > 0)
 5310 tgl@sss.pgh.pa.us         350                 :UBC           0 :             ++j;
 5310 tgl@sss.pgh.pa.us         351         [ +  + ]:CBC          27 :         else if (difference == 0)
                                352                 :             14 :             ++i, ++j;
                                353                 :                :         else
                                354                 :                :         {
                                355   [ +  +  -  +  :             13 :             HS_COPYITEM(ed, bufd, pd,
                                     +  +  +  +  -  
                                           +  -  + ]
                                356                 :                :                         HSTORE_KEY(es, ps, i), HSTORE_KEYLEN(es, i),
                                357                 :                :                         HSTORE_VALLEN(es, i), HSTORE_VALISNULL(es, i));
                                358                 :             13 :             ++outcount;
                                359                 :             13 :             ++i;
                                360                 :                :         }
                                361                 :                :     }
                                362                 :                : 
 5161 bruce@momjian.us          363   [ +  +  +  + ]:              9 :     HS_FINALIZE(out, outcount, bufd, pd);
                                364                 :                : 
 5310 tgl@sss.pgh.pa.us         365                 :              9 :     PG_RETURN_POINTER(out);
                                366                 :                : }
                                367                 :                : 
                                368                 :                : 
                                369                 :              8 : PG_FUNCTION_INFO_V1(hstore_delete_hstore);
                                370                 :                : Datum
                                371                 :             12 : hstore_delete_hstore(PG_FUNCTION_ARGS)
                                372                 :                : {
 2400                           373                 :             12 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
                                374                 :             12 :     HStore     *hs2 = PG_GETARG_HSTORE_P(1);
 5310                           375                 :             12 :     HStore     *out = palloc(VARSIZE(hs));
 5161 bruce@momjian.us          376                 :             12 :     int         hs_count = HS_COUNT(hs);
                                377                 :             12 :     int         hs2_count = HS_COUNT(hs2);
                                378                 :                :     char       *ps,
                                379                 :                :                *ps2,
                                380                 :                :                *bufd,
                                381                 :                :                *pd;
                                382                 :                :     HEntry     *es,
                                383                 :                :                *es2,
                                384                 :                :                *ed;
                                385                 :                :     int         i,
                                386                 :                :                 j;
                                387                 :             12 :     int         outcount = 0;
                                388                 :                : 
 5310 tgl@sss.pgh.pa.us         389                 :             12 :     SET_VARSIZE(out, VARSIZE(hs));
 5161 bruce@momjian.us          390                 :             12 :     HS_SETCOUNT(out, hs_count); /* temporary! */
                                391                 :                : 
 5310 tgl@sss.pgh.pa.us         392                 :             12 :     ps = STRPTR(hs);
                                393                 :             12 :     es = ARRPTR(hs);
                                394                 :             12 :     ps2 = STRPTR(hs2);
                                395                 :             12 :     es2 = ARRPTR(hs2);
                                396                 :             12 :     bufd = pd = STRPTR(out);
                                397                 :             12 :     ed = ARRPTR(out);
                                398                 :                : 
                                399         [ +  + ]:             12 :     if (hs2_count == 0)
                                400                 :                :     {
                                401                 :                :         /* return a copy of the input, unchanged */
                                402                 :              3 :         memcpy(out, hs, VARSIZE(hs));
                                403         [ +  - ]:              3 :         HS_FIXSIZE(out, hs_count);
                                404                 :              3 :         HS_SETCOUNT(out, hs_count);
                                405                 :              3 :         PG_RETURN_POINTER(out);
                                406                 :                :     }
                                407                 :                : 
                                408                 :                :     /*
                                409                 :                :      * this is in effect a merge between hs and hs2, both of which are already
                                410                 :                :      * sorted by (keylen,key); we take keys from hs only; for equal keys, we
                                411                 :                :      * take the value from hs unless the values are equal
                                412                 :                :      */
                                413                 :                : 
 5161 bruce@momjian.us          414         [ +  + ]:             36 :     for (i = j = 0; i < hs_count;)
                                415                 :                :     {
                                416                 :                :         int         difference;
                                417                 :                : 
 5310 tgl@sss.pgh.pa.us         418         [ +  + ]:             27 :         if (j >= hs2_count)
                                419                 :              5 :             difference = -1;
                                420                 :                :         else
                                421                 :                :         {
 3069                           422         [ +  + ]:             22 :             int         skeylen = HSTORE_KEYLEN(es, i);
                                423         [ +  + ]:             22 :             int         s2keylen = HSTORE_KEYLEN(es2, j);
                                424                 :                : 
 5310                           425         [ +  + ]:             22 :             if (skeylen == s2keylen)
 3069                           426                 :             20 :                 difference = memcmp(HSTORE_KEY(es, ps, i),
                                427   [ +  +  +  + ]:             20 :                                     HSTORE_KEY(es2, ps2, j),
                                428                 :                :                                     skeylen);
                                429                 :                :             else
 5310                           430         [ -  + ]:              2 :                 difference = (skeylen > s2keylen) ? 1 : -1;
                                431                 :                :         }
                                432                 :                : 
                                433         [ -  + ]:             27 :         if (difference > 0)
 5310 tgl@sss.pgh.pa.us         434                 :UBC           0 :             ++j;
 5310 tgl@sss.pgh.pa.us         435         [ +  + ]:CBC          27 :         else if (difference == 0)
                                436                 :                :         {
 3069                           437         [ -  + ]:             17 :             int         svallen = HSTORE_VALLEN(es, i);
                                438                 :             17 :             int         snullval = HSTORE_VALISNULL(es, i);
                                439                 :                : 
                                440   [ +  +  +  - ]:             17 :             if (snullval != HSTORE_VALISNULL(es2, j) ||
                                441   [ -  +  +  - ]:             15 :                 (!snullval && (svallen != HSTORE_VALLEN(es2, j) ||
                                442         [ +  + ]:             15 :                                memcmp(HSTORE_VAL(es, ps, i),
                                443   [ +  -  +  - ]:             15 :                                       HSTORE_VAL(es2, ps2, j),
                                444                 :                :                                       svallen) != 0)))
                                445                 :                :             {
 5310                           446   [ -  +  +  -  :              4 :                 HS_COPYITEM(ed, bufd, pd,
                                        -  +  -  + ]
                                447                 :                :                             HSTORE_KEY(es, ps, i), HSTORE_KEYLEN(es, i),
                                448                 :                :                             svallen, snullval);
                                449                 :              4 :                 ++outcount;
                                450                 :                :             }
                                451                 :             17 :             ++i, ++j;
                                452                 :                :         }
                                453                 :                :         else
                                454                 :                :         {
                                455   [ +  +  -  +  :             10 :             HS_COPYITEM(ed, bufd, pd,
                                     +  +  +  +  -  
                                           +  -  + ]
                                456                 :                :                         HSTORE_KEY(es, ps, i), HSTORE_KEYLEN(es, i),
                                457                 :                :                         HSTORE_VALLEN(es, i), HSTORE_VALISNULL(es, i));
                                458                 :             10 :             ++outcount;
                                459                 :             10 :             ++i;
                                460                 :                :         }
                                461                 :                :     }
                                462                 :                : 
 5161 bruce@momjian.us          463   [ +  +  +  - ]:              9 :     HS_FINALIZE(out, outcount, bufd, pd);
                                464                 :                : 
 6431 teodor@sigaev.ru          465                 :              9 :     PG_RETURN_POINTER(out);
                                466                 :                : }
                                467                 :                : 
                                468                 :                : 
 5310 tgl@sss.pgh.pa.us         469                 :              8 : PG_FUNCTION_INFO_V1(hstore_concat);
                                470                 :                : Datum
                                471                 :             30 : hstore_concat(PG_FUNCTION_ARGS)
                                472                 :                : {
 2400                           473                 :             30 :     HStore     *s1 = PG_GETARG_HSTORE_P(0);
                                474                 :             30 :     HStore     *s2 = PG_GETARG_HSTORE_P(1);
 6255                           475                 :             30 :     HStore     *out = palloc(VARSIZE(s1) + VARSIZE(s2));
                                476                 :                :     char       *ps1,
                                477                 :                :                *ps2,
                                478                 :                :                *bufd,
                                479                 :                :                *pd;
                                480                 :                :     HEntry     *es1,
                                481                 :                :                *es2,
                                482                 :                :                *ed;
                                483                 :                :     int         s1idx;
                                484                 :                :     int         s2idx;
 5161 bruce@momjian.us          485                 :             30 :     int         s1count = HS_COUNT(s1);
                                486                 :             30 :     int         s2count = HS_COUNT(s2);
                                487                 :             30 :     int         outcount = 0;
                                488                 :                : 
 5310 tgl@sss.pgh.pa.us         489                 :             30 :     SET_VARSIZE(out, VARSIZE(s1) + VARSIZE(s2) - HSHRDSIZE);
                                490                 :             30 :     HS_SETCOUNT(out, s1count + s2count);
                                491                 :                : 
                                492         [ +  + ]:             30 :     if (s1count == 0)
                                493                 :                :     {
                                494                 :                :         /* return a copy of the input, unchanged */
                                495                 :              4 :         memcpy(out, s2, VARSIZE(s2));
                                496         [ +  + ]:              4 :         HS_FIXSIZE(out, s2count);
                                497                 :              4 :         HS_SETCOUNT(out, s2count);
                                498                 :              4 :         PG_RETURN_POINTER(out);
                                499                 :                :     }
                                500                 :                : 
                                501         [ +  + ]:             26 :     if (s2count == 0)
                                502                 :                :     {
                                503                 :                :         /* return a copy of the input, unchanged */
                                504                 :              2 :         memcpy(out, s1, VARSIZE(s1));
                                505         [ +  - ]:              2 :         HS_FIXSIZE(out, s1count);
                                506                 :              2 :         HS_SETCOUNT(out, s1count);
                                507                 :              2 :         PG_RETURN_POINTER(out);
                                508                 :                :     }
                                509                 :                : 
 6402 bruce@momjian.us          510                 :             24 :     ps1 = STRPTR(s1);
                                511                 :             24 :     ps2 = STRPTR(s2);
 5310 tgl@sss.pgh.pa.us         512                 :             24 :     bufd = pd = STRPTR(out);
 6402 bruce@momjian.us          513                 :             24 :     es1 = ARRPTR(s1);
                                514                 :             24 :     es2 = ARRPTR(s2);
                                515                 :             24 :     ed = ARRPTR(out);
                                516                 :                : 
                                517                 :                :     /*
                                518                 :                :      * this is in effect a merge between s1 and s2, both of which are already
                                519                 :                :      * sorted by (keylen,key); we take s2 for equal keys
                                520                 :                :      */
                                521                 :                : 
 5310 tgl@sss.pgh.pa.us         522   [ +  +  +  + ]:             90 :     for (s1idx = s2idx = 0; s1idx < s1count || s2idx < s2count; ++outcount)
                                523                 :                :     {
                                524                 :                :         int         difference;
                                525                 :                : 
                                526         [ +  + ]:             66 :         if (s1idx >= s1count)
                                527                 :             13 :             difference = 1;
                                528         [ +  + ]:             53 :         else if (s2idx >= s2count)
                                529                 :              7 :             difference = -1;
                                530                 :                :         else
                                531                 :                :         {
 3069                           532         [ +  + ]:             46 :             int         s1keylen = HSTORE_KEYLEN(es1, s1idx);
                                533         [ +  + ]:             46 :             int         s2keylen = HSTORE_KEYLEN(es2, s2idx);
                                534                 :                : 
 5310                           535         [ +  + ]:             46 :             if (s1keylen == s2keylen)
 3069                           536                 :             41 :                 difference = memcmp(HSTORE_KEY(es1, ps1, s1idx),
                                537   [ +  +  +  + ]:             41 :                                     HSTORE_KEY(es2, ps2, s2idx),
                                538                 :                :                                     s1keylen);
                                539                 :                :             else
 5310                           540         [ +  + ]:              5 :                 difference = (s1keylen > s2keylen) ? 1 : -1;
                                541                 :                :         }
                                542                 :                : 
                                543         [ +  + ]:             66 :         if (difference >= 0)
                                544                 :                :         {
                                545   [ +  +  -  +  :             38 :             HS_COPYITEM(ed, bufd, pd,
                                     +  +  +  +  -  
                                           +  -  + ]
                                546                 :                :                         HSTORE_KEY(es2, ps2, s2idx), HSTORE_KEYLEN(es2, s2idx),
                                547                 :                :                         HSTORE_VALLEN(es2, s2idx), HSTORE_VALISNULL(es2, s2idx));
                                548                 :             38 :             ++s2idx;
                                549         [ +  + ]:             38 :             if (difference == 0)
                                550                 :             19 :                 ++s1idx;
                                551                 :                :         }
                                552                 :                :         else
                                553                 :                :         {
                                554   [ +  +  -  +  :             28 :             HS_COPYITEM(ed, bufd, pd,
                                     +  +  +  +  -  
                                           +  -  + ]
                                555                 :                :                         HSTORE_KEY(es1, ps1, s1idx), HSTORE_KEYLEN(es1, s1idx),
                                556                 :                :                         HSTORE_VALLEN(es1, s1idx), HSTORE_VALISNULL(es1, s1idx));
                                557                 :             28 :             ++s1idx;
                                558                 :                :         }
                                559                 :                :     }
                                560                 :                : 
 5161 bruce@momjian.us          561   [ +  -  +  + ]:             24 :     HS_FINALIZE(out, outcount, bufd, pd);
                                562                 :                : 
 5310 tgl@sss.pgh.pa.us         563                 :             24 :     PG_RETURN_POINTER(out);
                                564                 :                : }
                                565                 :                : 
                                566                 :                : 
                                567                 :              8 : PG_FUNCTION_INFO_V1(hstore_slice_to_array);
                                568                 :                : Datum
                                569                 :              4 : hstore_slice_to_array(PG_FUNCTION_ARGS)
                                570                 :                : {
 2400                           571                 :              4 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 5310                           572                 :              4 :     HEntry     *entries = ARRPTR(hs);
 5161 bruce@momjian.us          573                 :              4 :     char       *ptr = STRPTR(hs);
 5310 tgl@sss.pgh.pa.us         574                 :              4 :     ArrayType  *key_array = PG_GETARG_ARRAYTYPE_P(1);
                                575                 :                :     ArrayType  *aout;
                                576                 :                :     Datum      *key_datums;
                                577                 :                :     bool       *key_nulls;
                                578                 :                :     Datum      *out_datums;
                                579                 :                :     bool       *out_nulls;
                                580                 :                :     int         key_count;
                                581                 :                :     int         i;
                                582                 :                : 
  653 peter@eisentraut.org      583                 :              4 :     deconstruct_array_builtin(key_array, TEXTOID, &key_datums, &key_nulls, &key_count);
                                584                 :                : 
 5310 tgl@sss.pgh.pa.us         585         [ -  + ]:              4 :     if (key_count == 0)
                                586                 :                :     {
 5310 tgl@sss.pgh.pa.us         587                 :UBC           0 :         aout = construct_empty_array(TEXTOID);
                                588                 :              0 :         PG_RETURN_POINTER(aout);
                                589                 :                :     }
                                590                 :                : 
 5310 tgl@sss.pgh.pa.us         591                 :CBC           4 :     out_datums = palloc(sizeof(Datum) * key_count);
                                592                 :              4 :     out_nulls = palloc(sizeof(bool) * key_count);
                                593                 :                : 
                                594         [ +  + ]:             15 :     for (i = 0; i < key_count; ++i)
                                595                 :                :     {
 5161 bruce@momjian.us          596                 :             11 :         text       *key = (text *) DatumGetPointer(key_datums[i]);
                                597                 :                :         int         idx;
                                598                 :                : 
 5310 tgl@sss.pgh.pa.us         599         [ +  + ]:             11 :         if (key_nulls[i])
                                600                 :              1 :             idx = -1;
                                601                 :                :         else
                                602                 :             10 :             idx = hstoreFindKey(hs, NULL, VARDATA(key), VARSIZE(key) - VARHDRSZ);
                                603                 :                : 
 3069                           604   [ +  +  +  + ]:             11 :         if (idx < 0 || HSTORE_VALISNULL(entries, idx))
                                605                 :                :         {
 5310                           606                 :              2 :             out_nulls[i] = true;
                                607                 :              2 :             out_datums[i] = (Datum) 0;
                                608                 :                :         }
                                609                 :                :         else
                                610                 :                :         {
 1536 alvherre@alvh.no-ip.      611                 :             18 :             out_datums[i] =
                                612         [ +  - ]:              9 :                 PointerGetDatum(cstring_to_text_with_len(HSTORE_VAL(entries, ptr, idx),
                                613         [ -  + ]:              9 :                                                          HSTORE_VALLEN(entries, idx)));
 5310 tgl@sss.pgh.pa.us         614                 :              9 :             out_nulls[i] = false;
                                615                 :                :         }
                                616                 :                :     }
                                617                 :                : 
                                618                 :              4 :     aout = construct_md_array(out_datums, out_nulls,
                                619                 :                :                               ARR_NDIM(key_array),
                                620                 :                :                               ARR_DIMS(key_array),
                                621                 :              4 :                               ARR_LBOUND(key_array),
                                622                 :                :                               TEXTOID, -1, false, TYPALIGN_INT);
                                623                 :                : 
                                624                 :              4 :     PG_RETURN_POINTER(aout);
                                625                 :                : }
                                626                 :                : 
                                627                 :                : 
                                628                 :              8 : PG_FUNCTION_INFO_V1(hstore_slice_to_hstore);
                                629                 :                : Datum
                                630                 :              6 : hstore_slice_to_hstore(PG_FUNCTION_ARGS)
                                631                 :                : {
 2400                           632                 :              6 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 5310                           633                 :              6 :     HEntry     *entries = ARRPTR(hs);
 5161 bruce@momjian.us          634                 :              6 :     char       *ptr = STRPTR(hs);
 5310 tgl@sss.pgh.pa.us         635                 :              6 :     ArrayType  *key_array = PG_GETARG_ARRAYTYPE_P(1);
                                636                 :                :     HStore     *out;
                                637                 :                :     int         nkeys;
 5161 bruce@momjian.us          638                 :              6 :     Pairs      *key_pairs = hstoreArrayToPairs(key_array, &nkeys);
                                639                 :                :     Pairs      *out_pairs;
                                640                 :                :     int         bufsiz;
                                641                 :              6 :     int         lastidx = 0;
                                642                 :                :     int         i;
                                643                 :              6 :     int         out_count = 0;
                                644                 :                : 
 5310 tgl@sss.pgh.pa.us         645         [ -  + ]:              6 :     if (nkeys == 0)
                                646                 :                :     {
 5310 tgl@sss.pgh.pa.us         647                 :UBC           0 :         out = hstorePairs(NULL, 0, 0);
                                648                 :              0 :         PG_RETURN_POINTER(out);
                                649                 :                :     }
                                650                 :                : 
                                651                 :                :     /* hstoreArrayToPairs() checked overflow */
 5310 tgl@sss.pgh.pa.us         652                 :CBC           6 :     out_pairs = palloc(sizeof(Pairs) * nkeys);
                                653                 :              6 :     bufsiz = 0;
                                654                 :                : 
                                655                 :                :     /*
                                656                 :                :      * we exploit the fact that the pairs list is already sorted into strictly
                                657                 :                :      * increasing order to narrow the hstoreFindKey search; each search can
                                658                 :                :      * start one entry past the previous "found" entry, or at the lower bound
                                659                 :                :      * of the last search.
                                660                 :                :      */
                                661                 :                : 
                                662         [ +  + ]:             21 :     for (i = 0; i < nkeys; ++i)
                                663                 :                :     {
 5161 bruce@momjian.us          664                 :             15 :         int         idx = hstoreFindKey(hs, &lastidx,
 2489 tgl@sss.pgh.pa.us         665                 :             15 :                                         key_pairs[i].key, key_pairs[i].keylen);
                                666                 :                : 
 5310                           667         [ +  + ]:             15 :         if (idx >= 0)
                                668                 :                :         {
                                669                 :             12 :             out_pairs[out_count].key = key_pairs[i].key;
                                670                 :             12 :             bufsiz += (out_pairs[out_count].keylen = key_pairs[i].keylen);
 3069                           671         [ +  - ]:             12 :             out_pairs[out_count].val = HSTORE_VAL(entries, ptr, idx);
                                672         [ -  + ]:             12 :             bufsiz += (out_pairs[out_count].vallen = HSTORE_VALLEN(entries, idx));
                                673                 :             12 :             out_pairs[out_count].isnull = HSTORE_VALISNULL(entries, idx);
 5310                           674                 :             12 :             out_pairs[out_count].needfree = false;
                                675                 :             12 :             ++out_count;
                                676                 :                :         }
                                677                 :                :     }
                                678                 :                : 
                                679                 :                :     /*
                                680                 :                :      * we don't use hstoreUniquePairs here because we know that the pairs list
                                681                 :                :      * is already sorted and uniq'ed.
                                682                 :                :      */
                                683                 :                : 
                                684                 :              6 :     out = hstorePairs(out_pairs, out_count, bufsiz);
                                685                 :                : 
 6431 teodor@sigaev.ru          686                 :              6 :     PG_RETURN_POINTER(out);
                                687                 :                : }
                                688                 :                : 
                                689                 :                : 
 5310 tgl@sss.pgh.pa.us         690                 :              8 : PG_FUNCTION_INFO_V1(hstore_akeys);
                                691                 :                : Datum
                                692                 :              3 : hstore_akeys(PG_FUNCTION_ARGS)
                                693                 :                : {
 2400                           694                 :              3 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
                                695                 :                :     Datum      *d;
                                696                 :                :     ArrayType  *a;
 5310                           697                 :              3 :     HEntry     *entries = ARRPTR(hs);
 6402 bruce@momjian.us          698                 :              3 :     char       *base = STRPTR(hs);
 5161                           699                 :              3 :     int         count = HS_COUNT(hs);
                                700                 :                :     int         i;
                                701                 :                : 
 5310 tgl@sss.pgh.pa.us         702         [ +  + ]:              3 :     if (count == 0)
                                703                 :                :     {
                                704                 :              1 :         a = construct_empty_array(TEXTOID);
                                705                 :              1 :         PG_RETURN_POINTER(a);
                                706                 :                :     }
                                707                 :                : 
                                708                 :              2 :     d = (Datum *) palloc(sizeof(Datum) * count);
                                709                 :                : 
                                710         [ +  + ]:              7 :     for (i = 0; i < count; ++i)
                                711                 :                :     {
 3069                           712         [ +  + ]:              5 :         text       *t = cstring_to_text_with_len(HSTORE_KEY(entries, base, i),
                                713         [ +  + ]:              5 :                                                  HSTORE_KEYLEN(entries, i));
                                714                 :                : 
                                715                 :              5 :         d[i] = PointerGetDatum(t);
                                716                 :                :     }
                                717                 :                : 
  653 peter@eisentraut.org      718                 :              2 :     a = construct_array_builtin(d, count, TEXTOID);
                                719                 :                : 
 6431 teodor@sigaev.ru          720                 :              2 :     PG_RETURN_POINTER(a);
                                721                 :                : }
                                722                 :                : 
                                723                 :                : 
 5310 tgl@sss.pgh.pa.us         724                 :              8 : PG_FUNCTION_INFO_V1(hstore_avals);
                                725                 :                : Datum
                                726                 :              4 : hstore_avals(PG_FUNCTION_ARGS)
                                727                 :                : {
 2400                           728                 :              4 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
                                729                 :                :     Datum      *d;
                                730                 :                :     bool       *nulls;
                                731                 :                :     ArrayType  *a;
 5310                           732                 :              4 :     HEntry     *entries = ARRPTR(hs);
 6402 bruce@momjian.us          733                 :              4 :     char       *base = STRPTR(hs);
 5161                           734                 :              4 :     int         count = HS_COUNT(hs);
                                735                 :              4 :     int         lb = 1;
                                736                 :                :     int         i;
                                737                 :                : 
 5310 tgl@sss.pgh.pa.us         738         [ +  + ]:              4 :     if (count == 0)
                                739                 :                :     {
                                740                 :              1 :         a = construct_empty_array(TEXTOID);
                                741                 :              1 :         PG_RETURN_POINTER(a);
                                742                 :                :     }
                                743                 :                : 
                                744                 :              3 :     d = (Datum *) palloc(sizeof(Datum) * count);
                                745                 :              3 :     nulls = (bool *) palloc(sizeof(bool) * count);
                                746                 :                : 
                                747         [ +  + ]:             12 :     for (i = 0; i < count; ++i)
                                748                 :                :     {
 3069                           749         [ +  + ]:              9 :         if (HSTORE_VALISNULL(entries, i))
                                750                 :                :         {
 5310                           751                 :              1 :             d[i] = (Datum) 0;
                                752                 :              1 :             nulls[i] = true;
                                753                 :                :         }
                                754                 :                :         else
                                755                 :                :         {
 3069                           756         [ +  - ]:              8 :             text       *item = cstring_to_text_with_len(HSTORE_VAL(entries, base, i),
 2489                           757         [ -  + ]:              8 :                                                         HSTORE_VALLEN(entries, i));
                                758                 :                : 
 5310                           759                 :              8 :             d[i] = PointerGetDatum(item);
                                760                 :              8 :             nulls[i] = false;
                                761                 :                :         }
                                762                 :                :     }
                                763                 :                : 
                                764                 :              3 :     a = construct_md_array(d, nulls, 1, &count, &lb,
                                765                 :                :                            TEXTOID, -1, false, TYPALIGN_INT);
                                766                 :                : 
 6431 teodor@sigaev.ru          767                 :              3 :     PG_RETURN_POINTER(a);
                                768                 :                : }
                                769                 :                : 
                                770                 :                : 
                                771                 :                : static ArrayType *
 5310 tgl@sss.pgh.pa.us         772                 :              4 : hstore_to_array_internal(HStore *hs, int ndims)
                                773                 :                : {
                                774                 :              4 :     HEntry     *entries = ARRPTR(hs);
                                775                 :              4 :     char       *base = STRPTR(hs);
 5161 bruce@momjian.us          776                 :              4 :     int         count = HS_COUNT(hs);
                                777                 :              4 :     int         out_size[2] = {0, 2};
                                778                 :              4 :     int         lb[2] = {1, 1};
                                779                 :                :     Datum      *out_datums;
                                780                 :                :     bool       *out_nulls;
                                781                 :                :     int         i;
                                782                 :                : 
 5310 tgl@sss.pgh.pa.us         783         [ -  + ]:              4 :     Assert(ndims < 3);
                                784                 :                : 
                                785   [ +  -  -  + ]:              4 :     if (count == 0 || ndims == 0)
 5310 tgl@sss.pgh.pa.us         786                 :UBC           0 :         return construct_empty_array(TEXTOID);
                                787                 :                : 
 5310 tgl@sss.pgh.pa.us         788                 :CBC           4 :     out_size[0] = count * 2 / ndims;
                                789                 :              4 :     out_datums = palloc(sizeof(Datum) * count * 2);
                                790                 :              4 :     out_nulls = palloc(sizeof(bool) * count * 2);
                                791                 :                : 
                                792         [ +  + ]:             20 :     for (i = 0; i < count; ++i)
                                793                 :                :     {
 3069                           794         [ +  + ]:             16 :         text       *key = cstring_to_text_with_len(HSTORE_KEY(entries, base, i),
                                795         [ +  + ]:             16 :                                                    HSTORE_KEYLEN(entries, i));
                                796                 :                : 
 5161 bruce@momjian.us          797                 :             16 :         out_datums[i * 2] = PointerGetDatum(key);
                                798                 :             16 :         out_nulls[i * 2] = false;
                                799                 :                : 
 3069 tgl@sss.pgh.pa.us         800         [ +  + ]:             16 :         if (HSTORE_VALISNULL(entries, i))
                                801                 :                :         {
 5161 bruce@momjian.us          802                 :              4 :             out_datums[i * 2 + 1] = (Datum) 0;
                                803                 :              4 :             out_nulls[i * 2 + 1] = true;
                                804                 :                :         }
                                805                 :                :         else
                                806                 :                :         {
 3069 tgl@sss.pgh.pa.us         807         [ +  - ]:             12 :             text       *item = cstring_to_text_with_len(HSTORE_VAL(entries, base, i),
 2489                           808         [ -  + ]:             12 :                                                         HSTORE_VALLEN(entries, i));
                                809                 :                : 
 5161 bruce@momjian.us          810                 :             12 :             out_datums[i * 2 + 1] = PointerGetDatum(item);
                                811                 :             12 :             out_nulls[i * 2 + 1] = false;
                                812                 :                :         }
                                813                 :                :     }
                                814                 :                : 
 5310 tgl@sss.pgh.pa.us         815                 :              4 :     return construct_md_array(out_datums, out_nulls,
                                816                 :                :                               ndims, out_size, lb,
                                817                 :                :                               TEXTOID, -1, false, TYPALIGN_INT);
                                818                 :                : }
                                819                 :                : 
                                820                 :              8 : PG_FUNCTION_INFO_V1(hstore_to_array);
                                821                 :                : Datum
                                822                 :              2 : hstore_to_array(PG_FUNCTION_ARGS)
                                823                 :                : {
 2400                           824                 :              2 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 5310                           825                 :              2 :     ArrayType  *out = hstore_to_array_internal(hs, 1);
                                826                 :                : 
                                827                 :              2 :     PG_RETURN_POINTER(out);
                                828                 :                : }
                                829                 :                : 
                                830                 :              8 : PG_FUNCTION_INFO_V1(hstore_to_matrix);
                                831                 :                : Datum
                                832                 :              2 : hstore_to_matrix(PG_FUNCTION_ARGS)
                                833                 :                : {
 2400                           834                 :              2 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 5310                           835                 :              2 :     ArrayType  *out = hstore_to_array_internal(hs, 2);
                                836                 :                : 
                                837                 :              2 :     PG_RETURN_POINTER(out);
                                838                 :                : }
                                839                 :                : 
                                840                 :                : /*
                                841                 :                :  * Common initialization function for the various set-returning
                                842                 :                :  * funcs. fcinfo is only passed if the function is to return a
                                843                 :                :  * composite; it will be used to look up the return tupledesc.
                                844                 :                :  * we stash a copy of the hstore in the multi-call context in
                                845                 :                :  * case it was originally toasted. (At least I assume that's why;
                                846                 :                :  * there was no explanatory comment in the original code. --AG)
                                847                 :                :  */
                                848                 :                : 
                                849                 :                : static void
 5161 bruce@momjian.us          850                 :           2010 : setup_firstcall(FuncCallContext *funcctx, HStore *hs,
                                851                 :                :                 FunctionCallInfo fcinfo)
                                852                 :                : {
                                853                 :                :     MemoryContext oldcontext;
                                854                 :                :     HStore     *st;
                                855                 :                : 
 6431 teodor@sigaev.ru          856                 :           2010 :     oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
                                857                 :                : 
 5310 tgl@sss.pgh.pa.us         858                 :           2010 :     st = (HStore *) palloc(VARSIZE(hs));
                                859                 :           2010 :     memcpy(st, hs, VARSIZE(hs));
                                860                 :                : 
 6402 bruce@momjian.us          861                 :           2010 :     funcctx->user_fctx = (void *) st;
                                862                 :                : 
 5310 tgl@sss.pgh.pa.us         863         [ +  + ]:           2010 :     if (fcinfo)
                                864                 :                :     {
                                865                 :                :         TupleDesc   tupdesc;
                                866                 :                : 
                                867                 :                :         /* Build a tuple descriptor for our result type */
                                868         [ -  + ]:           2003 :         if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
 5310 tgl@sss.pgh.pa.us         869         [ #  # ]:UBC           0 :             elog(ERROR, "return type must be a row type");
                                870                 :                : 
 5310 tgl@sss.pgh.pa.us         871                 :CBC        2003 :         funcctx->tuple_desc = BlessTupleDesc(tupdesc);
                                872                 :                :     }
                                873                 :                : 
 6431 teodor@sigaev.ru          874                 :           2010 :     MemoryContextSwitchTo(oldcontext);
                                875                 :           2010 : }
                                876                 :                : 
                                877                 :                : 
 5310 tgl@sss.pgh.pa.us         878                 :              8 : PG_FUNCTION_INFO_V1(hstore_skeys);
                                879                 :                : Datum
                                880                 :              8 : hstore_skeys(PG_FUNCTION_ARGS)
                                881                 :                : {
                                882                 :                :     FuncCallContext *funcctx;
                                883                 :                :     HStore     *hs;
                                884                 :                :     int         i;
                                885                 :                : 
 6402 bruce@momjian.us          886         [ +  + ]:              8 :     if (SRF_IS_FIRSTCALL())
                                887                 :                :     {
 2400 tgl@sss.pgh.pa.us         888                 :              3 :         hs = PG_GETARG_HSTORE_P(0);
 6431 teodor@sigaev.ru          889                 :              3 :         funcctx = SRF_FIRSTCALL_INIT();
 5310 tgl@sss.pgh.pa.us         890                 :              3 :         setup_firstcall(funcctx, hs, NULL);
                                891                 :                :     }
                                892                 :                : 
 6431 teodor@sigaev.ru          893                 :              8 :     funcctx = SRF_PERCALL_SETUP();
 5310 tgl@sss.pgh.pa.us         894                 :              8 :     hs = (HStore *) funcctx->user_fctx;
                                895                 :              8 :     i = funcctx->call_cntr;
                                896                 :                : 
                                897         [ +  + ]:              8 :     if (i < HS_COUNT(hs))
                                898                 :                :     {
 5161 bruce@momjian.us          899                 :              5 :         HEntry     *entries = ARRPTR(hs);
                                900                 :                :         text       *item;
                                901                 :                : 
 3069 tgl@sss.pgh.pa.us         902         [ +  + ]:              5 :         item = cstring_to_text_with_len(HSTORE_KEY(entries, STRPTR(hs), i),
                                903         [ +  + ]:              5 :                                         HSTORE_KEYLEN(entries, i));
                                904                 :                : 
 6431 teodor@sigaev.ru          905                 :              5 :         SRF_RETURN_NEXT(funcctx, PointerGetDatum(item));
                                906                 :                :     }
                                907                 :                : 
 6402 bruce@momjian.us          908                 :              3 :     SRF_RETURN_DONE(funcctx);
                                909                 :                : }
                                910                 :                : 
                                911                 :                : 
 5310 tgl@sss.pgh.pa.us         912                 :              8 : PG_FUNCTION_INFO_V1(hstore_svals);
                                913                 :                : Datum
                                914                 :             13 : hstore_svals(PG_FUNCTION_ARGS)
                                915                 :                : {
                                916                 :                :     FuncCallContext *funcctx;
                                917                 :                :     HStore     *hs;
                                918                 :                :     int         i;
                                919                 :                : 
 6402 bruce@momjian.us          920         [ +  + ]:             13 :     if (SRF_IS_FIRSTCALL())
                                921                 :                :     {
 2400 tgl@sss.pgh.pa.us         922                 :              4 :         hs = PG_GETARG_HSTORE_P(0);
 6431 teodor@sigaev.ru          923                 :              4 :         funcctx = SRF_FIRSTCALL_INIT();
 5310 tgl@sss.pgh.pa.us         924                 :              4 :         setup_firstcall(funcctx, hs, NULL);
                                925                 :                :     }
                                926                 :                : 
 6431 teodor@sigaev.ru          927                 :             13 :     funcctx = SRF_PERCALL_SETUP();
 5310 tgl@sss.pgh.pa.us         928                 :             13 :     hs = (HStore *) funcctx->user_fctx;
                                929                 :             13 :     i = funcctx->call_cntr;
                                930                 :                : 
                                931         [ +  + ]:             13 :     if (i < HS_COUNT(hs))
                                932                 :                :     {
 5161 bruce@momjian.us          933                 :              9 :         HEntry     *entries = ARRPTR(hs);
                                934                 :                : 
 3069 tgl@sss.pgh.pa.us         935         [ +  + ]:              9 :         if (HSTORE_VALISNULL(entries, i))
                                936                 :                :         {
                                937                 :                :             ReturnSetInfo *rsi;
                                938                 :                : 
                                939                 :                :             /* ugly ugly ugly. why no macro for this? */
 6431 teodor@sigaev.ru          940                 :              1 :             (funcctx)->call_cntr++;
                                941                 :              1 :             rsi = (ReturnSetInfo *) fcinfo->resultinfo;
                                942                 :              1 :             rsi->isDone = ExprMultipleResult;
                                943                 :              1 :             PG_RETURN_NULL();
                                944                 :                :         }
                                945                 :                :         else
                                946                 :                :         {
                                947                 :                :             text       *item;
                                948                 :                : 
 3069 tgl@sss.pgh.pa.us         949         [ +  - ]:              8 :             item = cstring_to_text_with_len(HSTORE_VAL(entries, STRPTR(hs), i),
                                950         [ -  + ]:              8 :                                             HSTORE_VALLEN(entries, i));
                                951                 :                : 
 6431 teodor@sigaev.ru          952                 :              8 :             SRF_RETURN_NEXT(funcctx, PointerGetDatum(item));
                                953                 :                :         }
                                954                 :                :     }
                                955                 :                : 
 6402 bruce@momjian.us          956                 :              4 :     SRF_RETURN_DONE(funcctx);
                                957                 :                : }
                                958                 :                : 
                                959                 :                : 
 5310 tgl@sss.pgh.pa.us         960                 :              8 : PG_FUNCTION_INFO_V1(hstore_contains);
                                961                 :                : Datum
                                962                 :           3560 : hstore_contains(PG_FUNCTION_ARGS)
                                963                 :                : {
 2400                           964                 :           3560 :     HStore     *val = PG_GETARG_HSTORE_P(0);
                                965                 :           3560 :     HStore     *tmpl = PG_GETARG_HSTORE_P(1);
 6402 bruce@momjian.us          966                 :           3560 :     bool        res = true;
                                967                 :           3560 :     HEntry     *te = ARRPTR(tmpl);
 5310 tgl@sss.pgh.pa.us         968                 :           3560 :     char       *tstr = STRPTR(tmpl);
                                969                 :           3560 :     HEntry     *ve = ARRPTR(val);
                                970                 :           3560 :     char       *vstr = STRPTR(val);
 5161 bruce@momjian.us          971                 :           3560 :     int         tcount = HS_COUNT(tmpl);
                                972                 :           3560 :     int         lastidx = 0;
                                973                 :                :     int         i;
                                974                 :                : 
                                975                 :                :     /*
                                976                 :                :      * we exploit the fact that keys in "tmpl" are in strictly increasing
                                977                 :                :      * order to narrow the hstoreFindKey search; each search can start one
                                978                 :                :      * entry past the previous "found" entry, or at the lower bound of the
                                979                 :                :      * search
                                980                 :                :      */
                                981                 :                : 
 5310 tgl@sss.pgh.pa.us         982   [ +  +  +  + ]:           7148 :     for (i = 0; res && i < tcount; ++i)
                                983                 :                :     {
 5161 bruce@momjian.us          984                 :           3588 :         int         idx = hstoreFindKey(val, &lastidx,
 3069 tgl@sss.pgh.pa.us         985         [ +  + ]:           3588 :                                         HSTORE_KEY(te, tstr, i),
                                986         [ +  + ]:           3588 :                                         HSTORE_KEYLEN(te, i));
                                987                 :                : 
 5310                           988         [ +  + ]:           3588 :         if (idx >= 0)
                                989                 :                :         {
 3069                           990                 :           1083 :             bool        nullval = HSTORE_VALISNULL(te, i);
                                991         [ -  + ]:           1083 :             int         vallen = HSTORE_VALLEN(te, i);
                                992                 :                : 
                                993         [ +  + ]:           1083 :             if (nullval != HSTORE_VALISNULL(ve, idx) ||
                                994   [ +  +  -  +  :            513 :                 (!nullval && (vallen != HSTORE_VALLEN(ve, idx) ||
                                              +  + ]
                                995         [ +  + ]:            305 :                               memcmp(HSTORE_VAL(te, tstr, i),
                                996   [ +  -  +  - ]:            305 :                                      HSTORE_VAL(ve, vstr, idx),
                                997                 :                :                                      vallen) != 0)))
 5995 bruce@momjian.us          998                 :            980 :                 res = false;
                                999                 :                :         }
                               1000                 :                :         else
 6431 teodor@sigaev.ru         1001                 :           2505 :             res = false;
                               1002                 :                :     }
                               1003                 :                : 
                               1004                 :           3560 :     PG_RETURN_BOOL(res);
                               1005                 :                : }
                               1006                 :                : 
                               1007                 :                : 
 5310 tgl@sss.pgh.pa.us        1008                 :              7 : PG_FUNCTION_INFO_V1(hstore_contained);
                               1009                 :                : Datum
 5310 tgl@sss.pgh.pa.us        1010                 :UBC           0 : hstore_contained(PG_FUNCTION_ARGS)
                               1011                 :                : {
                               1012                 :              0 :     PG_RETURN_DATUM(DirectFunctionCall2(hstore_contains,
                               1013                 :                :                                         PG_GETARG_DATUM(1),
                               1014                 :                :                                         PG_GETARG_DATUM(0)
                               1015                 :                :                                         ));
                               1016                 :                : }
                               1017                 :                : 
                               1018                 :                : 
 5310 tgl@sss.pgh.pa.us        1019                 :CBC           8 : PG_FUNCTION_INFO_V1(hstore_each);
                               1020                 :                : Datum
                               1021                 :          11568 : hstore_each(PG_FUNCTION_ARGS)
                               1022                 :                : {
                               1023                 :                :     FuncCallContext *funcctx;
                               1024                 :                :     HStore     *hs;
                               1025                 :                :     int         i;
                               1026                 :                : 
 6402 bruce@momjian.us         1027         [ +  + ]:          11568 :     if (SRF_IS_FIRSTCALL())
                               1028                 :                :     {
 2400 tgl@sss.pgh.pa.us        1029                 :           2003 :         hs = PG_GETARG_HSTORE_P(0);
 6431 teodor@sigaev.ru         1030                 :           2003 :         funcctx = SRF_FIRSTCALL_INIT();
 5310 tgl@sss.pgh.pa.us        1031                 :           2003 :         setup_firstcall(funcctx, hs, fcinfo);
                               1032                 :                :     }
                               1033                 :                : 
 6431 teodor@sigaev.ru         1034                 :          11568 :     funcctx = SRF_PERCALL_SETUP();
 5310 tgl@sss.pgh.pa.us        1035                 :          11568 :     hs = (HStore *) funcctx->user_fctx;
                               1036                 :          11568 :     i = funcctx->call_cntr;
                               1037                 :                : 
                               1038         [ +  + ]:          11568 :     if (i < HS_COUNT(hs))
                               1039                 :                :     {
                               1040                 :           9565 :         HEntry     *entries = ARRPTR(hs);
 5161 bruce@momjian.us         1041                 :           9565 :         char       *ptr = STRPTR(hs);
                               1042                 :                :         Datum       res,
                               1043                 :                :                     dvalues[2];
 5642 tgl@sss.pgh.pa.us        1044                 :           9565 :         bool        nulls[2] = {false, false};
                               1045                 :                :         text       *item;
                               1046                 :                :         HeapTuple   tuple;
                               1047                 :                : 
 3069                          1048         [ +  + ]:           9565 :         item = cstring_to_text_with_len(HSTORE_KEY(entries, ptr, i),
                               1049         [ +  + ]:           9565 :                                         HSTORE_KEYLEN(entries, i));
 6431 teodor@sigaev.ru         1050                 :           9565 :         dvalues[0] = PointerGetDatum(item);
                               1051                 :                : 
 3069 tgl@sss.pgh.pa.us        1052         [ +  + ]:           9565 :         if (HSTORE_VALISNULL(entries, i))
                               1053                 :                :         {
 6402 bruce@momjian.us         1054                 :              3 :             dvalues[1] = (Datum) 0;
 5642 tgl@sss.pgh.pa.us        1055                 :              3 :             nulls[1] = true;
                               1056                 :                :         }
                               1057                 :                :         else
                               1058                 :                :         {
 3069                          1059         [ +  - ]:           9562 :             item = cstring_to_text_with_len(HSTORE_VAL(entries, ptr, i),
                               1060         [ -  + ]:           9562 :                                             HSTORE_VALLEN(entries, i));
 6431 teodor@sigaev.ru         1061                 :           9562 :             dvalues[1] = PointerGetDatum(item);
                               1062                 :                :         }
                               1063                 :                : 
 5310 tgl@sss.pgh.pa.us        1064                 :           9565 :         tuple = heap_form_tuple(funcctx->tuple_desc, dvalues, nulls);
 6076                          1065                 :           9565 :         res = HeapTupleGetDatum(tuple);
                               1066                 :                : 
  595 peter@eisentraut.org     1067                 :           9565 :         SRF_RETURN_NEXT(funcctx, res);
                               1068                 :                :     }
                               1069                 :                : 
 6402 bruce@momjian.us         1070                 :           2003 :     SRF_RETURN_DONE(funcctx);
                               1071                 :                : }
                               1072                 :                : 
                               1073                 :                : 
                               1074                 :                : /*
                               1075                 :                :  * btree sort order for hstores isn't intended to be useful; we really only
                               1076                 :                :  * care about equality versus non-equality.  we compare the entire string
                               1077                 :                :  * buffer first, then the entry pos array.
                               1078                 :                :  */
                               1079                 :                : 
 5310 tgl@sss.pgh.pa.us        1080                 :              8 : PG_FUNCTION_INFO_V1(hstore_cmp);
                               1081                 :                : Datum
                               1082                 :          43266 : hstore_cmp(PG_FUNCTION_ARGS)
                               1083                 :                : {
 2400                          1084                 :          43266 :     HStore     *hs1 = PG_GETARG_HSTORE_P(0);
                               1085                 :          43266 :     HStore     *hs2 = PG_GETARG_HSTORE_P(1);
 5161 bruce@momjian.us         1086                 :          43266 :     int         hcount1 = HS_COUNT(hs1);
                               1087                 :          43266 :     int         hcount2 = HS_COUNT(hs2);
                               1088                 :          43266 :     int         res = 0;
                               1089                 :                : 
 5310 tgl@sss.pgh.pa.us        1090   [ +  +  +  + ]:          43266 :     if (hcount1 == 0 || hcount2 == 0)
                               1091                 :                :     {
                               1092                 :                :         /*
                               1093                 :                :          * if either operand is empty, and the other is nonempty, the nonempty
                               1094                 :                :          * one is larger. If both are empty they are equal.
                               1095                 :                :          */
                               1096         [ +  + ]:           3676 :         if (hcount1 > 0)
                               1097                 :            253 :             res = 1;
                               1098         [ +  + ]:           3423 :         else if (hcount2 > 0)
                               1099                 :           1635 :             res = -1;
                               1100                 :                :     }
                               1101                 :                :     else
                               1102                 :                :     {
                               1103                 :                :         /* here we know both operands are nonempty */
 5161 bruce@momjian.us         1104                 :          39590 :         char       *str1 = STRPTR(hs1);
                               1105                 :          39590 :         char       *str2 = STRPTR(hs2);
                               1106                 :          39590 :         HEntry     *ent1 = ARRPTR(hs1);
                               1107                 :          39590 :         HEntry     *ent2 = ARRPTR(hs2);
                               1108                 :          39590 :         size_t      len1 = HSE_ENDPOS(ent1[2 * hcount1 - 1]);
                               1109                 :          39590 :         size_t      len2 = HSE_ENDPOS(ent2[2 * hcount2 - 1]);
                               1110                 :                : 
                               1111                 :          39590 :         res = memcmp(str1, str2, Min(len1, len2));
                               1112                 :                : 
 5310 tgl@sss.pgh.pa.us        1113         [ +  + ]:          39590 :         if (res == 0)
                               1114                 :                :         {
                               1115         [ -  + ]:           2770 :             if (len1 > len2)
 5310 tgl@sss.pgh.pa.us        1116                 :UBC           0 :                 res = 1;
 5310 tgl@sss.pgh.pa.us        1117         [ -  + ]:CBC        2770 :             else if (len1 < len2)
 5310 tgl@sss.pgh.pa.us        1118                 :UBC           0 :                 res = -1;
 5310 tgl@sss.pgh.pa.us        1119         [ -  + ]:CBC        2770 :             else if (hcount1 > hcount2)
 5310 tgl@sss.pgh.pa.us        1120                 :UBC           0 :                 res = 1;
 5310 tgl@sss.pgh.pa.us        1121         [ -  + ]:CBC        2770 :             else if (hcount2 > hcount1)
 5310 tgl@sss.pgh.pa.us        1122                 :UBC           0 :                 res = -1;
                               1123                 :                :             else
                               1124                 :                :             {
 5161 bruce@momjian.us         1125                 :CBC        2770 :                 int         count = hcount1 * 2;
                               1126                 :                :                 int         i;
                               1127                 :                : 
 5310 tgl@sss.pgh.pa.us        1128         [ +  + ]:          32770 :                 for (i = 0; i < count; ++i)
                               1129         [ +  - ]:          30000 :                     if (HSE_ENDPOS(ent1[i]) != HSE_ENDPOS(ent2[i]) ||
                               1130         [ +  - ]:          30000 :                         HSE_ISNULL(ent1[i]) != HSE_ISNULL(ent2[i]))
                               1131                 :                :                         break;
                               1132         [ -  + ]:           2770 :                 if (i < count)
                               1133                 :                :                 {
 5310 tgl@sss.pgh.pa.us        1134         [ #  # ]:UBC           0 :                     if (HSE_ENDPOS(ent1[i]) < HSE_ENDPOS(ent2[i]))
                               1135                 :              0 :                         res = -1;
                               1136         [ #  # ]:              0 :                     else if (HSE_ENDPOS(ent1[i]) > HSE_ENDPOS(ent2[i]))
                               1137                 :              0 :                         res = 1;
                               1138         [ #  # ]:              0 :                     else if (HSE_ISNULL(ent1[i]))
                               1139                 :              0 :                         res = 1;
                               1140         [ #  # ]:              0 :                     else if (HSE_ISNULL(ent2[i]))
                               1141                 :              0 :                         res = -1;
                               1142                 :                :                 }
                               1143                 :                :             }
                               1144                 :                :         }
                               1145                 :                :         else
                               1146                 :                :         {
 5310 tgl@sss.pgh.pa.us        1147         [ +  + ]:CBC       36820 :             res = (res > 0) ? 1 : -1;
                               1148                 :                :         }
                               1149                 :                :     }
                               1150                 :                : 
                               1151                 :                :     /*
                               1152                 :                :      * this is a btree support function; this is one of the few places where
                               1153                 :                :      * memory needs to be explicitly freed.
                               1154                 :                :      */
 5161 bruce@momjian.us         1155         [ +  + ]:          43266 :     PG_FREE_IF_COPY(hs1, 0);
                               1156         [ +  + ]:          43266 :     PG_FREE_IF_COPY(hs2, 1);
 5310 tgl@sss.pgh.pa.us        1157                 :          43266 :     PG_RETURN_INT32(res);
                               1158                 :                : }
                               1159                 :                : 
                               1160                 :                : 
                               1161                 :              8 : PG_FUNCTION_INFO_V1(hstore_eq);
                               1162                 :                : Datum
                               1163                 :           4122 : hstore_eq(PG_FUNCTION_ARGS)
                               1164                 :                : {
 5161 bruce@momjian.us         1165                 :           4122 :     int         res = DatumGetInt32(DirectFunctionCall2(hstore_cmp,
                               1166                 :                :                                                         PG_GETARG_DATUM(0),
                               1167                 :                :                                                         PG_GETARG_DATUM(1)));
                               1168                 :                : 
 5310 tgl@sss.pgh.pa.us        1169                 :           4122 :     PG_RETURN_BOOL(res == 0);
                               1170                 :                : }
                               1171                 :                : 
                               1172                 :              7 : PG_FUNCTION_INFO_V1(hstore_ne);
                               1173                 :                : Datum
 5310 tgl@sss.pgh.pa.us        1174                 :UBC           0 : hstore_ne(PG_FUNCTION_ARGS)
                               1175                 :                : {
 5161 bruce@momjian.us         1176                 :              0 :     int         res = DatumGetInt32(DirectFunctionCall2(hstore_cmp,
                               1177                 :                :                                                         PG_GETARG_DATUM(0),
                               1178                 :                :                                                         PG_GETARG_DATUM(1)));
                               1179                 :                : 
 5310 tgl@sss.pgh.pa.us        1180                 :              0 :     PG_RETURN_BOOL(res != 0);
                               1181                 :                : }
                               1182                 :                : 
 5310 tgl@sss.pgh.pa.us        1183                 :CBC           8 : PG_FUNCTION_INFO_V1(hstore_gt);
                               1184                 :                : Datum
                               1185                 :            131 : hstore_gt(PG_FUNCTION_ARGS)
                               1186                 :                : {
 5161 bruce@momjian.us         1187                 :            131 :     int         res = DatumGetInt32(DirectFunctionCall2(hstore_cmp,
                               1188                 :                :                                                         PG_GETARG_DATUM(0),
                               1189                 :                :                                                         PG_GETARG_DATUM(1)));
                               1190                 :                : 
 5310 tgl@sss.pgh.pa.us        1191                 :            131 :     PG_RETURN_BOOL(res > 0);
                               1192                 :                : }
                               1193                 :                : 
                               1194                 :              7 : PG_FUNCTION_INFO_V1(hstore_ge);
                               1195                 :                : Datum
 5310 tgl@sss.pgh.pa.us        1196                 :UBC           0 : hstore_ge(PG_FUNCTION_ARGS)
                               1197                 :                : {
 5161 bruce@momjian.us         1198                 :              0 :     int         res = DatumGetInt32(DirectFunctionCall2(hstore_cmp,
                               1199                 :                :                                                         PG_GETARG_DATUM(0),
                               1200                 :                :                                                         PG_GETARG_DATUM(1)));
                               1201                 :                : 
 5310 tgl@sss.pgh.pa.us        1202                 :              0 :     PG_RETURN_BOOL(res >= 0);
                               1203                 :                : }
                               1204                 :                : 
 5310 tgl@sss.pgh.pa.us        1205                 :CBC           7 : PG_FUNCTION_INFO_V1(hstore_lt);
                               1206                 :                : Datum
 5310 tgl@sss.pgh.pa.us        1207                 :UBC           0 : hstore_lt(PG_FUNCTION_ARGS)
                               1208                 :                : {
 5161 bruce@momjian.us         1209                 :              0 :     int         res = DatumGetInt32(DirectFunctionCall2(hstore_cmp,
                               1210                 :                :                                                         PG_GETARG_DATUM(0),
                               1211                 :                :                                                         PG_GETARG_DATUM(1)));
                               1212                 :                : 
 5310 tgl@sss.pgh.pa.us        1213                 :              0 :     PG_RETURN_BOOL(res < 0);
                               1214                 :                : }
                               1215                 :                : 
 5310 tgl@sss.pgh.pa.us        1216                 :CBC           7 : PG_FUNCTION_INFO_V1(hstore_le);
                               1217                 :                : Datum
 5310 tgl@sss.pgh.pa.us        1218                 :UBC           0 : hstore_le(PG_FUNCTION_ARGS)
                               1219                 :                : {
 5161 bruce@momjian.us         1220                 :              0 :     int         res = DatumGetInt32(DirectFunctionCall2(hstore_cmp,
                               1221                 :                :                                                         PG_GETARG_DATUM(0),
                               1222                 :                :                                                         PG_GETARG_DATUM(1)));
                               1223                 :                : 
 5310 tgl@sss.pgh.pa.us        1224                 :              0 :     PG_RETURN_BOOL(res <= 0);
                               1225                 :                : }
                               1226                 :                : 
                               1227                 :                : 
 5310 tgl@sss.pgh.pa.us        1228                 :CBC           8 : PG_FUNCTION_INFO_V1(hstore_hash);
                               1229                 :                : Datum
                               1230                 :           2014 : hstore_hash(PG_FUNCTION_ARGS)
                               1231                 :                : {
 2400                          1232                 :           2014 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 5161 bruce@momjian.us         1233                 :           2014 :     Datum       hval = hash_any((unsigned char *) VARDATA(hs),
 5310 tgl@sss.pgh.pa.us        1234                 :           2014 :                                 VARSIZE(hs) - VARHDRSZ);
                               1235                 :                : 
                               1236                 :                :     /*
                               1237                 :                :      * This (along with hstore_hash_extended) is the only place in the code
                               1238                 :                :      * that cares whether the overall varlena size exactly matches the true
                               1239                 :                :      * data size; this assertion should be maintained by all the other code,
                               1240                 :                :      * but we make it explicit here.
                               1241                 :                :      */
                               1242   [ +  +  -  + ]:           2014 :     Assert(VARSIZE(hs) ==
                               1243                 :                :            (HS_COUNT(hs) != 0 ?
                               1244                 :                :             CALCDATASIZE(HS_COUNT(hs),
                               1245                 :                :                          HSE_ENDPOS(ARRPTR(hs)[2 * HS_COUNT(hs) - 1])) :
                               1246                 :                :             HSHRDSIZE));
                               1247                 :                : 
 5161 bruce@momjian.us         1248         [ +  + ]:           2014 :     PG_FREE_IF_COPY(hs, 0);
 5310 tgl@sss.pgh.pa.us        1249                 :           2014 :     PG_RETURN_DATUM(hval);
                               1250                 :                : }
                               1251                 :                : 
 1969                          1252                 :              8 : PG_FUNCTION_INFO_V1(hstore_hash_extended);
                               1253                 :                : Datum
                               1254                 :             10 : hstore_hash_extended(PG_FUNCTION_ARGS)
                               1255                 :                : {
                               1256                 :             10 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
                               1257                 :             10 :     uint64      seed = PG_GETARG_INT64(1);
                               1258                 :                :     Datum       hval;
                               1259                 :                : 
                               1260                 :             10 :     hval = hash_any_extended((unsigned char *) VARDATA(hs),
                               1261                 :             10 :                              VARSIZE(hs) - VARHDRSZ,
                               1262                 :                :                              seed);
                               1263                 :                : 
                               1264                 :                :     /* See comment in hstore_hash */
                               1265   [ +  +  -  + ]:             10 :     Assert(VARSIZE(hs) ==
                               1266                 :                :            (HS_COUNT(hs) != 0 ?
                               1267                 :                :             CALCDATASIZE(HS_COUNT(hs),
                               1268                 :                :                          HSE_ENDPOS(ARRPTR(hs)[2 * HS_COUNT(hs) - 1])) :
                               1269                 :                :             HSHRDSIZE));
                               1270                 :                : 
                               1271         [ -  + ]:             10 :     PG_FREE_IF_COPY(hs, 0);
                               1272                 :             10 :     PG_RETURN_DATUM(hval);
                               1273                 :                : }
        

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