LCOV - differential code coverage report
Current view: top level - contrib/btree_gist - btree_interval.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 96.0 % 100 96 4 3 93 3
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 29 29 2 27
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*
       2                 :  * contrib/btree_gist/btree_interval.c
       3                 :  */
       4                 : #include "postgres.h"
       5                 : 
       6                 : #include "btree_gist.h"
       7                 : #include "btree_utils_num.h"
       8                 : #include "utils/builtins.h"
       9                 : #include "utils/timestamp.h"
      10                 : 
      11                 : typedef struct
      12                 : {
      13                 :     Interval    lower,
      14                 :                 upper;
      15                 : } intvKEY;
      16                 : 
      17                 : 
      18                 : /*
      19                 : ** Interval ops
      20                 : */
      21 CBC           2 : PG_FUNCTION_INFO_V1(gbt_intv_compress);
      22               2 : PG_FUNCTION_INFO_V1(gbt_intv_fetch);
      23               2 : PG_FUNCTION_INFO_V1(gbt_intv_decompress);
      24               2 : PG_FUNCTION_INFO_V1(gbt_intv_union);
      25               2 : PG_FUNCTION_INFO_V1(gbt_intv_picksplit);
      26               2 : PG_FUNCTION_INFO_V1(gbt_intv_consistent);
      27               2 : PG_FUNCTION_INFO_V1(gbt_intv_distance);
      28               2 : PG_FUNCTION_INFO_V1(gbt_intv_penalty);
      29               2 : PG_FUNCTION_INFO_V1(gbt_intv_same);
      30                 : 
      31                 : 
      32                 : static bool
      33            1554 : gbt_intvgt(const void *a, const void *b, FmgrInfo *flinfo)
      34                 : {
      35            1554 :     return DatumGetBool(DirectFunctionCall2(interval_gt, IntervalPGetDatum(a), IntervalPGetDatum(b)));
      36                 : }
      37                 : 
      38                 : static bool
      39             500 : gbt_intvge(const void *a, const void *b, FmgrInfo *flinfo)
      40                 : {
      41             500 :     return DatumGetBool(DirectFunctionCall2(interval_ge, IntervalPGetDatum(a), IntervalPGetDatum(b)));
      42                 : }
      43                 : 
      44                 : static bool
      45            1009 : gbt_intveq(const void *a, const void *b, FmgrInfo *flinfo)
      46                 : {
      47            1009 :     return DatumGetBool(DirectFunctionCall2(interval_eq, IntervalPGetDatum(a), IntervalPGetDatum(b)));
      48                 : }
      49                 : 
      50                 : static bool
      51             595 : gbt_intvle(const void *a, const void *b, FmgrInfo *flinfo)
      52                 : {
      53             595 :     return DatumGetBool(DirectFunctionCall2(interval_le, IntervalPGetDatum(a), IntervalPGetDatum(b)));
      54                 : }
      55                 : 
      56                 : static bool
      57            1378 : gbt_intvlt(const void *a, const void *b, FmgrInfo *flinfo)
      58                 : {
      59            1378 :     return DatumGetBool(DirectFunctionCall2(interval_lt, IntervalPGetDatum(a), IntervalPGetDatum(b)));
      60                 : }
      61                 : 
      62                 : static int
      63            3977 : gbt_intvkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
      64                 : {
      65            3977 :     intvKEY    *ia = (intvKEY *) (((const Nsrt *) a)->t);
      66            3977 :     intvKEY    *ib = (intvKEY *) (((const Nsrt *) b)->t);
      67                 :     int         res;
      68                 : 
      69            3977 :     res = DatumGetInt32(DirectFunctionCall2(interval_cmp, IntervalPGetDatum(&ia->lower), IntervalPGetDatum(&ib->lower)));
      70            3977 :     if (res == 0)
      71 UBC           0 :         return DatumGetInt32(DirectFunctionCall2(interval_cmp, IntervalPGetDatum(&ia->upper), IntervalPGetDatum(&ib->upper)));
      72                 : 
      73 CBC        3977 :     return res;
      74                 : }
      75                 : 
      76                 : 
      77                 : static double
      78            5236 : intr2num(const Interval *i)
      79                 : {
      80            5236 :     return INTERVAL_TO_SEC(i);
      81                 : }
      82                 : 
      83                 : static float8
      84             294 : gbt_intv_dist(const void *a, const void *b, FmgrInfo *flinfo)
      85                 : {
      86 GNC         294 :     return fabs(intr2num((const Interval *) a) - intr2num((const Interval *) b));
      87                 : }
      88                 : 
      89                 : /*
      90                 :  * INTERVALSIZE should be the actual size-on-disk of an Interval, as shown
      91                 :  * in pg_type.  This might be less than sizeof(Interval) if the compiler
      92                 :  * insists on adding alignment padding at the end of the struct.  (Note:
      93                 :  * this concern is obsolete with the current definition of Interval, but
      94                 :  * was real before a separate "day" field was added to it.)
      95                 :  */
      96                 : #define INTERVALSIZE 16
      97                 : 
      98                 : static const gbtree_ninfo tinfo =
      99                 : {
     100                 :     gbt_t_intv,
     101                 :     sizeof(Interval),
     102                 :     32,                         /* sizeof(gbtreekey32) */
     103                 :     gbt_intvgt,
     104                 :     gbt_intvge,
     105                 :     gbt_intveq,
     106                 :     gbt_intvle,
     107                 :     gbt_intvlt,
     108                 :     gbt_intvkey_cmp,
     109                 :     gbt_intv_dist
     110                 : };
     111                 : 
     112                 : 
     113                 : Interval *
     114 CBC        2234 : abs_interval(Interval *a)
     115                 : {
     116                 :     static Interval zero = {0, 0, 0};
     117                 : 
     118            2234 :     if (DatumGetBool(DirectFunctionCall2(interval_lt,
     119                 :                                          IntervalPGetDatum(a),
     120                 :                                          IntervalPGetDatum(&zero))))
     121            1239 :         a = DatumGetIntervalP(DirectFunctionCall1(interval_um,
     122                 :                                                   IntervalPGetDatum(a)));
     123                 : 
     124            2234 :     return a;
     125                 : }
     126                 : 
     127               2 : PG_FUNCTION_INFO_V1(interval_dist);
     128                 : Datum
     129             606 : interval_dist(PG_FUNCTION_ARGS)
     130                 : {
     131             606 :     Datum       diff = DirectFunctionCall2(interval_mi,
     132                 :                                            PG_GETARG_DATUM(0),
     133                 :                                            PG_GETARG_DATUM(1));
     134                 : 
     135             606 :     PG_RETURN_INTERVAL_P(abs_interval(DatumGetIntervalP(diff)));
     136                 : }
     137                 : 
     138                 : 
     139                 : /**************************************************
     140                 :  * interval ops
     141                 :  **************************************************/
     142                 : 
     143                 : 
     144                 : Datum
     145             613 : gbt_intv_compress(PG_FUNCTION_ARGS)
     146                 : {
     147             613 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     148             613 :     GISTENTRY  *retval = entry;
     149                 : 
     150             613 :     if (entry->leafkey || INTERVALSIZE != sizeof(Interval))
     151                 :     {
     152             600 :         char       *r = (char *) palloc(2 * INTERVALSIZE);
     153                 : 
     154             600 :         retval = palloc(sizeof(GISTENTRY));
     155                 : 
     156             600 :         if (entry->leafkey)
     157                 :         {
     158             600 :             Interval   *key = DatumGetIntervalP(entry->key);
     159                 : 
     160 GNC         600 :             memcpy(r, key, INTERVALSIZE);
     161             600 :             memcpy(r + INTERVALSIZE, key, INTERVALSIZE);
     162                 :         }
     163                 :         else
     164                 :         {
     165 UBC           0 :             intvKEY    *key = (intvKEY *) DatumGetPointer(entry->key);
     166                 : 
     167               0 :             memcpy(r, &key->lower, INTERVALSIZE);
     168               0 :             memcpy(r + INTERVALSIZE, &key->upper, INTERVALSIZE);
     169                 :         }
     170 CBC         600 :         gistentryinit(*retval, PointerGetDatum(r),
     171                 :                       entry->rel, entry->page,
     172                 :                       entry->offset, false);
     173                 :     }
     174                 : 
     175             613 :     PG_RETURN_POINTER(retval);
     176                 : }
     177                 : 
     178                 : Datum
     179             144 : gbt_intv_fetch(PG_FUNCTION_ARGS)
     180                 : {
     181             144 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     182                 : 
     183             144 :     PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
     184                 : }
     185                 : 
     186                 : Datum
     187            5253 : gbt_intv_decompress(PG_FUNCTION_ARGS)
     188                 : {
     189            5253 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     190            5253 :     GISTENTRY  *retval = entry;
     191                 : 
     192                 :     if (INTERVALSIZE != sizeof(Interval))
     193                 :     {
     194                 :         intvKEY    *r = palloc(sizeof(intvKEY));
     195                 :         char       *key = DatumGetPointer(entry->key);
     196                 : 
     197                 :         retval = palloc(sizeof(GISTENTRY));
     198                 :         memcpy(&r->lower, key, INTERVALSIZE);
     199                 :         memcpy(&r->upper, key + INTERVALSIZE, INTERVALSIZE);
     200                 : 
     201                 :         gistentryinit(*retval, PointerGetDatum(r),
     202                 :                       entry->rel, entry->page,
     203                 :                       entry->offset, false);
     204                 :     }
     205            5253 :     PG_RETURN_POINTER(retval);
     206                 : }
     207                 : 
     208                 : 
     209                 : Datum
     210            1652 : gbt_intv_consistent(PG_FUNCTION_ARGS)
     211                 : {
     212            1652 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     213            1652 :     Interval   *query = PG_GETARG_INTERVAL_P(1);
     214            1652 :     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
     215                 : 
     216                 :     /* Oid      subtype = PG_GETARG_OID(3); */
     217            1652 :     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
     218            1652 :     intvKEY    *kkk = (intvKEY *) DatumGetPointer(entry->key);
     219                 :     GBT_NUMKEY_R key;
     220                 : 
     221                 :     /* All cases served by this function are exact */
     222            1652 :     *recheck = false;
     223                 : 
     224            1652 :     key.lower = (GBT_NUMKEY *) &kkk->lower;
     225            1652 :     key.upper = (GBT_NUMKEY *) &kkk->upper;
     226                 : 
     227            1652 :     PG_RETURN_BOOL(gbt_num_consistent(&key, (void *) query, &strategy,
     228                 :                                       GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
     229                 : }
     230                 : 
     231                 : 
     232                 : Datum
     233             296 : gbt_intv_distance(PG_FUNCTION_ARGS)
     234                 : {
     235             296 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     236             296 :     Interval   *query = PG_GETARG_INTERVAL_P(1);
     237                 : 
     238                 :     /* Oid      subtype = PG_GETARG_OID(3); */
     239             296 :     intvKEY    *kkk = (intvKEY *) DatumGetPointer(entry->key);
     240                 :     GBT_NUMKEY_R key;
     241                 : 
     242             296 :     key.lower = (GBT_NUMKEY *) &kkk->lower;
     243             296 :     key.upper = (GBT_NUMKEY *) &kkk->upper;
     244                 : 
     245             296 :     PG_RETURN_FLOAT8(gbt_num_distance(&key, (void *) query, GIST_LEAF(entry),
     246                 :                                       &tinfo, fcinfo->flinfo));
     247                 : }
     248                 : 
     249                 : 
     250                 : Datum
     251             436 : gbt_intv_union(PG_FUNCTION_ARGS)
     252                 : {
     253             436 :     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
     254             436 :     void       *out = palloc(sizeof(intvKEY));
     255                 : 
     256             436 :     *(int *) PG_GETARG_POINTER(1) = sizeof(intvKEY);
     257             436 :     PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
     258                 : }
     259                 : 
     260                 : 
     261                 : Datum
     262            1162 : gbt_intv_penalty(PG_FUNCTION_ARGS)
     263                 : {
     264            1162 :     intvKEY    *origentry = (intvKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
     265            1162 :     intvKEY    *newentry = (intvKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
     266            1162 :     float      *result = (float *) PG_GETARG_POINTER(2);
     267                 :     double      iorg[2],
     268                 :                 inew[2];
     269                 : 
     270            1162 :     iorg[0] = intr2num(&origentry->lower);
     271            1162 :     iorg[1] = intr2num(&origentry->upper);
     272            1162 :     inew[0] = intr2num(&newentry->lower);
     273            1162 :     inew[1] = intr2num(&newentry->upper);
     274                 : 
     275            1162 :     penalty_num(result, iorg[0], iorg[1], inew[0], inew[1]);
     276                 : 
     277            1162 :     PG_RETURN_POINTER(result);
     278                 : }
     279                 : 
     280                 : Datum
     281               3 : gbt_intv_picksplit(PG_FUNCTION_ARGS)
     282                 : {
     283               3 :     PG_RETURN_POINTER(gbt_num_picksplit((GistEntryVector *) PG_GETARG_POINTER(0),
     284                 :                                         (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
     285                 :                                         &tinfo, fcinfo->flinfo));
     286                 : }
     287                 : 
     288                 : Datum
     289             435 : gbt_intv_same(PG_FUNCTION_ARGS)
     290                 : {
     291             435 :     intvKEY    *b1 = (intvKEY *) PG_GETARG_POINTER(0);
     292             435 :     intvKEY    *b2 = (intvKEY *) PG_GETARG_POINTER(1);
     293             435 :     bool       *result = (bool *) PG_GETARG_POINTER(2);
     294                 : 
     295             435 :     *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
     296             435 :     PG_RETURN_POINTER(result);
     297                 : }
        

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