LCOV - differential code coverage report
Current view: top level - contrib/btree_gist - btree_time.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 99.2 % 122 121 1 1 120 1
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 29 29 1 28
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_time.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/date.h"
      10                 : #include "utils/timestamp.h"
      11                 : 
      12                 : typedef struct
      13                 : {
      14                 :     TimeADT     lower;
      15                 :     TimeADT     upper;
      16                 : } timeKEY;
      17                 : 
      18                 : /*
      19                 : ** time ops
      20                 : */
      21 CBC           2 : PG_FUNCTION_INFO_V1(gbt_time_compress);
      22               2 : PG_FUNCTION_INFO_V1(gbt_timetz_compress);
      23               2 : PG_FUNCTION_INFO_V1(gbt_time_fetch);
      24               3 : PG_FUNCTION_INFO_V1(gbt_time_union);
      25               3 : PG_FUNCTION_INFO_V1(gbt_time_picksplit);
      26               2 : PG_FUNCTION_INFO_V1(gbt_time_consistent);
      27               2 : PG_FUNCTION_INFO_V1(gbt_time_distance);
      28               2 : PG_FUNCTION_INFO_V1(gbt_timetz_consistent);
      29               3 : PG_FUNCTION_INFO_V1(gbt_time_penalty);
      30               3 : PG_FUNCTION_INFO_V1(gbt_time_same);
      31                 : 
      32                 : 
      33                 : #ifdef USE_FLOAT8_BYVAL
      34                 : #define TimeADTGetDatumFast(X) TimeADTGetDatum(X)
      35                 : #else
      36                 : #define TimeADTGetDatumFast(X) PointerGetDatum(&(X))
      37                 : #endif
      38                 : 
      39                 : 
      40                 : static bool
      41            3179 : gbt_timegt(const void *a, const void *b, FmgrInfo *flinfo)
      42                 : {
      43            3179 :     const TimeADT *aa = (const TimeADT *) a;
      44            3179 :     const TimeADT *bb = (const TimeADT *) b;
      45                 : 
      46            3179 :     return DatumGetBool(DirectFunctionCall2(time_gt,
      47                 :                                             TimeADTGetDatumFast(*aa),
      48                 :                                             TimeADTGetDatumFast(*bb)));
      49                 : }
      50                 : 
      51                 : static bool
      52            1199 : gbt_timege(const void *a, const void *b, FmgrInfo *flinfo)
      53                 : {
      54            1199 :     const TimeADT *aa = (const TimeADT *) a;
      55            1199 :     const TimeADT *bb = (const TimeADT *) b;
      56                 : 
      57            1199 :     return DatumGetBool(DirectFunctionCall2(time_ge,
      58                 :                                             TimeADTGetDatumFast(*aa),
      59                 :                                             TimeADTGetDatumFast(*bb)));
      60                 : }
      61                 : 
      62                 : static bool
      63            1853 : gbt_timeeq(const void *a, const void *b, FmgrInfo *flinfo)
      64                 : {
      65            1853 :     const TimeADT *aa = (const TimeADT *) a;
      66            1853 :     const TimeADT *bb = (const TimeADT *) b;
      67                 : 
      68            1853 :     return DatumGetBool(DirectFunctionCall2(time_eq,
      69                 :                                             TimeADTGetDatumFast(*aa),
      70                 :                                             TimeADTGetDatumFast(*bb)));
      71                 : }
      72                 : 
      73                 : static bool
      74            1919 : gbt_timele(const void *a, const void *b, FmgrInfo *flinfo)
      75                 : {
      76            1919 :     const TimeADT *aa = (const TimeADT *) a;
      77            1919 :     const TimeADT *bb = (const TimeADT *) b;
      78                 : 
      79            1919 :     return DatumGetBool(DirectFunctionCall2(time_le,
      80                 :                                             TimeADTGetDatumFast(*aa),
      81                 :                                             TimeADTGetDatumFast(*bb)));
      82                 : }
      83                 : 
      84                 : static bool
      85            3846 : gbt_timelt(const void *a, const void *b, FmgrInfo *flinfo)
      86                 : {
      87            3846 :     const TimeADT *aa = (const TimeADT *) a;
      88            3846 :     const TimeADT *bb = (const TimeADT *) b;
      89                 : 
      90            3846 :     return DatumGetBool(DirectFunctionCall2(time_lt,
      91                 :                                             TimeADTGetDatumFast(*aa),
      92                 :                                             TimeADTGetDatumFast(*bb)));
      93                 : }
      94                 : 
      95                 : 
      96                 : 
      97                 : static int
      98            9061 : gbt_timekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
      99                 : {
     100            9061 :     timeKEY    *ia = (timeKEY *) (((const Nsrt *) a)->t);
     101            9061 :     timeKEY    *ib = (timeKEY *) (((const Nsrt *) b)->t);
     102                 :     int         res;
     103                 : 
     104            9061 :     res = DatumGetInt32(DirectFunctionCall2(time_cmp, TimeADTGetDatumFast(ia->lower), TimeADTGetDatumFast(ib->lower)));
     105            9061 :     if (res == 0)
     106 UBC           0 :         return DatumGetInt32(DirectFunctionCall2(time_cmp, TimeADTGetDatumFast(ia->upper), TimeADTGetDatumFast(ib->upper)));
     107                 : 
     108 CBC        9061 :     return res;
     109                 : }
     110                 : 
     111                 : static float8
     112             144 : gbt_time_dist(const void *a, const void *b, FmgrInfo *flinfo)
     113                 : {
     114             144 :     const TimeADT *aa = (const TimeADT *) a;
     115             144 :     const TimeADT *bb = (const TimeADT *) b;
     116                 :     Interval   *i;
     117                 : 
     118             144 :     i = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
     119                 :                                               TimeADTGetDatumFast(*aa),
     120                 :                                               TimeADTGetDatumFast(*bb)));
     121 GNC         144 :     return fabs(INTERVAL_TO_SEC(i));
     122                 : }
     123                 : 
     124                 : 
     125                 : static const gbtree_ninfo tinfo =
     126                 : {
     127                 :     gbt_t_time,
     128                 :     sizeof(TimeADT),
     129                 :     16,                         /* sizeof(gbtreekey16) */
     130                 :     gbt_timegt,
     131                 :     gbt_timege,
     132                 :     gbt_timeeq,
     133                 :     gbt_timele,
     134                 :     gbt_timelt,
     135                 :     gbt_timekey_cmp,
     136                 :     gbt_time_dist
     137                 : };
     138                 : 
     139                 : 
     140 CBC           2 : PG_FUNCTION_INFO_V1(time_dist);
     141                 : Datum
     142             547 : time_dist(PG_FUNCTION_ARGS)
     143                 : {
     144             547 :     Datum       diff = DirectFunctionCall2(time_mi_time,
     145                 :                                            PG_GETARG_DATUM(0),
     146                 :                                            PG_GETARG_DATUM(1));
     147                 : 
     148             547 :     PG_RETURN_INTERVAL_P(abs_interval(DatumGetIntervalP(diff)));
     149                 : }
     150                 : 
     151                 : 
     152                 : /**************************************************
     153                 :  * time ops
     154                 :  **************************************************/
     155                 : 
     156                 : 
     157                 : 
     158                 : Datum
     159             553 : gbt_time_compress(PG_FUNCTION_ARGS)
     160                 : {
     161             553 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     162                 : 
     163             553 :     PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
     164                 : }
     165                 : 
     166                 : 
     167                 : Datum
     168             538 : gbt_timetz_compress(PG_FUNCTION_ARGS)
     169                 : {
     170             538 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     171                 :     GISTENTRY  *retval;
     172                 : 
     173             538 :     if (entry->leafkey)
     174                 :     {
     175             531 :         timeKEY    *r = (timeKEY *) palloc(sizeof(timeKEY));
     176             531 :         TimeTzADT  *tz = DatumGetTimeTzADTP(entry->key);
     177                 :         TimeADT     tmp;
     178                 : 
     179             531 :         retval = palloc(sizeof(GISTENTRY));
     180                 : 
     181                 :         /* We are using the time + zone only to compress */
     182             531 :         tmp = tz->time + (tz->zone * INT64CONST(1000000));
     183             531 :         r->lower = r->upper = tmp;
     184             531 :         gistentryinit(*retval, PointerGetDatum(r),
     185                 :                       entry->rel, entry->page,
     186                 :                       entry->offset, false);
     187                 :     }
     188                 :     else
     189               7 :         retval = entry;
     190             538 :     PG_RETURN_POINTER(retval);
     191                 : }
     192                 : 
     193                 : Datum
     194             142 : gbt_time_fetch(PG_FUNCTION_ARGS)
     195                 : {
     196             142 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     197                 : 
     198             142 :     PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
     199                 : }
     200                 : 
     201                 : Datum
     202            1529 : gbt_time_consistent(PG_FUNCTION_ARGS)
     203                 : {
     204            1529 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     205            1529 :     TimeADT     query = PG_GETARG_TIMEADT(1);
     206            1529 :     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
     207                 : 
     208                 :     /* Oid      subtype = PG_GETARG_OID(3); */
     209            1529 :     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
     210            1529 :     timeKEY    *kkk = (timeKEY *) DatumGetPointer(entry->key);
     211                 :     GBT_NUMKEY_R key;
     212                 : 
     213                 :     /* All cases served by this function are exact */
     214            1529 :     *recheck = false;
     215                 : 
     216            1529 :     key.lower = (GBT_NUMKEY *) &kkk->lower;
     217            1529 :     key.upper = (GBT_NUMKEY *) &kkk->upper;
     218                 : 
     219            1529 :     PG_RETURN_BOOL(gbt_num_consistent(&key, (void *) &query, &strategy,
     220                 :                                       GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
     221                 : }
     222                 : 
     223                 : Datum
     224             145 : gbt_time_distance(PG_FUNCTION_ARGS)
     225                 : {
     226             145 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     227             145 :     TimeADT     query = PG_GETARG_TIMEADT(1);
     228                 : 
     229                 :     /* Oid      subtype = PG_GETARG_OID(3); */
     230             145 :     timeKEY    *kkk = (timeKEY *) DatumGetPointer(entry->key);
     231                 :     GBT_NUMKEY_R key;
     232                 : 
     233             145 :     key.lower = (GBT_NUMKEY *) &kkk->lower;
     234             145 :     key.upper = (GBT_NUMKEY *) &kkk->upper;
     235                 : 
     236             145 :     PG_RETURN_FLOAT8(gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry),
     237                 :                                       &tinfo, fcinfo->flinfo));
     238                 : }
     239                 : 
     240                 : Datum
     241            4791 : gbt_timetz_consistent(PG_FUNCTION_ARGS)
     242                 : {
     243            4791 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     244            4791 :     TimeTzADT  *query = PG_GETARG_TIMETZADT_P(1);
     245            4791 :     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
     246                 : 
     247                 :     /* Oid      subtype = PG_GETARG_OID(3); */
     248            4791 :     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
     249            4791 :     timeKEY    *kkk = (timeKEY *) DatumGetPointer(entry->key);
     250                 :     TimeADT     qqq;
     251                 :     GBT_NUMKEY_R key;
     252                 : 
     253                 :     /* All cases served by this function are inexact */
     254            4791 :     *recheck = true;
     255                 : 
     256            4791 :     qqq = query->time + (query->zone * INT64CONST(1000000));
     257                 : 
     258            4791 :     key.lower = (GBT_NUMKEY *) &kkk->lower;
     259            4791 :     key.upper = (GBT_NUMKEY *) &kkk->upper;
     260                 : 
     261            4791 :     PG_RETURN_BOOL(gbt_num_consistent(&key, (void *) &qqq, &strategy,
     262                 :                                       GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
     263                 : }
     264                 : 
     265                 : 
     266                 : Datum
     267             599 : gbt_time_union(PG_FUNCTION_ARGS)
     268                 : {
     269             599 :     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
     270             599 :     void       *out = palloc(sizeof(timeKEY));
     271                 : 
     272             599 :     *(int *) PG_GETARG_POINTER(1) = sizeof(timeKEY);
     273             599 :     PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
     274                 : }
     275                 : 
     276                 : 
     277                 : Datum
     278            1055 : gbt_time_penalty(PG_FUNCTION_ARGS)
     279                 : {
     280            1055 :     timeKEY    *origentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
     281            1055 :     timeKEY    *newentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
     282            1055 :     float      *result = (float *) PG_GETARG_POINTER(2);
     283                 :     Interval   *intr;
     284                 :     double      res;
     285                 :     double      res2;
     286                 : 
     287            1055 :     intr = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
     288                 :                                                  TimeADTGetDatumFast(newentry->upper),
     289                 :                                                  TimeADTGetDatumFast(origentry->upper)));
     290            1055 :     res = INTERVAL_TO_SEC(intr);
     291            1055 :     res = Max(res, 0);
     292                 : 
     293            1055 :     intr = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
     294                 :                                                  TimeADTGetDatumFast(origentry->lower),
     295                 :                                                  TimeADTGetDatumFast(newentry->lower)));
     296            1055 :     res2 = INTERVAL_TO_SEC(intr);
     297            1055 :     res2 = Max(res2, 0);
     298                 : 
     299            1055 :     res += res2;
     300                 : 
     301            1055 :     *result = 0.0;
     302                 : 
     303            1055 :     if (res > 0)
     304                 :     {
     305             464 :         intr = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
     306                 :                                                      TimeADTGetDatumFast(origentry->upper),
     307                 :                                                      TimeADTGetDatumFast(origentry->lower)));
     308             464 :         *result += FLT_MIN;
     309             464 :         *result += (float) (res / (res + INTERVAL_TO_SEC(intr)));
     310             464 :         *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
     311                 :     }
     312                 : 
     313            1055 :     PG_RETURN_POINTER(result);
     314                 : }
     315                 : 
     316                 : 
     317                 : Datum
     318               4 : gbt_time_picksplit(PG_FUNCTION_ARGS)
     319                 : {
     320               4 :     PG_RETURN_POINTER(gbt_num_picksplit((GistEntryVector *) PG_GETARG_POINTER(0),
     321                 :                                         (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
     322                 :                                         &tinfo, fcinfo->flinfo));
     323                 : }
     324                 : 
     325                 : Datum
     326             597 : gbt_time_same(PG_FUNCTION_ARGS)
     327                 : {
     328             597 :     timeKEY    *b1 = (timeKEY *) PG_GETARG_POINTER(0);
     329             597 :     timeKEY    *b2 = (timeKEY *) PG_GETARG_POINTER(1);
     330             597 :     bool       *result = (bool *) PG_GETARG_POINTER(2);
     331                 : 
     332             597 :     *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
     333             597 :     PG_RETURN_POINTER(result);
     334                 : }
        

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