PostgreSQL Source Code: contrib/btree_gist/btree_numeric.c Source File

PostgreSQL Source Code git master
btree_numeric.c
Go to the documentation of this file.
1/*
2 * contrib/btree_gist/btree_numeric.c
3 */
4#include "postgres.h"
5
6#include <math.h>
7#include <float.h>
8
9#include "btree_gist.h"
10#include "btree_utils_var.h"
11#include "utils/builtins.h"
12#include "utils/numeric.h"
13#include "utils/rel.h"
14#include "utils/sortsupport.h"
15
16/* GiST support functions */
17 PG_FUNCTION_INFO_V1(gbt_numeric_compress);
18 PG_FUNCTION_INFO_V1(gbt_numeric_union);
19 PG_FUNCTION_INFO_V1(gbt_numeric_picksplit);
20 PG_FUNCTION_INFO_V1(gbt_numeric_consistent);
21 PG_FUNCTION_INFO_V1(gbt_numeric_penalty);
22 PG_FUNCTION_INFO_V1(gbt_numeric_same);
23 PG_FUNCTION_INFO_V1(gbt_numeric_sortsupport);
24
25
26/* define for comparison */
27
28static bool
29 gbt_numeric_gt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
30{
31 return DatumGetBool(DirectFunctionCall2(numeric_gt,
32 PointerGetDatum(a),
33 PointerGetDatum(b)));
34}
35
36static bool
37 gbt_numeric_ge(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
38{
39 return DatumGetBool(DirectFunctionCall2(numeric_ge,
40 PointerGetDatum(a),
41 PointerGetDatum(b)));
42}
43
44static bool
45 gbt_numeric_eq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
46{
47 return DatumGetBool(DirectFunctionCall2(numeric_eq,
48 PointerGetDatum(a),
49 PointerGetDatum(b)));
50}
51
52static bool
53 gbt_numeric_le(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
54{
55 return DatumGetBool(DirectFunctionCall2(numeric_le,
56 PointerGetDatum(a),
57 PointerGetDatum(b)));
58}
59
60static bool
61 gbt_numeric_lt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
62{
63 return DatumGetBool(DirectFunctionCall2(numeric_lt,
64 PointerGetDatum(a),
65 PointerGetDatum(b)));
66}
67
68static int32
69 gbt_numeric_cmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
70{
71 return DatumGetInt32(DirectFunctionCall2(numeric_cmp,
72 PointerGetDatum(a),
73 PointerGetDatum(b)));
74}
75
76
77 static const gbtree_vinfo tinfo =
78{
79 gbt_t_numeric,
80 0,
81 false,
82 gbt_numeric_gt,
83 gbt_numeric_ge,
84 gbt_numeric_eq,
85 gbt_numeric_le,
86 gbt_numeric_lt,
87 gbt_numeric_cmp,
88 NULL
89};
90
91
92/**************************************************
93 * GiST support functions
94 **************************************************/
95
96Datum
97 gbt_numeric_compress(PG_FUNCTION_ARGS)
98{
99 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
100
101 PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo));
102}
103
104Datum
105 gbt_numeric_consistent(PG_FUNCTION_ARGS)
106{
107 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
108 void *query = DatumGetNumeric(PG_GETARG_DATUM(1));
109 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
110
111 /* Oid subtype = PG_GETARG_OID(3); */
112 bool *recheck = (bool *) PG_GETARG_POINTER(4);
113 bool retval;
114 GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
115 GBT_VARKEY_R r = gbt_var_key_readable(key);
116
117 /* All cases served by this function are exact */
118 *recheck = false;
119
120 retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
121 GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
122 PG_RETURN_BOOL(retval);
123}
124
125Datum
126 gbt_numeric_union(PG_FUNCTION_ARGS)
127{
128 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
129 int32 *size = (int *) PG_GETARG_POINTER(1);
130
131 PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
132 &tinfo, fcinfo->flinfo));
133}
134
135Datum
136 gbt_numeric_same(PG_FUNCTION_ARGS)
137{
138 Datum d1 = PG_GETARG_DATUM(0);
139 Datum d2 = PG_GETARG_DATUM(1);
140 bool *result = (bool *) PG_GETARG_POINTER(2);
141
142 *result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
143 PG_RETURN_POINTER(result);
144}
145
146Datum
147 gbt_numeric_penalty(PG_FUNCTION_ARGS)
148{
149 GISTENTRY *o = (GISTENTRY *) PG_GETARG_POINTER(0);
150 GISTENTRY *n = (GISTENTRY *) PG_GETARG_POINTER(1);
151 float *result = (float *) PG_GETARG_POINTER(2);
152
153 Numeric us,
154 os,
155 ds;
156
157 GBT_VARKEY *org = (GBT_VARKEY *) DatumGetPointer(o->key);
158 GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key);
159 Datum uni;
160 GBT_VARKEY_R rk,
161 ok,
162 uk;
163
164 rk = gbt_var_key_readable(org);
165 uni = PointerGetDatum(gbt_var_key_copy(&rk));
166 gbt_var_bin_union(&uni, newe, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
167 ok = gbt_var_key_readable(org);
168 uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(uni));
169
170 us = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
171 PointerGetDatum(uk.upper),
172 PointerGetDatum(uk.lower)));
173
174 os = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
175 PointerGetDatum(ok.upper),
176 PointerGetDatum(ok.lower)));
177
178 ds = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
179 NumericGetDatum(us),
180 NumericGetDatum(os)));
181
182 if (numeric_is_nan(us))
183 {
184 if (numeric_is_nan(os))
185 *result = 0.0;
186 else
187 *result = 1.0;
188 }
189 else
190 {
191 Numeric nul = int64_to_numeric(0);
192
193 *result = 0.0;
194
195 if (DatumGetBool(DirectFunctionCall2(numeric_gt, NumericGetDatum(ds), NumericGetDatum(nul))))
196 {
197 *result += FLT_MIN;
198 os = DatumGetNumeric(DirectFunctionCall2(numeric_div,
199 NumericGetDatum(ds),
200 NumericGetDatum(us)));
201 *result += (float4) DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow, NumericGetDatum(os)));
202 }
203 }
204
205 if (*result > 0)
206 *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
207
208 PG_RETURN_POINTER(result);
209}
210
211Datum
212 gbt_numeric_picksplit(PG_FUNCTION_ARGS)
213{
214 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
215 GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
216
217 gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
218 &tinfo, fcinfo->flinfo);
219 PG_RETURN_POINTER(v);
220}
221
222static int
223 gbt_numeric_ssup_cmp(Datum x, Datum y, SortSupport ssup)
224{
225 GBT_VARKEY *key1 = PG_DETOAST_DATUM(x);
226 GBT_VARKEY *key2 = PG_DETOAST_DATUM(y);
227
228 GBT_VARKEY_R arg1 = gbt_var_key_readable(key1);
229 GBT_VARKEY_R arg2 = gbt_var_key_readable(key2);
230 Datum result;
231
232 /* for leaf items we expect lower == upper, so only compare lower */
233 result = DirectFunctionCall2(numeric_cmp,
234 PointerGetDatum(arg1.lower),
235 PointerGetDatum(arg2.lower));
236
237 GBT_FREE_IF_COPY(key1, x);
238 GBT_FREE_IF_COPY(key2, y);
239
240 return DatumGetInt32(result);
241}
242
243Datum
244 gbt_numeric_sortsupport(PG_FUNCTION_ARGS)
245{
246 SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
247
248 ssup->comparator = gbt_numeric_ssup_cmp;
249 ssup->ssup_extra = NULL;
250
251 PG_RETURN_VOID();
252}
Datum numeric_div(PG_FUNCTION_ARGS)
Definition: numeric.c:3135
Datum numeric_sub(PG_FUNCTION_ARGS)
Definition: numeric.c:2940
Datum numeric_cmp(PG_FUNCTION_ARGS)
Definition: numeric.c:2416
Numeric int64_to_numeric(int64 val)
Definition: numeric.c:4260
Datum numeric_ge(PG_FUNCTION_ARGS)
Definition: numeric.c:2477
Datum numeric_le(PG_FUNCTION_ARGS)
Definition: numeric.c:2507
bool numeric_is_nan(Numeric num)
Definition: numeric.c:834
Datum numeric_lt(PG_FUNCTION_ARGS)
Definition: numeric.c:2492
Datum numeric_float8_no_overflow(PG_FUNCTION_ARGS)
Definition: numeric.c:4590
Datum numeric_eq(PG_FUNCTION_ARGS)
Definition: numeric.c:2432
Datum numeric_gt(PG_FUNCTION_ARGS)
Definition: numeric.c:2462
@ gbt_t_numeric
Definition: btree_gist.h:22
Datum gbt_numeric_same(PG_FUNCTION_ARGS)
Definition: btree_numeric.c:136
static bool gbt_numeric_gt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
Definition: btree_numeric.c:29
static int gbt_numeric_ssup_cmp(Datum x, Datum y, SortSupport ssup)
Definition: btree_numeric.c:223
Datum gbt_numeric_picksplit(PG_FUNCTION_ARGS)
Definition: btree_numeric.c:212
static int32 gbt_numeric_cmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
Definition: btree_numeric.c:69
static bool gbt_numeric_eq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
Definition: btree_numeric.c:45
Datum gbt_numeric_union(PG_FUNCTION_ARGS)
Definition: btree_numeric.c:126
static bool gbt_numeric_ge(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
Definition: btree_numeric.c:37
Datum gbt_numeric_sortsupport(PG_FUNCTION_ARGS)
Definition: btree_numeric.c:244
static const gbtree_vinfo tinfo
Definition: btree_numeric.c:77
static bool gbt_numeric_lt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
Definition: btree_numeric.c:61
Datum gbt_numeric_consistent(PG_FUNCTION_ARGS)
Definition: btree_numeric.c:105
static bool gbt_numeric_le(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
Definition: btree_numeric.c:53
Datum gbt_numeric_compress(PG_FUNCTION_ARGS)
Definition: btree_numeric.c:97
PG_FUNCTION_INFO_V1(gbt_numeric_compress)
Datum gbt_numeric_penalty(PG_FUNCTION_ARGS)
Definition: btree_numeric.c:147
GBT_VARKEY * gbt_var_union(const GistEntryVector *entryvec, int32 *size, Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
bool gbt_var_consistent(GBT_VARKEY_R *key, const void *query, StrategyNumber strategy, Oid collation, bool is_leaf, const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
GISTENTRY * gbt_var_compress(GISTENTRY *entry, const gbtree_vinfo *tinfo)
GIST_SPLITVEC * gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
GBT_VARKEY_R gbt_var_key_readable(const GBT_VARKEY *k)
GBT_VARKEY * gbt_var_key_copy(const GBT_VARKEY_R *u)
bool gbt_var_same(Datum d1, Datum d2, Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
void gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
#define GBT_FREE_IF_COPY(ptr1, ptr2)
int32_t int32
Definition: c.h:534
float float4
Definition: c.h:634
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:684
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:682
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:272
#define PG_DETOAST_DATUM(datum)
Definition: fmgr.h:240
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define GIST_LEAF(entry)
Definition: gist.h:171
y
int y
Definition: isn.c:76
b
int b
Definition: isn.c:74
x
int x
Definition: isn.c:75
a
int a
Definition: isn.c:73
static Numeric DatumGetNumeric(Datum X)
Definition: numeric.h:64
static Datum NumericGetDatum(Numeric X)
Definition: numeric.h:76
static bool DatumGetBool(Datum X)
Definition: postgres.h:100
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:332
static float8 DatumGetFloat8(Datum X)
Definition: postgres.h:475
uint64_t Datum
Definition: postgres.h:70
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:322
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:212
unsigned int Oid
Definition: postgres_ext.h:32
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
uint16 StrategyNumber
Definition: stratnum.h:22
Definition: fmgr.h:57
bytea * upper
bytea * lower
Definition: gist.h:160
Datum key
Definition: gist.h:161
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:106
void * ssup_extra
Definition: sortsupport.h:87
Definition: c.h:692

AltStyle によって変換されたページ (->オリジナル) /