LCOV - differential code coverage report
Current view: top level - contrib/btree_gist - btree_utils_num.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 96.5 % 198 191 7 5 186 5
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 8 8 4 4
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (60,120] days: 100.0 % 4 4 4
Legend: Lines: hit not hit (180,240] days: 100.0 % 1 1 1
(240..) days: 96.4 % 193 186 7 186
Function coverage date bins:
(240..) days: 100.0 % 8 8 4 4

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*
                                  2                 :  * contrib/btree_gist/btree_utils_num.c
                                  3                 :  */
                                  4                 : #include "postgres.h"
                                  5                 : 
                                  6                 : #include "btree_gist.h"
                                  7                 : #include "btree_utils_num.h"
                                  8                 : #include "utils/cash.h"
                                  9                 : #include "utils/date.h"
                                 10                 : #include "utils/timestamp.h"
                                 11                 : 
                                 12                 : 
                                 13                 : GISTENTRY *
 2936 heikki.linnakangas         14 CBC       10430 : gbt_num_compress(GISTENTRY *entry, const gbtree_ninfo *tinfo)
                                 15                 : {
                                 16                 :     GISTENTRY  *retval;
                                 17                 : 
 6797 bruce                      18           10430 :     if (entry->leafkey)
                                 19                 :     {
                                 20                 :         union
                                 21                 :         {
                                 22                 :             bool        bo;
                                 23                 :             int16       i2;
                                 24                 :             int32       i4;
                                 25                 :             int64       i8;
                                 26                 :             float4      f4;
                                 27                 :             float8      f8;
                                 28                 :             DateADT     dt;
                                 29                 :             TimeADT     tm;
                                 30                 :             Timestamp   ts;
                                 31                 :             Cash        ch;
                                 32                 :         }           v;
                                 33                 : 
 3250 tgl                        34            9669 :         GBT_NUMKEY *r = (GBT_NUMKEY *) palloc0(tinfo->indexsize);
 6797 bruce                      35            9669 :         void       *leaf = NULL;
                                 36                 : 
                                 37            9669 :         switch (tinfo->t)
                                 38                 :         {
  519 tomas.vondra               39               2 :             case gbt_t_bool:
                                 40               2 :                 v.bo = DatumGetBool(entry->key);
                                 41               2 :                 leaf = &v.bo;
                                 42               2 :                 break;
 6797 bruce                      43             546 :             case gbt_t_int2:
                                 44             546 :                 v.i2 = DatumGetInt16(entry->key);
                                 45             546 :                 leaf = &v.i2;
                                 46             546 :                 break;
                                 47             550 :             case gbt_t_int4:
                                 48             550 :                 v.i4 = DatumGetInt32(entry->key);
                                 49             550 :                 leaf = &v.i4;
                                 50             550 :                 break;
 5466 tgl                        51             547 :             case gbt_t_int8:
                                 52             547 :                 v.i8 = DatumGetInt64(entry->key);
                                 53             547 :                 leaf = &v.i8;
                                 54             547 :                 break;
 6797 bruce                      55            1532 :             case gbt_t_oid:
                                 56                 :             case gbt_t_enum:
                                 57            1532 :                 v.i4 = DatumGetObjectId(entry->key);
                                 58            1532 :                 leaf = &v.i4;
                                 59            1532 :                 break;
 5466 tgl                        60             547 :             case gbt_t_float4:
                                 61             547 :                 v.f4 = DatumGetFloat4(entry->key);
                                 62             547 :                 leaf = &v.f4;
                                 63             547 :                 break;
                                 64             544 :             case gbt_t_float8:
                                 65             544 :                 v.f8 = DatumGetFloat8(entry->key);
                                 66             544 :                 leaf = &v.f8;
                                 67             544 :                 break;
 6797 bruce                      68             544 :             case gbt_t_date:
                                 69             544 :                 v.dt = DatumGetDateADT(entry->key);
                                 70             544 :                 leaf = &v.dt;
                                 71             544 :                 break;
 5466 tgl                        72             544 :             case gbt_t_time:
                                 73             544 :                 v.tm = DatumGetTimeADT(entry->key);
                                 74             544 :                 leaf = &v.tm;
                                 75             544 :                 break;
                                 76            2570 :             case gbt_t_ts:
                                 77            2570 :                 v.ts = DatumGetTimestamp(entry->key);
                                 78            2570 :                 leaf = &v.ts;
                                 79            2570 :                 break;
                                 80             543 :             case gbt_t_cash:
                                 81             543 :                 v.ch = DatumGetCash(entry->key);
                                 82             543 :                 leaf = &v.ch;
 5469 alvherre                   83             543 :                 break;
 6797 bruce                      84            1200 :             default:
                                 85            1200 :                 leaf = DatumGetPointer(entry->key);
                                 86                 :         }
                                 87                 : 
 3250 tgl                        88            9669 :         Assert(tinfo->indexsize >= 2 * tinfo->size);
                                 89                 : 
   61 peter                      90 GNC        9669 :         memcpy(&r[0], leaf, tinfo->size);
                                 91            9669 :         memcpy(&r[tinfo->size], leaf, tinfo->size);
 6797 bruce                      92 CBC        9669 :         retval = palloc(sizeof(GISTENTRY));
                                 93            9669 :         gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page,
                                 94                 :                       entry->offset, false);
                                 95                 :     }
                                 96                 :     else
                                 97             761 :         retval = entry;
                                 98                 : 
                                 99           10430 :     return retval;
                                100                 : }
                                101                 : 
                                102                 : /*
                                103                 :  * Convert a compressed leaf item back to the original type, for index-only
                                104                 :  * scans.
                                105                 :  */
                                106                 : GISTENTRY *
 2935 heikki.linnakangas        107            2210 : gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo)
                                108                 : {
                                109                 :     GISTENTRY  *retval;
                                110                 :     Datum       datum;
                                111                 : 
                                112            2210 :     Assert(tinfo->indexsize >= 2 * tinfo->size);
                                113                 : 
                                114                 :     /*
                                115                 :      * Get the original Datum from the stored datum. On leaf entries, the
                                116                 :      * lower and upper bound are the same. We just grab the lower bound and
                                117                 :      * return it.
                                118                 :      */
                                119            2210 :     switch (tinfo->t)
                                120                 :     {
  519 tomas.vondra              121               7 :         case gbt_t_bool:
                                122               7 :             datum = BoolGetDatum(*(bool *) entry->key);
                                123               7 :             break;
 2935 heikki.linnakangas        124             287 :         case gbt_t_int2:
                                125             287 :             datum = Int16GetDatum(*(int16 *) entry->key);
                                126             287 :             break;
                                127             287 :         case gbt_t_int4:
                                128             287 :             datum = Int32GetDatum(*(int32 *) entry->key);
                                129             287 :             break;
                                130             139 :         case gbt_t_int8:
                                131             139 :             datum = Int64GetDatum(*(int64 *) entry->key);
                                132             139 :             break;
 2935 heikki.linnakangas        133 UBC           0 :         case gbt_t_oid:
                                134                 :         case gbt_t_enum:
                                135               0 :             datum = ObjectIdGetDatum(*(Oid *) entry->key);
                                136               0 :             break;
 2935 heikki.linnakangas        137 CBC         265 :         case gbt_t_float4:
                                138             265 :             datum = Float4GetDatum(*(float4 *) entry->key);
                                139             265 :             break;
                                140             135 :         case gbt_t_float8:
                                141             135 :             datum = Float8GetDatum(*(float8 *) entry->key);
                                142             135 :             break;
                                143             281 :         case gbt_t_date:
                                144             281 :             datum = DateADTGetDatum(*(DateADT *) entry->key);
                                145             281 :             break;
                                146             142 :         case gbt_t_time:
                                147             142 :             datum = TimeADTGetDatum(*(TimeADT *) entry->key);
                                148             142 :             break;
                                149             364 :         case gbt_t_ts:
                                150             364 :             datum = TimestampGetDatum(*(Timestamp *) entry->key);
                                151             364 :             break;
                                152             143 :         case gbt_t_cash:
                                153             143 :             datum = CashGetDatum(*(Cash *) entry->key);
                                154             143 :             break;
                                155             160 :         default:
  224 peter                     156 GNC         160 :             datum = entry->key;
                                157                 :     }
                                158                 : 
 2935 heikki.linnakangas        159 CBC        2210 :     retval = palloc(sizeof(GISTENTRY));
                                160            2210 :     gistentryinit(*retval, datum, entry->rel, entry->page, entry->offset,
                                161                 :                   false);
                                162            2210 :     return retval;
                                163                 : }
                                164                 : 
                                165                 : 
                                166                 : 
                                167                 : /*
                                168                 : ** The GiST union method for numerical values
                                169                 : */
                                170                 : 
                                171                 : void *
 2210 andrew                    172            8412 : gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
                                173                 : {
                                174                 :     int         i,
                                175                 :                 numranges;
                                176                 :     GBT_NUMKEY *cur;
                                177                 :     GBT_NUMKEY_R o,
                                178                 :                 c;
                                179                 : 
 6797 bruce                     180            8412 :     numranges = entryvec->n;
                                181            8412 :     cur = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[0].key));
                                182                 : 
                                183                 : 
                                184            8412 :     o.lower = &((GBT_NUMKEY *) out)[0];
                                185            8412 :     o.upper = &((GBT_NUMKEY *) out)[tinfo->size];
                                186                 : 
   61 peter                     187 GNC        8412 :     memcpy(out, cur, 2 * tinfo->size);
                                188                 : 
 6797 bruce                     189 CBC       25690 :     for (i = 1; i < numranges; i++)
                                190                 :     {
                                191           17278 :         cur = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[i].key));
                                192           17278 :         c.lower = &cur[0];
                                193           17278 :         c.upper = &cur[tinfo->size];
                                194                 :         /* if out->lower > cur->lower, adopt cur as lower */
 2040 peter_e                   195           17278 :         if (tinfo->f_gt(o.lower, c.lower, flinfo))
 1531 peter                     196             134 :             memcpy(unconstify(GBT_NUMKEY *, o.lower), c.lower, tinfo->size);
                                197                 :         /* if out->upper < cur->upper, adopt cur as upper */
 2040 peter_e                   198           17278 :         if (tinfo->f_lt(o.upper, c.upper, flinfo))
 1531 peter                     199            1351 :             memcpy(unconstify(GBT_NUMKEY *, o.upper), c.upper, tinfo->size);
                                200                 :     }
                                201                 : 
 6797 bruce                     202            8412 :     return out;
                                203                 : }
                                204                 : 
                                205                 : 
                                206                 : 
                                207                 : /*
                                208                 : ** The GiST same method for numerical values
                                209                 : */
                                210                 : 
                                211                 : bool
 2210 andrew                    212            8369 : gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
                                213                 : {
                                214                 :     GBT_NUMKEY_R b1,
                                215                 :                 b2;
                                216                 : 
 1531 peter                     217            8369 :     b1.lower = &(a[0]);
                                218            8369 :     b1.upper = &(a[tinfo->size]);
                                219            8369 :     b2.lower = &(b[0]);
                                220            8369 :     b2.upper = &(b[tinfo->size]);
                                221                 : 
 2040 peter_e                   222           16707 :     return (tinfo->f_eq(b1.lower, b2.lower, flinfo) &&
                                223            8338 :             tinfo->f_eq(b1.upper, b2.upper, flinfo));
                                224                 : }
                                225                 : 
                                226                 : 
                                227                 : void
 2210 andrew                    228           16049 : gbt_num_bin_union(Datum *u, GBT_NUMKEY *e, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
                                229                 : {
                                230                 :     GBT_NUMKEY_R rd;
                                231                 : 
 6797 bruce                     232           16049 :     rd.lower = &e[0];
                                233           16049 :     rd.upper = &e[tinfo->size];
                                234                 : 
                                235           16049 :     if (!DatumGetPointer(*u))
                                236                 :     {
 3250 tgl                       237             132 :         *u = PointerGetDatum(palloc0(tinfo->indexsize));
 1531 peter                     238             132 :         memcpy(&(((GBT_NUMKEY *) DatumGetPointer(*u))[0]), rd.lower, tinfo->size);
                                239             132 :         memcpy(&(((GBT_NUMKEY *) DatumGetPointer(*u))[tinfo->size]), rd.upper, tinfo->size);
                                240                 :     }
                                241                 :     else
                                242                 :     {
                                243                 :         GBT_NUMKEY_R ur;
                                244                 : 
 6797 bruce                     245           15917 :         ur.lower = &(((GBT_NUMKEY *) DatumGetPointer(*u))[0]);
                                246           15917 :         ur.upper = &(((GBT_NUMKEY *) DatumGetPointer(*u))[tinfo->size]);
 1531 peter                     247           15917 :         if (tinfo->f_gt(ur.lower, rd.lower, flinfo))
 1531 peter                     248 UBC           0 :             memcpy(unconstify(GBT_NUMKEY *, ur.lower), rd.lower, tinfo->size);
 1531 peter                     249 CBC       15917 :         if (tinfo->f_lt(ur.upper, rd.upper, flinfo))
                                250           11065 :             memcpy(unconstify(GBT_NUMKEY *, ur.upper), rd.upper, tinfo->size);
                                251                 :     }
 6890 teodor                    252           16049 : }
                                253                 : 
                                254                 : 
                                255                 : 
                                256                 : /*
                                257                 :  * The GiST consistent method
                                258                 :  *
                                259                 :  * Note: we currently assume that no datatypes that use this routine are
                                260                 :  * collation-aware; so we don't bother passing collation through.
                                261                 :  */
                                262                 : bool
 4421 tgl                       263           41286 : gbt_num_consistent(const GBT_NUMKEY_R *key,
                                264                 :                    const void *query,
                                265                 :                    const StrategyNumber *strategy,
                                266                 :                    bool is_leaf,
                                267                 :                    const gbtree_ninfo *tinfo,
                                268                 :                    FmgrInfo *flinfo)
                                269                 : {
                                270                 :     bool        retval;
                                271                 : 
 6797 bruce                     272           41286 :     switch (*strategy)
                                273                 :     {
                                274            7818 :         case BTLessEqualStrategyNumber:
 2040 peter_e                   275            7818 :             retval = tinfo->f_ge(query, key->lower, flinfo);
 6797 bruce                     276            7818 :             break;
                                277            8127 :         case BTLessStrategyNumber:
                                278            8127 :             if (is_leaf)
 2040 peter_e                   279            8044 :                 retval = tinfo->f_gt(query, key->lower, flinfo);
                                280                 :             else
                                281              83 :                 retval = tinfo->f_ge(query, key->lower, flinfo);
 6797 bruce                     282            8127 :             break;
                                283            4887 :         case BTEqualStrategyNumber:
                                284            4887 :             if (is_leaf)
 2040 peter_e                   285            4804 :                 retval = tinfo->f_eq(query, key->lower, flinfo);
                                286                 :             else
                                287             128 :                 retval = (tinfo->f_le(key->lower, query, flinfo) &&
                                288              45 :                           tinfo->f_le(query, key->upper, flinfo));
 6797 bruce                     289            4887 :             break;
                                290           10124 :         case BTGreaterStrategyNumber:
                                291           10124 :             if (is_leaf)
 2040 peter_e                   292           10049 :                 retval = tinfo->f_lt(query, key->upper, flinfo);
                                293                 :             else
                                294              75 :                 retval = tinfo->f_le(query, key->upper, flinfo);
 6797 bruce                     295           10124 :             break;
                                296           10124 :         case BTGreaterEqualStrategyNumber:
 2040 peter_e                   297           10124 :             retval = tinfo->f_le(query, key->upper, flinfo);
 6797 bruce                     298           10124 :             break;
 4633 rhaas                     299             206 :         case BtreeGistNotEqualStrategyNumber:
 2040 peter_e                   300             409 :             retval = (!(tinfo->f_eq(query, key->lower, flinfo) &&
                                301             203 :                         tinfo->f_eq(query, key->upper, flinfo)));
 4633 rhaas                     302             206 :             break;
 6797 bruce                     303 UBC           0 :         default:
 4421 tgl                       304               0 :             retval = false;
                                305                 :     }
                                306                 : 
 2061 peter_e                   307 CBC       41286 :     return retval;
                                308                 : }
                                309                 : 
                                310                 : 
                                311                 : /*
                                312                 : ** The GiST distance method (for KNN-Gist)
                                313                 : */
                                314                 : 
                                315                 : float8
 4421 tgl                       316            2368 : gbt_num_distance(const GBT_NUMKEY_R *key,
                                317                 :                  const void *query,
                                318                 :                  bool is_leaf,
                                319                 :                  const gbtree_ninfo *tinfo,
                                320                 :                  FmgrInfo *flinfo)
                                321                 : {
                                322                 :     float8      retval;
                                323                 : 
                                324            2368 :     if (tinfo->f_dist == NULL)
 4421 tgl                       325 UBC           0 :         elog(ERROR, "KNN search is not supported for btree_gist type %d",
                                326                 :              (int) tinfo->t);
 2210 andrew                    327 CBC        2368 :     if (tinfo->f_le(query, key->lower, flinfo))
                                328            1254 :         retval = tinfo->f_dist(query, key->lower, flinfo);
                                329            1114 :     else if (tinfo->f_ge(query, key->upper, flinfo))
                                330            1102 :         retval = tinfo->f_dist(query, key->upper, flinfo);
                                331                 :     else
 4421 tgl                       332              12 :         retval = 0.0;
                                333                 : 
                                334            2368 :     return retval;
                                335                 : }
                                336                 : 
                                337                 : 
                                338                 : GIST_SPLITVEC *
 6797 bruce                     339              66 : gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
                                340                 :                   const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
                                341                 : {
                                342                 :     OffsetNumber i,
                                343              66 :                 maxoff = entryvec->n - 1;
                                344                 :     Nsrt       *arr;
                                345                 :     int         nbytes;
                                346                 : 
                                347              66 :     arr = (Nsrt *) palloc((maxoff + 1) * sizeof(Nsrt));
                                348              66 :     nbytes = (maxoff + 2) * sizeof(OffsetNumber);
                                349              66 :     v->spl_left = (OffsetNumber *) palloc(nbytes);
                                350              66 :     v->spl_right = (OffsetNumber *) palloc(nbytes);
                                351              66 :     v->spl_ldatum = PointerGetDatum(0);
                                352              66 :     v->spl_rdatum = PointerGetDatum(0);
                                353              66 :     v->spl_nleft = 0;
                                354              66 :     v->spl_nright = 0;
                                355                 : 
                                356                 :     /* Sort entries */
                                357                 : 
                                358           16115 :     for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
                                359                 :     {
                                360           16049 :         arr[i].t = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[i].key));
                                361           16049 :         arr[i].i = i;
                                362                 :     }
   61 peter                     363 GNC          66 :     qsort_arg(&arr[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1, sizeof(Nsrt), (qsort_arg_comparator) tinfo->f_cmp, flinfo);
                                364                 : 
                                365                 :     /* We do simply create two parts */
                                366                 : 
 6797 bruce                     367 CBC       16115 :     for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
                                368                 :     {
                                369           16049 :         if (i <= (maxoff - FirstOffsetNumber + 1) / 2)
                                370                 :         {
 2210 andrew                    371            8017 :             gbt_num_bin_union(&v->spl_ldatum, arr[i].t, tinfo, flinfo);
 6797 bruce                     372            8017 :             v->spl_left[v->spl_nleft] = arr[i].i;
                                373            8017 :             v->spl_nleft++;
                                374                 :         }
                                375                 :         else
                                376                 :         {
 2210 andrew                    377            8032 :             gbt_num_bin_union(&v->spl_rdatum, arr[i].t, tinfo, flinfo);
 6797 bruce                     378            8032 :             v->spl_right[v->spl_nright] = arr[i].i;
                                379            8032 :             v->spl_nright++;
                                380                 :         }
                                381                 :     }
                                382                 : 
                                383              66 :     return v;
                                384                 : }
        

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