summaryrefslogtreecommitdiffstats
path: root/contrib/btree_gist/btree_utils_num.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/btree_gist/btree_utils_num.h')
-rw-r--r--contrib/btree_gist/btree_utils_num.h135
1 files changed, 135 insertions, 0 deletions
diff --git a/contrib/btree_gist/btree_utils_num.h b/contrib/btree_gist/btree_utils_num.h
new file mode 100644
index 0000000..cec6986
--- /dev/null
+++ b/contrib/btree_gist/btree_utils_num.h
@@ -0,0 +1,135 @@
+/*
+ * contrib/btree_gist/btree_utils_num.h
+ */
+#ifndef __BTREE_UTILS_NUM_H__
+#define __BTREE_UTILS_NUM_H__
+
+#include <math.h>
+#include <float.h>
+
+#include "access/gist.h"
+#include "btree_gist.h"
+#include "utils/rel.h"
+
+typedef char GBT_NUMKEY;
+
+/* Better readable key */
+typedef struct
+{
+ const GBT_NUMKEY *lower,
+ *upper;
+} GBT_NUMKEY_R;
+
+
+/* for sorting */
+typedef struct
+{
+ int i;
+ GBT_NUMKEY *t;
+} Nsrt;
+
+
+/* type description */
+
+typedef struct
+{
+
+ /* Attribs */
+
+ enum gbtree_type t; /* data type */
+ int32 size; /* size of type, 0 means variable */
+ int32 indexsize; /* size of datums stored in index */
+
+ /* Methods */
+
+ bool (*f_gt) (const void *, const void *, FmgrInfo *); /* greater than */
+ bool (*f_ge) (const void *, const void *, FmgrInfo *); /* greater or equal */
+ bool (*f_eq) (const void *, const void *, FmgrInfo *); /* equal */
+ bool (*f_le) (const void *, const void *, FmgrInfo *); /* less or equal */
+ bool (*f_lt) (const void *, const void *, FmgrInfo *); /* less than */
+ int (*f_cmp) (const void *, const void *, FmgrInfo *); /* key compare function */
+ float8 (*f_dist) (const void *, const void *, FmgrInfo *); /* key distance function */
+} gbtree_ninfo;
+
+
+/*
+ * Numeric btree functions
+ */
+
+
+
+/*
+ * Note: The factor 0.49 in following macro avoids floating point overflows
+ */
+#define penalty_num(result,olower,oupper,nlower,nupper) do { \
+ double tmp = 0.0F; \
+ (*(result)) = 0.0F; \
+ if ( (nupper) > (oupper) ) \
+ tmp += ( ((double)nupper)*0.49F - ((double)oupper)*0.49F ); \
+ if ( (olower) > (nlower) ) \
+ tmp += ( ((double)olower)*0.49F - ((double)nlower)*0.49F ); \
+ if (tmp > 0.0F) \
+ { \
+ (*(result)) += FLT_MIN; \
+ (*(result)) += (float) ( ((double)(tmp)) / ( (double)(tmp) + ( ((double)(oupper))*0.49F - ((double)(olower))*0.49F ) ) ); \
+ (*(result)) *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1)); \
+ } \
+} while (0)
+
+
+/*
+ * Convert an Interval to an approximate equivalent number of seconds
+ * (as a double). Here because we need it for time/timetz as well as
+ * interval. See interval_cmp_internal for comparison.
+ */
+#define INTERVAL_TO_SEC(ivp) \
+ (((double) (ivp)->time) / ((double) USECS_PER_SEC) + \
+ (ivp)->day * (24.0 * SECS_PER_HOUR) + \
+ (ivp)->month * (30.0 * SECS_PER_DAY))
+
+#define GET_FLOAT_DISTANCE(t, arg1, arg2) Abs( ((float8) *((const t *) (arg1))) - ((float8) *((const t *) (arg2))) )
+
+/*
+ * check to see if a float4/8 val has underflowed or overflowed
+ * borrowed from src/backend/utils/adt/float.c
+ */
+#define CHECKFLOATVAL(val, inf_is_valid, zero_is_valid) \
+do { \
+ if (isinf(val) && !(inf_is_valid)) \
+ ereport(ERROR, \
+ (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), \
+ errmsg("value out of range: overflow"))); \
+ \
+ if ((val) == 0.0 && !(zero_is_valid)) \
+ ereport(ERROR, \
+ (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), \
+ errmsg("value out of range: underflow"))); \
+} while(0)
+
+
+extern Interval *abs_interval(Interval *a);
+
+extern bool gbt_num_consistent(const GBT_NUMKEY_R *key, const void *query,
+ const StrategyNumber *strategy, bool is_leaf,
+ const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
+
+extern float8 gbt_num_distance(const GBT_NUMKEY_R *key, const void *query,
+ bool is_leaf, const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
+
+extern GIST_SPLITVEC *gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
+ const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
+
+extern GISTENTRY *gbt_num_compress(GISTENTRY *entry, const gbtree_ninfo *tinfo);
+
+extern GISTENTRY *gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo);
+
+extern void *gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec,
+ const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
+
+extern bool gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b,
+ const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
+
+extern void gbt_num_bin_union(Datum *u, GBT_NUMKEY *e,
+ const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
+
+#endif