1 /* 2 * contrib/btree_gist/btree_utils_num.h 3 */ 4 #ifndef __BTREE_UTILS_NUM_H__ 5 #define __BTREE_UTILS_NUM_H__ 6 7 #include "btree_gist.h" 8 #include "access/gist.h" 9 #include "utils/rel.h" 10 11 #include <math.h> 12 #include <float.h> 13 14 typedef char GBT_NUMKEY; 15 16 /* Better readable key */ 17 typedef struct 18 { 19 const GBT_NUMKEY *lower, 20 *upper; 21 } GBT_NUMKEY_R; 22 23 24 /* for sorting */ 25 typedef struct 26 { 27 int i; 28 GBT_NUMKEY *t; 29 } Nsrt; 30 31 32 /* type description */ 33 34 typedef struct 35 { 36 37 /* Attribs */ 38 39 enum gbtree_type t; /* data type */ 40 int32 size; /* size of type, 0 means variable */ 41 int32 indexsize; /* size of datums stored in index */ 42 43 /* Methods */ 44 45 bool (*f_gt) (const void *, const void *, FmgrInfo *); /* greater than */ 46 bool (*f_ge) (const void *, const void *, FmgrInfo *); /* greater or equal */ 47 bool (*f_eq) (const void *, const void *, FmgrInfo *); /* equal */ 48 bool (*f_le) (const void *, const void *, FmgrInfo *); /* less or equal */ 49 bool (*f_lt) (const void *, const void *, FmgrInfo *); /* less than */ 50 int (*f_cmp) (const void *, const void *, FmgrInfo *); /* key compare function */ 51 float8 (*f_dist) (const void *, const void *, FmgrInfo *); /* key distance function */ 52 } gbtree_ninfo; 53 54 55 /* 56 * Numeric btree functions 57 */ 58 59 60 61 /* 62 * Note: The factor 0.49 in following macro avoids floating point overflows 63 */ 64 #define penalty_num(result,olower,oupper,nlower,nupper) do { \ 65 double tmp = 0.0F; \ 66 (*(result)) = 0.0F; \ 67 if ( (nupper) > (oupper) ) \ 68 tmp += ( ((double)nupper)*0.49F - ((double)oupper)*0.49F ); \ 69 if ( (olower) > (nlower) ) \ 70 tmp += ( ((double)olower)*0.49F - ((double)nlower)*0.49F ); \ 71 if (tmp > 0.0F) \ 72 { \ 73 (*(result)) += FLT_MIN; \ 74 (*(result)) += (float) ( ((double)(tmp)) / ( (double)(tmp) + ( ((double)(oupper))*0.49F - ((double)(olower))*0.49F ) ) ); \ 75 (*(result)) *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1)); \ 76 } \ 77 } while (0) 78 79 80 /* 81 * Convert an Interval to an approximate equivalent number of seconds 82 * (as a double). Here because we need it for time/timetz as well as 83 * interval. See interval_cmp_internal for comparison. 84 */ 85 #define INTERVAL_TO_SEC(ivp) \ 86 (((double) (ivp)->time) / ((double) USECS_PER_SEC) + \ 87 (ivp)->day * (24.0 * SECS_PER_HOUR) + \ 88 (ivp)->month * (30.0 * SECS_PER_DAY)) 89 90 #define GET_FLOAT_DISTANCE(t, arg1, arg2) Abs( ((float8) *((const t *) (arg1))) - ((float8) *((const t *) (arg2))) ) 91 92 /* 93 * check to see if a float4/8 val has underflowed or overflowed 94 * borrowed from src/backend/utils/adt/float.c 95 */ 96 #define CHECKFLOATVAL(val, inf_is_valid, zero_is_valid) \ 97 do { \ 98 if (isinf(val) && !(inf_is_valid)) \ 99 ereport(ERROR, \ 100 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), \ 101 errmsg("value out of range: overflow"))); \ 102 \ 103 if ((val) == 0.0 && !(zero_is_valid)) \ 104 ereport(ERROR, \ 105 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), \ 106 errmsg("value out of range: underflow"))); \ 107 } while(0) 108 109 110 extern Interval *abs_interval(Interval *a); 111 112 extern bool gbt_num_consistent(const GBT_NUMKEY_R *key, const void *query, 113 const StrategyNumber *strategy, bool is_leaf, 114 const gbtree_ninfo *tinfo, FmgrInfo *flinfo); 115 116 extern float8 gbt_num_distance(const GBT_NUMKEY_R *key, const void *query, 117 bool is_leaf, const gbtree_ninfo *tinfo, FmgrInfo *flinfo); 118 119 extern GIST_SPLITVEC *gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, 120 const gbtree_ninfo *tinfo, FmgrInfo *flinfo); 121 122 extern GISTENTRY *gbt_num_compress(GISTENTRY *entry, const gbtree_ninfo *tinfo); 123 124 extern GISTENTRY *gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo); 125 126 extern void *gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, 127 const gbtree_ninfo *tinfo, FmgrInfo *flinfo); 128 129 extern bool gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b, 130 const gbtree_ninfo *tinfo, FmgrInfo *flinfo); 131 132 extern void gbt_num_bin_union(Datum *u, GBT_NUMKEY *e, 133 const gbtree_ninfo *tinfo, FmgrInfo *flinfo); 134 135 #endif 136