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: 2025-08-31 01:17:28 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             : 
     158             :     /* Oid      subtype = PG_GETARG_OID(3); */
     159        3828 :     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
     160        3828 :     dateKEY    *kkk = (dateKEY *) DatumGetPointer(entry->key);
     161             :     GBT_NUMKEY_R key;
     162             : 
     163             :     /* All cases served by this function are exact */
     164        3828 :     *recheck = false;
     165             : 
     166        3828 :     key.lower = (GBT_NUMKEY *) &kkk->lower;
     167        3828 :     key.upper = (GBT_NUMKEY *) &kkk->upper;
     168             : 
     169        3828 :     PG_RETURN_BOOL(gbt_num_consistent(&key, &query, &strategy,
     170             :                                       GIST_LEAF(entry), &tinfo,
     171             :                                       fcinfo->flinfo));
     172             : }
     173             : 
     174             : Datum
     175         548 : gbt_date_distance(PG_FUNCTION_ARGS)
     176             : {
     177         548 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     178         548 :     DateADT     query = PG_GETARG_DATEADT(1);
     179             : 
     180             :     /* Oid      subtype = PG_GETARG_OID(3); */
     181         548 :     dateKEY    *kkk = (dateKEY *) DatumGetPointer(entry->key);
     182             :     GBT_NUMKEY_R key;
     183             : 
     184         548 :     key.lower = (GBT_NUMKEY *) &kkk->lower;
     185         548 :     key.upper = (GBT_NUMKEY *) &kkk->upper;
     186             : 
     187         548 :     PG_RETURN_FLOAT8(gbt_num_distance(&key, &query, GIST_LEAF(entry),
     188             :                                       &tinfo, fcinfo->flinfo));
     189             : }
     190             : 
     191             : Datum
     192           2 : gbt_date_union(PG_FUNCTION_ARGS)
     193             : {
     194           2 :     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
     195           2 :     void       *out = palloc(sizeof(dateKEY));
     196             : 
     197           2 :     *(int *) PG_GETARG_POINTER(1) = sizeof(dateKEY);
     198           2 :     PG_RETURN_POINTER(gbt_num_union(out, entryvec, &tinfo, fcinfo->flinfo));
     199             : }
     200             : 
     201             : Datum
     202           0 : gbt_date_penalty(PG_FUNCTION_ARGS)
     203             : {
     204           0 :     dateKEY    *origentry = (dateKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
     205           0 :     dateKEY    *newentry = (dateKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
     206           0 :     float      *result = (float *) PG_GETARG_POINTER(2);
     207             :     int32       diff,
     208             :                 res;
     209             : 
     210           0 :     diff = DatumGetInt32(DirectFunctionCall2(date_mi,
     211             :                                              DateADTGetDatum(newentry->upper),
     212             :                                              DateADTGetDatum(origentry->upper)));
     213             : 
     214           0 :     res = Max(diff, 0);
     215             : 
     216           0 :     diff = DatumGetInt32(DirectFunctionCall2(date_mi,
     217             :                                              DateADTGetDatum(origentry->lower),
     218             :                                              DateADTGetDatum(newentry->lower)));
     219             : 
     220           0 :     res += Max(diff, 0);
     221             : 
     222           0 :     *result = 0.0;
     223             : 
     224           0 :     if (res > 0)
     225             :     {
     226           0 :         diff = DatumGetInt32(DirectFunctionCall2(date_mi,
     227             :                                                  DateADTGetDatum(origentry->upper),
     228             :                                                  DateADTGetDatum(origentry->lower)));
     229           0 :         *result += FLT_MIN;
     230           0 :         *result += (float) (res / ((double) (res + diff)));
     231           0 :         *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
     232             :     }
     233             : 
     234           0 :     PG_RETURN_POINTER(result);
     235             : }
     236             : 
     237             : Datum
     238           2 : gbt_date_picksplit(PG_FUNCTION_ARGS)
     239             : {
     240           2 :     PG_RETURN_POINTER(gbt_num_picksplit((GistEntryVector *) PG_GETARG_POINTER(0),
     241             :                                         (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
     242             :                                         &tinfo, fcinfo->flinfo));
     243             : }
     244             : 
     245             : Datum
     246           0 : gbt_date_same(PG_FUNCTION_ARGS)
     247             : {
     248           0 :     dateKEY    *b1 = (dateKEY *) PG_GETARG_POINTER(0);
     249           0 :     dateKEY    *b2 = (dateKEY *) PG_GETARG_POINTER(1);
     250           0 :     bool       *result = (bool *) PG_GETARG_POINTER(2);
     251             : 
     252           0 :     *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
     253           0 :     PG_RETURN_POINTER(result);
     254             : }
     255             : 
     256             : static int
     257       10728 : gbt_date_ssup_cmp(Datum x, Datum y, SortSupport ssup)
     258             : {
     259       10728 :     dateKEY    *akey = (dateKEY *) DatumGetPointer(x);
     260       10728 :     dateKEY    *bkey = (dateKEY *) DatumGetPointer(y);
     261             : 
     262             :     /* for leaf items we expect lower == upper, so only compare lower */
     263       10728 :     return DatumGetInt32(DirectFunctionCall2(date_cmp,
     264             :                                              DateADTGetDatum(akey->lower),
     265             :                                              DateADTGetDatum(bkey->lower)));
     266             : }
     267             : 
     268             : Datum
     269           2 : gbt_date_sortsupport(PG_FUNCTION_ARGS)
     270             : {
     271           2 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
     272             : 
     273           2 :     ssup->comparator = gbt_date_ssup_cmp;
     274           2 :     ssup->ssup_extra = NULL;
     275             : 
     276           2 :     PG_RETURN_VOID();
     277             : }

Generated by: LCOV version 1.16