LCOV - code coverage report
Current view: top level - contrib/btree_gist - btree_date.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 83 83 100.0 %
Date: 2024-04-25 06:13:26 Functions: 25 25 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * contrib/btree_gist/btree_date.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             : 
      11             : typedef struct
      12             : {
      13             :     DateADT     lower;
      14             :     DateADT     upper;
      15             : } dateKEY;
      16             : 
      17             : /*
      18             : ** date ops
      19             : */
      20           4 : PG_FUNCTION_INFO_V1(gbt_date_compress);
      21           4 : PG_FUNCTION_INFO_V1(gbt_date_fetch);
      22           4 : PG_FUNCTION_INFO_V1(gbt_date_union);
      23           4 : PG_FUNCTION_INFO_V1(gbt_date_picksplit);
      24           4 : PG_FUNCTION_INFO_V1(gbt_date_consistent);
      25           4 : PG_FUNCTION_INFO_V1(gbt_date_distance);
      26           4 : PG_FUNCTION_INFO_V1(gbt_date_penalty);
      27           4 : PG_FUNCTION_INFO_V1(gbt_date_same);
      28             : 
      29             : static bool
      30        2378 : gbt_dategt(const void *a, const void *b, FmgrInfo *flinfo)
      31             : {
      32        2378 :     return DatumGetBool(DirectFunctionCall2(date_gt,
      33             :                                             DateADTGetDatum(*((const DateADT *) a)),
      34             :                                             DateADTGetDatum(*((const DateADT *) b))));
      35             : }
      36             : 
      37             : static bool
      38        1032 : gbt_datege(const void *a, const void *b, FmgrInfo *flinfo)
      39             : {
      40        1032 :     return DatumGetBool(DirectFunctionCall2(date_ge,
      41             :                                             DateADTGetDatum(*((const DateADT *) a)),
      42             :                                             DateADTGetDatum(*((const DateADT *) b))));
      43             : }
      44             : 
      45             : static bool
      46        1400 : gbt_dateeq(const void *a, const void *b, FmgrInfo *flinfo)
      47             : {
      48        1400 :     return DatumGetBool(DirectFunctionCall2(date_eq,
      49             :                                             DateADTGetDatum(*((const DateADT *) a)),
      50             :                                             DateADTGetDatum(*((const DateADT *) b)))
      51             :         );
      52             : }
      53             : 
      54             : static bool
      55        1668 : gbt_datele(const void *a, const void *b, FmgrInfo *flinfo)
      56             : {
      57        1668 :     return DatumGetBool(DirectFunctionCall2(date_le,
      58             :                                             DateADTGetDatum(*((const DateADT *) a)),
      59             :                                             DateADTGetDatum(*((const DateADT *) b))));
      60             : }
      61             : 
      62             : static bool
      63        2904 : gbt_datelt(const void *a, const void *b, FmgrInfo *flinfo)
      64             : {
      65        2904 :     return DatumGetBool(DirectFunctionCall2(date_lt,
      66             :                                             DateADTGetDatum(*((const DateADT *) a)),
      67             :                                             DateADTGetDatum(*((const DateADT *) b))));
      68             : }
      69             : 
      70             : 
      71             : 
      72             : static int
      73        6218 : gbt_datekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
      74             : {
      75        6218 :     dateKEY    *ia = (dateKEY *) (((const Nsrt *) a)->t);
      76        6218 :     dateKEY    *ib = (dateKEY *) (((const Nsrt *) b)->t);
      77             :     int         res;
      78             : 
      79        6218 :     res = DatumGetInt32(DirectFunctionCall2(date_cmp,
      80             :                                             DateADTGetDatum(ia->lower),
      81             :                                             DateADTGetDatum(ib->lower)));
      82        6218 :     if (res == 0)
      83           2 :         return DatumGetInt32(DirectFunctionCall2(date_cmp,
      84             :                                                  DateADTGetDatum(ia->upper),
      85             :                                                  DateADTGetDatum(ib->upper)));
      86             : 
      87        6216 :     return res;
      88             : }
      89             : 
      90             : static float8
      91         564 : gdb_date_dist(const void *a, const void *b, FmgrInfo *flinfo)
      92             : {
      93             :     /* we assume the difference can't overflow */
      94         564 :     Datum       diff = DirectFunctionCall2(date_mi,
      95             :                                            DateADTGetDatum(*((const DateADT *) a)),
      96             :                                            DateADTGetDatum(*((const DateADT *) b)));
      97             : 
      98         564 :     return (float8) abs(DatumGetInt32(diff));
      99             : }
     100             : 
     101             : 
     102             : static const gbtree_ninfo tinfo =
     103             : {
     104             :     gbt_t_date,
     105             :     sizeof(DateADT),
     106             :     8,                          /* sizeof(gbtreekey8) */
     107             :     gbt_dategt,
     108             :     gbt_datege,
     109             :     gbt_dateeq,
     110             :     gbt_datele,
     111             :     gbt_datelt,
     112             :     gbt_datekey_cmp,
     113             :     gdb_date_dist
     114             : };
     115             : 
     116             : 
     117           4 : PG_FUNCTION_INFO_V1(date_dist);
     118             : Datum
     119        1094 : date_dist(PG_FUNCTION_ARGS)
     120             : {
     121             :     /* we assume the difference can't overflow */
     122        1094 :     Datum       diff = DirectFunctionCall2(date_mi,
     123             :                                            PG_GETARG_DATUM(0),
     124             :                                            PG_GETARG_DATUM(1));
     125             : 
     126        1094 :     PG_RETURN_INT32(abs(DatumGetInt32(diff)));
     127             : }
     128             : 
     129             : 
     130             : /**************************************************
     131             :  * date ops
     132             :  **************************************************/
     133             : 
     134             : 
     135             : 
     136             : Datum
     137        1096 : gbt_date_compress(PG_FUNCTION_ARGS)
     138             : {
     139        1096 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     140             : 
     141        1096 :     PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
     142             : }
     143             : 
     144             : Datum
     145         562 : gbt_date_fetch(PG_FUNCTION_ARGS)
     146             : {
     147         562 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     148             : 
     149         562 :     PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
     150             : }
     151             : 
     152             : Datum
     153        3882 : gbt_date_consistent(PG_FUNCTION_ARGS)
     154             : {
     155        3882 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     156        3882 :     DateADT     query = PG_GETARG_DATEADT(1);
     157        3882 :     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
     158             : 
     159             :     /* Oid      subtype = PG_GETARG_OID(3); */
     160        3882 :     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
     161        3882 :     dateKEY    *kkk = (dateKEY *) DatumGetPointer(entry->key);
     162             :     GBT_NUMKEY_R key;
     163             : 
     164             :     /* All cases served by this function are exact */
     165        3882 :     *recheck = false;
     166             : 
     167        3882 :     key.lower = (GBT_NUMKEY *) &kkk->lower;
     168        3882 :     key.upper = (GBT_NUMKEY *) &kkk->upper;
     169             : 
     170        3882 :     PG_RETURN_BOOL(gbt_num_consistent(&key, (void *) &query, &strategy,
     171             :                                       GIST_LEAF(entry), &tinfo,
     172             :                                       fcinfo->flinfo));
     173             : }
     174             : 
     175             : 
     176             : Datum
     177         566 : gbt_date_distance(PG_FUNCTION_ARGS)
     178             : {
     179         566 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     180         566 :     DateADT     query = PG_GETARG_DATEADT(1);
     181             : 
     182             :     /* Oid      subtype = PG_GETARG_OID(3); */
     183         566 :     dateKEY    *kkk = (dateKEY *) DatumGetPointer(entry->key);
     184             :     GBT_NUMKEY_R key;
     185             : 
     186         566 :     key.lower = (GBT_NUMKEY *) &kkk->lower;
     187         566 :     key.upper = (GBT_NUMKEY *) &kkk->upper;
     188             : 
     189         566 :     PG_RETURN_FLOAT8(gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry),
     190             :                                       &tinfo, fcinfo->flinfo));
     191             : }
     192             : 
     193             : 
     194             : Datum
     195         422 : gbt_date_union(PG_FUNCTION_ARGS)
     196             : {
     197         422 :     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
     198         422 :     void       *out = palloc(sizeof(dateKEY));
     199             : 
     200         422 :     *(int *) PG_GETARG_POINTER(1) = sizeof(dateKEY);
     201         422 :     PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
     202             : }
     203             : 
     204             : 
     205             : Datum
     206         658 : gbt_date_penalty(PG_FUNCTION_ARGS)
     207             : {
     208         658 :     dateKEY    *origentry = (dateKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
     209         658 :     dateKEY    *newentry = (dateKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
     210         658 :     float      *result = (float *) PG_GETARG_POINTER(2);
     211             :     int32       diff,
     212             :                 res;
     213             : 
     214         658 :     diff = DatumGetInt32(DirectFunctionCall2(date_mi,
     215             :                                              DateADTGetDatum(newentry->upper),
     216             :                                              DateADTGetDatum(origentry->upper)));
     217             : 
     218         658 :     res = Max(diff, 0);
     219             : 
     220         658 :     diff = DatumGetInt32(DirectFunctionCall2(date_mi,
     221             :                                              DateADTGetDatum(origentry->lower),
     222             :                                              DateADTGetDatum(newentry->lower)));
     223             : 
     224         658 :     res += Max(diff, 0);
     225             : 
     226         658 :     *result = 0.0;
     227             : 
     228         658 :     if (res > 0)
     229             :     {
     230         240 :         diff = DatumGetInt32(DirectFunctionCall2(date_mi,
     231             :                                                  DateADTGetDatum(origentry->upper),
     232             :                                                  DateADTGetDatum(origentry->lower)));
     233         240 :         *result += FLT_MIN;
     234         240 :         *result += (float) (res / ((double) (res + diff)));
     235         240 :         *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
     236             :     }
     237             : 
     238         658 :     PG_RETURN_POINTER(result);
     239             : }
     240             : 
     241             : 
     242             : Datum
     243           2 : gbt_date_picksplit(PG_FUNCTION_ARGS)
     244             : {
     245           2 :     PG_RETURN_POINTER(gbt_num_picksplit((GistEntryVector *) PG_GETARG_POINTER(0),
     246             :                                         (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
     247             :                                         &tinfo, fcinfo->flinfo));
     248             : }
     249             : 
     250             : Datum
     251         420 : gbt_date_same(PG_FUNCTION_ARGS)
     252             : {
     253         420 :     dateKEY    *b1 = (dateKEY *) PG_GETARG_POINTER(0);
     254         420 :     dateKEY    *b2 = (dateKEY *) PG_GETARG_POINTER(1);
     255         420 :     bool       *result = (bool *) PG_GETARG_POINTER(2);
     256             : 
     257         420 :     *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
     258         420 :     PG_RETURN_POINTER(result);
     259             : }

Generated by: LCOV version 1.14