LCOV - code coverage report
Current view: top level - contrib/btree_gist - btree_inet.c (source / functions) Hit Total Coverage
Test: PostgreSQL 19devel Lines: 76 80 95.0 %
Date: 2025-08-19 14:18:13 Functions: 21 21 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * contrib/btree_gist/btree_inet.c
       3             :  */
       4             : #include "postgres.h"
       5             : 
       6             : #include "btree_gist.h"
       7             : #include "btree_utils_num.h"
       8             : #include "catalog/pg_type.h"
       9             : #include "utils/builtins.h"
      10             : #include "utils/rel.h"
      11             : #include "utils/sortsupport.h"
      12             : 
      13             : typedef struct inetkey
      14             : {
      15             :     double      lower;
      16             :     double      upper;
      17             : } inetKEY;
      18             : 
      19             : /* GiST support functions */
      20          10 : PG_FUNCTION_INFO_V1(gbt_inet_compress);
      21          10 : PG_FUNCTION_INFO_V1(gbt_inet_union);
      22          10 : PG_FUNCTION_INFO_V1(gbt_inet_picksplit);
      23          10 : PG_FUNCTION_INFO_V1(gbt_inet_consistent);
      24          10 : PG_FUNCTION_INFO_V1(gbt_inet_penalty);
      25          10 : PG_FUNCTION_INFO_V1(gbt_inet_same);
      26          10 : PG_FUNCTION_INFO_V1(gbt_inet_sortsupport);
      27             : 
      28             : 
      29             : static bool
      30       11994 : gbt_inetgt(const void *a, const void *b, FmgrInfo *flinfo)
      31             : {
      32       11994 :     return (*((const double *) a) > *((const double *) b));
      33             : }
      34             : static bool
      35        1232 : gbt_inetge(const void *a, const void *b, FmgrInfo *flinfo)
      36             : {
      37        1232 :     return (*((const double *) a) >= *((const double *) b));
      38             : }
      39             : static bool
      40        2844 : gbt_ineteq(const void *a, const void *b, FmgrInfo *flinfo)
      41             : {
      42        2844 :     return (*((const double *) a) == *((const double *) b));
      43             : }
      44             : static bool
      45        1880 : gbt_inetle(const void *a, const void *b, FmgrInfo *flinfo)
      46             : {
      47        1880 :     return (*((const double *) a) <= *((const double *) b));
      48             : }
      49             : static bool
      50       12594 : gbt_inetlt(const void *a, const void *b, FmgrInfo *flinfo)
      51             : {
      52       12594 :     return (*((const double *) a) < *((const double *) b));
      53             : }
      54             : 
      55             : static int
      56       14816 : gbt_inetkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
      57             : {
      58       14816 :     inetKEY    *ia = (inetKEY *) (((const Nsrt *) a)->t);
      59       14816 :     inetKEY    *ib = (inetKEY *) (((const Nsrt *) b)->t);
      60             : 
      61       14816 :     if (ia->lower == ib->lower)
      62             :     {
      63           0 :         if (ia->upper == ib->upper)
      64           0 :             return 0;
      65             : 
      66           0 :         return (ia->upper > ib->upper) ? 1 : -1;
      67             :     }
      68             : 
      69       14816 :     return (ia->lower > ib->lower) ? 1 : -1;
      70             : }
      71             : 
      72             : 
      73             : static const gbtree_ninfo tinfo =
      74             : {
      75             :     gbt_t_inet,
      76             :     sizeof(double),
      77             :     16,                         /* sizeof(gbtreekey16) */
      78             :     gbt_inetgt,
      79             :     gbt_inetge,
      80             :     gbt_ineteq,
      81             :     gbt_inetle,
      82             :     gbt_inetlt,
      83             :     gbt_inetkey_cmp,
      84             :     NULL
      85             : };
      86             : 
      87             : 
      88             : /**************************************************
      89             :  * GiST support functions
      90             :  **************************************************/
      91             : 
      92             : Datum
      93        3638 : gbt_inet_compress(PG_FUNCTION_ARGS)
      94             : {
      95        3638 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
      96             :     GISTENTRY  *retval;
      97             : 
      98        3638 :     if (entry->leafkey)
      99             :     {
     100        3600 :         inetKEY    *r = (inetKEY *) palloc(sizeof(inetKEY));
     101        3600 :         bool        failure = false;
     102             : 
     103        3600 :         retval = palloc(sizeof(GISTENTRY));
     104        3600 :         r->lower = convert_network_to_scalar(entry->key, INETOID, &failure);
     105             :         Assert(!failure);
     106        3600 :         r->upper = r->lower;
     107        3600 :         gistentryinit(*retval, PointerGetDatum(r),
     108             :                       entry->rel, entry->page,
     109             :                       entry->offset, false);
     110             :     }
     111             :     else
     112          38 :         retval = entry;
     113             : 
     114        3638 :     PG_RETURN_POINTER(retval);
     115             : }
     116             : 
     117             : Datum
     118        7308 : gbt_inet_consistent(PG_FUNCTION_ARGS)
     119             : {
     120        7308 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     121        7308 :     Datum       dquery = PG_GETARG_DATUM(1);
     122        7308 :     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
     123             : 
     124             :     /* Oid      subtype = PG_GETARG_OID(3); */
     125        7308 :     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
     126        7308 :     inetKEY    *kkk = (inetKEY *) DatumGetPointer(entry->key);
     127             :     GBT_NUMKEY_R key;
     128             :     double      query;
     129        7308 :     bool        failure = false;
     130             : 
     131        7308 :     query = convert_network_to_scalar(dquery, INETOID, &failure);
     132             :     Assert(!failure);
     133             : 
     134             :     /* All cases served by this function are inexact */
     135        7308 :     *recheck = true;
     136             : 
     137        7308 :     key.lower = (GBT_NUMKEY *) &kkk->lower;
     138        7308 :     key.upper = (GBT_NUMKEY *) &kkk->upper;
     139             : 
     140        7308 :     PG_RETURN_BOOL(gbt_num_consistent(&key, &query,
     141             :                                       &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
     142             : }
     143             : 
     144             : Datum
     145         834 : gbt_inet_union(PG_FUNCTION_ARGS)
     146             : {
     147         834 :     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
     148         834 :     void       *out = palloc(sizeof(inetKEY));
     149             : 
     150         834 :     *(int *) PG_GETARG_POINTER(1) = sizeof(inetKEY);
     151         834 :     PG_RETURN_POINTER(gbt_num_union(out, entryvec, &tinfo, fcinfo->flinfo));
     152             : }
     153             : 
     154             : Datum
     155        3548 : gbt_inet_penalty(PG_FUNCTION_ARGS)
     156             : {
     157        3548 :     inetKEY    *origentry = (inetKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
     158        3548 :     inetKEY    *newentry = (inetKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
     159        3548 :     float      *result = (float *) PG_GETARG_POINTER(2);
     160             : 
     161        3548 :     penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
     162             : 
     163        3548 :     PG_RETURN_POINTER(result);
     164             : }
     165             : 
     166             : Datum
     167          18 : gbt_inet_picksplit(PG_FUNCTION_ARGS)
     168             : {
     169          18 :     PG_RETURN_POINTER(gbt_num_picksplit((GistEntryVector *) PG_GETARG_POINTER(0),
     170             :                                         (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
     171             :                                         &tinfo, fcinfo->flinfo));
     172             : }
     173             : 
     174             : Datum
     175         822 : gbt_inet_same(PG_FUNCTION_ARGS)
     176             : {
     177         822 :     inetKEY    *b1 = (inetKEY *) PG_GETARG_POINTER(0);
     178         822 :     inetKEY    *b2 = (inetKEY *) PG_GETARG_POINTER(1);
     179         822 :     bool       *result = (bool *) PG_GETARG_POINTER(2);
     180             : 
     181         822 :     *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
     182         822 :     PG_RETURN_POINTER(result);
     183             : }
     184             : 
     185             : static int
     186       24108 : gbt_inet_ssup_cmp(Datum x, Datum y, SortSupport ssup)
     187             : {
     188       24108 :     inetKEY    *arg1 = (inetKEY *) DatumGetPointer(x);
     189       24108 :     inetKEY    *arg2 = (inetKEY *) DatumGetPointer(y);
     190             : 
     191             :     /* for leaf items we expect lower == upper, so only compare lower */
     192       24108 :     if (arg1->lower < arg2->lower)
     193       13168 :         return -1;
     194       10940 :     else if (arg1->lower > arg2->lower)
     195       10940 :         return 1;
     196             :     else
     197           0 :         return 0;
     198             : }
     199             : 
     200             : Datum
     201           4 : gbt_inet_sortsupport(PG_FUNCTION_ARGS)
     202             : {
     203           4 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
     204             : 
     205           4 :     ssup->comparator = gbt_inet_ssup_cmp;
     206           4 :     ssup->ssup_extra = NULL;
     207             : 
     208           4 :     PG_RETURN_VOID();
     209             : }

Generated by: LCOV version 1.16