LCOV - code coverage report
Current view: top level - contrib/btree_gist - btree_numeric.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 74 74 100.0 %
Date: 2024-12-03 08:15:25 Functions: 18 18 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             : 
      15             : /*
      16             : ** Bytea ops
      17             : */
      18           6 : PG_FUNCTION_INFO_V1(gbt_numeric_compress);
      19           6 : PG_FUNCTION_INFO_V1(gbt_numeric_union);
      20           6 : PG_FUNCTION_INFO_V1(gbt_numeric_picksplit);
      21           6 : PG_FUNCTION_INFO_V1(gbt_numeric_consistent);
      22           6 : PG_FUNCTION_INFO_V1(gbt_numeric_penalty);
      23           6 : PG_FUNCTION_INFO_V1(gbt_numeric_same);
      24             : 
      25             : 
      26             : /* define for comparison */
      27             : 
      28             : static bool
      29        4928 : gbt_numeric_gt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
      30             : {
      31        4928 :     return DatumGetBool(DirectFunctionCall2(numeric_gt,
      32             :                                             PointerGetDatum(a),
      33             :                                             PointerGetDatum(b)));
      34             : }
      35             : 
      36             : static bool
      37        5238 : gbt_numeric_ge(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
      38             : {
      39        5238 :     return DatumGetBool(DirectFunctionCall2(numeric_ge,
      40             :                                             PointerGetDatum(a),
      41             :                                             PointerGetDatum(b)));
      42             : }
      43             : 
      44             : static bool
      45        1792 : gbt_numeric_eq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
      46             : {
      47        1792 :     return DatumGetBool(DirectFunctionCall2(numeric_eq,
      48             :                                             PointerGetDatum(a),
      49             :                                             PointerGetDatum(b)));
      50             : }
      51             : 
      52             : static bool
      53        4056 : gbt_numeric_le(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
      54             : {
      55        4056 :     return DatumGetBool(DirectFunctionCall2(numeric_le,
      56             :                                             PointerGetDatum(a),
      57             :                                             PointerGetDatum(b)));
      58             : }
      59             : 
      60             : static bool
      61        3466 : gbt_numeric_lt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
      62             : {
      63        3466 :     return DatumGetBool(DirectFunctionCall2(numeric_lt,
      64             :                                             PointerGetDatum(a),
      65             :                                             PointerGetDatum(b)));
      66             : }
      67             : 
      68             : static int32
      69      127314 : gbt_numeric_cmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
      70             : {
      71      127314 :     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             :  * Text ops
      94             :  **************************************************/
      95             : 
      96             : 
      97             : Datum
      98        6336 : gbt_numeric_compress(PG_FUNCTION_ARGS)
      99             : {
     100        6336 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     101             : 
     102        6336 :     PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo));
     103             : }
     104             : 
     105             : 
     106             : 
     107             : Datum
     108       19744 : gbt_numeric_consistent(PG_FUNCTION_ARGS)
     109             : {
     110       19744 :     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
     111       19744 :     void       *query = DatumGetNumeric(PG_GETARG_DATUM(1));
     112       19744 :     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
     113             : 
     114             :     /* Oid      subtype = PG_GETARG_OID(3); */
     115       19744 :     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
     116             :     bool        retval;
     117       19744 :     GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
     118       19744 :     GBT_VARKEY_R r = gbt_var_key_readable(key);
     119             : 
     120             :     /* All cases served by this function are exact */
     121       19744 :     *recheck = false;
     122             : 
     123       39488 :     retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
     124       19744 :                                 GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
     125       19744 :     PG_RETURN_BOOL(retval);
     126             : }
     127             : 
     128             : 
     129             : 
     130             : Datum
     131        5490 : gbt_numeric_union(PG_FUNCTION_ARGS)
     132             : {
     133        5490 :     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
     134        5490 :     int32      *size = (int *) PG_GETARG_POINTER(1);
     135             : 
     136        5490 :     PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
     137             :                                     &tinfo, fcinfo->flinfo));
     138             : }
     139             : 
     140             : 
     141             : Datum
     142        5400 : gbt_numeric_same(PG_FUNCTION_ARGS)
     143             : {
     144        5400 :     Datum       d1 = PG_GETARG_DATUM(0);
     145        5400 :     Datum       d2 = PG_GETARG_DATUM(1);
     146        5400 :     bool       *result = (bool *) PG_GETARG_POINTER(2);
     147             : 
     148        5400 :     *result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
     149        5400 :     PG_RETURN_POINTER(result);
     150             : }
     151             : 
     152             : 
     153             : Datum
     154       13356 : gbt_numeric_penalty(PG_FUNCTION_ARGS)
     155             : {
     156       13356 :     GISTENTRY  *o = (GISTENTRY *) PG_GETARG_POINTER(0);
     157       13356 :     GISTENTRY  *n = (GISTENTRY *) PG_GETARG_POINTER(1);
     158       13356 :     float      *result = (float *) PG_GETARG_POINTER(2);
     159             : 
     160             :     Numeric     us,
     161             :                 os,
     162             :                 ds;
     163             : 
     164       13356 :     GBT_VARKEY *org = (GBT_VARKEY *) DatumGetPointer(o->key);
     165       13356 :     GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key);
     166             :     Datum       uni;
     167             :     GBT_VARKEY_R rk,
     168             :                 ok,
     169             :                 uk;
     170             : 
     171       13356 :     rk = gbt_var_key_readable(org);
     172       13356 :     uni = PointerGetDatum(gbt_var_key_copy(&rk));
     173       13356 :     gbt_var_bin_union(&uni, newe, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
     174       13356 :     ok = gbt_var_key_readable(org);
     175       13356 :     uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(uni));
     176             : 
     177       13356 :     us = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
     178             :                                              PointerGetDatum(uk.upper),
     179             :                                              PointerGetDatum(uk.lower)));
     180             : 
     181       13356 :     os = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
     182             :                                              PointerGetDatum(ok.upper),
     183             :                                              PointerGetDatum(ok.lower)));
     184             : 
     185       13356 :     ds = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
     186             :                                              NumericGetDatum(us),
     187             :                                              NumericGetDatum(os)));
     188             : 
     189       13356 :     if (numeric_is_nan(us))
     190             :     {
     191         966 :         if (numeric_is_nan(os))
     192         952 :             *result = 0.0;
     193             :         else
     194          14 :             *result = 1.0;
     195             :     }
     196             :     else
     197             :     {
     198       12390 :         Numeric     nul = int64_to_numeric(0);
     199             : 
     200       12390 :         *result = 0.0;
     201             : 
     202       12390 :         if (DirectFunctionCall2(numeric_gt, NumericGetDatum(ds), NumericGetDatum(nul)))
     203             :         {
     204        4168 :             *result += FLT_MIN;
     205        4168 :             os = DatumGetNumeric(DirectFunctionCall2(numeric_div,
     206             :                                                      NumericGetDatum(ds),
     207             :                                                      NumericGetDatum(us)));
     208        4168 :             *result += (float4) DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow, NumericGetDatum(os)));
     209             :         }
     210             :     }
     211             : 
     212       13356 :     if (*result > 0)
     213        4182 :         *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
     214             : 
     215       13356 :     PG_RETURN_POINTER(result);
     216             : }
     217             : 
     218             : 
     219             : 
     220             : Datum
     221          52 : gbt_numeric_picksplit(PG_FUNCTION_ARGS)
     222             : {
     223          52 :     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
     224          52 :     GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
     225             : 
     226          52 :     gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
     227             :                       &tinfo, fcinfo->flinfo);
     228          52 :     PG_RETURN_POINTER(v);
     229             : }

Generated by: LCOV version 1.14