LCOV - code coverage report
Current view: top level - contrib/btree_gist - btree_int4.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 78 92 84.8 %
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_int4.c
       3             :  */
       4             : #include "postgres.h"
       5             : #include "btree_gist.h"
       6             : #include "btree_utils_num.h"
       7             : #include "common/int.h"
       8             : #include "utils/sortsupport.h"
       9             : 
      10             : typedef struct int32key
      11             : {
      12             :     int32       lower;
      13             :     int32       upper;
      14             : } int32KEY;
      15             : 
      16             : /* GiST support functions */
      17          10 : PG_FUNCTION_INFO_V1(gbt_int4_compress);
      18          10 : PG_FUNCTION_INFO_V1(gbt_int4_fetch);
      19          10 : PG_FUNCTION_INFO_V1(gbt_int4_union);
      20          10 : PG_FUNCTION_INFO_V1(gbt_int4_picksplit);
      21          10 : PG_FUNCTION_INFO_V1(gbt_int4_consistent);
      22          10 : PG_FUNCTION_INFO_V1(gbt_int4_distance);
      23          10 : PG_FUNCTION_INFO_V1(gbt_int4_penalty);
      24          10 : PG_FUNCTION_INFO_V1(gbt_int4_same);
      25          10 : PG_FUNCTION_INFO_V1(gbt_int4_sortsupport);
      26             : 
      27             : static bool
      28        3270 : gbt_int4gt(const void *a, const void *b, FmgrInfo *flinfo)
      29             : {
      30        3270 :     return (*((const int32 *) a) > *((const int32 *) b));
      31             : }
      32             : static bool
      33        1152 : gbt_int4ge(const void *a, const void *b, FmgrInfo *flinfo)
      34             : {
      35        1152 :     return (*((const int32 *) a) >= *((const int32 *) b));
      36             : }
      37             : static bool
      38         716 : gbt_int4eq(const void *a, const void *b, FmgrInfo *flinfo)
      39             : {
      40         716 :     return (*((const int32 *) a) == *((const int32 *) b));
      41             : }
      42             : static bool
      43        1112 : gbt_int4le(const void *a, const void *b, FmgrInfo *flinfo)
      44             : {
      45        1112 :     return (*((const int32 *) a) <= *((const int32 *) b));
      46             : }
      47             : static bool
      48        2724 : gbt_int4lt(const void *a, const void *b, FmgrInfo *flinfo)
      49             : {
      50        2724 :     return (*((const int32 *) a) < *((const int32 *) b));
      51             : }
      52             : 
      53             : static int
      54        1090 : gbt_int4key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
      55             : {
      56        1090 :     int32KEY   *ia = (int32KEY *) (((const Nsrt *) a)->t);
      57        1090 :     int32KEY   *ib = (int32KEY *) (((const Nsrt *) b)->t);
      58             : 
      59        1090 :     if (ia->lower == ib->lower)
      60             :     {
      61          28 :         if (ia->upper == ib->upper)
      62          28 :             return 0;
      63             : 
      64           0 :         return (ia->upper > ib->upper) ? 1 : -1;
      65             :     }
      66             : 
      67        1062 :     return (ia->lower > ib->lower) ? 1 : -1;
      68             : }
      69             : 
      70             : static float8
      71         548 : gbt_int4_dist(const void *a, const void *b, FmgrInfo *flinfo)
      72             : {
      73         548 :     return GET_FLOAT_DISTANCE(int32, a, b);
      74             : }
      75             : 
      76             : 
      77             : static const gbtree_ninfo tinfo =
      78             : {
      79             :     gbt_t_int4,
      80             :     sizeof(int32),
      81             :     8,                          /* sizeof(gbtreekey8) */
      82             :     gbt_int4gt,
      83             :     gbt_int4ge,
      84             :     gbt_int4eq,
      85             :     gbt_int4le,
      86             :     gbt_int4lt,
      87             :     gbt_int4key_cmp,
      88             :     gbt_int4_dist
      89             : };
      90             : 
      91             : 
      92           4 : PG_FUNCTION_INFO_V1(int4_dist);
      93             : Datum
      94        1098 : int4_dist(PG_FUNCTION_ARGS)
      95             : {
      96        1098 :     int32       a = PG_GETARG_INT32(0);
      97        1098 :     int32       b = PG_GETARG_INT32(1);
      98             :     int32       r;
      99             :     int32       ra;
     100             : 
     101        1098 :     if (pg_sub_s32_overflow(a, b, &r) ||
     102        1098 :         r == PG_INT32_MIN)
     103           0 :         ereport(ERROR,
     104             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     105             :                  errmsg("integer out of range")));
     106             : 
     107        1098 :     ra = abs(r);
     108             : 
     109        1098 :     PG_RETURN_INT32(ra);
     110             : }
     111             : 
     112             : 
     113             : /**************************************************
     114             :  * GiST support functions
     115             :  **************************************************/
     116             : 
     117             : Datum
     118        1140 : gbt_int4_compress(PG_FUNCTION_ARGS)
     119             : {
     120        1140 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     121             : 
     122        1140 :     PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
     123             : }
     124             : 
     125             : Datum
     126         546 : gbt_int4_fetch(PG_FUNCTION_ARGS)
     127             : {
     128         546 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     129             : 
     130         546 :     PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
     131             : }
     132             : 
     133             : Datum
     134        4012 : gbt_int4_consistent(PG_FUNCTION_ARGS)
     135             : {
     136        4012 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     137        4012 :     int32       query = PG_GETARG_INT32(1);
     138        4012 :     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
     139             : 
     140             :     /* Oid      subtype = PG_GETARG_OID(3); */
     141        4012 :     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
     142        4012 :     int32KEY   *kkk = (int32KEY *) DatumGetPointer(entry->key);
     143             :     GBT_NUMKEY_R key;
     144             : 
     145             :     /* All cases served by this function are exact */
     146        4012 :     *recheck = false;
     147             : 
     148        4012 :     key.lower = (GBT_NUMKEY *) &kkk->lower;
     149        4012 :     key.upper = (GBT_NUMKEY *) &kkk->upper;
     150             : 
     151        4012 :     PG_RETURN_BOOL(gbt_num_consistent(&key, &query, &strategy,
     152             :                                       GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
     153             : }
     154             : 
     155             : Datum
     156         550 : gbt_int4_distance(PG_FUNCTION_ARGS)
     157             : {
     158         550 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     159         550 :     int32       query = PG_GETARG_INT32(1);
     160             : 
     161             :     /* Oid      subtype = PG_GETARG_OID(3); */
     162         550 :     int32KEY   *kkk = (int32KEY *) DatumGetPointer(entry->key);
     163             :     GBT_NUMKEY_R key;
     164             : 
     165         550 :     key.lower = (GBT_NUMKEY *) &kkk->lower;
     166         550 :     key.upper = (GBT_NUMKEY *) &kkk->upper;
     167             : 
     168         550 :     PG_RETURN_FLOAT8(gbt_num_distance(&key, &query, GIST_LEAF(entry),
     169             :                                       &tinfo, fcinfo->flinfo));
     170             : }
     171             : 
     172             : Datum
     173           2 : gbt_int4_union(PG_FUNCTION_ARGS)
     174             : {
     175           2 :     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
     176           2 :     void       *out = palloc(sizeof(int32KEY));
     177             : 
     178           2 :     *(int *) PG_GETARG_POINTER(1) = sizeof(int32KEY);
     179           2 :     PG_RETURN_POINTER(gbt_num_union(out, entryvec, &tinfo, fcinfo->flinfo));
     180             : }
     181             : 
     182             : Datum
     183           0 : gbt_int4_penalty(PG_FUNCTION_ARGS)
     184             : {
     185           0 :     int32KEY   *origentry = (int32KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
     186           0 :     int32KEY   *newentry = (int32KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
     187           0 :     float      *result = (float *) PG_GETARG_POINTER(2);
     188             : 
     189           0 :     penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
     190             : 
     191           0 :     PG_RETURN_POINTER(result);
     192             : }
     193             : 
     194             : Datum
     195           2 : gbt_int4_picksplit(PG_FUNCTION_ARGS)
     196             : {
     197           2 :     PG_RETURN_POINTER(gbt_num_picksplit((GistEntryVector *) PG_GETARG_POINTER(0),
     198             :                                         (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
     199             :                                         &tinfo, fcinfo->flinfo));
     200             : }
     201             : 
     202             : Datum
     203           0 : gbt_int4_same(PG_FUNCTION_ARGS)
     204             : {
     205           0 :     int32KEY   *b1 = (int32KEY *) PG_GETARG_POINTER(0);
     206           0 :     int32KEY   *b2 = (int32KEY *) PG_GETARG_POINTER(1);
     207           0 :     bool       *result = (bool *) PG_GETARG_POINTER(2);
     208             : 
     209           0 :     *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
     210           0 :     PG_RETURN_POINTER(result);
     211             : }
     212             : 
     213             : static int
     214       10148 : gbt_int4_ssup_cmp(Datum a, Datum b, SortSupport ssup)
     215             : {
     216       10148 :     int32KEY   *ia = (int32KEY *) DatumGetPointer(a);
     217       10148 :     int32KEY   *ib = (int32KEY *) DatumGetPointer(b);
     218             : 
     219             :     /* for leaf items we expect lower == upper, so only compare lower */
     220       10148 :     if (ia->lower < ib->lower)
     221        4712 :         return -1;
     222        5436 :     else if (ia->lower > ib->lower)
     223        5406 :         return 1;
     224             :     else
     225          30 :         return 0;
     226             : }
     227             : 
     228             : Datum
     229          12 : gbt_int4_sortsupport(PG_FUNCTION_ARGS)
     230             : {
     231          12 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
     232             : 
     233          12 :     ssup->comparator = gbt_int4_ssup_cmp;
     234          12 :     PG_RETURN_VOID();
     235             : }

Generated by: LCOV version 1.14