Header And Logo

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

btree_float8.c

Go to the documentation of this file.
00001 /*
00002  * contrib/btree_gist/btree_float8.c
00003  */
00004 #include "postgres.h"
00005 
00006 #include "btree_gist.h"
00007 #include "btree_utils_num.h"
00008 
00009 typedef struct float8key
00010 {
00011     float8      lower;
00012     float8      upper;
00013 } float8KEY;
00014 
00015 /*
00016 ** float8 ops
00017 */
00018 PG_FUNCTION_INFO_V1(gbt_float8_compress);
00019 PG_FUNCTION_INFO_V1(gbt_float8_union);
00020 PG_FUNCTION_INFO_V1(gbt_float8_picksplit);
00021 PG_FUNCTION_INFO_V1(gbt_float8_consistent);
00022 PG_FUNCTION_INFO_V1(gbt_float8_distance);
00023 PG_FUNCTION_INFO_V1(gbt_float8_penalty);
00024 PG_FUNCTION_INFO_V1(gbt_float8_same);
00025 
00026 Datum       gbt_float8_compress(PG_FUNCTION_ARGS);
00027 Datum       gbt_float8_union(PG_FUNCTION_ARGS);
00028 Datum       gbt_float8_picksplit(PG_FUNCTION_ARGS);
00029 Datum       gbt_float8_consistent(PG_FUNCTION_ARGS);
00030 Datum       gbt_float8_distance(PG_FUNCTION_ARGS);
00031 Datum       gbt_float8_penalty(PG_FUNCTION_ARGS);
00032 Datum       gbt_float8_same(PG_FUNCTION_ARGS);
00033 
00034 
00035 static bool
00036 gbt_float8gt(const void *a, const void *b)
00037 {
00038     return (*((const float8 *) a) > *((const float8 *) b));
00039 }
00040 static bool
00041 gbt_float8ge(const void *a, const void *b)
00042 {
00043     return (*((const float8 *) a) >= *((const float8 *) b));
00044 }
00045 static bool
00046 gbt_float8eq(const void *a, const void *b)
00047 {
00048     return (*((const float8 *) a) == *((const float8 *) b));
00049 }
00050 static bool
00051 gbt_float8le(const void *a, const void *b)
00052 {
00053     return (*((const float8 *) a) <= *((const float8 *) b));
00054 }
00055 static bool
00056 gbt_float8lt(const void *a, const void *b)
00057 {
00058     return (*((const float8 *) a) < *((const float8 *) b));
00059 }
00060 
00061 static int
00062 gbt_float8key_cmp(const void *a, const void *b)
00063 {
00064     float8KEY  *ia = (float8KEY *) (((const Nsrt *) a)->t);
00065     float8KEY  *ib = (float8KEY *) (((const Nsrt *) b)->t);
00066 
00067     if (ia->lower == ib->lower)
00068     {
00069         if (ia->upper == ib->upper)
00070             return 0;
00071 
00072         return (ia->upper > ib->upper) ? 1 : -1;
00073     }
00074 
00075     return (ia->lower > ib->lower) ? 1 : -1;
00076 }
00077 
00078 static float8
00079 gbt_float8_dist(const void *a, const void *b)
00080 {
00081     float8      arg1 = *(const float8 *) a;
00082     float8      arg2 = *(const float8 *) b;
00083     float8      r;
00084 
00085     r = arg1 - arg2;
00086     CHECKFLOATVAL(r, isinf(arg1) || isinf(arg2), true);
00087 
00088     return Abs(r);
00089 }
00090 
00091 
00092 static const gbtree_ninfo tinfo =
00093 {
00094     gbt_t_float8,
00095     sizeof(float8),
00096     gbt_float8gt,
00097     gbt_float8ge,
00098     gbt_float8eq,
00099     gbt_float8le,
00100     gbt_float8lt,
00101     gbt_float8key_cmp,
00102     gbt_float8_dist
00103 };
00104 
00105 
00106 PG_FUNCTION_INFO_V1(float8_dist);
00107 Datum       float8_dist(PG_FUNCTION_ARGS);
00108 Datum
00109 float8_dist(PG_FUNCTION_ARGS)
00110 {
00111     float8      a = PG_GETARG_FLOAT8(0);
00112     float8      b = PG_GETARG_FLOAT8(1);
00113     float8      r;
00114 
00115     r = a - b;
00116     CHECKFLOATVAL(r, isinf(a) || isinf(b), true);
00117 
00118     PG_RETURN_FLOAT8(Abs(r));
00119 }
00120 
00121 /**************************************************
00122  * float8 ops
00123  **************************************************/
00124 
00125 
00126 Datum
00127 gbt_float8_compress(PG_FUNCTION_ARGS)
00128 {
00129     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00130     GISTENTRY  *retval = NULL;
00131 
00132     PG_RETURN_POINTER(gbt_num_compress(retval, entry, &tinfo));
00133 }
00134 
00135 
00136 Datum
00137 gbt_float8_consistent(PG_FUNCTION_ARGS)
00138 {
00139     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00140     float8      query = PG_GETARG_FLOAT8(1);
00141     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
00142 
00143     /* Oid      subtype = PG_GETARG_OID(3); */
00144     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
00145     float8KEY  *kkk = (float8KEY *) DatumGetPointer(entry->key);
00146     GBT_NUMKEY_R key;
00147 
00148     /* All cases served by this function are exact */
00149     *recheck = false;
00150 
00151     key.lower = (GBT_NUMKEY *) &kkk->lower;
00152     key.upper = (GBT_NUMKEY *) &kkk->upper;
00153 
00154     PG_RETURN_BOOL(
00155                    gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
00156         );
00157 }
00158 
00159 
00160 Datum
00161 gbt_float8_distance(PG_FUNCTION_ARGS)
00162 {
00163     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00164     float8      query = PG_GETARG_FLOAT8(1);
00165 
00166     /* Oid      subtype = PG_GETARG_OID(3); */
00167     float8KEY  *kkk = (float8KEY *) DatumGetPointer(entry->key);
00168     GBT_NUMKEY_R key;
00169 
00170     key.lower = (GBT_NUMKEY *) &kkk->lower;
00171     key.upper = (GBT_NUMKEY *) &kkk->upper;
00172 
00173     PG_RETURN_FLOAT8(
00174             gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
00175         );
00176 }
00177 
00178 
00179 Datum
00180 gbt_float8_union(PG_FUNCTION_ARGS)
00181 {
00182     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
00183     void       *out = palloc(sizeof(float8KEY));
00184 
00185     *(int *) PG_GETARG_POINTER(1) = sizeof(float8KEY);
00186     PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
00187 }
00188 
00189 
00190 Datum
00191 gbt_float8_penalty(PG_FUNCTION_ARGS)
00192 {
00193     float8KEY  *origentry = (float8KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
00194     float8KEY  *newentry = (float8KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
00195     float      *result = (float *) PG_GETARG_POINTER(2);
00196 
00197     penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
00198 
00199     PG_RETURN_POINTER(result);
00200 
00201 }
00202 
00203 Datum
00204 gbt_float8_picksplit(PG_FUNCTION_ARGS)
00205 {
00206     PG_RETURN_POINTER(gbt_num_picksplit(
00207                                     (GistEntryVector *) PG_GETARG_POINTER(0),
00208                                       (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
00209                                         &tinfo
00210                                         ));
00211 }
00212 
00213 Datum
00214 gbt_float8_same(PG_FUNCTION_ARGS)
00215 {
00216     float8KEY  *b1 = (float8KEY *) PG_GETARG_POINTER(0);
00217     float8KEY  *b2 = (float8KEY *) PG_GETARG_POINTER(1);
00218     bool       *result = (bool *) PG_GETARG_POINTER(2);
00219 
00220     *result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
00221     PG_RETURN_POINTER(result);
00222 }