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

Generated by: LCOV version 1.14