LCOV - code coverage report
Current view: top level - contrib/btree_gist - btree_utils_var.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 334 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 20 0
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*
       2              :  * contrib/btree_gist/btree_utils_var.c
       3              :  */
       4              : #include "postgres.h"
       5              : 
       6              : #include <limits.h>
       7              : #include <float.h>
       8              : 
       9              : #include "btree_gist.h"
      10              : #include "btree_utils_var.h"
      11              : #include "mb/pg_wchar.h"
      12              : #include "utils/rel.h"
      13              : #include "varatt.h"
      14              : 
      15              : /* used for key sorting */
      16              : typedef struct
      17              : {
      18              :         int                     i;
      19              :         GBT_VARKEY *t;
      20              : } Vsrt;
      21              : 
      22              : typedef struct
      23              : {
      24              :         const gbtree_vinfo *tinfo;
      25              :         Oid                     collation;
      26              :         FmgrInfo   *flinfo;
      27              : } gbt_vsrt_arg;
      28              : 
      29              : 
      30            0 : PG_FUNCTION_INFO_V1(gbt_var_decompress);
      31            0 : PG_FUNCTION_INFO_V1(gbt_var_fetch);
      32              : 
      33              : 
      34              : Datum
      35            0 : gbt_var_decompress(PG_FUNCTION_ARGS)
      36              : {
      37            0 :         GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
      38            0 :         GBT_VARKEY *key = (GBT_VARKEY *) PG_DETOAST_DATUM(entry->key);
      39              : 
      40            0 :         if (key != (GBT_VARKEY *) DatumGetPointer(entry->key))
      41              :         {
      42            0 :                 GISTENTRY  *retval = palloc_object(GISTENTRY);
      43              : 
      44            0 :                 gistentryinit(*retval, PointerGetDatum(key),
      45              :                                           entry->rel, entry->page,
      46              :                                           entry->offset, false);
      47              : 
      48            0 :                 PG_RETURN_POINTER(retval);
      49            0 :         }
      50              : 
      51            0 :         PG_RETURN_POINTER(entry);
      52            0 : }
      53              : 
      54              : /* Returns a better readable representation of variable key ( sets pointer ) */
      55              : GBT_VARKEY_R
      56            0 : gbt_var_key_readable(const GBT_VARKEY *k)
      57              : {
      58              :         GBT_VARKEY_R r;
      59              : 
      60            0 :         r.lower = (bytea *) &(((char *) k)[VARHDRSZ]);
      61            0 :         if (VARSIZE(k) > (VARHDRSZ + (VARSIZE(r.lower))))
      62            0 :                 r.upper = (bytea *) &(((char *) k)[VARHDRSZ + INTALIGN(VARSIZE(r.lower))]);
      63              :         else
      64            0 :                 r.upper = r.lower;
      65            0 :         return r;
      66              : }
      67              : 
      68              : 
      69              : /*
      70              :  * Create a leaf-entry to store in the index, from a single Datum.
      71              :  */
      72              : static GBT_VARKEY *
      73            0 : gbt_var_key_from_datum(const struct varlena *u)
      74              : {
      75            0 :         int32           lowersize = VARSIZE(u);
      76            0 :         GBT_VARKEY *r;
      77              : 
      78            0 :         r = (GBT_VARKEY *) palloc(lowersize + VARHDRSZ);
      79            0 :         memcpy(VARDATA(r), u, lowersize);
      80            0 :         SET_VARSIZE(r, lowersize + VARHDRSZ);
      81              : 
      82            0 :         return r;
      83            0 : }
      84              : 
      85              : /*
      86              :  * Create an entry to store in the index, from lower and upper bound.
      87              :  */
      88              : GBT_VARKEY *
      89            0 : gbt_var_key_copy(const GBT_VARKEY_R *u)
      90              : {
      91            0 :         int32           lowersize = VARSIZE(u->lower);
      92            0 :         int32           uppersize = VARSIZE(u->upper);
      93            0 :         GBT_VARKEY *r;
      94              : 
      95            0 :         r = (GBT_VARKEY *) palloc0(INTALIGN(lowersize) + uppersize + VARHDRSZ);
      96            0 :         memcpy(VARDATA(r), u->lower, lowersize);
      97            0 :         memcpy(VARDATA(r) + INTALIGN(lowersize), u->upper, uppersize);
      98            0 :         SET_VARSIZE(r, INTALIGN(lowersize) + uppersize + VARHDRSZ);
      99              : 
     100            0 :         return r;
     101            0 : }
     102              : 
     103              : 
     104              : static GBT_VARKEY *
     105            0 : gbt_var_leaf2node(GBT_VARKEY *leaf, const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
     106              : {
     107            0 :         GBT_VARKEY *out = leaf;
     108              : 
     109            0 :         if (tinfo->f_l2n)
     110            0 :                 out = tinfo->f_l2n(leaf, flinfo);
     111              : 
     112            0 :         return out;
     113            0 : }
     114              : 
     115              : 
     116              : /*
     117              :  * returns the common prefix length of a node key
     118              : */
     119              : static int32
     120            0 : gbt_var_node_cp_len(const GBT_VARKEY *node, const gbtree_vinfo *tinfo)
     121              : {
     122            0 :         GBT_VARKEY_R r = gbt_var_key_readable(node);
     123            0 :         int32           i = 0;
     124            0 :         int32           l = 0;
     125            0 :         int32           t1len = VARSIZE(r.lower) - VARHDRSZ;
     126            0 :         int32           t2len = VARSIZE(r.upper) - VARHDRSZ;
     127            0 :         int32           ml = Min(t1len, t2len);
     128            0 :         char       *p1 = VARDATA(r.lower);
     129            0 :         char       *p2 = VARDATA(r.upper);
     130              : 
     131            0 :         if (ml == 0)
     132            0 :                 return 0;
     133              : 
     134            0 :         while (i < ml)
     135              :         {
     136            0 :                 if (tinfo->eml > 1 && l == 0)
     137              :                 {
     138            0 :                         if ((l = pg_mblen(p1)) != pg_mblen(p2))
     139              :                         {
     140            0 :                                 return i;
     141              :                         }
     142            0 :                 }
     143            0 :                 if (*p1 != *p2)
     144              :                 {
     145            0 :                         if (tinfo->eml > 1)
     146              :                         {
     147            0 :                                 return (i - l + 1);
     148              :                         }
     149              :                         else
     150              :                         {
     151            0 :                                 return i;
     152              :                         }
     153              :                 }
     154              : 
     155            0 :                 p1++;
     156            0 :                 p2++;
     157            0 :                 l--;
     158            0 :                 i++;
     159              :         }
     160            0 :         return ml;                                      /* lower == upper */
     161            0 : }
     162              : 
     163              : 
     164              : /*
     165              :  * returns true, if query matches prefix ( common prefix )
     166              :  */
     167              : static bool
     168            0 : gbt_bytea_pf_match(const bytea *pf, const bytea *query, const gbtree_vinfo *tinfo)
     169              : {
     170            0 :         bool            out = false;
     171            0 :         int32           qlen = VARSIZE(query) - VARHDRSZ;
     172            0 :         int32           nlen = VARSIZE(pf) - VARHDRSZ;
     173              : 
     174            0 :         if (nlen <= qlen)
     175              :         {
     176            0 :                 char       *q = VARDATA(query);
     177            0 :                 char       *n = VARDATA(pf);
     178              : 
     179            0 :                 out = (memcmp(q, n, nlen) == 0);
     180            0 :         }
     181              : 
     182            0 :         return out;
     183            0 : }
     184              : 
     185              : 
     186              : /*
     187              :  * returns true, if query matches node using common prefix
     188              :  */
     189              : static bool
     190            0 : gbt_var_node_pf_match(const GBT_VARKEY_R *node, const bytea *query, const gbtree_vinfo *tinfo)
     191              : {
     192            0 :         return (tinfo->trnc &&
     193            0 :                         (gbt_bytea_pf_match(node->lower, query, tinfo) ||
     194            0 :                          gbt_bytea_pf_match(node->upper, query, tinfo)));
     195              : }
     196              : 
     197              : 
     198              : /*
     199              : *  truncates / compresses the node key
     200              : *  cpf_length .. common prefix length
     201              : */
     202              : static GBT_VARKEY *
     203            0 : gbt_var_node_truncate(const GBT_VARKEY *node, int32 cpf_length, const gbtree_vinfo *tinfo)
     204              : {
     205            0 :         GBT_VARKEY *out = NULL;
     206            0 :         GBT_VARKEY_R r = gbt_var_key_readable(node);
     207            0 :         int32           len1 = VARSIZE(r.lower) - VARHDRSZ;
     208            0 :         int32           len2 = VARSIZE(r.upper) - VARHDRSZ;
     209            0 :         int32           si;
     210            0 :         char       *out2;
     211              : 
     212            0 :         len1 = Min(len1, (cpf_length + 1));
     213            0 :         len2 = Min(len2, (cpf_length + 1));
     214              : 
     215            0 :         si = 2 * VARHDRSZ + INTALIGN(len1 + VARHDRSZ) + len2;
     216            0 :         out = (GBT_VARKEY *) palloc0(si);
     217            0 :         SET_VARSIZE(out, si);
     218              : 
     219            0 :         memcpy(VARDATA(out), r.lower, len1 + VARHDRSZ);
     220            0 :         SET_VARSIZE(VARDATA(out), len1 + VARHDRSZ);
     221              : 
     222            0 :         out2 = VARDATA(out) + INTALIGN(len1 + VARHDRSZ);
     223            0 :         memcpy(out2, r.upper, len2 + VARHDRSZ);
     224            0 :         SET_VARSIZE(out2, len2 + VARHDRSZ);
     225              : 
     226            0 :         return out;
     227            0 : }
     228              : 
     229              : 
     230              : 
     231              : void
     232            0 : gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation,
     233              :                                   const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
     234              : {
     235            0 :         GBT_VARKEY_R eo = gbt_var_key_readable(e);
     236            0 :         GBT_VARKEY_R nr;
     237              : 
     238            0 :         if (eo.lower == eo.upper)       /* leaf */
     239              :         {
     240            0 :                 GBT_VARKEY *tmp;
     241              : 
     242            0 :                 tmp = gbt_var_leaf2node(e, tinfo, flinfo);
     243            0 :                 if (tmp != e)
     244            0 :                         eo = gbt_var_key_readable(tmp);
     245            0 :         }
     246              : 
     247            0 :         if (DatumGetPointer(*u))
     248              :         {
     249            0 :                 GBT_VARKEY_R ro = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(*u));
     250            0 :                 bool            update = false;
     251              : 
     252            0 :                 nr.lower = ro.lower;
     253            0 :                 nr.upper = ro.upper;
     254              : 
     255            0 :                 if (tinfo->f_cmp(ro.lower, eo.lower, collation, flinfo) > 0)
     256              :                 {
     257            0 :                         nr.lower = eo.lower;
     258            0 :                         update = true;
     259            0 :                 }
     260              : 
     261            0 :                 if (tinfo->f_cmp(ro.upper, eo.upper, collation, flinfo) < 0)
     262              :                 {
     263            0 :                         nr.upper = eo.upper;
     264            0 :                         update = true;
     265            0 :                 }
     266              : 
     267            0 :                 if (update)
     268            0 :                         *u = PointerGetDatum(gbt_var_key_copy(&nr));
     269            0 :         }
     270              :         else
     271              :         {
     272            0 :                 nr.lower = eo.lower;
     273            0 :                 nr.upper = eo.upper;
     274            0 :                 *u = PointerGetDatum(gbt_var_key_copy(&nr));
     275              :         }
     276            0 : }
     277              : 
     278              : 
     279              : GISTENTRY *
     280            0 : gbt_var_compress(GISTENTRY *entry, const gbtree_vinfo *tinfo)
     281              : {
     282            0 :         GISTENTRY  *retval;
     283              : 
     284            0 :         if (entry->leafkey)
     285              :         {
     286            0 :                 struct varlena *leaf = PG_DETOAST_DATUM(entry->key);
     287            0 :                 GBT_VARKEY *r;
     288              : 
     289            0 :                 r = gbt_var_key_from_datum(leaf);
     290              : 
     291            0 :                 retval = palloc_object(GISTENTRY);
     292            0 :                 gistentryinit(*retval, PointerGetDatum(r),
     293              :                                           entry->rel, entry->page,
     294              :                                           entry->offset, true);
     295            0 :         }
     296              :         else
     297            0 :                 retval = entry;
     298              : 
     299            0 :         return retval;
     300            0 : }
     301              : 
     302              : 
     303              : Datum
     304            0 : gbt_var_fetch(PG_FUNCTION_ARGS)
     305              : {
     306            0 :         GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     307            0 :         GBT_VARKEY *key = (GBT_VARKEY *) PG_DETOAST_DATUM(entry->key);
     308            0 :         GBT_VARKEY_R r = gbt_var_key_readable(key);
     309            0 :         GISTENTRY  *retval;
     310              : 
     311            0 :         retval = palloc_object(GISTENTRY);
     312            0 :         gistentryinit(*retval, PointerGetDatum(r.lower),
     313              :                                   entry->rel, entry->page,
     314              :                                   entry->offset, true);
     315              : 
     316            0 :         PG_RETURN_POINTER(retval);
     317            0 : }
     318              : 
     319              : 
     320              : GBT_VARKEY *
     321            0 : gbt_var_union(const GistEntryVector *entryvec, int32 *size, Oid collation,
     322              :                           const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
     323              : {
     324            0 :         int                     i = 0,
     325            0 :                                 numranges = entryvec->n;
     326            0 :         GBT_VARKEY *cur;
     327            0 :         Datum           out;
     328            0 :         GBT_VARKEY_R rk;
     329              : 
     330            0 :         *size = sizeof(GBT_VARKEY);
     331              : 
     332            0 :         cur = (GBT_VARKEY *) DatumGetPointer(entryvec->vector[0].key);
     333            0 :         rk = gbt_var_key_readable(cur);
     334            0 :         out = PointerGetDatum(gbt_var_key_copy(&rk));
     335              : 
     336            0 :         for (i = 1; i < numranges; i++)
     337              :         {
     338            0 :                 cur = (GBT_VARKEY *) DatumGetPointer(entryvec->vector[i].key);
     339            0 :                 gbt_var_bin_union(&out, cur, collation, tinfo, flinfo);
     340            0 :         }
     341              : 
     342              : 
     343              :         /* Truncate (=compress) key */
     344            0 :         if (tinfo->trnc)
     345              :         {
     346            0 :                 int32           plen;
     347            0 :                 GBT_VARKEY *trc = NULL;
     348              : 
     349            0 :                 plen = gbt_var_node_cp_len((GBT_VARKEY *) DatumGetPointer(out), tinfo);
     350            0 :                 trc = gbt_var_node_truncate((GBT_VARKEY *) DatumGetPointer(out), plen + 1, tinfo);
     351              : 
     352            0 :                 out = PointerGetDatum(trc);
     353            0 :         }
     354              : 
     355            0 :         return ((GBT_VARKEY *) DatumGetPointer(out));
     356            0 : }
     357              : 
     358              : 
     359              : bool
     360            0 : gbt_var_same(Datum d1, Datum d2, Oid collation,
     361              :                          const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
     362              : {
     363            0 :         GBT_VARKEY *t1 = (GBT_VARKEY *) DatumGetPointer(d1);
     364            0 :         GBT_VARKEY *t2 = (GBT_VARKEY *) DatumGetPointer(d2);
     365            0 :         GBT_VARKEY_R r1,
     366              :                                 r2;
     367              : 
     368            0 :         r1 = gbt_var_key_readable(t1);
     369            0 :         r2 = gbt_var_key_readable(t2);
     370              : 
     371            0 :         return (tinfo->f_cmp(r1.lower, r2.lower, collation, flinfo) == 0 &&
     372            0 :                         tinfo->f_cmp(r1.upper, r2.upper, collation, flinfo) == 0);
     373            0 : }
     374              : 
     375              : 
     376              : float *
     377            0 : gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n,
     378              :                                 Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
     379              : {
     380            0 :         GBT_VARKEY *orge = (GBT_VARKEY *) DatumGetPointer(o->key);
     381            0 :         GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key);
     382            0 :         GBT_VARKEY_R ok,
     383              :                                 nk;
     384              : 
     385            0 :         *res = 0.0;
     386              : 
     387            0 :         nk = gbt_var_key_readable(newe);
     388            0 :         if (nk.lower == nk.upper)       /* leaf */
     389              :         {
     390            0 :                 GBT_VARKEY *tmp;
     391              : 
     392            0 :                 tmp = gbt_var_leaf2node(newe, tinfo, flinfo);
     393            0 :                 if (tmp != newe)
     394            0 :                         nk = gbt_var_key_readable(tmp);
     395            0 :         }
     396            0 :         ok = gbt_var_key_readable(orge);
     397              : 
     398            0 :         if ((VARSIZE(ok.lower) - VARHDRSZ) == 0 && (VARSIZE(ok.upper) - VARHDRSZ) == 0)
     399            0 :                 *res = 0.0;
     400            0 :         else if (!((tinfo->f_cmp(nk.lower, ok.lower, collation, flinfo) >= 0 ||
     401            0 :                                 gbt_bytea_pf_match(ok.lower, nk.lower, tinfo)) &&
     402            0 :                            (tinfo->f_cmp(nk.upper, ok.upper, collation, flinfo) <= 0 ||
     403            0 :                                 gbt_bytea_pf_match(ok.upper, nk.upper, tinfo))))
     404              :         {
     405            0 :                 Datum           d = PointerGetDatum(0);
     406            0 :                 double          dres;
     407            0 :                 int32           ol,
     408              :                                         ul;
     409              : 
     410            0 :                 gbt_var_bin_union(&d, orge, collation, tinfo, flinfo);
     411            0 :                 ol = gbt_var_node_cp_len((GBT_VARKEY *) DatumGetPointer(d), tinfo);
     412            0 :                 gbt_var_bin_union(&d, newe, collation, tinfo, flinfo);
     413            0 :                 ul = gbt_var_node_cp_len((GBT_VARKEY *) DatumGetPointer(d), tinfo);
     414              : 
     415            0 :                 if (ul < ol)
     416              :                 {
     417            0 :                         dres = (ol - ul);       /* reduction of common prefix len */
     418            0 :                 }
     419              :                 else
     420              :                 {
     421            0 :                         GBT_VARKEY_R uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(d));
     422            0 :                         unsigned char tmp[4];
     423              : 
     424            0 :                         tmp[0] = (unsigned char) (((VARSIZE(ok.lower) - VARHDRSZ) <= ul) ? 0 : (VARDATA(ok.lower)[ul]));
     425            0 :                         tmp[1] = (unsigned char) (((VARSIZE(uk.lower) - VARHDRSZ) <= ul) ? 0 : (VARDATA(uk.lower)[ul]));
     426            0 :                         tmp[2] = (unsigned char) (((VARSIZE(ok.upper) - VARHDRSZ) <= ul) ? 0 : (VARDATA(ok.upper)[ul]));
     427            0 :                         tmp[3] = (unsigned char) (((VARSIZE(uk.upper) - VARHDRSZ) <= ul) ? 0 : (VARDATA(uk.upper)[ul]));
     428            0 :                         dres = abs(tmp[0] - tmp[1]) + abs(tmp[3] - tmp[2]);
     429            0 :                         dres /= 256.0;
     430            0 :                 }
     431              : 
     432            0 :                 *res += FLT_MIN;
     433            0 :                 *res += (float) (dres / ((double) (ol + 1)));
     434            0 :                 *res *= (FLT_MAX / (o->rel->rd_att->natts + 1));
     435            0 :         }
     436              : 
     437            0 :         return res;
     438            0 : }
     439              : 
     440              : 
     441              : static int
     442            0 : gbt_vsrt_cmp(const void *a, const void *b, void *arg)
     443              : {
     444            0 :         GBT_VARKEY_R ar = gbt_var_key_readable(((const Vsrt *) a)->t);
     445            0 :         GBT_VARKEY_R br = gbt_var_key_readable(((const Vsrt *) b)->t);
     446            0 :         const gbt_vsrt_arg *varg = (const gbt_vsrt_arg *) arg;
     447            0 :         int                     res;
     448              : 
     449            0 :         res = varg->tinfo->f_cmp(ar.lower, br.lower, varg->collation, varg->flinfo);
     450            0 :         if (res == 0)
     451            0 :                 return varg->tinfo->f_cmp(ar.upper, br.upper, varg->collation, varg->flinfo);
     452              : 
     453            0 :         return res;
     454            0 : }
     455              : 
     456              : GIST_SPLITVEC *
     457            0 : gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
     458              :                                   Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
     459              : {
     460            0 :         OffsetNumber i,
     461            0 :                                 maxoff = entryvec->n - 1;
     462            0 :         Vsrt       *arr;
     463            0 :         int                     svcntr = 0,
     464              :                                 nbytes;
     465            0 :         char       *cur;
     466            0 :         GBT_VARKEY **sv = NULL;
     467            0 :         gbt_vsrt_arg varg;
     468              : 
     469            0 :         arr = palloc_array(Vsrt, maxoff + 1);
     470            0 :         nbytes = (maxoff + 2) * sizeof(OffsetNumber);
     471            0 :         v->spl_left = (OffsetNumber *) palloc(nbytes);
     472            0 :         v->spl_right = (OffsetNumber *) palloc(nbytes);
     473            0 :         v->spl_ldatum = PointerGetDatum(0);
     474            0 :         v->spl_rdatum = PointerGetDatum(0);
     475            0 :         v->spl_nleft = 0;
     476            0 :         v->spl_nright = 0;
     477              : 
     478            0 :         sv = palloc_array(GBT_VARKEY *, maxoff + 1);
     479              : 
     480              :         /* Sort entries */
     481              : 
     482            0 :         for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
     483              :         {
     484            0 :                 GBT_VARKEY_R ro;
     485              : 
     486            0 :                 cur = (char *) DatumGetPointer(entryvec->vector[i].key);
     487            0 :                 ro = gbt_var_key_readable((GBT_VARKEY *) cur);
     488            0 :                 if (ro.lower == ro.upper)       /* leaf */
     489              :                 {
     490            0 :                         sv[svcntr] = gbt_var_leaf2node((GBT_VARKEY *) cur, tinfo, flinfo);
     491            0 :                         arr[i].t = sv[svcntr];
     492            0 :                         if (sv[svcntr] != (GBT_VARKEY *) cur)
     493            0 :                                 svcntr++;
     494            0 :                 }
     495              :                 else
     496            0 :                         arr[i].t = (GBT_VARKEY *) cur;
     497            0 :                 arr[i].i = i;
     498            0 :         }
     499              : 
     500              :         /* sort */
     501            0 :         varg.tinfo = tinfo;
     502            0 :         varg.collation = collation;
     503            0 :         varg.flinfo = flinfo;
     504            0 :         qsort_arg(&arr[FirstOffsetNumber],
     505            0 :                           maxoff - FirstOffsetNumber + 1,
     506              :                           sizeof(Vsrt),
     507              :                           gbt_vsrt_cmp,
     508              :                           &varg);
     509              : 
     510              :         /* We do simply create two parts */
     511              : 
     512            0 :         for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
     513              :         {
     514            0 :                 if (i <= (maxoff - FirstOffsetNumber + 1) / 2)
     515              :                 {
     516            0 :                         gbt_var_bin_union(&v->spl_ldatum, arr[i].t, collation, tinfo, flinfo);
     517            0 :                         v->spl_left[v->spl_nleft] = arr[i].i;
     518            0 :                         v->spl_nleft++;
     519            0 :                 }
     520              :                 else
     521              :                 {
     522            0 :                         gbt_var_bin_union(&v->spl_rdatum, arr[i].t, collation, tinfo, flinfo);
     523            0 :                         v->spl_right[v->spl_nright] = arr[i].i;
     524            0 :                         v->spl_nright++;
     525              :                 }
     526            0 :         }
     527              : 
     528              :         /* Truncate (=compress) key */
     529            0 :         if (tinfo->trnc)
     530              :         {
     531            0 :                 int32           ll = gbt_var_node_cp_len((GBT_VARKEY *) DatumGetPointer(v->spl_ldatum), tinfo);
     532            0 :                 int32           lr = gbt_var_node_cp_len((GBT_VARKEY *) DatumGetPointer(v->spl_rdatum), tinfo);
     533            0 :                 GBT_VARKEY *dl;
     534            0 :                 GBT_VARKEY *dr;
     535              : 
     536            0 :                 ll = Max(ll, lr);
     537            0 :                 ll++;
     538              : 
     539            0 :                 dl = gbt_var_node_truncate((GBT_VARKEY *) DatumGetPointer(v->spl_ldatum), ll, tinfo);
     540            0 :                 dr = gbt_var_node_truncate((GBT_VARKEY *) DatumGetPointer(v->spl_rdatum), ll, tinfo);
     541            0 :                 v->spl_ldatum = PointerGetDatum(dl);
     542            0 :                 v->spl_rdatum = PointerGetDatum(dr);
     543            0 :         }
     544              : 
     545            0 :         return v;
     546            0 : }
     547              : 
     548              : 
     549              : /*
     550              :  * The GiST consistent method
     551              :  */
     552              : bool
     553            0 : gbt_var_consistent(GBT_VARKEY_R *key,
     554              :                                    const void *query,
     555              :                                    StrategyNumber strategy,
     556              :                                    Oid collation,
     557              :                                    bool is_leaf,
     558              :                                    const gbtree_vinfo *tinfo,
     559              :                                    FmgrInfo *flinfo)
     560              : {
     561            0 :         bool            retval = false;
     562              : 
     563            0 :         switch (strategy)
     564              :         {
     565              :                 case BTLessEqualStrategyNumber:
     566            0 :                         if (is_leaf)
     567            0 :                                 retval = tinfo->f_ge(query, key->lower, collation, flinfo);
     568              :                         else
     569            0 :                                 retval = tinfo->f_cmp(query, key->lower, collation, flinfo) >= 0
     570            0 :                                         || gbt_var_node_pf_match(key, query, tinfo);
     571            0 :                         break;
     572              :                 case BTLessStrategyNumber:
     573            0 :                         if (is_leaf)
     574            0 :                                 retval = tinfo->f_gt(query, key->lower, collation, flinfo);
     575              :                         else
     576            0 :                                 retval = tinfo->f_cmp(query, key->lower, collation, flinfo) >= 0
     577            0 :                                         || gbt_var_node_pf_match(key, query, tinfo);
     578            0 :                         break;
     579              :                 case BTEqualStrategyNumber:
     580            0 :                         if (is_leaf)
     581            0 :                                 retval = tinfo->f_eq(query, key->lower, collation, flinfo);
     582              :                         else
     583            0 :                                 retval =
     584            0 :                                         (tinfo->f_cmp(key->lower, query, collation, flinfo) <= 0 &&
     585            0 :                                          tinfo->f_cmp(query, key->upper, collation, flinfo) <= 0) ||
     586            0 :                                         gbt_var_node_pf_match(key, query, tinfo);
     587            0 :                         break;
     588              :                 case BTGreaterStrategyNumber:
     589            0 :                         if (is_leaf)
     590            0 :                                 retval = tinfo->f_lt(query, key->upper, collation, flinfo);
     591              :                         else
     592            0 :                                 retval = tinfo->f_cmp(query, key->upper, collation, flinfo) <= 0
     593            0 :                                         || gbt_var_node_pf_match(key, query, tinfo);
     594            0 :                         break;
     595              :                 case BTGreaterEqualStrategyNumber:
     596            0 :                         if (is_leaf)
     597            0 :                                 retval = tinfo->f_le(query, key->upper, collation, flinfo);
     598              :                         else
     599            0 :                                 retval = tinfo->f_cmp(query, key->upper, collation, flinfo) <= 0
     600            0 :                                         || gbt_var_node_pf_match(key, query, tinfo);
     601            0 :                         break;
     602              :                 case BtreeGistNotEqualStrategyNumber:
     603            0 :                         retval = !(tinfo->f_eq(query, key->lower, collation, flinfo) &&
     604            0 :                                            tinfo->f_eq(query, key->upper, collation, flinfo));
     605            0 :                         break;
     606              :                 default:
     607            0 :                         retval = false;
     608            0 :         }
     609              : 
     610            0 :         return retval;
     611            0 : }
        

Generated by: LCOV version 2.3.2-1