PostgreSQL Source Code git master
Loading...
Searching...
No Matches
btree_float8.c
Go to the documentation of this file.
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
17
18/* GiST support functions */
28
29
30/*
31 * Use the NaN-aware comparators from utils/float.h, so that our results
32 * will agree with standard btree indexes. Note that penalty and distance
33 * functions below must also cope with NaNs, in particular with the policy
34 * that all NaNs are equal.
35 */
36static bool
37gbt_float8gt(const void *a, const void *b, FmgrInfo *flinfo)
38{
39 return float8_gt(*((const float8 *) a), *((const float8 *) b));
40}
41static bool
42gbt_float8ge(const void *a, const void *b, FmgrInfo *flinfo)
43{
44 return float8_ge(*((const float8 *) a), *((const float8 *) b));
45}
46static bool
47gbt_float8eq(const void *a, const void *b, FmgrInfo *flinfo)
48{
49 return float8_eq(*((const float8 *) a), *((const float8 *) b));
50}
51static bool
52gbt_float8le(const void *a, const void *b, FmgrInfo *flinfo)
53{
54 return float8_le(*((const float8 *) a), *((const float8 *) b));
55}
56static bool
57gbt_float8lt(const void *a, const void *b, FmgrInfo *flinfo)
58{
59 return float8_lt(*((const float8 *) a), *((const float8 *) b));
60}
61
62static int
63gbt_float8key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
64{
65 float8KEY *ia = (float8KEY *) (((const Nsrt *) a)->t);
66 float8KEY *ib = (float8KEY *) (((const Nsrt *) b)->t);
67 int res;
68
69 res = float8_cmp_internal(ia->lower, ib->lower);
70 if (res != 0)
71 return res;
72 return float8_cmp_internal(ia->upper, ib->upper);
73}
74
75static float8
76gbt_float8_dist(const void *a, const void *b, FmgrInfo *flinfo)
77{
78 float8 arg1 = *(const float8 *) a;
79 float8 arg2 = *(const float8 *) b;
80 float8 r;
81
82 r = arg1 - arg2;
83 if (unlikely(isinf(r)) && !isinf(arg1) && !isinf(arg2))
85 if (unlikely(isnan(r)))
86 {
87 if (isnan(arg1) && isnan(arg2))
88 r = 0.0; /* treat NaNs as equal */
89 else if (isnan(arg1) || isnan(arg2))
90 r = get_float8_infinity(); /* max dist for NaN vs non-NaN */
91 else
92 r = 0.0; /* must be Inf - Inf case */
93 }
94 return fabs(r);
95}
96
97
98static const gbtree_ninfo tinfo =
99{
101 sizeof(float8),
102 16, /* sizeof(gbtreekey16) */
110};
111
112
114Datum
116{
119 float8 r;
120
121 r = a - b;
122 if (unlikely(isinf(r)) && !isinf(a) && !isinf(b))
124 if (unlikely(isnan(r)))
125 {
126 if (isnan(a) && isnan(b))
127 r = 0.0; /* treat NaNs as equal */
128 else if (isnan(a) || isnan(b))
129 r = get_float8_infinity(); /* max dist for NaN vs non-NaN */
130 else
131 r = 0.0; /* must be Inf - Inf case */
132 }
134}
135
136
137/**************************************************
138 * GiST support functions
139 **************************************************/
140
141Datum
148
149Datum
156
157Datum
159{
160 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
161 float8 query = PG_GETARG_FLOAT8(1);
163#ifdef NOT_USED
164 Oid subtype = PG_GETARG_OID(3);
165#endif
166 bool *recheck = (bool *) PG_GETARG_POINTER(4);
168 GBT_NUMKEY_R key;
169
170 /* All cases served by this function are exact */
171 *recheck = false;
172
173 key.lower = (GBT_NUMKEY *) &kkk->lower;
174 key.upper = (GBT_NUMKEY *) &kkk->upper;
175
176 PG_RETURN_BOOL(gbt_num_consistent(&key, &query, strategy,
177 GIST_LEAF(entry), &tinfo,
178 fcinfo->flinfo));
179}
180
181Datum
183{
184 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
185 float8 query = PG_GETARG_FLOAT8(1);
186#ifdef NOT_USED
187 Oid subtype = PG_GETARG_OID(3);
188#endif
190 GBT_NUMKEY_R key;
191
192 key.lower = (GBT_NUMKEY *) &kkk->lower;
193 key.upper = (GBT_NUMKEY *) &kkk->upper;
194
195 PG_RETURN_FLOAT8(gbt_num_distance(&key, &query, GIST_LEAF(entry),
196 &tinfo, fcinfo->flinfo));
197}
198
199Datum
201{
203 void *out = palloc(sizeof(float8KEY));
204
205 *(int *) PG_GETARG_POINTER(1) = sizeof(float8KEY);
206 PG_RETURN_POINTER(gbt_num_union(out, entryvec, &tinfo, fcinfo->flinfo));
207}
208
209Datum
220
221Datum
228
229Datum
231{
234 bool *result = (bool *) PG_GETARG_POINTER(2);
235
236 *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
238}
239
240static int
242{
245
246 /* for leaf items we expect lower == upper, so only compare lower */
247 return float8_cmp_internal(arg1->lower, arg2->lower);
248}
249
250Datum
Datum gbt_float8_same(PG_FUNCTION_ARGS)
struct float8key float8KEY
static int gbt_float8_ssup_cmp(Datum x, Datum y, SortSupport ssup)
static bool gbt_float8eq(const void *a, const void *b, FmgrInfo *flinfo)
Datum gbt_float8_picksplit(PG_FUNCTION_ARGS)
static bool gbt_float8gt(const void *a, const void *b, FmgrInfo *flinfo)
Datum gbt_float8_sortsupport(PG_FUNCTION_ARGS)
static float8 gbt_float8_dist(const void *a, const void *b, FmgrInfo *flinfo)
static const gbtree_ninfo tinfo
Datum gbt_float8_compress(PG_FUNCTION_ARGS)
Datum gbt_float8_fetch(PG_FUNCTION_ARGS)
Datum gbt_float8_distance(PG_FUNCTION_ARGS)
static bool gbt_float8le(const void *a, const void *b, FmgrInfo *flinfo)
static bool gbt_float8ge(const void *a, const void *b, FmgrInfo *flinfo)
static int gbt_float8key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
Datum float8_dist(PG_FUNCTION_ARGS)
Datum gbt_float8_union(PG_FUNCTION_ARGS)
static bool gbt_float8lt(const void *a, const void *b, FmgrInfo *flinfo)
Datum gbt_float8_penalty(PG_FUNCTION_ARGS)
Datum gbt_float8_consistent(PG_FUNCTION_ARGS)
@ gbt_t_float8
Definition btree_gist.h:21
GISTENTRY * gbt_num_compress(GISTENTRY *entry, const gbtree_ninfo *tinfo)
float8 gbt_num_distance(const GBT_NUMKEY_R *key, const void *query, bool is_leaf, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
bool gbt_num_consistent(const GBT_NUMKEY_R *key, const void *query, StrategyNumber strategy, bool is_leaf, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
bool gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
GISTENTRY * gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo)
GIST_SPLITVEC * gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
void * gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
char GBT_NUMKEY
#define float_penalty_num(result, olower, oupper, nlower, nupper)
double float8
Definition c.h:773
#define unlikely(x)
Definition c.h:497
uint32 result
struct SortSupportData * SortSupport
Definition execnodes.h:61
pg_noinline void float_overflow_error(void)
Definition float.c:103
int float8_cmp_internal(float8 a, float8 b)
Definition float.c:951
static float8 get_float8_infinity(void)
Definition float.h:68
static bool float8_ge(const float8 val1, const float8 val2)
Definition float.h:310
static bool float8_le(const float8 val1, const float8 val2)
Definition float.h:286
static bool float8_eq(const float8 val1, const float8 val2)
Definition float.h:250
static bool float8_lt(const float8 val1, const float8 val2)
Definition float.h:274
static bool float8_gt(const float8 val1, const float8 val2)
Definition float.h:298
#define PG_RETURN_VOID()
Definition fmgr.h:350
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_GETARG_FLOAT8(n)
Definition fmgr.h:283
#define PG_RETURN_FLOAT8(x)
Definition fmgr.h:369
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
#define PG_FUNCTION_INFO_V1(funcname)
Definition fmgr.h:417
#define PG_GETARG_UINT16(n)
Definition fmgr.h:272
#define PG_RETURN_POINTER(x)
Definition fmgr.h:363
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
#define GIST_LEAF(entry)
Definition gist.h:171
int y
Definition isn.c:76
int b
Definition isn.c:74
int x
Definition isn.c:75
int a
Definition isn.c:73
void * palloc(Size size)
Definition mcxt.c:1390
uint64_t Datum
Definition postgres.h:70
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:332
unsigned int Oid
static int fb(int x)
uint16 StrategyNumber
Definition stratnum.h:22
Datum key
Definition gist.h:161
int(* comparator)(Datum x, Datum y, SortSupport ssup)
float8 upper
float8 lower