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

Generated by: LCOV version 1.14