LCOV - code coverage report
Current view: top level - contrib/btree_gist - btree_date.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 72 93 77.4 %
Date: 2025-04-24 12:15:10 Functions: 26 28 92.9 %
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/fmgrprotos.h"
       9             : #include "utils/date.h"
      10             : #include "utils/sortsupport.h"
      11             : 
      12             : typedef struct
      13             : {
      14             :     DateADT     lower;
      15             :     DateADT     upper;
      16             : } dateKEY;
      17             : 
      18             : /* GiST support functions */
      19           4 : PG_FUNCTION_INFO_V1(gbt_date_compress);
      20           4 : PG_FUNCTION_INFO_V1(gbt_date_fetch);
      21           4 : PG_FUNCTION_INFO_V1(gbt_date_union);
      22           4 : PG_FUNCTION_INFO_V1(gbt_date_picksplit);
      23           4 : PG_FUNCTION_INFO_V1(gbt_date_consistent);
      24           4 : PG_FUNCTION_INFO_V1(gbt_date_distance);
      25           4 : PG_FUNCTION_INFO_V1(gbt_date_penalty);
      26           4 : PG_FUNCTION_INFO_V1(gbt_date_same);
      27           4 : PG_FUNCTION_INFO_V1(gbt_date_sortsupport);
      28             : 
      29             : static bool
      30        2714 : gbt_dategt(const void *a, const void *b, FmgrInfo *flinfo)
      31             : {
      32        2714 :     return DatumGetBool(DirectFunctionCall2(date_gt,
      33             :                                             DateADTGetDatum(*((const DateADT *) a)),
      34             :                                             DateADTGetDatum(*((const DateADT *) b))));
      35             : }
      36             : 
      37             : static bool
      38        1014 : gbt_datege(const void *a, const void *b, FmgrInfo *flinfo)
      39             : {
      40        1014 :     return DatumGetBool(DirectFunctionCall2(date_ge,
      41             :                                             DateADTGetDatum(*((const DateADT *) a)),
      42             :                                             DateADTGetDatum(*((const DateADT *) b))));
      43             : }
      44             : 
      45             : static bool
      46         544 : gbt_dateeq(const void *a, const void *b, FmgrInfo *flinfo)
      47             : {
      48         544 :     return DatumGetBool(DirectFunctionCall2(date_eq,
      49             :                                             DateADTGetDatum(*((const DateADT *) a)),
      50             :                                             DateADTGetDatum(*((const DateADT *) b)))
      51             :         );
      52             : }
      53             : 
      54             : static bool
      55        1650 : gbt_datele(const void *a, const void *b, FmgrInfo *flinfo)
      56             : {
      57        1650 :     return DatumGetBool(DirectFunctionCall2(date_le,
      58             :                                             DateADTGetDatum(*((const DateADT *) a)),
      59             :                                             DateADTGetDatum(*((const DateADT *) b))));
      60             : }
      61             : 
      62             : static bool
      63        3258 : gbt_datelt(const void *a, const void *b, FmgrInfo *flinfo)
      64             : {
      65        3258 :     return DatumGetBool(DirectFunctionCall2(date_lt,
      66             :                                             DateADTGetDatum(*((const DateADT *) a)),
      67             :                                             DateADTGetDatum(*((const DateADT *) b))));
      68             : }
      69             : 
      70             : 
      71             : 
      72             : static int
      73        1086 : gbt_datekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
      74             : {
      75        1086 :     dateKEY    *ia = (dateKEY *) (((const Nsrt *) a)->t);
      76        1086 :     dateKEY    *ib = (dateKEY *) (((const Nsrt *) b)->t);
      77             :     int         res;
      78             : 
      79        1086 :     res = DatumGetInt32(DirectFunctionCall2(date_cmp,
      80             :                                             DateADTGetDatum(ia->lower),
      81             :                                             DateADTGetDatum(ib->lower)));
      82        1086 :     if (res == 0)
      83          10 :         return DatumGetInt32(DirectFunctionCall2(date_cmp,
      84             :                                                  DateADTGetDatum(ia->upper),
      85             :                                                  DateADTGetDatum(ib->upper)));
      86             : 
      87        1076 :     return res;
      88             : }
      89             : 
      90             : static float8
      91         546 : gdb_date_dist(const void *a, const void *b, FmgrInfo *flinfo)
      92             : {
      93             :     /* we assume the difference can't overflow */
      94         546 :     Datum       diff = DirectFunctionCall2(date_mi,
      95             :                                            DateADTGetDatum(*((const DateADT *) a)),
      96             :                                            DateADTGetDatum(*((const DateADT *) b)));
      97             : 
      98         546 :     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             :  * GiST support functions
     132             :  **************************************************/
     133             : 
     134             : Datum
     135        1092 : gbt_date_compress(PG_FUNCTION_ARGS)
     136             : {
     137        1092 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     138             : 
     139        1092 :     PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
     140             : }
     141             : 
     142             : Datum
     143         544 : gbt_date_fetch(PG_FUNCTION_ARGS)
     144             : {
     145         544 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     146             : 
     147         544 :     PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
     148             : }
     149             : 
     150             : Datum
     151        3828 : gbt_date_consistent(PG_FUNCTION_ARGS)
     152             : {
     153        3828 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     154        3828 :     DateADT     query = PG_GETARG_DATEADT(1);
     155        3828 :     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
     156             : 
     157             :     /* Oid      subtype = PG_GETARG_OID(3); */
     158        3828 :     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
     159        3828 :     dateKEY    *kkk = (dateKEY *) DatumGetPointer(entry->key);
     160             :     GBT_NUMKEY_R key;
     161             : 
     162             :     /* All cases served by this function are exact */
     163        3828 :     *recheck = false;
     164             : 
     165        3828 :     key.lower = (GBT_NUMKEY *) &kkk->lower;
     166        3828 :     key.upper = (GBT_NUMKEY *) &kkk->upper;
     167             : 
     168        3828 :     PG_RETURN_BOOL(gbt_num_consistent(&key, &query, &strategy,
     169             :                                       GIST_LEAF(entry), &tinfo,
     170             :                                       fcinfo->flinfo));
     171             : }
     172             : 
     173             : Datum
     174         548 : gbt_date_distance(PG_FUNCTION_ARGS)
     175             : {
     176         548 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     177         548 :     DateADT     query = PG_GETARG_DATEADT(1);
     178             : 
     179             :     /* Oid      subtype = PG_GETARG_OID(3); */
     180         548 :     dateKEY    *kkk = (dateKEY *) DatumGetPointer(entry->key);
     181             :     GBT_NUMKEY_R key;
     182             : 
     183         548 :     key.lower = (GBT_NUMKEY *) &kkk->lower;
     184         548 :     key.upper = (GBT_NUMKEY *) &kkk->upper;
     185             : 
     186         548 :     PG_RETURN_FLOAT8(gbt_num_distance(&key, &query, GIST_LEAF(entry),
     187             :                                       &tinfo, fcinfo->flinfo));
     188             : }
     189             : 
     190             : Datum
     191           2 : gbt_date_union(PG_FUNCTION_ARGS)
     192             : {
     193           2 :     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
     194           2 :     void       *out = palloc(sizeof(dateKEY));
     195             : 
     196           2 :     *(int *) PG_GETARG_POINTER(1) = sizeof(dateKEY);
     197           2 :     PG_RETURN_POINTER(gbt_num_union(out, entryvec, &tinfo, fcinfo->flinfo));
     198             : }
     199             : 
     200             : Datum
     201           0 : gbt_date_penalty(PG_FUNCTION_ARGS)
     202             : {
     203           0 :     dateKEY    *origentry = (dateKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
     204           0 :     dateKEY    *newentry = (dateKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
     205           0 :     float      *result = (float *) PG_GETARG_POINTER(2);
     206             :     int32       diff,
     207             :                 res;
     208             : 
     209           0 :     diff = DatumGetInt32(DirectFunctionCall2(date_mi,
     210             :                                              DateADTGetDatum(newentry->upper),
     211             :                                              DateADTGetDatum(origentry->upper)));
     212             : 
     213           0 :     res = Max(diff, 0);
     214             : 
     215           0 :     diff = DatumGetInt32(DirectFunctionCall2(date_mi,
     216             :                                              DateADTGetDatum(origentry->lower),
     217             :                                              DateADTGetDatum(newentry->lower)));
     218             : 
     219           0 :     res += Max(diff, 0);
     220             : 
     221           0 :     *result = 0.0;
     222             : 
     223           0 :     if (res > 0)
     224             :     {
     225           0 :         diff = DatumGetInt32(DirectFunctionCall2(date_mi,
     226             :                                                  DateADTGetDatum(origentry->upper),
     227             :                                                  DateADTGetDatum(origentry->lower)));
     228           0 :         *result += FLT_MIN;
     229           0 :         *result += (float) (res / ((double) (res + diff)));
     230           0 :         *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
     231             :     }
     232             : 
     233           0 :     PG_RETURN_POINTER(result);
     234             : }
     235             : 
     236             : Datum
     237           2 : gbt_date_picksplit(PG_FUNCTION_ARGS)
     238             : {
     239           2 :     PG_RETURN_POINTER(gbt_num_picksplit((GistEntryVector *) PG_GETARG_POINTER(0),
     240             :                                         (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
     241             :                                         &tinfo, fcinfo->flinfo));
     242             : }
     243             : 
     244             : Datum
     245           0 : gbt_date_same(PG_FUNCTION_ARGS)
     246             : {
     247           0 :     dateKEY    *b1 = (dateKEY *) PG_GETARG_POINTER(0);
     248           0 :     dateKEY    *b2 = (dateKEY *) PG_GETARG_POINTER(1);
     249           0 :     bool       *result = (bool *) PG_GETARG_POINTER(2);
     250             : 
     251           0 :     *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
     252           0 :     PG_RETURN_POINTER(result);
     253             : }
     254             : 
     255             : static int
     256       10728 : gbt_date_ssup_cmp(Datum x, Datum y, SortSupport ssup)
     257             : {
     258       10728 :     dateKEY    *akey = (dateKEY *) DatumGetPointer(x);
     259       10728 :     dateKEY    *bkey = (dateKEY *) DatumGetPointer(y);
     260             : 
     261             :     /* for leaf items we expect lower == upper, so only compare lower */
     262       10728 :     return DatumGetInt32(DirectFunctionCall2(date_cmp,
     263             :                                              DateADTGetDatum(akey->lower),
     264             :                                              DateADTGetDatum(bkey->lower)));
     265             : }
     266             : 
     267             : Datum
     268           2 : gbt_date_sortsupport(PG_FUNCTION_ARGS)
     269             : {
     270           2 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
     271             : 
     272           2 :     ssup->comparator = gbt_date_ssup_cmp;
     273           2 :     ssup->ssup_extra = NULL;
     274             : 
     275           2 :     PG_RETURN_VOID();
     276             : }

Generated by: LCOV version 1.14