LCOV - differential code coverage report
Current view: top level - contrib/btree_gist - btree_utils_var.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: 0e5ff9b9b45a657aea12440478dc002e9b01f138 vs 0123ce131fca454009439dfa3b2266d1d40737d7 Lines: 83.1 % 284 236 48 7 229 7
Current Date: 2026-03-14 14:10:32 -0400 Functions: 95.0 % 20 19 1 5 14 1
Baseline: lcov-20260315-024220-baseline Branches: 69.2 % 133 92 41 92
Baseline Date: 2026-03-14 15:27:56 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(30,360] days: 66.7 % 18 12 6 7 5
(360..) days: 84.2 % 266 224 42 224
Function coverage date bins:
(30,360] days: 100.0 % 1 1 1
(360..) days: 94.7 % 19 18 1 4 14
Branch coverage date bins:
(30,360] days: 16.7 % 6 1 5 1
(360..) days: 71.7 % 127 91 36 91

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

Generated by: LCOV version 2.4-beta