Preserve CurrentMemoryContext across notify and sinval interrupts.
[pgsql.git] / contrib / btree_gist / btree_float8.c
blob081a719b0061c535e251a4e51fa71004e5728bac
1 /*
2 * contrib/btree_gist/btree_float8.c
3 */
4 #include "postgres.h"
6 #include "btree_gist.h"
7 #include "btree_utils_num.h"
8 #include "utils/float.h"
10 typedef struct float8key
12 float8 lower;
13 float8 upper;
14 } float8KEY;
17 ** float8 ops
19 PG_FUNCTION_INFO_V1(gbt_float8_compress);
20 PG_FUNCTION_INFO_V1(gbt_float8_fetch);
21 PG_FUNCTION_INFO_V1(gbt_float8_union);
22 PG_FUNCTION_INFO_V1(gbt_float8_picksplit);
23 PG_FUNCTION_INFO_V1(gbt_float8_consistent);
24 PG_FUNCTION_INFO_V1(gbt_float8_distance);
25 PG_FUNCTION_INFO_V1(gbt_float8_penalty);
26 PG_FUNCTION_INFO_V1(gbt_float8_same);
29 static bool
30 gbt_float8gt(const void *a, const void *b, FmgrInfo *flinfo)
32 return (*((const float8 *) a) > *((const float8 *) b));
34 static bool
35 gbt_float8ge(const void *a, const void *b, FmgrInfo *flinfo)
37 return (*((const float8 *) a) >= *((const float8 *) b));
39 static bool
40 gbt_float8eq(const void *a, const void *b, FmgrInfo *flinfo)
42 return (*((const float8 *) a) == *((const float8 *) b));
44 static bool
45 gbt_float8le(const void *a, const void *b, FmgrInfo *flinfo)
47 return (*((const float8 *) a) <= *((const float8 *) b));
49 static bool
50 gbt_float8lt(const void *a, const void *b, FmgrInfo *flinfo)
52 return (*((const float8 *) a) < *((const float8 *) b));
55 static int
56 gbt_float8key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
58 float8KEY *ia = (float8KEY *) (((const Nsrt *) a)->t);
59 float8KEY *ib = (float8KEY *) (((const Nsrt *) b)->t);
61 if (ia->lower == ib->lower)
63 if (ia->upper == ib->upper)
64 return 0;
66 return (ia->upper > ib->upper) ? 1 : -1;
69 return (ia->lower > ib->lower) ? 1 : -1;
72 static float8
73 gbt_float8_dist(const void *a, const void *b, FmgrInfo *flinfo)
75 float8 arg1 = *(const float8 *) a;
76 float8 arg2 = *(const float8 *) b;
77 float8 r;
79 r = arg1 - arg2;
80 if (unlikely(isinf(r)) && !isinf(arg1) && !isinf(arg2))
81 float_overflow_error();
82 return fabs(r);
86 static const gbtree_ninfo tinfo =
88 gbt_t_float8,
89 sizeof(float8),
90 16, /* sizeof(gbtreekey16) */
91 gbt_float8gt,
92 gbt_float8ge,
93 gbt_float8eq,
94 gbt_float8le,
95 gbt_float8lt,
96 gbt_float8key_cmp,
97 gbt_float8_dist
101 PG_FUNCTION_INFO_V1(float8_dist);
102 Datum
103 float8_dist(PG_FUNCTION_ARGS)
105 float8 a = PG_GETARG_FLOAT8(0);
106 float8 b = PG_GETARG_FLOAT8(1);
107 float8 r;
109 r = a - b;
110 if (unlikely(isinf(r)) && !isinf(a) && !isinf(b))
111 float_overflow_error();
113 PG_RETURN_FLOAT8(fabs(r));
116 /**************************************************
117 * float8 ops
118 **************************************************/
121 Datum
122 gbt_float8_compress(PG_FUNCTION_ARGS)
124 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
126 PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
129 Datum
130 gbt_float8_fetch(PG_FUNCTION_ARGS)
132 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
134 PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
137 Datum
138 gbt_float8_consistent(PG_FUNCTION_ARGS)
140 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
141 float8 query = PG_GETARG_FLOAT8(1);
142 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
144 /* Oid subtype = PG_GETARG_OID(3); */
145 bool *recheck = (bool *) PG_GETARG_POINTER(4);
146 float8KEY *kkk = (float8KEY *) DatumGetPointer(entry->key);
147 GBT_NUMKEY_R key;
149 /* All cases served by this function are exact */
150 *recheck = false;
152 key.lower = (GBT_NUMKEY *) &kkk->lower;
153 key.upper = (GBT_NUMKEY *) &kkk->upper;
155 PG_RETURN_BOOL(gbt_num_consistent(&key, (void *) &query, &strategy,
156 GIST_LEAF(entry), &tinfo,
157 fcinfo->flinfo));
161 Datum
162 gbt_float8_distance(PG_FUNCTION_ARGS)
164 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
165 float8 query = PG_GETARG_FLOAT8(1);
167 /* Oid subtype = PG_GETARG_OID(3); */
168 float8KEY *kkk = (float8KEY *) DatumGetPointer(entry->key);
169 GBT_NUMKEY_R key;
171 key.lower = (GBT_NUMKEY *) &kkk->lower;
172 key.upper = (GBT_NUMKEY *) &kkk->upper;
174 PG_RETURN_FLOAT8(gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry),
175 &tinfo, fcinfo->flinfo));
179 Datum
180 gbt_float8_union(PG_FUNCTION_ARGS)
182 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
183 void *out = palloc(sizeof(float8KEY));
185 *(int *) PG_GETARG_POINTER(1) = sizeof(float8KEY);
186 PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
190 Datum
191 gbt_float8_penalty(PG_FUNCTION_ARGS)
193 float8KEY *origentry = (float8KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
194 float8KEY *newentry = (float8KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
195 float *result = (float *) PG_GETARG_POINTER(2);
197 penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
199 PG_RETURN_POINTER(result);
202 Datum
203 gbt_float8_picksplit(PG_FUNCTION_ARGS)
205 PG_RETURN_POINTER(gbt_num_picksplit((GistEntryVector *) PG_GETARG_POINTER(0),
206 (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
207 &tinfo, fcinfo->flinfo));
210 Datum
211 gbt_float8_same(PG_FUNCTION_ARGS)
213 float8KEY *b1 = (float8KEY *) PG_GETARG_POINTER(0);
214 float8KEY *b2 = (float8KEY *) PG_GETARG_POINTER(1);
215 bool *result = (bool *) PG_GETARG_POINTER(2);
217 *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
218 PG_RETURN_POINTER(result);