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

Generated by: LCOV version 1.13