LCOV - differential code coverage report
Current view: top level - contrib/btree_gist - btree_ts.c (source / functions) Coverage Total Hit GNC CBC DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 100.0 % 151 151 1 150 1
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 34 34 1 33
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_ts.c
       3                 :  */
       4                 : #include "postgres.h"
       5                 : 
       6                 : #include <limits.h>
       7                 : 
       8                 : #include "btree_gist.h"
       9                 : #include "btree_utils_num.h"
      10                 : #include "utils/builtins.h"
      11                 : #include "utils/datetime.h"
      12                 : #include "utils/float.h"
      13                 : 
      14                 : typedef struct
      15                 : {
      16                 :     Timestamp   lower;
      17                 :     Timestamp   upper;
      18                 : } tsKEY;
      19                 : 
      20                 : /*
      21                 : ** timestamp ops
      22                 : */
      23 CBC           3 : PG_FUNCTION_INFO_V1(gbt_ts_compress);
      24               2 : PG_FUNCTION_INFO_V1(gbt_tstz_compress);
      25               4 : PG_FUNCTION_INFO_V1(gbt_ts_fetch);
      26               4 : PG_FUNCTION_INFO_V1(gbt_ts_union);
      27               4 : PG_FUNCTION_INFO_V1(gbt_ts_picksplit);
      28               3 : PG_FUNCTION_INFO_V1(gbt_ts_consistent);
      29               3 : PG_FUNCTION_INFO_V1(gbt_ts_distance);
      30               2 : PG_FUNCTION_INFO_V1(gbt_tstz_consistent);
      31               2 : PG_FUNCTION_INFO_V1(gbt_tstz_distance);
      32               4 : PG_FUNCTION_INFO_V1(gbt_ts_penalty);
      33               4 : PG_FUNCTION_INFO_V1(gbt_ts_same);
      34                 : 
      35                 : 
      36                 : #ifdef USE_FLOAT8_BYVAL
      37                 : #define TimestampGetDatumFast(X) TimestampGetDatum(X)
      38                 : #else
      39                 : #define TimestampGetDatumFast(X) PointerGetDatum(&(X))
      40                 : #endif
      41                 : 
      42                 : 
      43                 : static bool
      44           12512 : gbt_tsgt(const void *a, const void *b, FmgrInfo *flinfo)
      45                 : {
      46           12512 :     const Timestamp *aa = (const Timestamp *) a;
      47           12512 :     const Timestamp *bb = (const Timestamp *) b;
      48                 : 
      49           12512 :     return DatumGetBool(DirectFunctionCall2(timestamp_gt,
      50                 :                                             TimestampGetDatumFast(*aa),
      51                 :                                             TimestampGetDatumFast(*bb)));
      52                 : }
      53                 : 
      54                 : static bool
      55            1851 : gbt_tsge(const void *a, const void *b, FmgrInfo *flinfo)
      56                 : {
      57            1851 :     const Timestamp *aa = (const Timestamp *) a;
      58            1851 :     const Timestamp *bb = (const Timestamp *) b;
      59                 : 
      60            1851 :     return DatumGetBool(DirectFunctionCall2(timestamp_ge,
      61                 :                                             TimestampGetDatumFast(*aa),
      62                 :                                             TimestampGetDatumFast(*bb)));
      63                 : }
      64                 : 
      65                 : static bool
      66            6043 : gbt_tseq(const void *a, const void *b, FmgrInfo *flinfo)
      67                 : {
      68            6043 :     const Timestamp *aa = (const Timestamp *) a;
      69            6043 :     const Timestamp *bb = (const Timestamp *) b;
      70                 : 
      71            6043 :     return DatumGetBool(DirectFunctionCall2(timestamp_eq,
      72                 :                                             TimestampGetDatumFast(*aa),
      73                 :                                             TimestampGetDatumFast(*bb)));
      74                 : }
      75                 : 
      76                 : static bool
      77            1774 : gbt_tsle(const void *a, const void *b, FmgrInfo *flinfo)
      78                 : {
      79            1774 :     const Timestamp *aa = (const Timestamp *) a;
      80            1774 :     const Timestamp *bb = (const Timestamp *) b;
      81                 : 
      82            1774 :     return DatumGetBool(DirectFunctionCall2(timestamp_le,
      83                 :                                             TimestampGetDatumFast(*aa),
      84                 :                                             TimestampGetDatumFast(*bb)));
      85                 : }
      86                 : 
      87                 : static bool
      88           12325 : gbt_tslt(const void *a, const void *b, FmgrInfo *flinfo)
      89                 : {
      90           12325 :     const Timestamp *aa = (const Timestamp *) a;
      91           12325 :     const Timestamp *bb = (const Timestamp *) b;
      92                 : 
      93           12325 :     return DatumGetBool(DirectFunctionCall2(timestamp_lt,
      94                 :                                             TimestampGetDatumFast(*aa),
      95                 :                                             TimestampGetDatumFast(*bb)));
      96                 : }
      97                 : 
      98                 : 
      99                 : static int
     100           12958 : gbt_tskey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
     101                 : {
     102           12958 :     tsKEY      *ia = (tsKEY *) (((const Nsrt *) a)->t);
     103           12958 :     tsKEY      *ib = (tsKEY *) (((const Nsrt *) b)->t);
     104                 :     int         res;
     105                 : 
     106           12958 :     res = DatumGetInt32(DirectFunctionCall2(timestamp_cmp, TimestampGetDatumFast(ia->lower), TimestampGetDatumFast(ib->lower)));
     107           12958 :     if (res == 0)
     108            3849 :         return DatumGetInt32(DirectFunctionCall2(timestamp_cmp, TimestampGetDatumFast(ia->upper), TimestampGetDatumFast(ib->upper)));
     109                 : 
     110            9109 :     return res;
     111                 : }
     112                 : 
     113                 : static float8
     114             368 : gbt_ts_dist(const void *a, const void *b, FmgrInfo *flinfo)
     115                 : {
     116             368 :     const Timestamp *aa = (const Timestamp *) a;
     117             368 :     const Timestamp *bb = (const Timestamp *) b;
     118                 :     Interval   *i;
     119                 : 
     120             368 :     if (TIMESTAMP_NOT_FINITE(*aa) || TIMESTAMP_NOT_FINITE(*bb))
     121              30 :         return get_float8_infinity();
     122                 : 
     123             338 :     i = DatumGetIntervalP(DirectFunctionCall2(timestamp_mi,
     124                 :                                               TimestampGetDatumFast(*aa),
     125                 :                                               TimestampGetDatumFast(*bb)));
     126 GNC         338 :     return fabs(INTERVAL_TO_SEC(i));
     127                 : }
     128                 : 
     129                 : 
     130                 : static const gbtree_ninfo tinfo =
     131                 : {
     132                 :     gbt_t_ts,
     133                 :     sizeof(Timestamp),
     134                 :     16,                         /* sizeof(gbtreekey16) */
     135                 :     gbt_tsgt,
     136                 :     gbt_tsge,
     137                 :     gbt_tseq,
     138                 :     gbt_tsle,
     139                 :     gbt_tslt,
     140                 :     gbt_tskey_cmp,
     141                 :     gbt_ts_dist
     142                 : };
     143                 : 
     144                 : 
     145 CBC           2 : PG_FUNCTION_INFO_V1(ts_dist);
     146                 : Datum
     147             571 : ts_dist(PG_FUNCTION_ARGS)
     148                 : {
     149             571 :     Timestamp   a = PG_GETARG_TIMESTAMP(0);
     150             571 :     Timestamp   b = PG_GETARG_TIMESTAMP(1);
     151                 :     Interval   *r;
     152                 : 
     153             571 :     if (TIMESTAMP_NOT_FINITE(a) || TIMESTAMP_NOT_FINITE(b))
     154                 :     {
     155              24 :         Interval   *p = palloc(sizeof(Interval));
     156                 : 
     157              24 :         p->day = INT_MAX;
     158              24 :         p->month = INT_MAX;
     159              24 :         p->time = PG_INT64_MAX;
     160              24 :         PG_RETURN_INTERVAL_P(p);
     161                 :     }
     162                 :     else
     163             547 :         r = DatumGetIntervalP(DirectFunctionCall2(timestamp_mi,
     164                 :                                                   PG_GETARG_DATUM(0),
     165                 :                                                   PG_GETARG_DATUM(1)));
     166             547 :     PG_RETURN_INTERVAL_P(abs_interval(r));
     167                 : }
     168                 : 
     169               2 : PG_FUNCTION_INFO_V1(tstz_dist);
     170                 : Datum
     171             552 : tstz_dist(PG_FUNCTION_ARGS)
     172                 : {
     173             552 :     TimestampTz a = PG_GETARG_TIMESTAMPTZ(0);
     174             552 :     TimestampTz b = PG_GETARG_TIMESTAMPTZ(1);
     175                 :     Interval   *r;
     176                 : 
     177             552 :     if (TIMESTAMP_NOT_FINITE(a) || TIMESTAMP_NOT_FINITE(b))
     178                 :     {
     179              18 :         Interval   *p = palloc(sizeof(Interval));
     180                 : 
     181              18 :         p->day = INT_MAX;
     182              18 :         p->month = INT_MAX;
     183              18 :         p->time = PG_INT64_MAX;
     184              18 :         PG_RETURN_INTERVAL_P(p);
     185                 :     }
     186                 : 
     187             534 :     r = DatumGetIntervalP(DirectFunctionCall2(timestamp_mi,
     188                 :                                               PG_GETARG_DATUM(0),
     189                 :                                               PG_GETARG_DATUM(1)));
     190             534 :     PG_RETURN_INTERVAL_P(abs_interval(r));
     191                 : }
     192                 : 
     193                 : 
     194                 : /**************************************************
     195                 :  * timestamp ops
     196                 :  **************************************************/
     197                 : 
     198                 : 
     199                 : static inline Timestamp
     200            5531 : tstz_to_ts_gmt(TimestampTz ts)
     201                 : {
     202                 :     /* No timezone correction is needed, since GMT is offset 0 by definition */
     203            5531 :     return (Timestamp) ts;
     204                 : }
     205                 : 
     206                 : 
     207                 : Datum
     208            2619 : gbt_ts_compress(PG_FUNCTION_ARGS)
     209                 : {
     210            2619 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     211                 : 
     212            2619 :     PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
     213                 : }
     214                 : 
     215                 : 
     216                 : Datum
     217             557 : gbt_tstz_compress(PG_FUNCTION_ARGS)
     218                 : {
     219             557 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     220                 :     GISTENTRY  *retval;
     221                 : 
     222             557 :     if (entry->leafkey)
     223                 :     {
     224             549 :         tsKEY      *r = (tsKEY *) palloc(sizeof(tsKEY));
     225             549 :         TimestampTz ts = DatumGetTimestampTz(entry->key);
     226                 :         Timestamp   gmt;
     227                 : 
     228             549 :         gmt = tstz_to_ts_gmt(ts);
     229                 : 
     230             549 :         retval = palloc(sizeof(GISTENTRY));
     231             549 :         r->lower = r->upper = gmt;
     232             549 :         gistentryinit(*retval, PointerGetDatum(r),
     233                 :                       entry->rel, entry->page,
     234                 :                       entry->offset, false);
     235                 :     }
     236                 :     else
     237               8 :         retval = entry;
     238                 : 
     239             557 :     PG_RETURN_POINTER(retval);
     240                 : }
     241                 : 
     242                 : Datum
     243             364 : gbt_ts_fetch(PG_FUNCTION_ARGS)
     244                 : {
     245             364 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     246                 : 
     247             364 :     PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
     248                 : }
     249                 : 
     250                 : Datum
     251            1957 : gbt_ts_consistent(PG_FUNCTION_ARGS)
     252                 : {
     253            1957 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     254            1957 :     Timestamp   query = PG_GETARG_TIMESTAMP(1);
     255            1957 :     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
     256                 : 
     257                 :     /* Oid      subtype = PG_GETARG_OID(3); */
     258            1957 :     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
     259            1957 :     tsKEY      *kkk = (tsKEY *) DatumGetPointer(entry->key);
     260                 :     GBT_NUMKEY_R key;
     261                 : 
     262                 :     /* All cases served by this function are exact */
     263            1957 :     *recheck = false;
     264                 : 
     265            1957 :     key.lower = (GBT_NUMKEY *) &kkk->lower;
     266            1957 :     key.upper = (GBT_NUMKEY *) &kkk->upper;
     267                 : 
     268            1957 :     PG_RETURN_BOOL(gbt_num_consistent(&key, (void *) &query, &strategy,
     269                 :                                       GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
     270                 : }
     271                 : 
     272                 : Datum
     273             203 : gbt_ts_distance(PG_FUNCTION_ARGS)
     274                 : {
     275             203 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     276             203 :     Timestamp   query = PG_GETARG_TIMESTAMP(1);
     277                 : 
     278                 :     /* Oid      subtype = PG_GETARG_OID(3); */
     279             203 :     tsKEY      *kkk = (tsKEY *) DatumGetPointer(entry->key);
     280                 :     GBT_NUMKEY_R key;
     281                 : 
     282             203 :     key.lower = (GBT_NUMKEY *) &kkk->lower;
     283             203 :     key.upper = (GBT_NUMKEY *) &kkk->upper;
     284                 : 
     285             203 :     PG_RETURN_FLOAT8(gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry),
     286                 :                                       &tinfo, fcinfo->flinfo));
     287                 : }
     288                 : 
     289                 : Datum
     290            4815 : gbt_tstz_consistent(PG_FUNCTION_ARGS)
     291                 : {
     292            4815 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     293            4815 :     TimestampTz query = PG_GETARG_TIMESTAMPTZ(1);
     294            4815 :     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
     295                 : 
     296                 :     /* Oid      subtype = PG_GETARG_OID(3); */
     297            4815 :     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
     298            4815 :     char       *kkk = (char *) DatumGetPointer(entry->key);
     299                 :     GBT_NUMKEY_R key;
     300                 :     Timestamp   qqq;
     301                 : 
     302                 :     /* All cases served by this function are exact */
     303            4815 :     *recheck = false;
     304                 : 
     305            4815 :     key.lower = (GBT_NUMKEY *) &kkk[0];
     306            4815 :     key.upper = (GBT_NUMKEY *) &kkk[MAXALIGN(tinfo.size)];
     307            4815 :     qqq = tstz_to_ts_gmt(query);
     308                 : 
     309            4815 :     PG_RETURN_BOOL(gbt_num_consistent(&key, (void *) &qqq, &strategy,
     310                 :                                       GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
     311                 : }
     312                 : 
     313                 : Datum
     314             167 : gbt_tstz_distance(PG_FUNCTION_ARGS)
     315                 : {
     316             167 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     317             167 :     TimestampTz query = PG_GETARG_TIMESTAMPTZ(1);
     318                 : 
     319                 :     /* Oid      subtype = PG_GETARG_OID(3); */
     320             167 :     char       *kkk = (char *) DatumGetPointer(entry->key);
     321                 :     GBT_NUMKEY_R key;
     322                 :     Timestamp   qqq;
     323                 : 
     324             167 :     key.lower = (GBT_NUMKEY *) &kkk[0];
     325             167 :     key.upper = (GBT_NUMKEY *) &kkk[MAXALIGN(tinfo.size)];
     326             167 :     qqq = tstz_to_ts_gmt(query);
     327                 : 
     328             167 :     PG_RETURN_FLOAT8(gbt_num_distance(&key, (void *) &qqq, GIST_LEAF(entry),
     329                 :                                       &tinfo, fcinfo->flinfo));
     330                 : }
     331                 : 
     332                 : 
     333                 : Datum
     334            2497 : gbt_ts_union(PG_FUNCTION_ARGS)
     335                 : {
     336            2497 :     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
     337            2497 :     void       *out = palloc(sizeof(tsKEY));
     338                 : 
     339            2497 :     *(int *) PG_GETARG_POINTER(1) = sizeof(tsKEY);
     340            2497 :     PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
     341                 : }
     342                 : 
     343                 : 
     344                 : #define penalty_check_max_float(val) \
     345                 :     do { \
     346                 :         if ( val > FLT_MAX ) \
     347                 :                 val = FLT_MAX; \
     348                 :         if ( val < -FLT_MAX ) \
     349                 :                 val = -FLT_MAX; \
     350                 :     } while (0)
     351                 : 
     352                 : 
     353                 : Datum
     354            5019 : gbt_ts_penalty(PG_FUNCTION_ARGS)
     355                 : {
     356            5019 :     tsKEY      *origentry = (tsKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
     357            5019 :     tsKEY      *newentry = (tsKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
     358            5019 :     float      *result = (float *) PG_GETARG_POINTER(2);
     359                 : 
     360                 :     double      orgdbl[2],
     361                 :                 newdbl[2];
     362                 : 
     363                 :     /*
     364                 :      * We are always using "double" timestamps here. Precision should be good
     365                 :      * enough.
     366                 :      */
     367            5019 :     orgdbl[0] = ((double) origentry->lower);
     368            5019 :     orgdbl[1] = ((double) origentry->upper);
     369            5019 :     newdbl[0] = ((double) newentry->lower);
     370            5019 :     newdbl[1] = ((double) newentry->upper);
     371                 : 
     372            5019 :     penalty_check_max_float(orgdbl[0]);
     373            5019 :     penalty_check_max_float(orgdbl[1]);
     374            5019 :     penalty_check_max_float(newdbl[0]);
     375            5019 :     penalty_check_max_float(newdbl[1]);
     376                 : 
     377            5019 :     penalty_num(result, orgdbl[0], orgdbl[1], newdbl[0], newdbl[1]);
     378                 : 
     379            5019 :     PG_RETURN_POINTER(result);
     380                 : }
     381                 : 
     382                 : 
     383                 : Datum
     384              23 : gbt_ts_picksplit(PG_FUNCTION_ARGS)
     385                 : {
     386              23 :     PG_RETURN_POINTER(gbt_num_picksplit((GistEntryVector *) PG_GETARG_POINTER(0),
     387                 :                                         (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
     388                 :                                         &tinfo, fcinfo->flinfo));
     389                 : }
     390                 : 
     391                 : Datum
     392            2474 : gbt_ts_same(PG_FUNCTION_ARGS)
     393                 : {
     394            2474 :     tsKEY      *b1 = (tsKEY *) PG_GETARG_POINTER(0);
     395            2474 :     tsKEY      *b2 = (tsKEY *) PG_GETARG_POINTER(1);
     396            2474 :     bool       *result = (bool *) PG_GETARG_POINTER(2);
     397                 : 
     398            2474 :     *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
     399            2474 :     PG_RETURN_POINTER(result);
     400                 : }
        

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