Header And Logo

PostgreSQL
| The world's most advanced open source database.

btree_utils_num.h

Go to the documentation of this file.
00001 /*
00002  * contrib/btree_gist/btree_utils_num.h
00003  */
00004 #ifndef __BTREE_UTILS_NUM_H__
00005 #define __BTREE_UTILS_NUM_H__
00006 
00007 #include "btree_gist.h"
00008 #include "access/gist.h"
00009 #include "utils/rel.h"
00010 
00011 #include <math.h>
00012 #include <float.h>
00013 
00014 typedef char GBT_NUMKEY;
00015 
00016 /* Better readable key */
00017 typedef struct
00018 {
00019     const GBT_NUMKEY *lower,
00020                *upper;
00021 } GBT_NUMKEY_R;
00022 
00023 
00024 /* for sorting */
00025 typedef struct
00026 {
00027     int         i;
00028     GBT_NUMKEY *t;
00029 } Nsrt;
00030 
00031 
00032 /* type description */
00033 
00034 typedef struct
00035 {
00036 
00037     /* Attribs */
00038 
00039     enum gbtree_type t;         /* data type */
00040     int32       size;           /* size of type , 0 means variable */
00041 
00042     /* Methods */
00043 
00044     bool        (*f_gt) (const void *, const void *);   /* greater than */
00045     bool        (*f_ge) (const void *, const void *);   /* greater or equal */
00046     bool        (*f_eq) (const void *, const void *);   /* equal */
00047     bool        (*f_le) (const void *, const void *);   /* less or equal */
00048     bool        (*f_lt) (const void *, const void *);   /* less than */
00049     int         (*f_cmp) (const void *, const void *);  /* key compare function */
00050     float8      (*f_dist) (const void *, const void *); /* key distance function */
00051 } gbtree_ninfo;
00052 
00053 
00054 /*
00055  *  Numeric btree functions
00056  */
00057 
00058 
00059 
00060 /*
00061  * Note: The factor 0.49 in following macro avoids floating point overflows
00062  */
00063 #define penalty_num(result,olower,oupper,nlower,nupper) do { \
00064   double    tmp = 0.0F; \
00065   (*(result))   = 0.0F; \
00066   if ( (nupper) > (oupper) ) \
00067       tmp += ( ((double)nupper)*0.49F - ((double)oupper)*0.49F ); \
00068   if (  (olower) > (nlower)  ) \
00069       tmp += ( ((double)olower)*0.49F - ((double)nlower)*0.49F ); \
00070   if (tmp > 0.0F) \
00071   { \
00072     (*(result)) += FLT_MIN; \
00073     (*(result)) += (float) ( ((double)(tmp)) / ( (double)(tmp) + ( ((double)(oupper))*0.49F - ((double)(olower))*0.49F ) ) ); \
00074     (*(result)) *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1)); \
00075   } \
00076 } while (0);
00077 
00078 
00079 /*
00080  * Convert an Interval to an approximate equivalent number of seconds
00081  * (as a double).  Here because we need it for time/timetz as well as
00082  * interval.  See interval_cmp_internal for comparison.
00083  */
00084 #ifdef HAVE_INT64_TIMESTAMP
00085 #define INTERVAL_TO_SEC(ivp) \
00086     (((double) (ivp)->time) / ((double) USECS_PER_SEC) + \
00087      (ivp)->day * (24.0 * SECS_PER_HOUR) + \
00088      (ivp)->month * (30.0 * SECS_PER_DAY))
00089 #else
00090 #define INTERVAL_TO_SEC(ivp) \
00091     ((ivp)->time + \
00092      (ivp)->day * (24.0 * SECS_PER_HOUR) + \
00093      (ivp)->month * (30.0 * SECS_PER_DAY))
00094 #endif
00095 
00096 #define GET_FLOAT_DISTANCE(t, arg1, arg2)   Abs( ((float8) *((const t *) (arg1))) - ((float8) *((const t *) (arg2))) )
00097 
00098 #define SAMESIGN(a,b)   (((a) < 0) == ((b) < 0))
00099 
00100 /*
00101  * check to see if a float4/8 val has underflowed or overflowed
00102  * borrowed from src/backend/utils/adt/float.c
00103  */
00104 #define CHECKFLOATVAL(val, inf_is_valid, zero_is_valid)         \
00105 do {                                                            \
00106     if (isinf(val) && !(inf_is_valid))                          \
00107         ereport(ERROR,                                          \
00108                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),   \
00109           errmsg("value out of range: overflow")));             \
00110                                                                 \
00111     if ((val) == 0.0 && !(zero_is_valid))                       \
00112         ereport(ERROR,                                          \
00113                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),   \
00114          errmsg("value out of range: underflow")));             \
00115 } while(0)
00116 
00117 
00118 extern Interval *abs_interval(Interval *a);
00119 
00120 extern bool gbt_num_consistent(const GBT_NUMKEY_R *key, const void *query,
00121                    const StrategyNumber *strategy, bool is_leaf,
00122                    const gbtree_ninfo *tinfo);
00123 
00124 extern float8 gbt_num_distance(const GBT_NUMKEY_R *key, const void *query,
00125                  bool is_leaf, const gbtree_ninfo *tinfo);
00126 
00127 extern GIST_SPLITVEC *gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
00128                   const gbtree_ninfo *tinfo);
00129 
00130 extern GISTENTRY *gbt_num_compress(GISTENTRY *retval, GISTENTRY *entry,
00131                  const gbtree_ninfo *tinfo);
00132 
00133 
00134 extern void *gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec,
00135               const gbtree_ninfo *tinfo);
00136 
00137 extern bool gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b,
00138              const gbtree_ninfo *tinfo);
00139 
00140 extern void gbt_num_bin_union(Datum *u, GBT_NUMKEY *e,
00141                   const gbtree_ninfo *tinfo);
00142 
00143 #endif