LCOV - differential code coverage report
Current view: top level - contrib/hstore - hstore_gist.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 87.1 % 263 229 4 13 14 3 15 110 3 101 14 113 2 2
Current Date: 2023-04-08 15:15:32 Functions: 88.9 % 27 24 1 2 21 3 1 21 1
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*
       2                 :  * contrib/hstore/hstore_gist.c
       3                 :  */
       4                 : #include "postgres.h"
       5                 : 
       6                 : #include "access/gist.h"
       7                 : #include "access/reloptions.h"
       8                 : #include "access/stratnum.h"
       9                 : #include "catalog/pg_type.h"
      10                 : #include "hstore.h"
      11                 : #include "utils/pg_crc.h"
      12                 : 
      13                 : /* gist_hstore_ops opclass options */
      14                 : typedef struct
      15                 : {
      16                 :     int32       vl_len_;        /* varlena header (do not touch directly!) */
      17                 :     int         siglen;         /* signature length in bytes */
      18                 : } GistHstoreOptions;
      19                 : 
      20                 : /* bigint defines */
      21                 : #define BITBYTE 8
      22                 : #define SIGLEN_DEFAULT  (sizeof(int32) * 4)
      23                 : #define SIGLEN_MAX      GISTMaxIndexKeySize
      24                 : #define SIGLENBIT(siglen) ((siglen) * BITBYTE)
      25                 : #define GET_SIGLEN()    (PG_HAS_OPCLASS_OPTIONS() ? \
      26                 :                          ((GistHstoreOptions *) PG_GET_OPCLASS_OPTIONS())->siglen : \
      27                 :                          SIGLEN_DEFAULT)
      28                 : 
      29                 : 
      30                 : typedef char *BITVECP;
      31                 : 
      32                 : #define LOOPBYTE(siglen) \
      33                 :             for (i = 0; i < (siglen); i++)
      34                 : 
      35                 : #define LOOPBIT(siglen) \
      36                 :             for (i = 0; i < SIGLENBIT(siglen); i++)
      37                 : 
      38                 : /* beware of multiple evaluation of arguments to these macros! */
      39                 : #define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITBYTE ) ) )
      40                 : #define GETBITBYTE(x,i) ( (*((char*)(x)) >> (i)) & 0x01 )
      41                 : #define CLRBIT(x,i)   GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITBYTE ) )
      42                 : #define SETBIT(x,i)   GETBYTE(x,i) |=  ( 0x01 << ( (i) % BITBYTE ) )
      43                 : #define GETBIT(x,i) ( (GETBYTE(x,i) >> ( (i) % BITBYTE )) & 0x01 )
      44                 : #define HASHVAL(val, siglen) (((unsigned int)(val)) % SIGLENBIT(siglen))
      45                 : #define HASH(sign, val, siglen) SETBIT((sign), HASHVAL(val, siglen))
      46                 : 
      47                 : typedef struct
      48                 : {
      49                 :     int32       vl_len_;        /* varlena header (do not touch directly!) */
      50                 :     int32       flag;
      51                 :     char        data[FLEXIBLE_ARRAY_MEMBER];
      52                 : } GISTTYPE;
      53                 : 
      54                 : #define ALLISTRUE       0x04
      55                 : 
      56                 : #define ISALLTRUE(x)    ( ((GISTTYPE*)x)->flag & ALLISTRUE )
      57                 : 
      58                 : #define GTHDRSIZE       (VARHDRSZ + sizeof(int32))
      59                 : #define CALCGTSIZE(flag, siglen) ( GTHDRSIZE+(((flag) & ALLISTRUE) ? 0 : (siglen)) )
      60                 : 
      61                 : #define GETSIGN(x)      ( (BITVECP)( (char*)x+GTHDRSIZE ) )
      62                 : 
      63                 : #define SUMBIT(val) (       \
      64                 :     GETBITBYTE((val),0) + \
      65                 :     GETBITBYTE((val),1) + \
      66                 :     GETBITBYTE((val),2) + \
      67                 :     GETBITBYTE((val),3) + \
      68                 :     GETBITBYTE((val),4) + \
      69                 :     GETBITBYTE((val),5) + \
      70                 :     GETBITBYTE((val),6) + \
      71                 :     GETBITBYTE((val),7)   \
      72                 : )
      73                 : 
      74                 : #define GETENTRY(vec,pos) ((GISTTYPE *) DatumGetPointer((vec)->vector[(pos)].key))
      75                 : 
      76                 : #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
      77                 : 
      78                 : /* shorthand for calculating CRC-32 of a single chunk of data. */
      79                 : static pg_crc32
      80 CBC       33062 : crc32_sz(char *buf, int size)
      81                 : {
      82                 :     pg_crc32    crc;
      83                 : 
      84           33062 :     INIT_TRADITIONAL_CRC32(crc);
      85          176322 :     COMP_TRADITIONAL_CRC32(crc, buf, size);
      86           33062 :     FIN_TRADITIONAL_CRC32(crc);
      87                 : 
      88           33062 :     return crc;
      89                 : }
      90                 : 
      91                 : 
      92               7 : PG_FUNCTION_INFO_V1(ghstore_in);
      93               7 : PG_FUNCTION_INFO_V1(ghstore_out);
      94                 : 
      95                 : 
      96                 : Datum
      97 UBC           0 : ghstore_in(PG_FUNCTION_ARGS)
      98                 : {
      99 UNC           0 :     ereport(ERROR,
     100                 :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     101                 :              errmsg("cannot accept a value of type %s", "ghstore")));
     102                 : 
     103                 :     PG_RETURN_VOID();           /* keep compiler quiet */
     104                 : }
     105                 : 
     106                 : Datum
     107 UIC           0 : ghstore_out(PG_FUNCTION_ARGS)
     108                 : {
     109 UNC           0 :     ereport(ERROR,
     110                 :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     111                 :              errmsg("cannot display a value of type %s", "ghstore")));
     112                 : 
     113                 :     PG_RETURN_VOID();           /* keep compiler quiet */
     114                 : }
     115 EUB             : 
     116                 : static GISTTYPE *
     117 GIC        9475 : ghstore_alloc(bool allistrue, int siglen, BITVECP sign)
     118                 : {
     119            9475 :     int         flag = allistrue ? ALLISTRUE : 0;
     120            9475 :     int         size = CALCGTSIZE(flag, siglen);
     121            9475 :     GISTTYPE   *res = palloc(size);
     122                 : 
     123 CBC        9475 :     SET_VARSIZE(res, size);
     124 GIC        9475 :     res->flag = flag;
     125 ECB             : 
     126 CBC        9475 :     if (!allistrue)
     127 ECB             :     {
     128 GIC        9475 :         if (sign)
     129 CBC        1314 :             memcpy(GETSIGN(res), sign, siglen);
     130 ECB             :         else
     131 GIC        8161 :             memset(GETSIGN(res), 0, siglen);
     132 ECB             :     }
     133                 : 
     134 CBC        9475 :     return res;
     135 ECB             : }
     136                 : 
     137 CBC           8 : PG_FUNCTION_INFO_V1(ghstore_consistent);
     138 GIC           8 : PG_FUNCTION_INFO_V1(ghstore_compress);
     139               8 : PG_FUNCTION_INFO_V1(ghstore_decompress);
     140 CBC           8 : PG_FUNCTION_INFO_V1(ghstore_penalty);
     141 GIC           8 : PG_FUNCTION_INFO_V1(ghstore_picksplit);
     142               8 : PG_FUNCTION_INFO_V1(ghstore_union);
     143 CBC           8 : PG_FUNCTION_INFO_V1(ghstore_same);
     144               8 : PG_FUNCTION_INFO_V1(ghstore_options);
     145 ECB             : 
     146                 : Datum
     147 CBC        8142 : ghstore_compress(PG_FUNCTION_ARGS)
     148 ECB             : {
     149 CBC        8142 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     150            8142 :     int         siglen = GET_SIGLEN();
     151 GIC        8142 :     GISTENTRY  *retval = entry;
     152                 : 
     153 CBC        8142 :     if (entry->leafkey)
     154                 :     {
     155            2002 :         GISTTYPE   *res = ghstore_alloc(false, siglen, NULL);
     156            2002 :         HStore     *val = DatumGetHStoreP(entry->key);
     157            2002 :         HEntry     *hsent = ARRPTR(val);
     158 GIC        2002 :         char       *ptr = STRPTR(val);
     159 CBC        2002 :         int         count = HS_COUNT(val);
     160                 :         int         i;
     161 ECB             : 
     162 CBC       11564 :         for (i = 0; i < count; ++i)
     163 ECB             :         {
     164                 :             int         h;
     165                 : 
     166 GIC        9562 :             h = crc32_sz((char *) HSTORE_KEY(hsent, ptr, i),
     167            9562 :                          HSTORE_KEYLEN(hsent, i));
     168 CBC        9562 :             HASH(GETSIGN(res), h, siglen);
     169 GIC        9562 :             if (!HSTORE_VALISNULL(hsent, i))
     170                 :             {
     171            9560 :                 h = crc32_sz((char *) HSTORE_VAL(hsent, ptr, i),
     172 CBC        9560 :                              HSTORE_VALLEN(hsent, i));
     173            9560 :                 HASH(GETSIGN(res), h, siglen);
     174 ECB             :             }
     175                 :         }
     176                 : 
     177 CBC        2002 :         retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
     178            2002 :         gistentryinit(*retval, PointerGetDatum(res),
     179 ECB             :                       entry->rel, entry->page,
     180                 :                       entry->offset,
     181                 :                       false);
     182                 :     }
     183 CBC        6140 :     else if (!ISALLTRUE(DatumGetPointer(entry->key)))
     184 ECB             :     {
     185                 :         int32       i;
     186                 :         GISTTYPE   *res;
     187 GIC        6140 :         BITVECP     sign = GETSIGN(DatumGetPointer(entry->key));
     188                 : 
     189 CBC        6140 :         LOOPBYTE(siglen)
     190                 :         {
     191 GIC        6140 :             if ((sign[i] & 0xff) != 0xff)
     192            6140 :                 PG_RETURN_POINTER(retval);
     193 ECB             :         }
     194                 : 
     195 LBC           0 :         res = ghstore_alloc(true, siglen, NULL);
     196                 : 
     197               0 :         retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
     198               0 :         gistentryinit(*retval, PointerGetDatum(res),
     199                 :                       entry->rel, entry->page,
     200                 :                       entry->offset,
     201 EUB             :                       false);
     202                 :     }
     203                 : 
     204 GBC        2002 :     PG_RETURN_POINTER(retval);
     205                 : }
     206                 : 
     207                 : /*
     208                 :  * Since type ghstore isn't toastable (and doesn't need to be),
     209                 :  * this function can be a no-op.
     210 ECB             :  */
     211                 : Datum
     212 GIC       48666 : ghstore_decompress(PG_FUNCTION_ARGS)
     213                 : {
     214           48666 :     PG_RETURN_POINTER(PG_GETARG_POINTER(0));
     215                 : }
     216                 : 
     217                 : Datum
     218 CBC        6159 : ghstore_same(PG_FUNCTION_ARGS)
     219                 : {
     220            6159 :     GISTTYPE   *a = (GISTTYPE *) PG_GETARG_POINTER(0);
     221 GIC        6159 :     GISTTYPE   *b = (GISTTYPE *) PG_GETARG_POINTER(1);
     222            6159 :     bool       *result = (bool *) PG_GETARG_POINTER(2);
     223            6159 :     int         siglen = GET_SIGLEN();
     224 ECB             : 
     225                 : 
     226 CBC        6159 :     if (ISALLTRUE(a) && ISALLTRUE(b))
     227 LBC           0 :         *result = true;
     228 CBC        6159 :     else if (ISALLTRUE(a))
     229 LBC           0 :         *result = false;
     230 GIC        6159 :     else if (ISALLTRUE(b))
     231 UIC           0 :         *result = false;
     232 ECB             :     else
     233 EUB             :     {
     234 ECB             :         int32       i;
     235 GBC        6159 :         BITVECP     sa = GETSIGN(a),
     236 CBC        6159 :                     sb = GETSIGN(b);
     237 EUB             : 
     238 GIC        6159 :         *result = true;
     239         4565619 :         LOOPBYTE(siglen)
     240                 :         {
     241 CBC     4564286 :             if (sa[i] != sb[i])
     242 ECB             :             {
     243 GIC        4826 :                 *result = false;
     244 CBC        4826 :                 break;
     245 ECB             :             }
     246                 :         }
     247                 :     }
     248 GIC        6159 :     PG_RETURN_POINTER(result);
     249 ECB             : }
     250                 : 
     251                 : static int32
     252 UIC           0 : sizebitvec(BITVECP sign, int siglen)
     253                 : {
     254 LBC           0 :     int32       size = 0,
     255                 :                 i;
     256                 : 
     257 UIC           0 :     LOOPBYTE(siglen)
     258 EUB             :     {
     259 UIC           0 :         size += SUMBIT(sign);
     260 UBC           0 :         sign = (BITVECP) (((char *) sign) + 1);
     261                 :     }
     262 UIC           0 :     return size;
     263 EUB             : }
     264                 : 
     265                 : static int
     266 GBC      132428 : hemdistsign(BITVECP a, BITVECP b, int siglen)
     267                 : {
     268 EUB             :     int         i,
     269 GIC      132428 :                 dist = 0;
     270                 : 
     271       383229964 :     LOOPBIT(siglen)
     272 ECB             :     {
     273 GIC   383097536 :         if (GETBIT(a, i) != GETBIT(b, i))
     274         3347577 :             dist++;
     275 ECB             :     }
     276 GIC      132428 :     return dist;
     277 ECB             : }
     278                 : 
     279                 : static int
     280 CBC      132428 : hemdist(GISTTYPE *a, GISTTYPE *b, int siglen)
     281                 : {
     282          132428 :     if (ISALLTRUE(a))
     283                 :     {
     284 UIC           0 :         if (ISALLTRUE(b))
     285               0 :             return 0;
     286 ECB             :         else
     287 UIC           0 :             return SIGLENBIT(siglen) - sizebitvec(GETSIGN(b), siglen);
     288 ECB             :     }
     289 GIC      132428 :     else if (ISALLTRUE(b))
     290 UBC           0 :         return SIGLENBIT(siglen) - sizebitvec(GETSIGN(a), siglen);
     291 EUB             : 
     292 GIC      132428 :     return hemdistsign(GETSIGN(a), GETSIGN(b), siglen);
     293 EUB             : }
     294                 : 
     295 ECB             : static int32
     296 GBC       12318 : unionkey(BITVECP sbase, GISTTYPE *add, int siglen)
     297                 : {
     298 ECB             :     int32       i;
     299 GIC       12318 :     BITVECP     sadd = GETSIGN(add);
     300                 : 
     301           12318 :     if (ISALLTRUE(add))
     302 LBC           0 :         return 1;
     303 GIC    21743198 :     LOOPBYTE(siglen)
     304        21730880 :         sbase[i] |= sadd[i];
     305 CBC       12318 :     return 0;
     306                 : }
     307 ECB             : 
     308 EUB             : Datum
     309 CBC        6159 : ghstore_union(PG_FUNCTION_ARGS)
     310 ECB             : {
     311 CBC        6159 :     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
     312 GIC        6159 :     int32       len = entryvec->n;
     313                 : 
     314            6159 :     int        *size = (int *) PG_GETARG_POINTER(1);
     315 CBC        6159 :     int         siglen = GET_SIGLEN();
     316                 :     int32       i;
     317            6159 :     GISTTYPE   *result = ghstore_alloc(false, siglen, NULL);
     318            6159 :     BITVECP     base = GETSIGN(result);
     319                 : 
     320           18477 :     for (i = 0; i < len; i++)
     321 ECB             :     {
     322 GIC       12318 :         if (unionkey(base, GETENTRY(entryvec, i), siglen))
     323 ECB             :         {
     324 LBC           0 :             result->flag |= ALLISTRUE;
     325 UIC           0 :             SET_VARSIZE(result, CALCGTSIZE(ALLISTRUE, siglen));
     326 LBC           0 :             break;
     327                 :         }
     328 ECB             :     }
     329                 : 
     330 GBC        6159 :     *size = VARSIZE(result);
     331 EUB             : 
     332 GBC        6159 :     PG_RETURN_POINTER(result);
     333                 : }
     334                 : 
     335                 : Datum
     336 CBC       16073 : ghstore_penalty(PG_FUNCTION_ARGS)
     337                 : {
     338           16073 :     GISTENTRY  *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */
     339 GIC       16073 :     GISTENTRY  *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
     340           16073 :     float      *penalty = (float *) PG_GETARG_POINTER(2);
     341           16073 :     int         siglen = GET_SIGLEN();
     342 CBC       16073 :     GISTTYPE   *origval = (GISTTYPE *) DatumGetPointer(origentry->key);
     343 GIC       16073 :     GISTTYPE   *newval = (GISTTYPE *) DatumGetPointer(newentry->key);
     344 ECB             : 
     345 CBC       16073 :     *penalty = hemdist(origval, newval, siglen);
     346           16073 :     PG_RETURN_POINTER(penalty);
     347 ECB             : }
     348                 : 
     349                 : 
     350                 : typedef struct
     351                 : {
     352                 :     OffsetNumber pos;
     353                 :     int32       cost;
     354                 : } SPLITCOST;
     355                 : 
     356                 : static int
     357 GIC        5946 : comparecost(const void *a, const void *b)
     358                 : {
     359            5946 :     return ((const SPLITCOST *) a)->cost - ((const SPLITCOST *) b)->cost;
     360                 : }
     361                 : 
     362                 : 
     363 ECB             : Datum
     364 GIC         657 : ghstore_picksplit(PG_FUNCTION_ARGS)
     365 ECB             : {
     366 GIC         657 :     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
     367             657 :     OffsetNumber maxoff = entryvec->n - 2;
     368                 : 
     369             657 :     GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
     370 CBC         657 :     int         siglen = GET_SIGLEN();
     371                 :     OffsetNumber k,
     372 ECB             :                 j;
     373                 :     GISTTYPE   *datum_l,
     374                 :                *datum_r;
     375                 :     BITVECP     union_l,
     376                 :                 union_r;
     377                 :     int32       size_alpha,
     378                 :                 size_beta;
     379                 :     int32       size_waste,
     380 GIC         657 :                 waste = -1;
     381                 :     int32       nbytes;
     382             657 :     OffsetNumber seed_1 = 0,
     383             657 :                 seed_2 = 0;
     384                 :     OffsetNumber *left,
     385                 :                *right;
     386 ECB             :     BITVECP     ptr;
     387                 :     int         i;
     388                 :     SPLITCOST  *costvector;
     389                 :     GISTTYPE   *_k,
     390                 :                *_j;
     391                 : 
     392 GIC         657 :     nbytes = (maxoff + 2) * sizeof(OffsetNumber);
     393             657 :     v->spl_left = (OffsetNumber *) palloc(nbytes);
     394             657 :     v->spl_right = (OffsetNumber *) palloc(nbytes);
     395                 : 
     396            2971 :     for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
     397                 :     {
     398 CBC        2314 :         _k = GETENTRY(entryvec, k);
     399          106785 :         for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
     400 ECB             :         {
     401 GIC      104471 :             size_waste = hemdist(_k, GETENTRY(entryvec, j), siglen);
     402 CBC      104471 :             if (size_waste > waste)
     403                 :             {
     404            1089 :                 waste = size_waste;
     405            1089 :                 seed_1 = k;
     406 GIC        1089 :                 seed_2 = j;
     407 ECB             :             }
     408                 :         }
     409                 :     }
     410                 : 
     411 CBC         657 :     left = v->spl_left;
     412             657 :     v->spl_nleft = 0;
     413 GIC         657 :     right = v->spl_right;
     414             657 :     v->spl_nright = 0;
     415                 : 
     416             657 :     if (seed_1 == 0 || seed_2 == 0)
     417 ECB             :     {
     418 LBC           0 :         seed_1 = 1;
     419               0 :         seed_2 = 2;
     420 ECB             :     }
     421                 : 
     422                 :     /* form initial .. */
     423 GIC         657 :     datum_l = ghstore_alloc(ISALLTRUE(GETENTRY(entryvec, seed_1)), siglen,
     424 GBC         657 :                             GETSIGN(GETENTRY(entryvec, seed_1)));
     425             657 :     datum_r = ghstore_alloc(ISALLTRUE(GETENTRY(entryvec, seed_2)), siglen,
     426 GIC         657 :                             GETSIGN(GETENTRY(entryvec, seed_2)));
     427                 : 
     428             657 :     maxoff = OffsetNumberNext(maxoff);
     429 ECB             :     /* sort before ... */
     430 CBC         657 :     costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
     431            4285 :     for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
     432 ECB             :     {
     433 GIC        3628 :         costvector[j - 1].pos = j;
     434 CBC        3628 :         _j = GETENTRY(entryvec, j);
     435 GIC        3628 :         size_alpha = hemdist(datum_l, _j, siglen);
     436 CBC        3628 :         size_beta = hemdist(datum_r, _j, siglen);
     437            3628 :         costvector[j - 1].cost = abs(size_alpha - size_beta);
     438                 :     }
     439 GNC         657 :     qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
     440 ECB             : 
     441 CBC         657 :     union_l = GETSIGN(datum_l);
     442             657 :     union_r = GETSIGN(datum_r);
     443 ECB             : 
     444 GIC        4285 :     for (k = 0; k < maxoff; k++)
     445 ECB             :     {
     446 GIC        3628 :         j = costvector[k].pos;
     447 CBC        3628 :         if (j == seed_1)
     448 ECB             :         {
     449 GIC         657 :             *left++ = j;
     450 CBC         657 :             v->spl_nleft++;
     451 GIC         657 :             continue;
     452 ECB             :         }
     453 CBC        2971 :         else if (j == seed_2)
     454                 :         {
     455             657 :             *right++ = j;
     456             657 :             v->spl_nright++;
     457             657 :             continue;
     458                 :         }
     459            2314 :         _j = GETENTRY(entryvec, j);
     460 GIC        2314 :         size_alpha = hemdist(datum_l, _j, siglen);
     461 CBC        2314 :         size_beta = hemdist(datum_r, _j, siglen);
     462 ECB             : 
     463 CBC        2314 :         if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.0001))
     464                 :         {
     465            1126 :             if (ISALLTRUE(datum_l) || ISALLTRUE(_j))
     466 ECB             :             {
     467 LBC           0 :                 if (!ISALLTRUE(datum_l))
     468 UNC           0 :                     memset(union_l, 0xff, siglen);
     469 ECB             :             }
     470                 :             else
     471                 :             {
     472 GIC        1126 :                 ptr = GETSIGN(_j);
     473 GBC     1278158 :                 LOOPBYTE(siglen)
     474         1277032 :                     union_l[i] |= ptr[i];
     475                 :             }
     476 GIC        1126 :             *left++ = j;
     477            1126 :             v->spl_nleft++;
     478 ECB             :         }
     479                 :         else
     480                 :         {
     481 GIC        1188 :             if (ISALLTRUE(datum_r) || ISALLTRUE(_j))
     482 ECB             :             {
     483 LBC           0 :                 if (!ISALLTRUE(datum_r))
     484 UNC           0 :                     memset(union_r, 0xff, siglen);
     485                 :             }
     486                 :             else
     487 ECB             :             {
     488 GIC        1188 :                 ptr = GETSIGN(_j);
     489 GBC     1379612 :                 LOOPBYTE(siglen)
     490         1378424 :                     union_r[i] |= ptr[i];
     491                 :             }
     492 GIC        1188 :             *right++ = j;
     493            1188 :             v->spl_nright++;
     494 ECB             :         }
     495                 :     }
     496                 : 
     497 GIC         657 :     *right = *left = FirstOffsetNumber;
     498 ECB             : 
     499 CBC         657 :     v->spl_ldatum = PointerGetDatum(datum_l);
     500 GIC         657 :     v->spl_rdatum = PointerGetDatum(datum_r);
     501                 : 
     502             657 :     PG_RETURN_POINTER(v);
     503 ECB             : }
     504                 : 
     505                 : 
     506                 : Datum
     507 GIC       10488 : ghstore_consistent(PG_FUNCTION_ARGS)
     508 ECB             : {
     509 GIC       10488 :     GISTTYPE   *entry = (GISTTYPE *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
     510           10488 :     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
     511                 : 
     512                 :     /* Oid      subtype = PG_GETARG_OID(3); */
     513 CBC       10488 :     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
     514 GIC       10488 :     int         siglen = GET_SIGLEN();
     515 CBC       10488 :     bool        res = true;
     516 ECB             :     BITVECP     sign;
     517                 : 
     518                 :     /* All cases served by this function are inexact */
     519 CBC       10488 :     *recheck = true;
     520 ECB             : 
     521 CBC       10488 :     if (ISALLTRUE(entry))
     522 UIC           0 :         PG_RETURN_BOOL(true);
     523                 : 
     524 GIC       10488 :     sign = GETSIGN(entry);
     525 ECB             : 
     526 GIC       10488 :     if (strategy == HStoreContainsStrategyNumber ||
     527 ECB             :         strategy == HStoreOldContainsStrategyNumber)
     528 GBC        4691 :     {
     529 GIC        4691 :         HStore     *query = PG_GETARG_HSTORE_P(1);
     530 CBC        4691 :         HEntry     *qe = ARRPTR(query);
     531 GIC        4691 :         char       *qv = STRPTR(query);
     532 CBC        4691 :         int         count = HS_COUNT(query);
     533                 :         int         i;
     534 ECB             : 
     535 CBC        9589 :         for (i = 0; res && i < count; ++i)
     536 ECB             :         {
     537 CBC        4898 :             int         crc = crc32_sz((char *) HSTORE_KEY(qe, qv, i),
     538            4898 :                                        HSTORE_KEYLEN(qe, i));
     539                 : 
     540 GIC        4898 :             if (GETBIT(sign, HASHVAL(crc, siglen)))
     541 ECB             :             {
     542 GIC        1961 :                 if (!HSTORE_VALISNULL(qe, i))
     543 ECB             :                 {
     544 CBC        1170 :                     crc = crc32_sz((char *) HSTORE_VAL(qe, qv, i),
     545 GIC        1170 :                                    HSTORE_VALLEN(qe, i));
     546 CBC        1170 :                     if (!GETBIT(sign, HASHVAL(crc, siglen)))
     547 GIC         583 :                         res = false;
     548 ECB             :                 }
     549                 :             }
     550                 :             else
     551 CBC        2937 :                 res = false;
     552 ECB             :         }
     553                 :     }
     554 GIC        5797 :     else if (strategy == HStoreExistsStrategyNumber)
     555                 :     {
     556            1939 :         text       *query = PG_GETARG_TEXT_PP(1);
     557 CBC        1939 :         int         crc = crc32_sz(VARDATA_ANY(query), VARSIZE_ANY_EXHDR(query));
     558                 : 
     559 GIC        1939 :         res = (GETBIT(sign, HASHVAL(crc, siglen))) ? true : false;
     560 ECB             :     }
     561 GIC        3858 :     else if (strategy == HStoreExistsAllStrategyNumber)
     562 ECB             :     {
     563 CBC        1622 :         ArrayType  *query = PG_GETARG_ARRAYTYPE_P(1);
     564                 :         Datum      *key_datums;
     565 ECB             :         bool       *key_nulls;
     566                 :         int         key_count;
     567                 :         int         i;
     568                 : 
     569 GNC        1622 :         deconstruct_array_builtin(query, TEXTOID, &key_datums, &key_nulls, &key_count);
     570                 : 
     571 GIC        3875 :         for (i = 0; res && i < key_count; ++i)
     572                 :         {
     573 ECB             :             int         crc;
     574                 : 
     575 CBC        2253 :             if (key_nulls[i])
     576 UIC           0 :                 continue;
     577 GIC        2253 :             crc = crc32_sz(VARDATA(key_datums[i]), VARSIZE(key_datums[i]) - VARHDRSZ);
     578            2253 :             if (!(GETBIT(sign, HASHVAL(crc, siglen))))
     579 CBC        1297 :                 res = false;
     580 EUB             :         }
     581 ECB             :     }
     582 CBC        2236 :     else if (strategy == HStoreExistsAnyStrategyNumber)
     583 ECB             :     {
     584 GIC        2236 :         ArrayType  *query = PG_GETARG_ARRAYTYPE_P(1);
     585                 :         Datum      *key_datums;
     586 ECB             :         bool       *key_nulls;
     587                 :         int         key_count;
     588                 :         int         i;
     589                 : 
     590 GNC        2236 :         deconstruct_array_builtin(query, TEXTOID, &key_datums, &key_nulls, &key_count);
     591                 : 
     592 CBC        2236 :         res = false;
     593                 : 
     594            5916 :         for (i = 0; !res && i < key_count; ++i)
     595                 :         {
     596 ECB             :             int         crc;
     597                 : 
     598 GIC        3680 :             if (key_nulls[i])
     599 UIC           0 :                 continue;
     600 CBC        3680 :             crc = crc32_sz(VARDATA(key_datums[i]), VARSIZE(key_datums[i]) - VARHDRSZ);
     601 GBC        3680 :             if (GETBIT(sign, HASHVAL(crc, siglen)))
     602 CBC        1201 :                 res = true;
     603 ECB             :         }
     604                 :     }
     605                 :     else
     606 UIC           0 :         elog(ERROR, "Unsupported strategy number: %d", strategy);
     607                 : 
     608 GBC       10488 :     PG_RETURN_BOOL(res);
     609                 : }
     610 ECB             : 
     611                 : Datum
     612 GIC           9 : ghstore_options(PG_FUNCTION_ARGS)
     613                 : {
     614 CBC           9 :     local_relopts *relopts = (local_relopts *) PG_GETARG_POINTER(0);
     615                 : 
     616               9 :     init_local_reloptions(relopts, sizeof(GistHstoreOptions));
     617 GIC           9 :     add_local_int_reloption(relopts, "siglen",
     618 ECB             :                             "signature length in bytes",
     619                 :                             SIGLEN_DEFAULT, 1, SIGLEN_MAX,
     620                 :                             offsetof(GistHstoreOptions, siglen));
     621                 : 
     622 GIC           9 :     PG_RETURN_VOID();
     623                 : }
        

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