LCOV - differential code coverage report
Current view: top level - contrib/ltree - _ltree_gist.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 88.6 % 271 240 2 12 15 2 6 126 2 106 23 118 4
Current Date: 2023-04-08 17:13:01 Functions: 96.0 % 25 24 1 24 1 24
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (60,120] days: 33.3 % 3 1 2 1
Legend: Lines: hit not hit (180,240] days: 100.0 % 1 1 1
(240..) days: 89.1 % 267 238 12 15 2 6 126 106 23 117
Function coverage date bins:
(240..) days: 48.0 % 50 24 1 24 1 24

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*
                                  2                 :  * contrib/ltree/_ltree_gist.c
                                  3                 :  *
                                  4                 :  *
                                  5                 :  * GiST support for ltree[]
                                  6                 :  * Teodor Sigaev <teodor@stack.net>
                                  7                 :  */
                                  8                 : #include "postgres.h"
                                  9                 : 
                                 10                 : #include <math.h>
                                 11                 : 
                                 12                 : #include "access/gist.h"
                                 13                 : #include "access/reloptions.h"
                                 14                 : #include "access/stratnum.h"
                                 15                 : #include "crc32.h"
                                 16                 : #include "ltree.h"
                                 17                 : #include "port/pg_bitutils.h"
                                 18                 : #include "utils/array.h"
                                 19                 : 
 7522 bruce                      20 GIC           3 : PG_FUNCTION_INFO_V1(_ltree_compress);
                                 21               3 : PG_FUNCTION_INFO_V1(_ltree_same);
                                 22               3 : PG_FUNCTION_INFO_V1(_ltree_union);
 7522 bruce                      23 CBC           3 : PG_FUNCTION_INFO_V1(_ltree_penalty);
                                 24               3 : PG_FUNCTION_INFO_V1(_ltree_picksplit);
                                 25               3 : PG_FUNCTION_INFO_V1(_ltree_consistent);
 1105 akorotkov                  26               3 : PG_FUNCTION_INFO_V1(_ltree_gist_options);
 7558 bruce                      27 ECB             : 
 6949 teodor                     28                 : #define GETENTRY(vec,pos) ((ltree_gist *) DatumGetPointer((vec)->vector[(pos)].key))
 7558 bruce                      29                 : #define NEXTVAL(x) ( (ltree*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
                                 30                 : 
                                 31                 : #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
                                 32                 : 
                                 33                 : 
                                 34                 : static void
 1105 akorotkov                  35 GIC        7058 : hashing(BITVECP sign, ltree *t, int siglen)
                                 36                 : {
 7522 bruce                      37            7058 :     int         tlen = t->numlevel;
 7558 bruce                      38 CBC        7058 :     ltree_level *cur = LTREE_FIRST(t);
                                 39                 :     int         hash;
 7558 bruce                      40 ECB             : 
 7522 bruce                      41 CBC       53466 :     while (tlen > 0)
                                 42                 :     {
 7522 bruce                      43 GIC       46408 :         hash = ltree_crc32_sz(cur->name, cur->len);
 1105 akorotkov                  44 CBC       46408 :         AHASH(sign, hash, siglen);
 7558 bruce                      45 GIC       46408 :         cur = LEVEL_NEXT(cur);
 7558 bruce                      46 CBC       46408 :         tlen--;
 7558 bruce                      47 ECB             :     }
 7558 bruce                      48 CBC        7058 : }
 7558 bruce                      49 ECB             : 
                                 50                 : Datum
 7522 bruce                      51 CBC        5939 : _ltree_compress(PG_FUNCTION_ARGS)
                                 52                 : {
 7522 bruce                      53 GIC        5939 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 7558 bruce                      54 CBC        5939 :     GISTENTRY  *retval = entry;
 1105 akorotkov                  55 GIC        5939 :     int         siglen = LTREE_GET_ASIGLEN();
 7558 bruce                      56 ECB             : 
 7522 bruce                      57 CBC        5939 :     if (entry->leafkey)
 7522 bruce                      58 ECB             :     {                           /* ltree */
                                 59                 :         ltree_gist *key;
 7522 bruce                      60 CBC        2000 :         ArrayType  *val = DatumGetArrayTypeP(entry->key);
 7522 bruce                      61 GIC        2000 :         int         num = ArrayGetNItems(ARR_NDIM(val), ARR_DIMS(val));
                                 62            2000 :         ltree      *item = (ltree *) ARR_DATA_PTR(val);
 7558 bruce                      63 ECB             : 
 4792 tgl                        64 CBC        2000 :         if (ARR_NDIM(val) > 1)
 7199 tgl                        65 LBC           0 :             ereport(ERROR,
                                 66                 :                     (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
 6797 bruce                      67 ECB             :                      errmsg("array must be one-dimensional")));
 4473 tgl                        68 GBC        2000 :         if (array_contains_nulls(val))
 6350 tgl                        69 UIC           0 :             ereport(ERROR,
                                 70                 :                     (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
 6350 tgl                        71 ECB             :                      errmsg("array must not contain nulls")));
 7558 bruce                      72 EUB             : 
 1105 akorotkov                  73 GIC        2000 :         key = ltree_gist_alloc(false, NULL, siglen, NULL, NULL);
                                 74                 : 
 7522 bruce                      75            9058 :         while (num > 0)
 7522 bruce                      76 ECB             :         {
 1105 akorotkov                  77 GIC        7058 :             hashing(LTG_SIGN(key), item, siglen);
 7558 bruce                      78 CBC        7058 :             num--;
 7558 bruce                      79 GIC        7058 :             item = NEXTVAL(item);
 7558 bruce                      80 ECB             :         }
                                 81                 : 
 7522 bruce                      82 CBC        2000 :         retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
 7558 bruce                      83 GIC        2000 :         gistentryinit(*retval, PointerGetDatum(key),
                                 84                 :                       entry->rel, entry->page,
 2062 peter_e                    85 ECB             :                       entry->offset, false);
 7522 bruce                      86                 :     }
 6797 bruce                      87 GIC        3939 :     else if (!LTG_ISALLTRUE(entry->key))
                                 88                 :     {
                                 89                 :         int32       i;
 7522 bruce                      90 ECB             :         ltree_gist *key;
 7522 bruce                      91 GIC        3939 :         BITVECP     sign = LTG_SIGN(DatumGetPointer(entry->key));
                                 92                 : 
 1105 akorotkov                  93            3939 :         ALOOPBYTE(siglen)
 5623 bruce                      94 ECB             :         {
 5623 bruce                      95 GIC        3939 :             if ((sign[i] & 0xff) != 0xff)
 5623 bruce                      96 CBC        3939 :                 PG_RETURN_POINTER(retval);
                                 97                 :         }
 7558 bruce                      98 ECB             : 
 1105 akorotkov                  99 LBC           0 :         key = ltree_gist_alloc(true, sign, siglen, NULL, NULL);
 7522 bruce                     100 UIC           0 :         retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
 7558                           101               0 :         gistentryinit(*retval, PointerGetDatum(key),
 7522 bruce                     102 EUB             :                       entry->rel, entry->page,
 2062 peter_e                   103                 :                       entry->offset, false);
 7558 bruce                     104                 :     }
 7558 bruce                     105 GIC        2000 :     PG_RETURN_POINTER(retval);
                                106                 : }
                                107                 : 
 7522 bruce                     108 ECB             : Datum
 7522 bruce                     109 GIC        8024 : _ltree_same(PG_FUNCTION_ARGS)
                                110                 : {
                                111            8024 :     ltree_gist *a = (ltree_gist *) PG_GETARG_POINTER(0);
 7522 bruce                     112 CBC        8024 :     ltree_gist *b = (ltree_gist *) PG_GETARG_POINTER(1);
 7522 bruce                     113 GIC        8024 :     bool       *result = (bool *) PG_GETARG_POINTER(2);
 1105 akorotkov                 114 CBC        8024 :     int         siglen = LTREE_GET_ASIGLEN();
 7558 bruce                     115 ECB             : 
 7522 bruce                     116 CBC        8024 :     if (LTG_ISALLTRUE(a) && LTG_ISALLTRUE(b))
 7558 bruce                     117 LBC           0 :         *result = true;
 7522 bruce                     118 GIC        8024 :     else if (LTG_ISALLTRUE(a))
 7558 bruce                     119 LBC           0 :         *result = false;
 7522 bruce                     120 GBC        8024 :     else if (LTG_ISALLTRUE(b))
 7558 bruce                     121 LBC           0 :         *result = false;
 7522 bruce                     122 EUB             :     else
 7522 bruce                     123 ECB             :     {
 3940 peter_e                   124 EUB             :         int32       i;
 7522 bruce                     125 GIC        8024 :         BITVECP     sa = LTG_SIGN(a),
                                126            8024 :                     sb = LTG_SIGN(b);
                                127                 : 
 7558 bruce                     128 CBC        8024 :         *result = true;
 1105 akorotkov                 129        11642858 :         ALOOPBYTE(siglen)
                                130                 :         {
 5623 bruce                     131        11636903 :             if (sa[i] != sb[i])
 5623 bruce                     132 ECB             :             {
 5623 bruce                     133 GIC        2069 :                 *result = false;
 5623 bruce                     134 CBC        2069 :                 break;
                                135                 :             }
 7522 bruce                     136 ECB             :         }
                                137                 :     }
 7522 bruce                     138 GIC        8024 :     PG_RETURN_POINTER(result);
                                139                 : }
                                140                 : 
 3940 peter_e                   141 ECB             : static int32
 1105 akorotkov                 142 GIC       16048 : unionkey(BITVECP sbase, ltree_gist *add, int siglen)
                                143                 : {
                                144                 :     int32       i;
 7522 bruce                     145 CBC       16048 :     BITVECP     sadd = LTG_SIGN(add);
                                146                 : 
 7522 bruce                     147 GIC       16048 :     if (LTG_ISALLTRUE(add))
 7558 bruce                     148 LBC           0 :         return 1;
                                149                 : 
 1105 akorotkov                 150 CBC    29068072 :     ALOOPBYTE(siglen)
 5623 bruce                     151 GBC    29052024 :         sbase[i] |= sadd[i];
 7558 bruce                     152 GIC       16048 :     return 0;
 7558 bruce                     153 ECB             : }
                                154                 : 
 7522                           155                 : Datum
 7522 bruce                     156 GIC        8024 : _ltree_union(PG_FUNCTION_ARGS)
                                157                 : {
 6797                           158            8024 :     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
 7522 bruce                     159 CBC        8024 :     int        *size = (int *) PG_GETARG_POINTER(1);
 1105 akorotkov                 160 GIC        8024 :     int         siglen = LTREE_GET_ASIGLEN();
 1105 akorotkov                 161 ECB             :     int32       i;
 1105 akorotkov                 162 CBC        8024 :     ltree_gist *result = ltree_gist_alloc(false, NULL, siglen, NULL, NULL);
                                163            8024 :     BITVECP     base = LTG_SIGN(result);
                                164                 : 
 6949 teodor                    165           24072 :     for (i = 0; i < entryvec->n; i++)
 7522 bruce                     166 ECB             :     {
 1105 akorotkov                 167 GIC       16048 :         if (unionkey(base, GETENTRY(entryvec, i), siglen))
 7522 bruce                     168 ECB             :         {
 1105 akorotkov                 169 UIC           0 :             result->flag |= LTG_ALLTRUE;
 1105 akorotkov                 170 LBC           0 :             SET_VARSIZE(result, LTG_HDRSIZE);
 7558 bruce                     171 UIC           0 :             break;
 7558 bruce                     172 EUB             :         }
                                173                 :     }
                                174                 : 
 1105 akorotkov                 175 GIC        8024 :     *size = VARSIZE(result);
                                176                 : 
 7522 bruce                     177            8024 :     PG_RETURN_POINTER(result);
 7558 bruce                     178 ECB             : }
                                179                 : 
 3940 peter_e                   180                 : static int32
 1105 akorotkov                 181 UIC           0 : sizebitvec(BITVECP sign, int siglen)
                                182                 : {
                                183               0 :     return pg_popcount((const char *) sign, siglen);
 7558 bruce                     184 EUB             : }
                                185                 : 
 6797                           186                 : static int
 1105 akorotkov                 187 GIC      115743 : hemdistsign(BITVECP a, BITVECP b, int siglen)
                                188                 : {
                                189                 :     int         i,
 6288 tgl                       190 ECB             :                 diff,
 6797 bruce                     191 GIC      115743 :                 dist = 0;
                                192                 : 
 1105 akorotkov                 193        60639751 :     ALOOPBYTE(siglen)
 5623 bruce                     194 ECB             :     {
 5623 bruce                     195 GIC    60524008 :         diff = (unsigned char) (a[i] ^ b[i]);
 1514 tgl                       196 ECB             :         /* Using the popcount functions here isn't likely to win */
 1514 tgl                       197 GIC    60524008 :         dist += pg_number_of_ones[diff];
 5623 bruce                     198 ECB             :     }
 7242 bruce                     199 GIC      115743 :     return dist;
 7242 bruce                     200 ECB             : }
                                201                 : 
                                202                 : static int
 1105 akorotkov                 203 GIC      115743 : hemdist(ltree_gist *a, ltree_gist *b, int siglen)
                                204                 : {
 6797 bruce                     205          115743 :     if (LTG_ISALLTRUE(a))
 6797 bruce                     206 ECB             :     {
 6797 bruce                     207 UIC           0 :         if (LTG_ISALLTRUE(b))
 6797 bruce                     208 LBC           0 :             return 0;
                                209                 :         else
 1105 akorotkov                 210 UBC           0 :             return ASIGLENBIT(siglen) - sizebitvec(LTG_SIGN(b), siglen);
 6797 bruce                     211 EUB             :     }
 6797 bruce                     212 GIC      115743 :     else if (LTG_ISALLTRUE(b))
 1105 akorotkov                 213 UBC           0 :         return ASIGLENBIT(siglen) - sizebitvec(LTG_SIGN(a), siglen);
                                214                 : 
 1105 akorotkov                 215 CBC      115743 :     return hemdistsign(LTG_SIGN(a), LTG_SIGN(b), siglen);
 7242 bruce                     216 EUB             : }
                                217                 : 
 7242 bruce                     218 ECB             : 
                                219                 : Datum
 7522 bruce                     220 GIC       19518 : _ltree_penalty(PG_FUNCTION_ARGS)
                                221                 : {
                                222           19518 :     ltree_gist *origval = (ltree_gist *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
 7522 bruce                     223 CBC       19518 :     ltree_gist *newval = (ltree_gist *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
 7522 bruce                     224 GIC       19518 :     float      *penalty = (float *) PG_GETARG_POINTER(2);
 1105 akorotkov                 225 CBC       19518 :     int         siglen = LTREE_GET_ASIGLEN();
 7558 bruce                     226 ECB             : 
 1105 akorotkov                 227 CBC       19518 :     *penalty = hemdist(origval, newval, siglen);
 7522 bruce                     228           19518 :     PG_RETURN_POINTER(penalty);
                                229                 : }
 7558 bruce                     230 ECB             : 
 7522                           231                 : typedef struct
                                232                 : {
                                233                 :     OffsetNumber pos;
                                234                 :     int32       cost;
                                235                 : } SPLITCOST;
                                236                 : 
                                237                 : static int
 7522 bruce                     238 GIC        7911 : comparecost(const void *a, const void *b)
                                239                 : {
 4228 peter_e                   240            7911 :     return ((const SPLITCOST *) a)->cost - ((const SPLITCOST *) b)->cost;
 7558 bruce                     241 ECB             : }
                                242                 : 
 7522                           243                 : Datum
 7522 bruce                     244 GIC         935 : _ltree_picksplit(PG_FUNCTION_ARGS)
                                245                 : {
 6797                           246             935 :     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
 7522 bruce                     247 CBC         935 :     GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
 1105 akorotkov                 248 GIC         935 :     int         siglen = LTREE_GET_ASIGLEN();
 7522 bruce                     249 ECB             :     OffsetNumber k,
                                250                 :                 j;
                                251                 :     ltree_gist *datum_l,
                                252                 :                *datum_r;
                                253                 :     BITVECP     union_l,
                                254                 :                 union_r;
                                255                 :     int32       size_alpha,
                                256                 :                 size_beta;
                                257                 :     int32       size_waste,
 7242 bruce                     258 GIC         935 :                 waste = -1;
                                259                 :     int32       nbytes;
 7522                           260             935 :     OffsetNumber seed_1 = 0,
 7522 bruce                     261 CBC         935 :                 seed_2 = 0;
                                262                 :     OffsetNumber *left,
 7522 bruce                     263 ECB             :                *right;
 7558                           264                 :     OffsetNumber maxoff;
                                265                 :     BITVECP     ptr;
                                266                 :     int         i;
                                267                 :     SPLITCOST  *costvector;
                                268                 :     ltree_gist *_k,
                                269                 :                *_j;
                                270                 : 
 6949 teodor                    271 GIC         935 :     maxoff = entryvec->n - 2;
 7558 bruce                     272             935 :     nbytes = (maxoff + 2) * sizeof(OffsetNumber);
                                273             935 :     v->spl_left = (OffsetNumber *) palloc(nbytes);
 7558 bruce                     274 CBC         935 :     v->spl_right = (OffsetNumber *) palloc(nbytes);
 7558 bruce                     275 ECB             : 
 6797 bruce                     276 CBC        3901 :     for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
 6797 bruce                     277 ECB             :     {
 7522 bruce                     278 GIC        2966 :         _k = GETENTRY(entryvec, k);
 6797 bruce                     279 CBC       83587 :         for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
                                280                 :         {
 1105 akorotkov                 281           80621 :             size_waste = hemdist(_k, GETENTRY(entryvec, j), siglen);
 6797 bruce                     282           80621 :             if (size_waste > waste)
                                283                 :             {
 7558                           284            1744 :                 waste = size_waste;
                                285            1744 :                 seed_1 = k;
 7558 bruce                     286 GIC        1744 :                 seed_2 = j;
 7558 bruce                     287 ECB             :             }
                                288                 :         }
                                289                 :     }
                                290                 : 
 7558 bruce                     291 GIC         935 :     left = v->spl_left;
                                292             935 :     v->spl_nleft = 0;
                                293             935 :     right = v->spl_right;
 7558 bruce                     294 CBC         935 :     v->spl_nright = 0;
 7558 bruce                     295 ECB             : 
 7522 bruce                     296 CBC         935 :     if (seed_1 == 0 || seed_2 == 0)
 7522 bruce                     297 ECB             :     {
 7558 bruce                     298 UIC           0 :         seed_1 = 1;
 7558 bruce                     299 LBC           0 :         seed_2 = 2;
                                300                 :     }
 7558 bruce                     301 EUB             : 
                                302                 :     /* form initial .. */
 1105 akorotkov                 303 GIC         935 :     datum_l = ltree_gist_alloc(LTG_ISALLTRUE(GETENTRY(entryvec, seed_1)),
                                304             935 :                                LTG_SIGN(GETENTRY(entryvec, seed_1)),
                                305                 :                                siglen, NULL, NULL);
 1105 akorotkov                 306 ECB             : 
 1105 akorotkov                 307 CBC         935 :     datum_r = ltree_gist_alloc(LTG_ISALLTRUE(GETENTRY(entryvec, seed_2)),
 1105 akorotkov                 308 GIC         935 :                                LTG_SIGN(GETENTRY(entryvec, seed_2)),
                                309                 :                                siglen, NULL, NULL);
 7558 bruce                     310 ECB             : 
 7558 bruce                     311 CBC         935 :     maxoff = OffsetNumberNext(maxoff);
                                312                 :     /* sort before ... */
 7522 bruce                     313 GIC         935 :     costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
 7522 bruce                     314 CBC        5771 :     for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
                                315                 :     {
                                316            4836 :         costvector[j - 1].pos = j;
                                317            4836 :         _j = GETENTRY(entryvec, j);
 1105 akorotkov                 318 GIC        4836 :         size_alpha = hemdist(datum_l, _j, siglen);
 1105 akorotkov                 319 CBC        4836 :         size_beta = hemdist(datum_r, _j, siglen);
  184 peter                     320 GNC        4836 :         costvector[j - 1].cost = abs(size_alpha - size_beta);
 7558 bruce                     321 ECB             :     }
   61 peter                     322 GNC         935 :     qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
 7558 bruce                     323 ECB             : 
 6797 bruce                     324 GIC         935 :     union_l = LTG_SIGN(datum_l);
 6797 bruce                     325 CBC         935 :     union_r = LTG_SIGN(datum_r);
                                326                 : 
 7522                           327            5771 :     for (k = 0; k < maxoff; k++)
 7522 bruce                     328 ECB             :     {
 7558 bruce                     329 GIC        4836 :         j = costvector[k].pos;
 7522 bruce                     330 CBC        4836 :         if (j == seed_1)
                                331                 :         {
 7558                           332             935 :             *left++ = j;
                                333             935 :             v->spl_nleft++;
 7558 bruce                     334 GIC         935 :             continue;
 7522 bruce                     335 ECB             :         }
 7522 bruce                     336 CBC        3901 :         else if (j == seed_2)
 7522 bruce                     337 ECB             :         {
 7558 bruce                     338 GIC         935 :             *right++ = j;
 7558 bruce                     339 CBC         935 :             v->spl_nright++;
 7558 bruce                     340 GIC         935 :             continue;
 7558 bruce                     341 ECB             :         }
 7242 bruce                     342 CBC        2966 :         _j = GETENTRY(entryvec, j);
 1105 akorotkov                 343            2966 :         size_alpha = hemdist(datum_l, _j, siglen);
 1105 akorotkov                 344 GIC        2966 :         size_beta = hemdist(datum_r, _j, siglen);
 7558 bruce                     345 ECB             : 
 6797 bruce                     346 CBC        2966 :         if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.00001))
 7522 bruce                     347 ECB             :         {
 6797 bruce                     348 GIC        1410 :             if (LTG_ISALLTRUE(datum_l) || LTG_ISALLTRUE(_j))
 6797 bruce                     349 ECB             :             {
 7242 bruce                     350 UIC           0 :                 if (!LTG_ISALLTRUE(datum_l))
   61 peter                     351 UNC           0 :                     memset(union_l, 0xff, siglen);
                                352                 :             }
 6797 bruce                     353 EUB             :             else
                                354                 :             {
 6797 bruce                     355 GIC        1410 :                 ptr = LTG_SIGN(_j);
 1105 akorotkov                 356         1731502 :                 ALOOPBYTE(siglen)
 5623 bruce                     357         1730092 :                     union_l[i] |= ptr[i];
 7558 bruce                     358 ECB             :             }
 7558 bruce                     359 CBC        1410 :             *left++ = j;
                                360            1410 :             v->spl_nleft++;
                                361                 :         }
 7522 bruce                     362 ECB             :         else
                                363                 :         {
 6797 bruce                     364 GIC        1556 :             if (LTG_ISALLTRUE(datum_r) || LTG_ISALLTRUE(_j))
                                365                 :             {
 7242 bruce                     366 UIC           0 :                 if (!LTG_ISALLTRUE(datum_r))
   61 peter                     367 UNC           0 :                     memset(union_r, 0xff, siglen);
                                368                 :             }
 6797 bruce                     369 EUB             :             else
                                370                 :             {
 6797 bruce                     371 GIC        1556 :                 ptr = LTG_SIGN(_j);
 1105 akorotkov                 372         2055096 :                 ALOOPBYTE(siglen)
 5623 bruce                     373         2053540 :                     union_r[i] |= ptr[i];
 7558 bruce                     374 ECB             :             }
 7558 bruce                     375 CBC        1556 :             *right++ = j;
                                376            1556 :             v->spl_nright++;
                                377                 :         }
 7558 bruce                     378 ECB             :     }
                                379                 : 
 7558 bruce                     380 GIC         935 :     *right = *left = FirstOffsetNumber;
                                381                 : 
                                382             935 :     v->spl_ldatum = PointerGetDatum(datum_l);
 7558 bruce                     383 CBC         935 :     v->spl_rdatum = PointerGetDatum(datum_r);
                                384                 : 
 7522                           385             935 :     PG_RETURN_POINTER(v);
 7558 bruce                     386 ECB             : }
                                387                 : 
                                388                 : static bool
 1105 akorotkov                 389 GIC        2592 : gist_te(ltree_gist *key, ltree *query, int siglen)
                                390                 : {
 7522 bruce                     391            2592 :     ltree_level *curq = LTREE_FIRST(query);
 7522 bruce                     392 CBC        2592 :     BITVECP     sign = LTG_SIGN(key);
 7522 bruce                     393 GIC        2592 :     int         qlen = query->numlevel;
 7558 bruce                     394 ECB             :     unsigned int hv;
                                395                 : 
 7522 bruce                     396 CBC        2592 :     if (LTG_ISALLTRUE(key))
 7558 bruce                     397 UIC           0 :         return true;
                                398                 : 
 7522 bruce                     399 CBC        8739 :     while (qlen > 0)
 7522 bruce                     400 EUB             :     {
 7522 bruce                     401 GIC        6690 :         hv = ltree_crc32_sz(curq->name, curq->len);
 1105 akorotkov                 402 CBC        6690 :         if (!GETBIT(sign, AHASHVAL(hv, siglen)))
 7522 bruce                     403 GIC         543 :             return false;
 7558 bruce                     404 CBC        6147 :         curq = LEVEL_NEXT(curq);
                                405            6147 :         qlen--;
 7558 bruce                     406 ECB             :     }
                                407                 : 
 7558 bruce                     408 CBC        2049 :     return true;
                                409                 : }
                                410                 : 
 1105 akorotkov                 411 ECB             : typedef struct LtreeSignature
                                412                 : {
                                413                 :     BITVECP     sign;
                                414                 :     int         siglen;
                                415                 : } LtreeSignature;
                                416                 : 
                                417                 : static bool
 1105 akorotkov                 418 GIC        3827 : checkcondition_bit(void *cxt, ITEM *val)
                                419                 : {
                                420            3827 :     LtreeSignature *sig = cxt;
 1105 akorotkov                 421 ECB             : 
 1105 akorotkov                 422 GIC        3827 :     return (FLG_CANLOOKSIGN(val->flag)) ? GETBIT(sig->sign, AHASHVAL(val->val, sig->siglen)) : true;
 7558 bruce                     423 ECB             : }
                                424                 : 
                                425                 : static bool
 1105 akorotkov                 426 GIC        2276 : gist_qtxt(ltree_gist *key, ltxtquery *query, int siglen)
                                427                 : {
                                428                 :     LtreeSignature sig;
 1105 akorotkov                 429 ECB             : 
 7522 bruce                     430 GIC        2276 :     if (LTG_ISALLTRUE(key))
 7558 bruce                     431 UIC           0 :         return true;
                                432                 : 
 1105 akorotkov                 433 CBC        2276 :     sig.sign = LTG_SIGN(key);
 1105 akorotkov                 434 GBC        2276 :     sig.siglen = siglen;
                                435                 : 
 1165 alvherre                  436 CBC        2276 :     return ltree_execute(GETQUERY(query),
 1105 akorotkov                 437 ECB             :                          &sig, false,
                                438                 :                          checkcondition_bit);
 7558 bruce                     439                 : }
                                440                 : 
                                441                 : static bool
 1105 akorotkov                 442 GIC       15188 : gist_qe(ltree_gist *key, lquery *query, int siglen)
                                443                 : {
 7522 bruce                     444           15188 :     lquery_level *curq = LQUERY_FIRST(query);
 7522 bruce                     445 CBC       15188 :     BITVECP     sign = LTG_SIGN(key);
 7522 bruce                     446 GIC       15188 :     int         qlen = query->numlevel;
 7522 bruce                     447 ECB             : 
 7522 bruce                     448 CBC       15188 :     if (LTG_ISALLTRUE(key))
 7558 bruce                     449 LBC           0 :         return true;
                                450                 : 
 7522 bruce                     451 CBC       46144 :     while (qlen > 0)
 7522 bruce                     452 EUB             :     {
 7522 bruce                     453 GIC       36873 :         if (curq->numvar && LQL_CANLOOKSIGN(curq))
 7522 bruce                     454 ECB             :         {
 7522 bruce                     455 GIC       25759 :             bool        isexist = false;
 7522 bruce                     456 CBC       25759 :             int         vlen = curq->numvar;
 7558 bruce                     457 GIC       25759 :             lquery_variant *curv = LQL_FIRST(curq);
 7522 bruce                     458 ECB             : 
 7522 bruce                     459 CBC       31676 :             while (vlen > 0)
 7522 bruce                     460 ECB             :             {
 1105 akorotkov                 461 GIC       25759 :                 if (GETBIT(sign, AHASHVAL(curv->val, siglen)))
 7522 bruce                     462 ECB             :                 {
 7522 bruce                     463 GIC       19842 :                     isexist = true;
 7558 bruce                     464 CBC       19842 :                     break;
                                465                 :                 }
                                466            5917 :                 curv = LVAR_NEXT(curv);
                                467            5917 :                 vlen--;
                                468                 :             }
 7522                           469           25759 :             if (!isexist)
 7558                           470            5917 :                 return false;
                                471                 :         }
 7522 bruce                     472 ECB             : 
 7558 bruce                     473 CBC       30956 :         curq = LQL_NEXT(curq);
 7558 bruce                     474 GIC       30956 :         qlen--;
                                475                 :     }
 7558 bruce                     476 ECB             : 
 7558 bruce                     477 CBC        9271 :     return true;
                                478                 : }
                                479                 : 
 7354 bruce                     480 ECB             : static bool
 1105 akorotkov                 481 GIC        2429 : _arrq_cons(ltree_gist *key, ArrayType *_query, int siglen)
                                482                 : {
 6797 bruce                     483            2429 :     lquery     *query = (lquery *) ARR_DATA_PTR(_query);
 6797 bruce                     484 CBC        2429 :     int         num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
                                485                 : 
 4792 tgl                       486            2429 :     if (ARR_NDIM(_query) > 1)
 6797 bruce                     487 LBC           0 :         ereport(ERROR,
                                488                 :                 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
 7199 tgl                       489 ECB             :                  errmsg("array must be one-dimensional")));
 4473 tgl                       490 GBC        2429 :     if (array_contains_nulls(_query))
 6350 tgl                       491 UIC           0 :         ereport(ERROR,
                                492                 :                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
 6350 tgl                       493 ECB             :                  errmsg("array must not contain nulls")));
 7354 bruce                     494 EUB             : 
 6797 bruce                     495 GIC        4462 :     while (num > 0)
                                496                 :     {
 1105 akorotkov                 497            3560 :         if (gist_qe(key, query, siglen))
 6797 bruce                     498 CBC        1527 :             return true;
 6797 bruce                     499 GIC        2033 :         num--;
 6797 bruce                     500 CBC        2033 :         query = (lquery *) NEXTVAL(query);
 6797 bruce                     501 ECB             :     }
 6797 bruce                     502 CBC         902 :     return false;
 7354 bruce                     503 ECB             : }
                                504                 : 
 7522                           505                 : Datum
 7522 bruce                     506 GIC       18925 : _ltree_consistent(PG_FUNCTION_ARGS)
                                507                 : {
                                508           18925 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 2029 tgl                       509 CBC       18925 :     void       *query = (void *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
 7558 bruce                     510 GIC       18925 :     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
 5050 bruce                     511 ECB             : 
 5473 tgl                       512                 :     /* Oid      subtype = PG_GETARG_OID(3); */
 5473 tgl                       513 CBC       18925 :     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
 1105 akorotkov                 514 GIC       18925 :     int         siglen = LTREE_GET_ASIGLEN();
 5473 tgl                       515           18925 :     ltree_gist *key = (ltree_gist *) DatumGetPointer(entry->key);
 7522 bruce                     516 CBC       18925 :     bool        res = false;
 7558 bruce                     517 ECB             : 
 5473 tgl                       518                 :     /* All cases served by this function are inexact */
 5473 tgl                       519 CBC       18925 :     *recheck = true;
                                520                 : 
 7522 bruce                     521 GIC       18925 :     switch (strategy)
 7522 bruce                     522 ECB             :     {
 7558 bruce                     523 GIC        2592 :         case 10:
 7558 bruce                     524 ECB             :         case 11:
 1105 akorotkov                 525 GIC        2592 :             res = gist_te(key, (ltree *) query, siglen);
 7558 bruce                     526 CBC        2592 :             break;
 7558 bruce                     527 GIC       11628 :         case 12:
 7558 bruce                     528 ECB             :         case 13:
 1105 akorotkov                 529 CBC       11628 :             res = gist_qe(key, (lquery *) query, siglen);
 7522 bruce                     530           11628 :             break;
 7558 bruce                     531 GIC        2276 :         case 14:
 7558 bruce                     532 ECB             :         case 15:
 1105 akorotkov                 533 CBC        2276 :             res = gist_qtxt(key, (ltxtquery *) query, siglen);
 7522 bruce                     534            2276 :             break;
 7354 bruce                     535 GIC        2429 :         case 16:
 7354 bruce                     536 ECB             :         case 17:
 1105 akorotkov                 537 CBC        2429 :             res = _arrq_cons(key, (ArrayType *) query, siglen);
 7354 bruce                     538            2429 :             break;
 7558 bruce                     539 UIC           0 :         default:
 7199 tgl                       540 ECB             :             /* internal error */
 7199 tgl                       541 LBC           0 :             elog(ERROR, "unrecognized StrategyNumber: %d", strategy);
 7558 bruce                     542 EUB             :     }
 6031 bruce                     543 GIC       18925 :     PG_FREE_IF_COPY(query, 1);
 7558 bruce                     544 GBC       18925 :     PG_RETURN_BOOL(res);
                                545                 : }
 1105 akorotkov                 546 ECB             : 
                                547                 : Datum
 1105 akorotkov                 548 GIC           9 : _ltree_gist_options(PG_FUNCTION_ARGS)
                                549                 : {
                                550               9 :     local_relopts *relopts = (local_relopts *) PG_GETARG_POINTER(0);
 1105 akorotkov                 551 ECB             : 
 1105 akorotkov                 552 GIC           9 :     init_local_reloptions(relopts, sizeof(LtreeGistOptions));
 1105 akorotkov                 553 CBC           9 :     add_local_int_reloption(relopts, "siglen", "signature length",
                                554                 :                             LTREE_ASIGLEN_DEFAULT, 1, LTREE_ASIGLEN_MAX,
 1105 akorotkov                 555 ECB             :                             offsetof(LtreeGistOptions, siglen));
                                556                 : 
 1105 akorotkov                 557 GIC           9 :     PG_RETURN_VOID();
                                558                 : }
        

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