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

Generated by: LCOV version 1.16