LCOV - code coverage report
Current view: top level - contrib/btree_gist - btree_numeric.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 96.6 % 89 86
Test Date: 2026-03-03 11:15:01 Functions: 100.0 % 21 21
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*
       2              :  * contrib/btree_gist/btree_numeric.c
       3              :  */
       4              : #include "postgres.h"
       5              : 
       6              : #include <float.h>
       7              : 
       8              : #include "btree_gist.h"
       9              : #include "btree_utils_var.h"
      10              : #include "utils/builtins.h"
      11              : #include "utils/numeric.h"
      12              : #include "utils/rel.h"
      13              : #include "utils/sortsupport.h"
      14              : 
      15              : /* GiST support functions */
      16            5 : PG_FUNCTION_INFO_V1(gbt_numeric_compress);
      17            5 : PG_FUNCTION_INFO_V1(gbt_numeric_union);
      18            5 : PG_FUNCTION_INFO_V1(gbt_numeric_picksplit);
      19            5 : PG_FUNCTION_INFO_V1(gbt_numeric_consistent);
      20            5 : PG_FUNCTION_INFO_V1(gbt_numeric_penalty);
      21            5 : PG_FUNCTION_INFO_V1(gbt_numeric_same);
      22            5 : PG_FUNCTION_INFO_V1(gbt_numeric_sortsupport);
      23              : 
      24              : 
      25              : /* define for comparison */
      26              : 
      27              : static bool
      28         2180 : gbt_numeric_gt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
      29              : {
      30         2180 :     return DatumGetBool(DirectFunctionCall2(numeric_gt,
      31              :                                             PointerGetDatum(a),
      32              :                                             PointerGetDatum(b)));
      33              : }
      34              : 
      35              : static bool
      36         2193 : gbt_numeric_ge(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
      37              : {
      38         2193 :     return DatumGetBool(DirectFunctionCall2(numeric_ge,
      39              :                                             PointerGetDatum(a),
      40              :                                             PointerGetDatum(b)));
      41              : }
      42              : 
      43              : static bool
      44          568 : gbt_numeric_eq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
      45              : {
      46          568 :     return DatumGetBool(DirectFunctionCall2(numeric_eq,
      47              :                                             PointerGetDatum(a),
      48              :                                             PointerGetDatum(b)));
      49              : }
      50              : 
      51              : static bool
      52         1959 : gbt_numeric_le(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
      53              : {
      54         1959 :     return DatumGetBool(DirectFunctionCall2(numeric_le,
      55              :                                             PointerGetDatum(a),
      56              :                                             PointerGetDatum(b)));
      57              : }
      58              : 
      59              : static bool
      60         1689 : gbt_numeric_lt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
      61              : {
      62         1689 :     return DatumGetBool(DirectFunctionCall2(numeric_lt,
      63              :                                             PointerGetDatum(a),
      64              :                                             PointerGetDatum(b)));
      65              : }
      66              : 
      67              : static int32
      68        43642 : gbt_numeric_cmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
      69              : {
      70        43642 :     return DatumGetInt32(DirectFunctionCall2(numeric_cmp,
      71              :                                              PointerGetDatum(a),
      72              :                                              PointerGetDatum(b)));
      73              : }
      74              : 
      75              : 
      76              : static const gbtree_vinfo tinfo =
      77              : {
      78              :     gbt_t_numeric,
      79              :     0,
      80              :     false,
      81              :     gbt_numeric_gt,
      82              :     gbt_numeric_ge,
      83              :     gbt_numeric_eq,
      84              :     gbt_numeric_le,
      85              :     gbt_numeric_lt,
      86              :     gbt_numeric_cmp,
      87              :     NULL
      88              : };
      89              : 
      90              : 
      91              : /**************************************************
      92              :  * GiST support functions
      93              :  **************************************************/
      94              : 
      95              : Datum
      96         3151 : gbt_numeric_compress(PG_FUNCTION_ARGS)
      97              : {
      98         3151 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
      99              : 
     100         3151 :     PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo));
     101              : }
     102              : 
     103              : Datum
     104         8705 : gbt_numeric_consistent(PG_FUNCTION_ARGS)
     105              : {
     106         8705 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     107         8705 :     void       *query = DatumGetNumeric(PG_GETARG_DATUM(1));
     108         8705 :     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
     109              : #ifdef NOT_USED
     110              :     Oid         subtype = PG_GETARG_OID(3);
     111              : #endif
     112         8705 :     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
     113              :     bool        retval;
     114         8705 :     GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
     115         8705 :     GBT_VARKEY_R r = gbt_var_key_readable(key);
     116              : 
     117              :     /* All cases served by this function are exact */
     118         8705 :     *recheck = false;
     119              : 
     120        17410 :     retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
     121         8705 :                                 GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
     122         8705 :     PG_RETURN_BOOL(retval);
     123              : }
     124              : 
     125              : Datum
     126         1859 : gbt_numeric_union(PG_FUNCTION_ARGS)
     127              : {
     128         1859 :     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
     129         1859 :     int32      *size = (int *) PG_GETARG_POINTER(1);
     130              : 
     131         1859 :     PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
     132              :                                     &tinfo, fcinfo->flinfo));
     133              : }
     134              : 
     135              : Datum
     136         1814 : gbt_numeric_same(PG_FUNCTION_ARGS)
     137              : {
     138         1814 :     Datum       d1 = PG_GETARG_DATUM(0);
     139         1814 :     Datum       d2 = PG_GETARG_DATUM(1);
     140         1814 :     bool       *result = (bool *) PG_GETARG_POINTER(2);
     141              : 
     142         1814 :     *result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
     143         1814 :     PG_RETURN_POINTER(result);
     144              : }
     145              : 
     146              : Datum
     147         3551 : gbt_numeric_penalty(PG_FUNCTION_ARGS)
     148              : {
     149         3551 :     GISTENTRY  *o = (GISTENTRY *) PG_GETARG_POINTER(0);
     150         3551 :     GISTENTRY  *n = (GISTENTRY *) PG_GETARG_POINTER(1);
     151         3551 :     float      *result = (float *) PG_GETARG_POINTER(2);
     152              : 
     153              :     Numeric     us,
     154              :                 os,
     155              :                 ds;
     156              : 
     157         3551 :     GBT_VARKEY *org = (GBT_VARKEY *) DatumGetPointer(o->key);
     158         3551 :     GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key);
     159              :     Datum       uni;
     160              :     GBT_VARKEY_R rk,
     161              :                 ok,
     162              :                 uk;
     163              : 
     164         3551 :     rk = gbt_var_key_readable(org);
     165         3551 :     uni = PointerGetDatum(gbt_var_key_copy(&rk));
     166         3551 :     gbt_var_bin_union(&uni, newe, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
     167         3551 :     ok = gbt_var_key_readable(org);
     168         3551 :     uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(uni));
     169              : 
     170         3551 :     us = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
     171              :                                              PointerGetDatum(uk.upper),
     172              :                                              PointerGetDatum(uk.lower)));
     173              : 
     174         3551 :     os = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
     175              :                                              PointerGetDatum(ok.upper),
     176              :                                              PointerGetDatum(ok.lower)));
     177              : 
     178         3551 :     ds = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
     179              :                                              NumericGetDatum(us),
     180              :                                              NumericGetDatum(os)));
     181              : 
     182         3551 :     if (numeric_is_nan(us))
     183              :     {
     184            0 :         if (numeric_is_nan(os))
     185            0 :             *result = 0.0;
     186              :         else
     187            0 :             *result = 1.0;
     188              :     }
     189              :     else
     190              :     {
     191         3551 :         Numeric     nul = int64_to_numeric(0);
     192              : 
     193         3551 :         *result = 0.0;
     194              : 
     195         3551 :         if (DatumGetBool(DirectFunctionCall2(numeric_gt, NumericGetDatum(ds), NumericGetDatum(nul))))
     196              :         {
     197           14 :             *result += FLT_MIN;
     198           14 :             os = DatumGetNumeric(DirectFunctionCall2(numeric_div,
     199              :                                                      NumericGetDatum(ds),
     200              :                                                      NumericGetDatum(us)));
     201           14 :             *result += (float4) DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow, NumericGetDatum(os)));
     202              :         }
     203              :     }
     204              : 
     205         3551 :     if (*result > 0)
     206           14 :         *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
     207              : 
     208         3551 :     PG_RETURN_POINTER(result);
     209              : }
     210              : 
     211              : Datum
     212           24 : gbt_numeric_picksplit(PG_FUNCTION_ARGS)
     213              : {
     214           24 :     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
     215           24 :     GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
     216              : 
     217           24 :     gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
     218              :                       &tinfo, fcinfo->flinfo);
     219           24 :     PG_RETURN_POINTER(v);
     220              : }
     221              : 
     222              : static int
     223        11619 : gbt_numeric_ssup_cmp(Datum x, Datum y, SortSupport ssup)
     224              : {
     225        11619 :     GBT_VARKEY *key1 = PG_DETOAST_DATUM(x);
     226        11619 :     GBT_VARKEY *key2 = PG_DETOAST_DATUM(y);
     227              : 
     228        11619 :     GBT_VARKEY_R arg1 = gbt_var_key_readable(key1);
     229        11619 :     GBT_VARKEY_R arg2 = gbt_var_key_readable(key2);
     230              :     Datum       result;
     231              : 
     232              :     /* for leaf items we expect lower == upper, so only compare lower */
     233        11619 :     result = DirectFunctionCall2(numeric_cmp,
     234              :                                  PointerGetDatum(arg1.lower),
     235              :                                  PointerGetDatum(arg2.lower));
     236              : 
     237        11619 :     GBT_FREE_IF_COPY(key1, x);
     238        11619 :     GBT_FREE_IF_COPY(key2, y);
     239              : 
     240        11619 :     return DatumGetInt32(result);
     241              : }
     242              : 
     243              : Datum
     244            2 : gbt_numeric_sortsupport(PG_FUNCTION_ARGS)
     245              : {
     246            2 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
     247              : 
     248            2 :     ssup->comparator = gbt_numeric_ssup_cmp;
     249            2 :     ssup->ssup_extra = NULL;
     250              : 
     251            2 :     PG_RETURN_VOID();
     252              : }
        

Generated by: LCOV version 2.0-1