LCOV - differential code coverage report
Current view: top level - contrib/hstore - hstore_op.c (source / functions) Coverage Total Hit LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 91.5 % 574 525 8 24 17 11 259 4 251 20 263 1 3
Current Date: 2023-04-08 17:13:01 Functions: 66.3 % 86 57 5 24 55 1 1 5 55
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (180,240] days: 100.0 % 1 1 1
Legend: Lines: hit not hit (240..) days: 91.4 % 573 524 8 24 17 11 259 3 251 20 263
Function coverage date bins:
(240..) days: 39.0 % 146 57 5 24 55 1 1 5 55

 Age         Owner                  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 */
 4790 bruce                      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
 4790 bruce                      36 CBC        9456 : hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen)
                                 37                 : {
 4939 tgl                        38            9456 :     HEntry     *entries = ARRPTR(hs);
 4790 bruce                      39            9456 :     int         stopLow = lowbound ? *lowbound : 0;
                                 40            9456 :     int         stopHigh = HS_COUNT(hs);
                                 41                 :     int         stopMiddle;
 6031                            42            9456 :     char       *base = STRPTR(hs);
                                 43                 : 
 4939 tgl                        44           24849 :     while (stopLow < stopHigh)
                                 45                 :     {
                                 46                 :         int         difference;
                                 47                 : 
                                 48           18556 :         stopMiddle = stopLow + (stopHigh - stopLow) / 2;
                                 49                 : 
 2698                            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                 : 
 6060 teodor                     55           18556 :         if (difference == 0)
                                 56                 :         {
 4939 tgl                        57            3163 :             if (lowbound)
                                 58            2519 :                 *lowbound = stopMiddle + 1;
                                 59            3163 :             return stopMiddle;
                                 60                 :         }
 6060 teodor                     61           15393 :         else if (difference < 0)
 4939 tgl                        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                 : 
  282 peter                      83 GNC        2842 :     deconstruct_array_builtin(a, TEXTOID, &key_datums, &key_nulls, &key_count);
                                 84                 : 
 4939 tgl                        85 CBC        2842 :     if (key_count == 0)
 4939 tgl                        86 ECB             :     {
 4939 tgl                        87 GIC           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
 3338 noah                       96 ECB             :      * on palloc() to complain.
 3338 noah                       97 EUB             :      */
 3338 noah                       98 GIC        2837 :     if (key_count > MaxAllocSize / sizeof(Pairs))
 3338 noah                       99 UIC           0 :         ereport(ERROR,
                                100                 :                 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                                101                 :                  errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
 2118 tgl                       102 ECB             :                         key_count, (int) (MaxAllocSize / sizeof(Pairs)))));
                                103                 : 
 4939 tgl                       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])
 4939 tgl                       109 ECB             :         {
 4939 tgl                       110 CBC        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;
 4939 tgl                       115 GIC        5679 :             key_pairs[j].isnull = 1;
                                116            5679 :             j++;
                                117                 :         }
 4939 tgl                       118 ECB             :     }
                                119                 : 
 4939 tgl                       120 CBC        2837 :     *npairs = hstoreUniquePairs(key_pairs, j, &bufsiz);
                                121                 : 
 4939 tgl                       122 GIC        2837 :     return key_pairs;
                                123                 : }
 4939 tgl                       124 ECB             : 
                                125                 : 
 4939 tgl                       126 CBC           8 : PG_FUNCTION_INFO_V1(hstore_fetchval);
                                127                 : Datum
                                128               6 : hstore_fetchval(PG_FUNCTION_ARGS)
 6031 bruce                     129 ECB             : {
 2029 tgl                       130 CBC           6 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 4939 tgl                       131 GIC           6 :     text       *key = PG_GETARG_TEXT_PP(1);
 4939 tgl                       132 CBC           6 :     HEntry     *entries = ARRPTR(hs);
 6031 bruce                     133 ECB             :     text       *out;
 4790 bruce                     134 GIC          12 :     int         idx = hstoreFindKey(hs, NULL,
 4939 tgl                       135 CBC          12 :                                     VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key));
 6031 bruce                     136 ECB             : 
 2698 tgl                       137 GIC           6 :     if (idx < 0 || HSTORE_VALISNULL(entries, idx))
 6060 teodor                    138 CBC           2 :         PG_RETURN_NULL();
 6060 teodor                    139 ECB             : 
 2698 tgl                       140 GIC           4 :     out = cstring_to_text_with_len(HSTORE_VAL(entries, STRPTR(hs), idx),
 2698 tgl                       141 CBC           4 :                                    HSTORE_VALLEN(entries, idx));
                                142                 : 
 5493 tgl                       143 GIC           4 :     PG_RETURN_TEXT_P(out);
                                144                 : }
 6060 teodor                    145 ECB             : 
                                146                 : 
 4939 tgl                       147 CBC          16 : PG_FUNCTION_INFO_V1(hstore_exists);
                                148                 : Datum
                                149            1440 : hstore_exists(PG_FUNCTION_ARGS)
 6031 bruce                     150 ECB             : {
 2029 tgl                       151 CBC        1440 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 4939                           152            1440 :     text       *key = PG_GETARG_TEXT_PP(1);
 4790 bruce                     153 GIC        2880 :     int         idx = hstoreFindKey(hs, NULL,
 4939 tgl                       154 CBC        2880 :                                     VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key));
                                155                 : 
 4939 tgl                       156 GIC        1440 :     PG_RETURN_BOOL(idx >= 0);
                                157                 : }
 6060 teodor                    158 ECB             : 
                                159                 : 
 4939 tgl                       160 CBC           8 : PG_FUNCTION_INFO_V1(hstore_exists_any);
                                161                 : Datum
                                162            1727 : hstore_exists_any(PG_FUNCTION_ARGS)
 4939 tgl                       163 ECB             : {
 2029 tgl                       164 GIC        1727 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 4939 tgl                       165 CBC        1727 :     ArrayType  *keys = PG_GETARG_ARRAYTYPE_P(1);
                                166                 :     int         nkeys;
 4790 bruce                     167            1727 :     Pairs      *key_pairs = hstoreArrayToPairs(keys, &nkeys);
 4790 bruce                     168 ECB             :     int         i;
 4790 bruce                     169 GIC        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
 4790 bruce                     176 ECB             :      * of the last search.
                                177                 :      */
 4473 tgl                       178 CBC        3580 :     for (i = 0; i < nkeys; i++)
 4939 tgl                       179 ECB             :     {
 4790 bruce                     180 GIC        2867 :         int         idx = hstoreFindKey(hs, &lowbound,
 2118 tgl                       181 CBC        2867 :                                         key_pairs[i].key, key_pairs[i].keylen);
                                182                 : 
 4939                           183            2867 :         if (idx >= 0)
 4473 tgl                       184 ECB             :         {
 4939 tgl                       185 GIC        1014 :             res = true;
 4473                           186            1014 :             break;
                                187                 :         }
 4939 tgl                       188 ECB             :     }
                                189                 : 
 4939 tgl                       190 GIC        1727 :     PG_RETURN_BOOL(res);
                                191                 : }
 6060 teodor                    192 ECB             : 
                                193                 : 
 4939 tgl                       194 CBC           8 : PG_FUNCTION_INFO_V1(hstore_exists_all);
                                195                 : Datum
                                196            1097 : hstore_exists_all(PG_FUNCTION_ARGS)
 6031 bruce                     197 ECB             : {
 2029 tgl                       198 GIC        1097 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 4939 tgl                       199 CBC        1097 :     ArrayType  *keys = PG_GETARG_ARRAYTYPE_P(1);
                                200                 :     int         nkeys;
 4790 bruce                     201            1097 :     Pairs      *key_pairs = hstoreArrayToPairs(keys, &nkeys);
 4790 bruce                     202 ECB             :     int         i;
 4790 bruce                     203 GIC        1097 :     int         lowbound = 0;
 4473 tgl                       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
 4790 bruce                     210 ECB             :      * of the last search.
                                211                 :      */
 4473 tgl                       212 CBC        1507 :     for (i = 0; i < nkeys; i++)
 4939 tgl                       213 ECB             :     {
 4790 bruce                     214 GIC        1378 :         int         idx = hstoreFindKey(hs, &lowbound,
 2118 tgl                       215 CBC        1378 :                                         key_pairs[i].key, key_pairs[i].keylen);
                                216                 : 
 4939                           217            1378 :         if (idx < 0)
 4473 tgl                       218 ECB             :         {
 4939 tgl                       219 GIC         968 :             res = false;
 4473                           220             968 :             break;
                                221                 :         }
 4939 tgl                       222 ECB             :     }
                                223                 : 
 4939 tgl                       224 GIC        1097 :     PG_RETURN_BOOL(res);
                                225                 : }
 6060 teodor                    226 ECB             : 
                                227                 : 
 4939 tgl                       228 CBC          15 : PG_FUNCTION_INFO_V1(hstore_defined);
                                229                 : Datum
                                230               4 : hstore_defined(PG_FUNCTION_ARGS)
 4939 tgl                       231 ECB             : {
 2029 tgl                       232 CBC           4 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 4939                           233               4 :     text       *key = PG_GETARG_TEXT_PP(1);
                                234               4 :     HEntry     *entries = ARRPTR(hs);
 4790 bruce                     235               8 :     int         idx = hstoreFindKey(hs, NULL,
 4939 tgl                       236 GIC           8 :                                     VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key));
 2698 tgl                       237 CBC           4 :     bool        res = (idx >= 0 && !HSTORE_VALISNULL(entries, idx));
                                238                 : 
 6060 teodor                    239 GIC           4 :     PG_RETURN_BOOL(res);
                                240                 : }
 6060 teodor                    241 ECB             : 
                                242                 : 
 4939 tgl                       243 CBC           8 : PG_FUNCTION_INFO_V1(hstore_delete);
                                244                 : Datum
                                245              11 : hstore_delete(PG_FUNCTION_ARGS)
 6031 bruce                     246 ECB             : {
 2029 tgl                       247 CBC          11 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 4939                           248              11 :     text       *key = PG_GETARG_TEXT_PP(1);
 4790 bruce                     249              11 :     char       *keyptr = VARDATA_ANY(key);
 4790 bruce                     250 GIC          11 :     int         keylen = VARSIZE_ANY_EXHDR(key);
 5884 tgl                       251              11 :     HStore     *out = palloc(VARSIZE(hs));
                                252                 :     char       *bufs,
                                253                 :                *bufd,
                                254                 :                *ptrd;
                                255                 :     HEntry     *es,
 6031 bruce                     256 ECB             :                *ed;
 4790                           257                 :     int         i;
 4790 bruce                     258 GIC          11 :     int         count = HS_COUNT(hs);
 4790 bruce                     259 CBC          11 :     int         outcount = 0;
 6031 bruce                     260 ECB             : 
 5884 tgl                       261 GIC          11 :     SET_VARSIZE(out, VARSIZE(hs));
 4790 bruce                     262 CBC          11 :     HS_SETCOUNT(out, count);    /* temporary! */
 6031 bruce                     263 ECB             : 
 4939 tgl                       264 CBC          11 :     bufs = STRPTR(hs);
 6031 bruce                     265              11 :     es = ARRPTR(hs);
 4939 tgl                       266 GIC          11 :     bufd = ptrd = STRPTR(out);
 6031 bruce                     267 CBC          11 :     ed = ARRPTR(out);
                                268                 : 
 4939 tgl                       269              44 :     for (i = 0; i < count; ++i)
 6031 bruce                     270 ECB             :     {
 2698 tgl                       271 GIC          33 :         int         len = HSTORE_KEYLEN(es, i);
 2698 tgl                       272 CBC          33 :         char       *ptrs = HSTORE_KEY(es, bufs, i);
                                273                 : 
 4492 rhaas                     274              33 :         if (!(len == keylen && memcmp(ptrs, keyptr, keylen) == 0))
                                275                 :         {
 2698 tgl                       276              24 :             int         vallen = HSTORE_VALLEN(es, i);
                                277                 : 
                                278              24 :             HS_COPYITEM(ed, bufd, ptrd, ptrs, len, vallen,
                                279                 :                         HSTORE_VALISNULL(es, i));
 4939 tgl                       280 GIC          24 :             ++outcount;
                                281                 :         }
 6060 teodor                    282 ECB             :     }
                                283                 : 
 4790 bruce                     284 CBC          11 :     HS_FINALIZE(out, outcount, bufd, ptrd);
                                285                 : 
 4939 tgl                       286 GIC          11 :     PG_RETURN_POINTER(out);
                                287                 : }
 4939 tgl                       288 ECB             : 
                                289                 : 
 4939 tgl                       290 CBC           8 : PG_FUNCTION_INFO_V1(hstore_delete_array);
                                291                 : Datum
                                292              12 : hstore_delete_array(PG_FUNCTION_ARGS)
 4939 tgl                       293 ECB             : {
 2029 tgl                       294 CBC          12 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 4939 tgl                       295 GIC          12 :     HStore     *out = palloc(VARSIZE(hs));
 4790 bruce                     296              12 :     int         hs_count = HS_COUNT(hs);
                                297                 :     char       *ps,
                                298                 :                *bufd,
                                299                 :                *pd;
                                300                 :     HEntry     *es,
                                301                 :                *ed;
 4790 bruce                     302 ECB             :     int         i,
                                303                 :                 j;
 4790 bruce                     304 GIC          12 :     int         outcount = 0;
 4939 tgl                       305 CBC          12 :     ArrayType  *key_array = PG_GETARG_ARRAYTYPE_P(1);
                                306                 :     int         nkeys;
 4790 bruce                     307              12 :     Pairs      *key_pairs = hstoreArrayToPairs(key_array, &nkeys);
 4939 tgl                       308 ECB             : 
 4939 tgl                       309 GIC          12 :     SET_VARSIZE(out, VARSIZE(hs));
 4790 bruce                     310 CBC          12 :     HS_SETCOUNT(out, hs_count); /* temporary! */
 4939 tgl                       311 ECB             : 
 4939 tgl                       312 CBC          12 :     ps = STRPTR(hs);
                                313              12 :     es = ARRPTR(hs);
 4939 tgl                       314 GIC          12 :     bufd = pd = STRPTR(out);
 4939 tgl                       315 CBC          12 :     ed = ARRPTR(out);
                                316                 : 
 4939 tgl                       317 GIC          12 :     if (nkeys == 0)
 6031 bruce                     318 ECB             :     {
 4939 tgl                       319                 :         /* return a copy of the input, unchanged */
 4939 tgl                       320 CBC           3 :         memcpy(out, hs, VARSIZE(hs));
                                321               3 :         HS_FIXSIZE(out, hs_count);
 4939 tgl                       322 GIC           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
 4939 tgl                       329 ECB             :      */
                                330                 : 
 4790 bruce                     331 GIC          36 :     for (i = j = 0; i < hs_count;)
                                332                 :     {
 4790 bruce                     333 ECB             :         int         difference;
 4790 bruce                     334 EUB             : 
 4939 tgl                       335 GIC          27 :         if (j >= nkeys)
 4939 tgl                       336 UIC           0 :             difference = -1;
 4939 tgl                       337 ECB             :         else
                                338                 :         {
 2698 tgl                       339 CBC          27 :             int         skeylen = HSTORE_KEYLEN(es, i);
 4790 bruce                     340 ECB             : 
 4939 tgl                       341 CBC          27 :             if (skeylen == key_pairs[j].keylen)
 2698                           342              27 :                 difference = memcmp(HSTORE_KEY(es, ps, i),
 4492 rhaas                     343 GIC          27 :                                     key_pairs[j].key,
 4492 rhaas                     344 GBC          27 :                                     key_pairs[j].keylen);
                                345                 :             else
 4939 tgl                       346 UIC           0 :                 difference = (skeylen > key_pairs[j].keylen) ? 1 : -1;
 4939 tgl                       347 ECB             :         }
 4939 tgl                       348 EUB             : 
 4939 tgl                       349 CBC          27 :         if (difference > 0)
 4939 tgl                       350 LBC           0 :             ++j;
 4939 tgl                       351 GIC          27 :         else if (difference == 0)
                                352              14 :             ++i, ++j;
 4939 tgl                       353 ECB             :         else
                                354                 :         {
 4939 tgl                       355 GIC          13 :             HS_COPYITEM(ed, bufd, pd,
 2698 tgl                       356 ECB             :                         HSTORE_KEY(es, ps, i), HSTORE_KEYLEN(es, i),
                                357                 :                         HSTORE_VALLEN(es, i), HSTORE_VALISNULL(es, i));
 4939 tgl                       358 GIC          13 :             ++outcount;
                                359              13 :             ++i;
                                360                 :         }
 4939 tgl                       361 ECB             :     }
                                362                 : 
 4790 bruce                     363 CBC           9 :     HS_FINALIZE(out, outcount, bufd, pd);
                                364                 : 
 4939 tgl                       365 GIC           9 :     PG_RETURN_POINTER(out);
                                366                 : }
 4939 tgl                       367 ECB             : 
                                368                 : 
 4939 tgl                       369 CBC           8 : PG_FUNCTION_INFO_V1(hstore_delete_hstore);
                                370                 : Datum
                                371              12 : hstore_delete_hstore(PG_FUNCTION_ARGS)
 4939 tgl                       372 ECB             : {
 2029 tgl                       373 CBC          12 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
                                374              12 :     HStore     *hs2 = PG_GETARG_HSTORE_P(1);
 4939                           375              12 :     HStore     *out = palloc(VARSIZE(hs));
 4790 bruce                     376 GIC          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;
 4790 bruce                     385 ECB             :     int         i,
                                386                 :                 j;
 4790 bruce                     387 CBC          12 :     int         outcount = 0;
 6060 teodor                    388 ECB             : 
 4939 tgl                       389 GIC          12 :     SET_VARSIZE(out, VARSIZE(hs));
 4790 bruce                     390 CBC          12 :     HS_SETCOUNT(out, hs_count); /* temporary! */
 6060 teodor                    391 ECB             : 
 4939 tgl                       392 CBC          12 :     ps = STRPTR(hs);
                                393              12 :     es = ARRPTR(hs);
                                394              12 :     ps2 = STRPTR(hs2);
                                395              12 :     es2 = ARRPTR(hs2);
 4939 tgl                       396 GIC          12 :     bufd = pd = STRPTR(out);
 4939 tgl                       397 CBC          12 :     ed = ARRPTR(out);
                                398                 : 
 4939 tgl                       399 GIC          12 :     if (hs2_count == 0)
 4939 tgl                       400 ECB             :     {
                                401                 :         /* return a copy of the input, unchanged */
 4939 tgl                       402 CBC           3 :         memcpy(out, hs, VARSIZE(hs));
                                403               3 :         HS_FIXSIZE(out, hs_count);
 4939 tgl                       404 GIC           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
 4939 tgl                       412 ECB             :      */
                                413                 : 
 4790 bruce                     414 GIC          36 :     for (i = j = 0; i < hs_count;)
                                415                 :     {
 4790 bruce                     416 ECB             :         int         difference;
                                417                 : 
 4939 tgl                       418 GIC          27 :         if (j >= hs2_count)
                                419               5 :             difference = -1;
 4939 tgl                       420 ECB             :         else
                                421                 :         {
 2698 tgl                       422 GIC          22 :             int         skeylen = HSTORE_KEYLEN(es, i);
 2698 tgl                       423 CBC          22 :             int         s2keylen = HSTORE_KEYLEN(es2, j);
 4790 bruce                     424 ECB             : 
 4939 tgl                       425 CBC          22 :             if (skeylen == s2keylen)
 2698 tgl                       426 GIC          20 :                 difference = memcmp(HSTORE_KEY(es, ps, i),
                                427              20 :                                     HSTORE_KEY(es2, ps2, j),
 4492 rhaas                     428 ECB             :                                     skeylen);
                                429                 :             else
 4939 tgl                       430 GIC           2 :                 difference = (skeylen > s2keylen) ? 1 : -1;
 4939 tgl                       431 ECB             :         }
 4939 tgl                       432 EUB             : 
 4939 tgl                       433 CBC          27 :         if (difference > 0)
 4939 tgl                       434 UIC           0 :             ++j;
 4939 tgl                       435 CBC          27 :         else if (difference == 0)
 4939 tgl                       436 ECB             :         {
 2698 tgl                       437 GIC          17 :             int         svallen = HSTORE_VALLEN(es, i);
 2698 tgl                       438 CBC          17 :             int         snullval = HSTORE_VALISNULL(es, i);
 2698 tgl                       439 ECB             : 
 2698 tgl                       440 CBC          17 :             if (snullval != HSTORE_VALISNULL(es2, j) ||
                                441              15 :                 (!snullval && (svallen != HSTORE_VALLEN(es2, j) ||
 2698 tgl                       442 GIC          15 :                                memcmp(HSTORE_VAL(es, ps, i),
                                443              15 :                                       HSTORE_VAL(es2, ps2, j),
 2698 tgl                       444 ECB             :                                       svallen) != 0)))
                                445                 :             {
 4939 tgl                       446 GIC           4 :                 HS_COPYITEM(ed, bufd, pd,
 2698 tgl                       447 ECB             :                             HSTORE_KEY(es, ps, i), HSTORE_KEYLEN(es, i),
                                448                 :                             svallen, snullval);
 4939 tgl                       449 CBC           4 :                 ++outcount;
                                450                 :             }
 4939 tgl                       451 GIC          17 :             ++i, ++j;
                                452                 :         }
 4939 tgl                       453 ECB             :         else
                                454                 :         {
 4939 tgl                       455 GIC          10 :             HS_COPYITEM(ed, bufd, pd,
 2698 tgl                       456 ECB             :                         HSTORE_KEY(es, ps, i), HSTORE_KEYLEN(es, i),
                                457                 :                         HSTORE_VALLEN(es, i), HSTORE_VALISNULL(es, i));
 4939 tgl                       458 GIC          10 :             ++outcount;
                                459              10 :             ++i;
                                460                 :         }
 4939 tgl                       461 ECB             :     }
                                462                 : 
 4790 bruce                     463 CBC           9 :     HS_FINALIZE(out, outcount, bufd, pd);
                                464                 : 
 6060 teodor                    465 GIC           9 :     PG_RETURN_POINTER(out);
                                466                 : }
 6060 teodor                    467 ECB             : 
                                468                 : 
 4939 tgl                       469 CBC           8 : PG_FUNCTION_INFO_V1(hstore_concat);
                                470                 : Datum
                                471              30 : hstore_concat(PG_FUNCTION_ARGS)
 6031 bruce                     472 ECB             : {
 2029 tgl                       473 CBC          30 :     HStore     *s1 = PG_GETARG_HSTORE_P(0);
 2029 tgl                       474 GIC          30 :     HStore     *s2 = PG_GETARG_HSTORE_P(1);
 5884                           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;
 4790 bruce                     483 ECB             :     int         s1idx;
                                484                 :     int         s2idx;
 4790 bruce                     485 CBC          30 :     int         s1count = HS_COUNT(s1);
 4790 bruce                     486 GIC          30 :     int         s2count = HS_COUNT(s2);
 4790 bruce                     487 CBC          30 :     int         outcount = 0;
 6060 teodor                    488 ECB             : 
 4939 tgl                       489 GIC          30 :     SET_VARSIZE(out, VARSIZE(s1) + VARSIZE(s2) - HSHRDSIZE);
 4939 tgl                       490 CBC          30 :     HS_SETCOUNT(out, s1count + s2count);
                                491                 : 
 4939 tgl                       492 GIC          30 :     if (s1count == 0)
 4939 tgl                       493 ECB             :     {
                                494                 :         /* return a copy of the input, unchanged */
 4939 tgl                       495 CBC           4 :         memcpy(out, s2, VARSIZE(s2));
                                496               4 :         HS_FIXSIZE(out, s2count);
 4939 tgl                       497 GIC           4 :         HS_SETCOUNT(out, s2count);
                                498               4 :         PG_RETURN_POINTER(out);
 4939 tgl                       499 ECB             :     }
                                500                 : 
 4939 tgl                       501 GIC          26 :     if (s2count == 0)
 4939 tgl                       502 ECB             :     {
                                503                 :         /* return a copy of the input, unchanged */
 4939 tgl                       504 CBC           2 :         memcpy(out, s1, VARSIZE(s1));
                                505               2 :         HS_FIXSIZE(out, s1count);
 4939 tgl                       506 GIC           2 :         HS_SETCOUNT(out, s1count);
                                507               2 :         PG_RETURN_POINTER(out);
 4939 tgl                       508 ECB             :     }
 6060 teodor                    509                 : 
 6031 bruce                     510 CBC          24 :     ps1 = STRPTR(s1);
                                511              24 :     ps2 = STRPTR(s2);
 4939 tgl                       512              24 :     bufd = pd = STRPTR(out);
 6031 bruce                     513              24 :     es1 = ARRPTR(s1);
 6031 bruce                     514 GIC          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
 4939 tgl                       520 ECB             :      */
                                521                 : 
 4939 tgl                       522 GIC          90 :     for (s1idx = s2idx = 0; s1idx < s1count || s2idx < s2count; ++outcount)
                                523                 :     {
 4790 bruce                     524 ECB             :         int         difference;
                                525                 : 
 4939 tgl                       526 CBC          66 :         if (s1idx >= s1count)
                                527              13 :             difference = 1;
 4939 tgl                       528 GIC          53 :         else if (s2idx >= s2count)
                                529               7 :             difference = -1;
 6060 teodor                    530 ECB             :         else
 6031 bruce                     531                 :         {
 2698 tgl                       532 GIC          46 :             int         s1keylen = HSTORE_KEYLEN(es1, s1idx);
 2698 tgl                       533 CBC          46 :             int         s2keylen = HSTORE_KEYLEN(es2, s2idx);
 4790 bruce                     534 ECB             : 
 4939 tgl                       535 CBC          46 :             if (s1keylen == s2keylen)
 2698 tgl                       536 GIC          41 :                 difference = memcmp(HSTORE_KEY(es1, ps1, s1idx),
                                537              41 :                                     HSTORE_KEY(es2, ps2, s2idx),
 4492 rhaas                     538 ECB             :                                     s1keylen);
                                539                 :             else
 4939 tgl                       540 GIC           5 :                 difference = (s1keylen > s2keylen) ? 1 : -1;
 6031 bruce                     541 ECB             :         }
                                542                 : 
 4939 tgl                       543 CBC          66 :         if (difference >= 0)
                                544                 :         {
 4939 tgl                       545 GIC          38 :             HS_COPYITEM(ed, bufd, pd,
 2118 tgl                       546 ECB             :                         HSTORE_KEY(es2, ps2, s2idx), HSTORE_KEYLEN(es2, s2idx),
                                547                 :                         HSTORE_VALLEN(es2, s2idx), HSTORE_VALISNULL(es2, s2idx));
 4939 tgl                       548 CBC          38 :             ++s2idx;
 4939 tgl                       549 GIC          38 :             if (difference == 0)
                                550              19 :                 ++s1idx;
                                551                 :         }
 6031 bruce                     552 ECB             :         else
                                553                 :         {
 4939 tgl                       554 GIC          28 :             HS_COPYITEM(ed, bufd, pd,
 2118 tgl                       555 ECB             :                         HSTORE_KEY(es1, ps1, s1idx), HSTORE_KEYLEN(es1, s1idx),
                                556                 :                         HSTORE_VALLEN(es1, s1idx), HSTORE_VALISNULL(es1, s1idx));
 4939 tgl                       557 GIC          28 :             ++s1idx;
                                558                 :         }
 6060 teodor                    559 ECB             :     }
                                560                 : 
 4790 bruce                     561 CBC          24 :     HS_FINALIZE(out, outcount, bufd, pd);
                                562                 : 
 4939 tgl                       563 GIC          24 :     PG_RETURN_POINTER(out);
                                564                 : }
 6060 teodor                    565 ECB             : 
                                566                 : 
 4939 tgl                       567 CBC           8 : PG_FUNCTION_INFO_V1(hstore_slice_to_array);
                                568                 : Datum
                                569               4 : hstore_slice_to_array(PG_FUNCTION_ARGS)
 4939 tgl                       570 ECB             : {
 2029 tgl                       571 CBC           4 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 4939                           572               4 :     HEntry     *entries = ARRPTR(hs);
 4790 bruce                     573 GIC           4 :     char       *ptr = STRPTR(hs);
 4939 tgl                       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;
 4790 bruce                     581 ECB             :     int         i;
                                582                 : 
  282 peter                     583 GNC           4 :     deconstruct_array_builtin(key_array, TEXTOID, &key_datums, &key_nulls, &key_count);
 4939 tgl                       584 EUB             : 
 4939 tgl                       585 GIC           4 :     if (key_count == 0)
                                586                 :     {
 4939 tgl                       587 LBC           0 :         aout = construct_empty_array(TEXTOID);
                                588               0 :         PG_RETURN_POINTER(aout);
                                589                 :     }
 6060 teodor                    590 ECB             : 
 4939 tgl                       591 GIC           4 :     out_datums = palloc(sizeof(Datum) * key_count);
 4939 tgl                       592 CBC           4 :     out_nulls = palloc(sizeof(bool) * key_count);
                                593                 : 
 4939 tgl                       594 GIC          15 :     for (i = 0; i < key_count; ++i)
 4939 tgl                       595 ECB             :     {
 4790 bruce                     596 CBC          11 :         text       *key = (text *) DatumGetPointer(key_datums[i]);
                                597                 :         int         idx;
 6060 teodor                    598 ECB             : 
 4939 tgl                       599 GIC          11 :         if (key_nulls[i])
 4939 tgl                       600 CBC           1 :             idx = -1;
                                601                 :         else
                                602              10 :             idx = hstoreFindKey(hs, NULL, VARDATA(key), VARSIZE(key) - VARHDRSZ);
 6060 teodor                    603 ECB             : 
 2698 tgl                       604 GIC          11 :         if (idx < 0 || HSTORE_VALISNULL(entries, idx))
                                605                 :         {
 4939                           606               2 :             out_nulls[i] = true;
 4939 tgl                       607 CBC           2 :             out_datums[i] = (Datum) 0;
 4939 tgl                       608 ECB             :         }
                                609                 :         else
                                610                 :         {
 1165 alvherre                  611 GIC          18 :             out_datums[i] =
                                612               9 :                 PointerGetDatum(cstring_to_text_with_len(HSTORE_VAL(entries, ptr, idx),
                                613               9 :                                                          HSTORE_VALLEN(entries, idx)));
 4939 tgl                       614 CBC           9 :             out_nulls[i] = false;
                                615                 :         }
                                616                 :     }
 6031 bruce                     617 ECB             : 
 4939 tgl                       618 GIC           4 :     aout = construct_md_array(out_datums, out_nulls,
                                619                 :                               ARR_NDIM(key_array),
 4939 tgl                       620 ECB             :                               ARR_DIMS(key_array),
 4939 tgl                       621 GIC           4 :                               ARR_LBOUND(key_array),
                                622                 :                               TEXTOID, -1, false, TYPALIGN_INT);
                                623                 : 
 4939 tgl                       624 CBC           4 :     PG_RETURN_POINTER(aout);
                                625                 : }
 6060 teodor                    626 ECB             : 
                                627                 : 
 4939 tgl                       628 CBC           8 : PG_FUNCTION_INFO_V1(hstore_slice_to_hstore);
 6060 teodor                    629 ECB             : Datum
 4939 tgl                       630 CBC           6 : hstore_slice_to_hstore(PG_FUNCTION_ARGS)
 6031 bruce                     631 ECB             : {
 2029 tgl                       632 GIC           6 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 4939                           633               6 :     HEntry     *entries = ARRPTR(hs);
 4790 bruce                     634 CBC           6 :     char       *ptr = STRPTR(hs);
 4939 tgl                       635 GIC           6 :     ArrayType  *key_array = PG_GETARG_ARRAYTYPE_P(1);
                                636                 :     HStore     *out;
 4790 bruce                     637 ECB             :     int         nkeys;
 4790 bruce                     638 GIC           6 :     Pairs      *key_pairs = hstoreArrayToPairs(key_array, &nkeys);
 4790 bruce                     639 ECB             :     Pairs      *out_pairs;
                                640                 :     int         bufsiz;
 4790 bruce                     641 CBC           6 :     int         lastidx = 0;
                                642                 :     int         i;
 4790 bruce                     643 GBC           6 :     int         out_count = 0;
 4939 tgl                       644 EUB             : 
 4939 tgl                       645 GIC           6 :     if (nkeys == 0)
                                646                 :     {
 4939 tgl                       647 UIC           0 :         out = hstorePairs(NULL, 0, 0);
 4939 tgl                       648 LBC           0 :         PG_RETURN_POINTER(out);
 4939 tgl                       649 ECB             :     }
                                650                 : 
                                651                 :     /* hstoreArrayToPairs() checked overflow */
 4939 tgl                       652 GIC           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
 4790 bruce                     658 ECB             :      * start one entry past the previous "found" entry, or at the lower bound
                                659                 :      * of the last search.
 4939 tgl                       660                 :      */
 5870 teodor                    661                 : 
 4939 tgl                       662 GIC          21 :     for (i = 0; i < nkeys; ++i)
 5870 teodor                    663 ECB             :     {
 4790 bruce                     664 GIC          15 :         int         idx = hstoreFindKey(hs, &lastidx,
 2118 tgl                       665 CBC          15 :                                         key_pairs[i].key, key_pairs[i].keylen);
 6060 teodor                    666 ECB             : 
 4939 tgl                       667 CBC          15 :         if (idx >= 0)
 4939 tgl                       668 ECB             :         {
 4939 tgl                       669 CBC          12 :             out_pairs[out_count].key = key_pairs[i].key;
                                670              12 :             bufsiz += (out_pairs[out_count].keylen = key_pairs[i].keylen);
 2698                           671              12 :             out_pairs[out_count].val = HSTORE_VAL(entries, ptr, idx);
 2698 tgl                       672 GIC          12 :             bufsiz += (out_pairs[out_count].vallen = HSTORE_VALLEN(entries, idx));
                                673              12 :             out_pairs[out_count].isnull = HSTORE_VALISNULL(entries, idx);
 4939                           674              12 :             out_pairs[out_count].needfree = false;
                                675              12 :             ++out_count;
                                676                 :         }
                                677                 :     }
                                678                 : 
                                679                 :     /*
 1329 michael                   680 ECB             :      * we don't use hstoreUniquePairs here because we know that the pairs list
                                681                 :      * is already sorted and uniq'ed.
 4939 tgl                       682                 :      */
                                683                 : 
 4939 tgl                       684 GIC           6 :     out = hstorePairs(out_pairs, out_count, bufsiz);
                                685                 : 
 6060 teodor                    686 CBC           6 :     PG_RETURN_POINTER(out);
                                687                 : }
 6060 teodor                    688 ECB             : 
                                689                 : 
 4939 tgl                       690 CBC           8 : PG_FUNCTION_INFO_V1(hstore_akeys);
                                691                 : Datum
 4939 tgl                       692 GIC           3 : hstore_akeys(PG_FUNCTION_ARGS)
 6031 bruce                     693 ECB             : {
 2029 tgl                       694 CBC           3 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 6031 bruce                     695 ECB             :     Datum      *d;
                                696                 :     ArrayType  *a;
 4939 tgl                       697 GIC           3 :     HEntry     *entries = ARRPTR(hs);
 6031 bruce                     698 CBC           3 :     char       *base = STRPTR(hs);
 4790 bruce                     699 GIC           3 :     int         count = HS_COUNT(hs);
 4790 bruce                     700 ECB             :     int         i;
 6031                           701                 : 
 4939 tgl                       702 GIC           3 :     if (count == 0)
                                703                 :     {
 4939 tgl                       704 CBC           1 :         a = construct_empty_array(TEXTOID);
 4939 tgl                       705 GIC           1 :         PG_RETURN_POINTER(a);
 6060 teodor                    706 ECB             :     }
                                707                 : 
 4939 tgl                       708 CBC           2 :     d = (Datum *) palloc(sizeof(Datum) * count);
 6031 bruce                     709 ECB             : 
 4939 tgl                       710 GIC           7 :     for (i = 0; i < count; ++i)
 6031 bruce                     711 ECB             :     {
 2698 tgl                       712 GIC           5 :         text       *t = cstring_to_text_with_len(HSTORE_KEY(entries, base, i),
                                713               5 :                                                  HSTORE_KEYLEN(entries, i));
 4790 bruce                     714 ECB             : 
 2698 tgl                       715 GIC           5 :         d[i] = PointerGetDatum(t);
 6060 teodor                    716 ECB             :     }
                                717                 : 
  282 peter                     718 GNC           2 :     a = construct_array_builtin(d, count, TEXTOID);
 6060 teodor                    719 ECB             : 
 6060 teodor                    720 GIC           2 :     PG_RETURN_POINTER(a);
 6060 teodor                    721 ECB             : }
                                722                 : 
 4939 tgl                       723                 : 
 4939 tgl                       724 GIC           8 : PG_FUNCTION_INFO_V1(hstore_avals);
                                725                 : Datum
                                726               4 : hstore_avals(PG_FUNCTION_ARGS)
 6031 bruce                     727 ECB             : {
 2029 tgl                       728 CBC           4 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 6031 bruce                     729 ECB             :     Datum      *d;
 4790                           730                 :     bool       *nulls;
                                731                 :     ArrayType  *a;
 4939 tgl                       732 GIC           4 :     HEntry     *entries = ARRPTR(hs);
 6031 bruce                     733 CBC           4 :     char       *base = STRPTR(hs);
 4790 bruce                     734 GIC           4 :     int         count = HS_COUNT(hs);
 4790 bruce                     735 CBC           4 :     int         lb = 1;
 4790 bruce                     736 ECB             :     int         i;
                                737                 : 
 4939 tgl                       738 GIC           4 :     if (count == 0)
 6031 bruce                     739 ECB             :     {
 4939 tgl                       740 CBC           1 :         a = construct_empty_array(TEXTOID);
 4939 tgl                       741 GIC           1 :         PG_RETURN_POINTER(a);
 6060 teodor                    742 ECB             :     }
                                743                 : 
 4939 tgl                       744 CBC           3 :     d = (Datum *) palloc(sizeof(Datum) * count);
 4939 tgl                       745 GIC           3 :     nulls = (bool *) palloc(sizeof(bool) * count);
 6031 bruce                     746 ECB             : 
 4939 tgl                       747 CBC          12 :     for (i = 0; i < count; ++i)
                                748                 :     {
 2698 tgl                       749 GIC           9 :         if (HSTORE_VALISNULL(entries, i))
                                750                 :         {
 4939 tgl                       751 CBC           1 :             d[i] = (Datum) 0;
                                752               1 :             nulls[i] = true;
                                753                 :         }
 4939 tgl                       754 ECB             :         else
                                755                 :         {
 2698 tgl                       756 GIC           8 :             text       *item = cstring_to_text_with_len(HSTORE_VAL(entries, base, i),
 2118                           757               8 :                                                         HSTORE_VALLEN(entries, i));
                                758                 : 
 4939 tgl                       759 CBC           8 :             d[i] = PointerGetDatum(item);
 4939 tgl                       760 GIC           8 :             nulls[i] = false;
                                761                 :         }
 6060 teodor                    762 ECB             :     }
                                763                 : 
 4939 tgl                       764 GIC           3 :     a = construct_md_array(d, nulls, 1, &count, &lb,
                                765                 :                            TEXTOID, -1, false, TYPALIGN_INT);
                                766                 : 
 6060 teodor                    767 CBC           3 :     PG_RETURN_POINTER(a);
                                768                 : }
 6060 teodor                    769 ECB             : 
 4939 tgl                       770                 : 
                                771                 : static ArrayType *
 4939 tgl                       772 CBC           4 : hstore_to_array_internal(HStore *hs, int ndims)
 4939 tgl                       773 ECB             : {
 4939 tgl                       774 GIC           4 :     HEntry     *entries = ARRPTR(hs);
                                775               4 :     char       *base = STRPTR(hs);
 4790 bruce                     776               4 :     int         count = HS_COUNT(hs);
                                777               4 :     int         out_size[2] = {0, 2};
 4790 bruce                     778 CBC           4 :     int         lb[2] = {1, 1};
                                779                 :     Datum      *out_datums;
 4939 tgl                       780 ECB             :     bool       *out_nulls;
 4790 bruce                     781 EUB             :     int         i;
                                782                 : 
 4939 tgl                       783 CBC           4 :     Assert(ndims < 3);
 4939 tgl                       784 ECB             : 
 4939 tgl                       785 CBC           4 :     if (count == 0 || ndims == 0)
 4939 tgl                       786 UIC           0 :         return construct_empty_array(TEXTOID);
 4939 tgl                       787 ECB             : 
 4939 tgl                       788 GIC           4 :     out_size[0] = count * 2 / ndims;
 4939 tgl                       789 CBC           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)
 4939 tgl                       793 ECB             :     {
 2698 tgl                       794 GIC          16 :         text       *key = cstring_to_text_with_len(HSTORE_KEY(entries, base, i),
 2698 tgl                       795 CBC          16 :                                                    HSTORE_KEYLEN(entries, i));
                                796                 : 
 4790 bruce                     797              16 :         out_datums[i * 2] = PointerGetDatum(key);
                                798              16 :         out_nulls[i * 2] = false;
                                799                 : 
 2698 tgl                       800 GIC          16 :         if (HSTORE_VALISNULL(entries, i))
                                801                 :         {
 4790 bruce                     802 CBC           4 :             out_datums[i * 2 + 1] = (Datum) 0;
                                803               4 :             out_nulls[i * 2 + 1] = true;
                                804                 :         }
 4939 tgl                       805 ECB             :         else
                                806                 :         {
 2698 tgl                       807 GIC          12 :             text       *item = cstring_to_text_with_len(HSTORE_VAL(entries, base, i),
 2118                           808              12 :                                                         HSTORE_VALLEN(entries, i));
                                809                 : 
 4790 bruce                     810 CBC          12 :             out_datums[i * 2 + 1] = PointerGetDatum(item);
 4790 bruce                     811 GIC          12 :             out_nulls[i * 2 + 1] = false;
                                812                 :         }
                                813                 :     }
                                814                 : 
 4939 tgl                       815 CBC           4 :     return construct_md_array(out_datums, out_nulls,
                                816                 :                               ndims, out_size, lb,
 1131 tgl                       817 ECB             :                               TEXTOID, -1, false, TYPALIGN_INT);
                                818                 : }
 4939                           819                 : 
 4939 tgl                       820 CBC           8 : PG_FUNCTION_INFO_V1(hstore_to_array);
                                821                 : Datum
                                822               2 : hstore_to_array(PG_FUNCTION_ARGS)
                                823                 : {
 2029 tgl                       824 GIC           2 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 4939 tgl                       825 CBC           2 :     ArrayType  *out = hstore_to_array_internal(hs, 1);
                                826                 : 
                                827               2 :     PG_RETURN_POINTER(out);
                                828                 : }
 4939 tgl                       829 ECB             : 
 4939 tgl                       830 CBC           8 : PG_FUNCTION_INFO_V1(hstore_to_matrix);
                                831                 : Datum
                                832               2 : hstore_to_matrix(PG_FUNCTION_ARGS)
                                833                 : {
 2029 tgl                       834 GIC           2 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 4939                           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
 4939 tgl                       845 ECB             :  * 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
 4790 bruce                     850 GIC        2010 : setup_firstcall(FuncCallContext *funcctx, HStore *hs,
 1534 andres                    851 ECB             :                 FunctionCallInfo fcinfo)
                                852                 : {
 6031 bruce                     853                 :     MemoryContext oldcontext;
 4790                           854                 :     HStore     *st;
                                855                 : 
 6060 teodor                    856 CBC        2010 :     oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
                                857                 : 
 4939 tgl                       858            2010 :     st = (HStore *) palloc(VARSIZE(hs));
 4939 tgl                       859 GIC        2010 :     memcpy(st, hs, VARSIZE(hs));
                                860                 : 
 6031 bruce                     861            2010 :     funcctx->user_fctx = (void *) st;
                                862                 : 
 4939 tgl                       863 CBC        2010 :     if (fcinfo)
 4939 tgl                       864 EUB             :     {
                                865                 :         TupleDesc   tupdesc;
 4939 tgl                       866 ECB             : 
                                867                 :         /* Build a tuple descriptor for our result type */
 4939 tgl                       868 GIC        2003 :         if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
 4939 tgl                       869 LBC           0 :             elog(ERROR, "return type must be a row type");
 4790 bruce                     870 ECB             : 
 4939 tgl                       871 GIC        2003 :         funcctx->tuple_desc = BlessTupleDesc(tupdesc);
                                872                 :     }
 4939 tgl                       873 ECB             : 
 6060 teodor                    874 GIC        2010 :     MemoryContextSwitchTo(oldcontext);
 6060 teodor                    875 CBC        2010 : }
                                876                 : 
                                877                 : 
 4939 tgl                       878 GIC           8 : PG_FUNCTION_INFO_V1(hstore_skeys);
                                879                 : Datum
                                880               8 : hstore_skeys(PG_FUNCTION_ARGS)
 6031 bruce                     881 ECB             : {
                                882                 :     FuncCallContext *funcctx;
 4790                           883                 :     HStore     *hs;
                                884                 :     int         i;
 6031                           885                 : 
 6031 bruce                     886 GIC           8 :     if (SRF_IS_FIRSTCALL())
                                887                 :     {
 2029 tgl                       888 CBC           3 :         hs = PG_GETARG_HSTORE_P(0);
 6060 teodor                    889               3 :         funcctx = SRF_FIRSTCALL_INIT();
 4939 tgl                       890               3 :         setup_firstcall(funcctx, hs, NULL);
                                891                 :     }
 6060 teodor                    892 ECB             : 
 6060 teodor                    893 GIC           8 :     funcctx = SRF_PERCALL_SETUP();
 4939 tgl                       894 CBC           8 :     hs = (HStore *) funcctx->user_fctx;
 4939 tgl                       895 GIC           8 :     i = funcctx->call_cntr;
                                896                 : 
 4939 tgl                       897 CBC           8 :     if (i < HS_COUNT(hs))
 6031 bruce                     898 ECB             :     {
 4790 bruce                     899 GIC           5 :         HEntry     *entries = ARRPTR(hs);
 5493 tgl                       900 ECB             :         text       *item;
                                901                 : 
 2698 tgl                       902 GIC           5 :         item = cstring_to_text_with_len(HSTORE_KEY(entries, STRPTR(hs), i),
 2698 tgl                       903 CBC           5 :                                         HSTORE_KEYLEN(entries, i));
                                904                 : 
 6060 teodor                    905 GIC           5 :         SRF_RETURN_NEXT(funcctx, PointerGetDatum(item));
                                906                 :     }
 6060 teodor                    907 ECB             : 
 6031 bruce                     908 GIC           3 :     SRF_RETURN_DONE(funcctx);
 6060 teodor                    909 ECB             : }
                                910                 : 
                                911                 : 
 4939 tgl                       912 GIC           8 : PG_FUNCTION_INFO_V1(hstore_svals);
                                913                 : Datum
                                914              13 : hstore_svals(PG_FUNCTION_ARGS)
 6031 bruce                     915 ECB             : {
                                916                 :     FuncCallContext *funcctx;
 4790                           917                 :     HStore     *hs;
                                918                 :     int         i;
 6031                           919                 : 
 6031 bruce                     920 GIC          13 :     if (SRF_IS_FIRSTCALL())
                                921                 :     {
 2029 tgl                       922 CBC           4 :         hs = PG_GETARG_HSTORE_P(0);
 6060 teodor                    923               4 :         funcctx = SRF_FIRSTCALL_INIT();
 4939 tgl                       924               4 :         setup_firstcall(funcctx, hs, NULL);
                                925                 :     }
 6060 teodor                    926 ECB             : 
 6060 teodor                    927 GIC          13 :     funcctx = SRF_PERCALL_SETUP();
 4939 tgl                       928 CBC          13 :     hs = (HStore *) funcctx->user_fctx;
 4939 tgl                       929 GIC          13 :     i = funcctx->call_cntr;
 6060 teodor                    930 ECB             : 
 4939 tgl                       931 GIC          13 :     if (i < HS_COUNT(hs))
                                932                 :     {
 4790 bruce                     933               9 :         HEntry     *entries = ARRPTR(hs);
                                934                 : 
 2698 tgl                       935 CBC           9 :         if (HSTORE_VALISNULL(entries, i))
 6031 bruce                     936 ECB             :         {
                                937                 :             ReturnSetInfo *rsi;
 6060 teodor                    938                 : 
                                939                 :             /* ugly ugly ugly. why no macro for this? */
 6060 teodor                    940 GIC           1 :             (funcctx)->call_cntr++;
                                941               1 :             rsi = (ReturnSetInfo *) fcinfo->resultinfo;
                                942               1 :             rsi->isDone = ExprMultipleResult;
                                943               1 :             PG_RETURN_NULL();
 6031 bruce                     944 ECB             :         }
                                945                 :         else
                                946                 :         {
 5493 tgl                       947                 :             text       *item;
                                948                 : 
 2698 tgl                       949 GIC           8 :             item = cstring_to_text_with_len(HSTORE_VAL(entries, STRPTR(hs), i),
                                950               8 :                                             HSTORE_VALLEN(entries, i));
 6060 teodor                    951 ECB             : 
 6060 teodor                    952 GIC           8 :             SRF_RETURN_NEXT(funcctx, PointerGetDatum(item));
                                953                 :         }
                                954                 :     }
 6060 teodor                    955 ECB             : 
 6031 bruce                     956 GIC           4 :     SRF_RETURN_DONE(funcctx);
 6060 teodor                    957 ECB             : }
                                958                 : 
 4939 tgl                       959                 : 
 4939 tgl                       960 CBC           8 : PG_FUNCTION_INFO_V1(hstore_contains);
 6060 teodor                    961 ECB             : Datum
 4939 tgl                       962 CBC        3560 : hstore_contains(PG_FUNCTION_ARGS)
 6031 bruce                     963 ECB             : {
 2029 tgl                       964 CBC        3560 :     HStore     *val = PG_GETARG_HSTORE_P(0);
                                965            3560 :     HStore     *tmpl = PG_GETARG_HSTORE_P(1);
 6031 bruce                     966            3560 :     bool        res = true;
                                967            3560 :     HEntry     *te = ARRPTR(tmpl);
 4939 tgl                       968 GIC        3560 :     char       *tstr = STRPTR(tmpl);
                                969            3560 :     HEntry     *ve = ARRPTR(val);
                                970            3560 :     char       *vstr = STRPTR(val);
 4790 bruce                     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
 4790 bruce                     977 ECB             :      * 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
 4939 tgl                       980                 :      */
                                981                 : 
 4939 tgl                       982 GIC        7148 :     for (i = 0; res && i < tcount; ++i)
 6031 bruce                     983 ECB             :     {
 4790 bruce                     984 GIC        3588 :         int         idx = hstoreFindKey(val, &lastidx,
 2698 tgl                       985 CBC        3588 :                                         HSTORE_KEY(te, tstr, i),
                                986            3588 :                                         HSTORE_KEYLEN(te, i));
                                987                 : 
 4939                           988            3588 :         if (idx >= 0)
 6031 bruce                     989 ECB             :         {
 2698 tgl                       990 CBC        1083 :             bool        nullval = HSTORE_VALISNULL(te, i);
                                991            1083 :             int         vallen = HSTORE_VALLEN(te, i);
                                992                 : 
                                993            1083 :             if (nullval != HSTORE_VALISNULL(ve, idx) ||
 2698 tgl                       994 GIC         513 :                 (!nullval && (vallen != HSTORE_VALLEN(ve, idx) ||
                                995             305 :                               memcmp(HSTORE_VAL(te, tstr, i),
 2698 tgl                       996 CBC         305 :                                      HSTORE_VAL(ve, vstr, idx),
                                997                 :                                      vallen) != 0)))
 5624 bruce                     998 GIC         980 :                 res = false;
 6031 bruce                     999 ECB             :         }
                               1000                 :         else
 6060 teodor                   1001 GIC        2505 :             res = false;
                               1002                 :     }
 6060 teodor                   1003 ECB             : 
 6060 teodor                   1004 GIC        3560 :     PG_RETURN_BOOL(res);
 6060 teodor                   1005 EUB             : }
                               1006                 : 
 4939 tgl                      1007                 : 
 4939 tgl                      1008 GIC           7 : PG_FUNCTION_INFO_V1(hstore_contained);
                               1009                 : Datum
 4939 tgl                      1010 UIC           0 : hstore_contained(PG_FUNCTION_ARGS)
                               1011                 : {
                               1012               0 :     PG_RETURN_DATUM(DirectFunctionCall2(hstore_contains,
                               1013                 :                                         PG_GETARG_DATUM(1),
 6031 bruce                    1014 ECB             :                                         PG_GETARG_DATUM(0)
                               1015                 :                                         ));
 6060 teodor                   1016                 : }
                               1017                 : 
                               1018                 : 
 4939 tgl                      1019 GIC           8 : PG_FUNCTION_INFO_V1(hstore_each);
                               1020                 : Datum
                               1021           11568 : hstore_each(PG_FUNCTION_ARGS)
 6031 bruce                    1022 ECB             : {
                               1023                 :     FuncCallContext *funcctx;
 4790                          1024                 :     HStore     *hs;
                               1025                 :     int         i;
 6060 teodor                   1026                 : 
 6031 bruce                    1027 GIC       11568 :     if (SRF_IS_FIRSTCALL())
                               1028                 :     {
 2029 tgl                      1029 CBC        2003 :         hs = PG_GETARG_HSTORE_P(0);
 6060 teodor                   1030            2003 :         funcctx = SRF_FIRSTCALL_INIT();
 4939 tgl                      1031            2003 :         setup_firstcall(funcctx, hs, fcinfo);
                               1032                 :     }
 6060 teodor                   1033 ECB             : 
 6060 teodor                   1034 GIC       11568 :     funcctx = SRF_PERCALL_SETUP();
 4939 tgl                      1035 CBC       11568 :     hs = (HStore *) funcctx->user_fctx;
                               1036           11568 :     i = funcctx->call_cntr;
                               1037                 : 
 4939 tgl                      1038 GIC       11568 :     if (i < HS_COUNT(hs))
 6031 bruce                    1039 ECB             :     {
 4939 tgl                      1040 GIC        9565 :         HEntry     *entries = ARRPTR(hs);
 4790 bruce                    1041            9565 :         char       *ptr = STRPTR(hs);
                               1042                 :         Datum       res,
 6031 bruce                    1043 ECB             :                     dvalues[2];
 5271 tgl                      1044 CBC        9565 :         bool        nulls[2] = {false, false};
 6031 bruce                    1045 ECB             :         text       *item;
                               1046                 :         HeapTuple   tuple;
                               1047                 : 
 2698 tgl                      1048 GIC        9565 :         item = cstring_to_text_with_len(HSTORE_KEY(entries, ptr, i),
 2698 tgl                      1049 CBC        9565 :                                         HSTORE_KEYLEN(entries, i));
 6060 teodor                   1050            9565 :         dvalues[0] = PointerGetDatum(item);
                               1051                 : 
 2698 tgl                      1052 GIC        9565 :         if (HSTORE_VALISNULL(entries, i))
                               1053                 :         {
 6031 bruce                    1054 CBC           3 :             dvalues[1] = (Datum) 0;
 5271 tgl                      1055               3 :             nulls[1] = true;
 6031 bruce                    1056 ECB             :         }
                               1057                 :         else
                               1058                 :         {
 2698 tgl                      1059 CBC        9562 :             item = cstring_to_text_with_len(HSTORE_VAL(entries, ptr, i),
                               1060            9562 :                                             HSTORE_VALLEN(entries, i));
 6060 teodor                   1061 GIC        9562 :             dvalues[1] = PointerGetDatum(item);
 6060 teodor                   1062 ECB             :         }
                               1063                 : 
 4939 tgl                      1064 GIC        9565 :         tuple = heap_form_tuple(funcctx->tuple_desc, dvalues, nulls);
 5705 tgl                      1065 CBC        9565 :         res = HeapTupleGetDatum(tuple);
                               1066                 : 
  224 peter                    1067 GNC        9565 :         SRF_RETURN_NEXT(funcctx, res);
                               1068                 :     }
                               1069                 : 
 6031 bruce                    1070 GIC        2003 :     SRF_RETURN_DONE(funcctx);
                               1071                 : }
                               1072                 : 
                               1073                 : 
                               1074                 : /*
 4939 tgl                      1075 ECB             :  * 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                 : 
 4939 tgl                      1080 CBC           8 : PG_FUNCTION_INFO_V1(hstore_cmp);
 4939 tgl                      1081 ECB             : Datum
 4939 tgl                      1082 CBC       43261 : hstore_cmp(PG_FUNCTION_ARGS)
 4939 tgl                      1083 ECB             : {
 2029 tgl                      1084 GIC       43261 :     HStore     *hs1 = PG_GETARG_HSTORE_P(0);
 2029 tgl                      1085 CBC       43261 :     HStore     *hs2 = PG_GETARG_HSTORE_P(1);
 4790 bruce                    1086 GIC       43261 :     int         hcount1 = HS_COUNT(hs1);
                               1087           43261 :     int         hcount2 = HS_COUNT(hs2);
                               1088           43261 :     int         res = 0;
                               1089                 : 
 4939 tgl                      1090           43261 :     if (hcount1 == 0 || hcount2 == 0)
 4939 tgl                      1091 ECB             :     {
                               1092                 :         /*
 4790 bruce                    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                 :          */
 4939 tgl                      1096 GIC        3676 :         if (hcount1 > 0)
                               1097             253 :             res = 1;
                               1098            3423 :         else if (hcount2 > 0)
 4939 tgl                      1099 CBC        1635 :             res = -1;
 4939 tgl                      1100 ECB             :     }
                               1101                 :     else
                               1102                 :     {
                               1103                 :         /* here we know both operands are nonempty */
 4790 bruce                    1104 CBC       39585 :         char       *str1 = STRPTR(hs1);
 4790 bruce                    1105 GIC       39585 :         char       *str2 = STRPTR(hs2);
 4790 bruce                    1106 CBC       39585 :         HEntry     *ent1 = ARRPTR(hs1);
 4790 bruce                    1107 GIC       39585 :         HEntry     *ent2 = ARRPTR(hs2);
 4790 bruce                    1108 CBC       39585 :         size_t      len1 = HSE_ENDPOS(ent1[2 * hcount1 - 1]);
 4790 bruce                    1109 GIC       39585 :         size_t      len2 = HSE_ENDPOS(ent2[2 * hcount2 - 1]);
 4939 tgl                      1110 ECB             : 
 4790 bruce                    1111 GBC       39585 :         res = memcmp(str1, str2, Min(len1, len2));
 4939 tgl                      1112 ECB             : 
 4939 tgl                      1113 GBC       39585 :         if (res == 0)
 4939 tgl                      1114 ECB             :         {
 4939 tgl                      1115 GBC        2770 :             if (len1 > len2)
 4939 tgl                      1116 LBC           0 :                 res = 1;
 4939 tgl                      1117 GBC        2770 :             else if (len1 < len2)
 4939 tgl                      1118 UIC           0 :                 res = -1;
 4939 tgl                      1119 GIC        2770 :             else if (hcount1 > hcount2)
 4939 tgl                      1120 LBC           0 :                 res = 1;
 4939 tgl                      1121 GIC        2770 :             else if (hcount2 > hcount1)
 4939 tgl                      1122 UIC           0 :                 res = -1;
 4939 tgl                      1123 ECB             :             else
                               1124                 :             {
 4790 bruce                    1125 CBC        2770 :                 int         count = hcount1 * 2;
                               1126                 :                 int         i;
 4939 tgl                      1127 ECB             : 
 4939 tgl                      1128 GIC       32770 :                 for (i = 0; i < count; ++i)
 4939 tgl                      1129 GBC       30000 :                     if (HSE_ENDPOS(ent1[i]) != HSE_ENDPOS(ent2[i]) ||
                               1130           30000 :                         HSE_ISNULL(ent1[i]) != HSE_ISNULL(ent2[i]))
 4939 tgl                      1131 EUB             :                         break;
 4939 tgl                      1132 GBC        2770 :                 if (i < count)
 4939 tgl                      1133 EUB             :                 {
 4939 tgl                      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]))
 4939 tgl                      1137 UIC           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;
 4939 tgl                      1142 ECB             :                 }
                               1143                 :             }
                               1144                 :         }
                               1145                 :         else
                               1146                 :         {
 4939 tgl                      1147 GIC       36815 :             res = (res > 0) ? 1 : -1;
                               1148                 :         }
                               1149                 :     }
 4939 tgl                      1150 ECB             : 
                               1151                 :     /*
 4790 bruce                    1152                 :      * this is a btree support function; this is one of the few places where
                               1153                 :      * memory needs to be explicitly freed.
                               1154                 :      */
 4790 bruce                    1155 GIC       43261 :     PG_FREE_IF_COPY(hs1, 0);
 4790 bruce                    1156 CBC       43261 :     PG_FREE_IF_COPY(hs2, 1);
 4939 tgl                      1157 GIC       43261 :     PG_RETURN_INT32(res);
 4939 tgl                      1158 ECB             : }
                               1159                 : 
                               1160                 : 
 4939 tgl                      1161 GIC           8 : PG_FUNCTION_INFO_V1(hstore_eq);
                               1162                 : Datum
                               1163            4121 : hstore_eq(PG_FUNCTION_ARGS)
 4939 tgl                      1164 ECB             : {
 4790 bruce                    1165 GIC        4121 :     int         res = DatumGetInt32(DirectFunctionCall2(hstore_cmp,
                               1166                 :                                                         PG_GETARG_DATUM(0),
 4790 bruce                    1167 ECB             :                                                         PG_GETARG_DATUM(1)));
                               1168                 : 
 4939 tgl                      1169 GBC        4121 :     PG_RETURN_BOOL(res == 0);
                               1170                 : }
 4939 tgl                      1171 EUB             : 
 4939 tgl                      1172 GIC           7 : PG_FUNCTION_INFO_V1(hstore_ne);
                               1173                 : Datum
 4939 tgl                      1174 UIC           0 : hstore_ne(PG_FUNCTION_ARGS)
 4939 tgl                      1175 EUB             : {
 4790 bruce                    1176 UIC           0 :     int         res = DatumGetInt32(DirectFunctionCall2(hstore_cmp,
                               1177                 :                                                         PG_GETARG_DATUM(0),
 4790 bruce                    1178 ECB             :                                                         PG_GETARG_DATUM(1)));
                               1179                 : 
 4939 tgl                      1180 LBC           0 :     PG_RETURN_BOOL(res != 0);
                               1181                 : }
 4939 tgl                      1182 ECB             : 
 4939 tgl                      1183 GIC           8 : PG_FUNCTION_INFO_V1(hstore_gt);
                               1184                 : Datum
                               1185             127 : hstore_gt(PG_FUNCTION_ARGS)
 4939 tgl                      1186 ECB             : {
 4790 bruce                    1187 GIC         127 :     int         res = DatumGetInt32(DirectFunctionCall2(hstore_cmp,
                               1188                 :                                                         PG_GETARG_DATUM(0),
 4790 bruce                    1189 ECB             :                                                         PG_GETARG_DATUM(1)));
                               1190                 : 
 4939 tgl                      1191 GBC         127 :     PG_RETURN_BOOL(res > 0);
                               1192                 : }
 4939 tgl                      1193 EUB             : 
 4939 tgl                      1194 GIC           7 : PG_FUNCTION_INFO_V1(hstore_ge);
                               1195                 : Datum
 4939 tgl                      1196 UIC           0 : hstore_ge(PG_FUNCTION_ARGS)
 4939 tgl                      1197 EUB             : {
 4790 bruce                    1198 UIC           0 :     int         res = DatumGetInt32(DirectFunctionCall2(hstore_cmp,
                               1199                 :                                                         PG_GETARG_DATUM(0),
 4790 bruce                    1200 ECB             :                                                         PG_GETARG_DATUM(1)));
                               1201                 : 
 4939 tgl                      1202 UBC           0 :     PG_RETURN_BOOL(res >= 0);
                               1203                 : }
 4939 tgl                      1204 EUB             : 
 4939 tgl                      1205 GIC           7 : PG_FUNCTION_INFO_V1(hstore_lt);
                               1206                 : Datum
 4939 tgl                      1207 UIC           0 : hstore_lt(PG_FUNCTION_ARGS)
 4939 tgl                      1208 EUB             : {
 4790 bruce                    1209 UIC           0 :     int         res = DatumGetInt32(DirectFunctionCall2(hstore_cmp,
                               1210                 :                                                         PG_GETARG_DATUM(0),
 4790 bruce                    1211 ECB             :                                                         PG_GETARG_DATUM(1)));
                               1212                 : 
 4939 tgl                      1213 UBC           0 :     PG_RETURN_BOOL(res < 0);
                               1214                 : }
 4939 tgl                      1215 EUB             : 
 4939 tgl                      1216 GIC           7 : PG_FUNCTION_INFO_V1(hstore_le);
                               1217                 : Datum
 4939 tgl                      1218 UIC           0 : hstore_le(PG_FUNCTION_ARGS)
 4939 tgl                      1219 EUB             : {
 4790 bruce                    1220 UIC           0 :     int         res = DatumGetInt32(DirectFunctionCall2(hstore_cmp,
                               1221                 :                                                         PG_GETARG_DATUM(0),
                               1222                 :                                                         PG_GETARG_DATUM(1)));
 4790 bruce                    1223 ECB             : 
 4939 tgl                      1224 UIC           0 :     PG_RETURN_BOOL(res <= 0);
 4939 tgl                      1225 ECB             : }
                               1226                 : 
                               1227                 : 
 4939 tgl                      1228 CBC           8 : PG_FUNCTION_INFO_V1(hstore_hash);
 4939 tgl                      1229 ECB             : Datum
 4939 tgl                      1230 GIC        2014 : hstore_hash(PG_FUNCTION_ARGS)
                               1231                 : {
 2029                          1232            2014 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 4790 bruce                    1233            2014 :     Datum       hval = hash_any((unsigned char *) VARDATA(hs),
 4939 tgl                      1234            2014 :                                 VARSIZE(hs) - VARHDRSZ);
                               1235                 : 
                               1236                 :     /*
 1598 tgl                      1237 ECB             :      * 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                 :      */
 4939 tgl                      1242 GIC        2014 :     Assert(VARSIZE(hs) ==
 4939 tgl                      1243 ECB             :            (HS_COUNT(hs) != 0 ?
                               1244                 :             CALCDATASIZE(HS_COUNT(hs),
                               1245                 :                          HSE_ENDPOS(ARRPTR(hs)[2 * HS_COUNT(hs) - 1])) :
                               1246                 :             HSHRDSIZE));
                               1247                 : 
 4790 bruce                    1248 GIC        2014 :     PG_FREE_IF_COPY(hs, 0);
 4939 tgl                      1249 CBC        2014 :     PG_RETURN_DATUM(hval);
                               1250                 : }
 1598 tgl                      1251 ECB             : 
 1598 tgl                      1252 CBC           8 : PG_FUNCTION_INFO_V1(hstore_hash_extended);
                               1253                 : Datum
 1598 tgl                      1254 GIC          10 : hstore_hash_extended(PG_FUNCTION_ARGS)
 1598 tgl                      1255 ECB             : {
 1598 tgl                      1256 CBC          10 :     HStore     *hs = PG_GETARG_HSTORE_P(0);
 1598 tgl                      1257 GIC          10 :     uint64      seed = PG_GETARG_INT64(1);
                               1258                 :     Datum       hval;
                               1259                 : 
 1598 tgl                      1260 CBC          10 :     hval = hash_any_extended((unsigned char *) VARDATA(hs),
 1598 tgl                      1261 GIC          10 :                              VARSIZE(hs) - VARHDRSZ,
                               1262                 :                              seed);
                               1263                 : 
                               1264                 :     /* See comment in hstore_hash */
                               1265              10 :     Assert(VARSIZE(hs) ==
 1598 tgl                      1266 ECB             :            (HS_COUNT(hs) != 0 ?
                               1267                 :             CALCDATASIZE(HS_COUNT(hs),
                               1268                 :                          HSE_ENDPOS(ARRPTR(hs)[2 * HS_COUNT(hs) - 1])) :
                               1269                 :             HSHRDSIZE));
                               1270                 : 
 1598 tgl                      1271 GIC          10 :     PG_FREE_IF_COPY(hs, 0);
                               1272              10 :     PG_RETURN_DATUM(hval);
                               1273                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a