Age Owner Branch data TLA Line data Source code
1 : : /*
2 : : * contrib/btree_gist/btree_float8.c
3 : : */
4 : : #include "postgres.h"
5 : :
6 : : #include "btree_gist.h"
7 : : #include "btree_utils_num.h"
8 : : #include "utils/float.h"
9 : : #include "utils/rel.h"
10 : : #include "utils/sortsupport.h"
11 : :
12 : : typedef struct float8key
13 : : {
14 : : float8 lower;
15 : : float8 upper;
16 : : } float8KEY;
17 : :
18 : : /* GiST support functions */
7771 teodor@sigaev.ru 19 :CBC 4 : PG_FUNCTION_INFO_V1(gbt_float8_compress);
3816 heikki.linnakangas@i 20 : 4 : PG_FUNCTION_INFO_V1(gbt_float8_fetch);
7771 teodor@sigaev.ru 21 : 4 : PG_FUNCTION_INFO_V1(gbt_float8_union);
22 : 4 : PG_FUNCTION_INFO_V1(gbt_float8_picksplit);
23 : 4 : PG_FUNCTION_INFO_V1(gbt_float8_consistent);
5302 tgl@sss.pgh.pa.us 24 : 4 : PG_FUNCTION_INFO_V1(gbt_float8_distance);
7771 teodor@sigaev.ru 25 : 4 : PG_FUNCTION_INFO_V1(gbt_float8_penalty);
26 : 4 : PG_FUNCTION_INFO_V1(gbt_float8_same);
156 heikki.linnakangas@i 27 : 4 : PG_FUNCTION_INFO_V1(gbt_float8_sortsupport);
28 : :
29 : :
30 : : static bool
3091 andrew@dunslane.net 31 : 1357 : gbt_float8gt(const void *a, const void *b, FmgrInfo *flinfo)
32 : : {
5109 peter_e@gmx.net 33 : 1357 : return (*((const float8 *) a) > *((const float8 *) b));
34 : : }
35 : : static bool
3091 andrew@dunslane.net 36 : 514 : gbt_float8ge(const void *a, const void *b, FmgrInfo *flinfo)
37 : : {
5109 peter_e@gmx.net 38 : 514 : return (*((const float8 *) a) >= *((const float8 *) b));
39 : : }
40 : : static bool
3091 andrew@dunslane.net 41 : 272 : gbt_float8eq(const void *a, const void *b, FmgrInfo *flinfo)
42 : : {
5109 peter_e@gmx.net 43 : 272 : return (*((const float8 *) a) == *((const float8 *) b));
44 : : }
45 : : static bool
3091 andrew@dunslane.net 46 : 825 : gbt_float8le(const void *a, const void *b, FmgrInfo *flinfo)
47 : : {
5109 peter_e@gmx.net 48 : 825 : return (*((const float8 *) a) <= *((const float8 *) b));
49 : : }
50 : : static bool
3091 andrew@dunslane.net 51 : 1629 : gbt_float8lt(const void *a, const void *b, FmgrInfo *flinfo)
52 : : {
5109 peter_e@gmx.net 53 : 1629 : return (*((const float8 *) a) < *((const float8 *) b));
54 : : }
55 : :
56 : : static int
3091 andrew@dunslane.net 57 : 543 : gbt_float8key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
58 : : {
5109 peter_e@gmx.net 59 : 543 : float8KEY *ia = (float8KEY *) (((const Nsrt *) a)->t);
60 : 543 : float8KEY *ib = (float8KEY *) (((const Nsrt *) b)->t);
61 : :
5757 teodor@sigaev.ru 62 [ - + ]: 543 : if (ia->lower == ib->lower)
63 : : {
5757 teodor@sigaev.ru 64 [ # # ]:UBC 0 : if (ia->upper == ib->upper)
65 : 0 : return 0;
66 : :
67 [ # # ]: 0 : return (ia->upper > ib->upper) ? 1 : -1;
68 : : }
69 : :
5757 teodor@sigaev.ru 70 [ - + ]:CBC 543 : return (ia->lower > ib->lower) ? 1 : -1;
71 : : }
72 : :
73 : : static float8
3091 andrew@dunslane.net 74 : 273 : gbt_float8_dist(const void *a, const void *b, FmgrInfo *flinfo)
75 : : {
5263 bruce@momjian.us 76 : 273 : float8 arg1 = *(const float8 *) a;
77 : 273 : float8 arg2 = *(const float8 *) b;
78 : : float8 r;
79 : :
5302 tgl@sss.pgh.pa.us 80 : 273 : r = arg1 - arg2;
1479 michael@paquier.xyz 81 [ - + - - : 273 : if (unlikely(isinf(r)) && !isinf(arg1) && !isinf(arg2))
- - ]
1479 michael@paquier.xyz 82 :UBC 0 : float_overflow_error();
1065 peter@eisentraut.org 83 :CBC 273 : return fabs(r);
84 : : }
85 : :
86 : :
87 : : static const gbtree_ninfo tinfo =
88 : : {
89 : : gbt_t_float8,
90 : : sizeof(float8),
91 : : 16, /* sizeof(gbtreekey16) */
92 : : gbt_float8gt,
93 : : gbt_float8ge,
94 : : gbt_float8eq,
95 : : gbt_float8le,
96 : : gbt_float8lt,
97 : : gbt_float8key_cmp,
98 : : gbt_float8_dist
99 : : };
100 : :
101 : :
5302 tgl@sss.pgh.pa.us 102 : 4 : PG_FUNCTION_INFO_V1(float8_dist);
103 : : Datum
104 : 547 : float8_dist(PG_FUNCTION_ARGS)
105 : : {
106 : 547 : float8 a = PG_GETARG_FLOAT8(0);
107 : 547 : float8 b = PG_GETARG_FLOAT8(1);
108 : : float8 r;
109 : :
110 : 547 : r = a - b;
1479 michael@paquier.xyz 111 [ - + - - : 547 : if (unlikely(isinf(r)) && !isinf(a) && !isinf(b))
- - ]
1479 michael@paquier.xyz 112 :UBC 0 : float_overflow_error();
113 : :
1065 peter@eisentraut.org 114 :CBC 547 : PG_RETURN_FLOAT8(fabs(r));
115 : : }
116 : :
117 : :
118 : : /**************************************************
119 : : * GiST support functions
120 : : **************************************************/
121 : :
122 : : Datum
7771 teodor@sigaev.ru 123 : 546 : gbt_float8_compress(PG_FUNCTION_ARGS)
124 : : {
7678 bruce@momjian.us 125 : 546 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
126 : :
3817 heikki.linnakangas@i 127 : 546 : PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
128 : : }
129 : :
130 : : Datum
3816 131 : 272 : gbt_float8_fetch(PG_FUNCTION_ARGS)
132 : : {
133 : 272 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
134 : :
135 : 272 : PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
136 : : }
137 : :
138 : : Datum
7771 teodor@sigaev.ru 139 : 1914 : gbt_float8_consistent(PG_FUNCTION_ARGS)
140 : : {
7678 bruce@momjian.us 141 : 1914 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
142 : 1914 : float8 query = PG_GETARG_FLOAT8(1);
6354 tgl@sss.pgh.pa.us 143 : 1914 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
144 : :
145 : : /* Oid subtype = PG_GETARG_OID(3); */
146 : 1914 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
7678 bruce@momjian.us 147 : 1914 : float8KEY *kkk = (float8KEY *) DatumGetPointer(entry->key);
148 : : GBT_NUMKEY_R key;
149 : :
150 : : /* All cases served by this function are exact */
6354 tgl@sss.pgh.pa.us 151 : 1914 : *recheck = false;
152 : :
5931 bruce@momjian.us 153 : 1914 : key.lower = (GBT_NUMKEY *) &kkk->lower;
154 : 1914 : key.upper = (GBT_NUMKEY *) &kkk->upper;
155 : :
282 peter@eisentraut.org 156 : 1914 : PG_RETURN_BOOL(gbt_num_consistent(&key, &query, &strategy,
157 : : GIST_LEAF(entry), &tinfo,
158 : : fcinfo->flinfo));
159 : : }
160 : :
161 : : Datum
5302 tgl@sss.pgh.pa.us 162 : 274 : gbt_float8_distance(PG_FUNCTION_ARGS)
163 : : {
164 : 274 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
165 : 274 : float8 query = PG_GETARG_FLOAT8(1);
166 : :
167 : : /* Oid subtype = PG_GETARG_OID(3); */
168 : 274 : float8KEY *kkk = (float8KEY *) DatumGetPointer(entry->key);
169 : : GBT_NUMKEY_R key;
170 : :
171 : 274 : key.lower = (GBT_NUMKEY *) &kkk->lower;
172 : 274 : key.upper = (GBT_NUMKEY *) &kkk->upper;
173 : :
282 peter@eisentraut.org 174 : 274 : PG_RETURN_FLOAT8(gbt_num_distance(&key, &query, GIST_LEAF(entry),
175 : : &tinfo, fcinfo->flinfo));
176 : : }
177 : :
178 : : Datum
7771 teodor@sigaev.ru 179 : 1 : gbt_float8_union(PG_FUNCTION_ARGS)
180 : : {
7678 bruce@momjian.us 181 : 1 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
182 : 1 : void *out = palloc(sizeof(float8KEY));
183 : :
184 : 1 : *(int *) PG_GETARG_POINTER(1) = sizeof(float8KEY);
282 peter@eisentraut.org 185 : 1 : PG_RETURN_POINTER(gbt_num_union(out, entryvec, &tinfo, fcinfo->flinfo));
186 : : }
187 : :
188 : : Datum
7771 teodor@sigaev.ru 189 :UBC 0 : gbt_float8_penalty(PG_FUNCTION_ARGS)
190 : : {
7678 bruce@momjian.us 191 : 0 : float8KEY *origentry = (float8KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
192 : 0 : float8KEY *newentry = (float8KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
193 : 0 : float *result = (float *) PG_GETARG_POINTER(2);
194 : :
7266 195 [ # # # # : 0 : penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
# # ]
196 : :
7678 197 : 0 : PG_RETURN_POINTER(result);
198 : : }
199 : :
200 : : Datum
7771 teodor@sigaev.ru 201 :CBC 1 : gbt_float8_picksplit(PG_FUNCTION_ARGS)
202 : : {
2046 alvherre@alvh.no-ip. 203 : 1 : PG_RETURN_POINTER(gbt_num_picksplit((GistEntryVector *) PG_GETARG_POINTER(0),
204 : : (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
205 : : &tinfo, fcinfo->flinfo));
206 : : }
207 : :
208 : : Datum
7771 teodor@sigaev.ru 209 :UBC 0 : gbt_float8_same(PG_FUNCTION_ARGS)
210 : : {
7678 bruce@momjian.us 211 : 0 : float8KEY *b1 = (float8KEY *) PG_GETARG_POINTER(0);
212 : 0 : float8KEY *b2 = (float8KEY *) PG_GETARG_POINTER(1);
213 : 0 : bool *result = (bool *) PG_GETARG_POINTER(2);
214 : :
3091 andrew@dunslane.net 215 : 0 : *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
7678 bruce@momjian.us 216 : 0 : PG_RETURN_POINTER(result);
217 : : }
218 : :
219 : : static int
156 heikki.linnakangas@i 220 :CBC 5277 : gbt_float8_ssup_cmp(Datum x, Datum y, SortSupport ssup)
221 : : {
222 : 5277 : float8KEY *arg1 = (float8KEY *) DatumGetPointer(x);
223 : 5277 : float8KEY *arg2 = (float8KEY *) DatumGetPointer(y);
224 : :
225 : : /* for leaf items we expect lower == upper, so only compare lower */
226 : 5277 : return float8_cmp_internal(arg1->lower, arg2->lower);
227 : : }
228 : :
229 : : Datum
230 : 1 : gbt_float8_sortsupport(PG_FUNCTION_ARGS)
231 : : {
232 : 1 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
233 : :
234 : 1 : ssup->comparator = gbt_float8_ssup_cmp;
235 : 1 : ssup->ssup_extra = NULL;
236 : :
237 : 1 : PG_RETURN_VOID();
238 : : }
|