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

Generated by: LCOV version 2.0-1