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

Generated by: LCOV version 1.16