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 15:15:32 Functions: 96.0 % 25 24 1 24 1 24
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

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