Age Owner TLA Line data Source code
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 :
15 : /*
16 : ** Bytea ops
17 : */
6890 teodor 18 CBC 3 : PG_FUNCTION_INFO_V1(gbt_numeric_compress);
19 3 : PG_FUNCTION_INFO_V1(gbt_numeric_union);
20 3 : PG_FUNCTION_INFO_V1(gbt_numeric_picksplit);
21 3 : PG_FUNCTION_INFO_V1(gbt_numeric_consistent);
22 3 : PG_FUNCTION_INFO_V1(gbt_numeric_penalty);
23 3 : PG_FUNCTION_INFO_V1(gbt_numeric_same);
24 :
25 :
26 : /* define for comparison */
27 :
28 : static bool
2210 andrew 29 2762 : gbt_numeric_gt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
30 : {
4370 tgl 31 2762 : return DatumGetBool(DirectFunctionCall2(numeric_gt,
32 : PointerGetDatum(a),
33 : PointerGetDatum(b)));
34 : }
35 :
36 : static bool
2210 andrew 37 3066 : gbt_numeric_ge(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
38 : {
4370 tgl 39 3066 : return DatumGetBool(DirectFunctionCall2(numeric_ge,
40 : PointerGetDatum(a),
41 : PointerGetDatum(b)));
42 : }
43 :
44 : static bool
2210 andrew 45 1356 : gbt_numeric_eq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
46 : {
4370 tgl 47 1356 : return DatumGetBool(DirectFunctionCall2(numeric_eq,
48 : PointerGetDatum(a),
49 : PointerGetDatum(b)));
50 : }
51 :
52 : static bool
2210 andrew 53 2466 : gbt_numeric_le(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
54 : {
4370 tgl 55 2466 : return DatumGetBool(DirectFunctionCall2(numeric_le,
56 : PointerGetDatum(a),
57 : PointerGetDatum(b)));
58 : }
59 :
60 : static bool
2210 andrew 61 1895 : gbt_numeric_lt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
62 : {
4370 tgl 63 1895 : return DatumGetBool(DirectFunctionCall2(numeric_lt,
64 : PointerGetDatum(a),
65 : PointerGetDatum(b)));
66 : }
67 :
68 : static int32
2210 andrew 69 60672 : gbt_numeric_cmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
70 : {
4370 tgl 71 60672 : 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 : * Text ops
94 : **************************************************/
95 :
96 :
97 : Datum
6797 bruce 98 3173 : gbt_numeric_compress(PG_FUNCTION_ARGS)
99 : {
100 3173 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
101 :
102 3173 : PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo));
103 : }
104 :
105 :
106 :
107 : Datum
6890 teodor 108 11661 : gbt_numeric_consistent(PG_FUNCTION_ARGS)
109 : {
6797 bruce 110 11661 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
111 11661 : void *query = (void *) DatumGetNumeric(PG_GETARG_DATUM(1));
112 11661 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
113 :
114 : /* Oid subtype = PG_GETARG_OID(3); */
5473 tgl 115 11661 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
116 : bool retval;
117 11661 : GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
6797 bruce 118 11661 : GBT_VARKEY_R r = gbt_var_key_readable(key);
119 :
120 : /* All cases served by this function are exact */
5473 tgl 121 11661 : *recheck = false;
122 :
4370 123 23322 : retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
2210 andrew 124 11661 : GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
6797 bruce 125 11661 : PG_RETURN_BOOL(retval);
126 : }
127 :
128 :
129 :
130 : Datum
6890 teodor 131 2745 : gbt_numeric_union(PG_FUNCTION_ARGS)
132 : {
6797 bruce 133 2745 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
134 2745 : int32 *size = (int *) PG_GETARG_POINTER(1);
135 :
4370 tgl 136 2745 : PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
137 : &tinfo, fcinfo->flinfo));
138 : }
139 :
140 :
141 : Datum
6890 teodor 142 2700 : gbt_numeric_same(PG_FUNCTION_ARGS)
143 : {
6797 bruce 144 2700 : Datum d1 = PG_GETARG_DATUM(0);
145 2700 : Datum d2 = PG_GETARG_DATUM(1);
146 2700 : bool *result = (bool *) PG_GETARG_POINTER(2);
147 :
2210 andrew 148 2700 : *result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
4370 tgl 149 2700 : PG_RETURN_POINTER(result);
150 : }
151 :
152 :
153 : Datum
6797 bruce 154 6129 : gbt_numeric_penalty(PG_FUNCTION_ARGS)
155 : {
156 6129 : GISTENTRY *o = (GISTENTRY *) PG_GETARG_POINTER(0);
157 6129 : GISTENTRY *n = (GISTENTRY *) PG_GETARG_POINTER(1);
158 6129 : float *result = (float *) PG_GETARG_POINTER(2);
159 :
160 : Numeric us,
161 : os,
162 : ds;
163 :
164 6129 : GBT_VARKEY *org = (GBT_VARKEY *) DatumGetPointer(o->key);
165 6129 : GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key);
166 : Datum uni;
167 : GBT_VARKEY_R rk,
168 : ok,
169 : uk;
170 :
171 6129 : rk = gbt_var_key_readable(org);
2936 heikki.linnakangas 172 6129 : uni = PointerGetDatum(gbt_var_key_copy(&rk));
2210 andrew 173 6129 : gbt_var_bin_union(&uni, newe, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
6797 bruce 174 6129 : ok = gbt_var_key_readable(org);
175 6129 : uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(uni));
176 :
1165 alvherre 177 6129 : us = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
178 : PointerGetDatum(uk.upper),
179 : PointerGetDatum(uk.lower)));
180 :
181 6129 : os = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
182 : PointerGetDatum(ok.upper),
183 : PointerGetDatum(ok.lower)));
184 :
185 6129 : ds = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
186 : NumericGetDatum(us),
187 : NumericGetDatum(os)));
188 :
4636 rhaas 189 6129 : if (numeric_is_nan(us))
190 : {
191 370 : if (numeric_is_nan(os))
6797 bruce 192 366 : *result = 0.0;
193 : else
194 4 : *result = 1.0;
195 : }
196 : else
197 : {
942 peter 198 5759 : Numeric nul = int64_to_numeric(0);
199 :
6797 bruce 200 5759 : *result = 0.0;
201 :
202 5759 : if (DirectFunctionCall2(numeric_gt, NumericGetDatum(ds), NumericGetDatum(nul)))
203 : {
204 1433 : *result += FLT_MIN;
1165 alvherre 205 1433 : os = DatumGetNumeric(DirectFunctionCall2(numeric_div,
206 : NumericGetDatum(ds),
207 : NumericGetDatum(us)));
6797 bruce 208 1433 : *result += (float4) DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow, NumericGetDatum(os)));
209 : }
210 : }
211 :
212 6129 : if (*result > 0)
213 1437 : *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
214 :
215 6129 : PG_RETURN_POINTER(result);
216 : }
217 :
218 :
219 :
220 : Datum
6890 teodor 221 25 : gbt_numeric_picksplit(PG_FUNCTION_ARGS)
222 : {
6797 bruce 223 25 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
224 25 : GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
225 :
4370 tgl 226 25 : gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
227 : &tinfo, fcinfo->flinfo);
6797 bruce 228 25 : PG_RETURN_POINTER(v);
229 : }
|