Age Owner Branch data 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 : : #include "utils/sortsupport.h"
15 : :
16 : : /* GiST support functions */
7771 teodor@sigaev.ru 17 :CBC 5 : PG_FUNCTION_INFO_V1(gbt_numeric_compress);
18 : 5 : PG_FUNCTION_INFO_V1(gbt_numeric_union);
19 : 5 : PG_FUNCTION_INFO_V1(gbt_numeric_picksplit);
20 : 5 : PG_FUNCTION_INFO_V1(gbt_numeric_consistent);
21 : 5 : PG_FUNCTION_INFO_V1(gbt_numeric_penalty);
22 : 5 : PG_FUNCTION_INFO_V1(gbt_numeric_same);
156 heikki.linnakangas@i 23 : 5 : PG_FUNCTION_INFO_V1(gbt_numeric_sortsupport);
24 : :
25 : :
26 : : /* define for comparison */
27 : :
28 : : static bool
3091 andrew@dunslane.net 29 : 2180 : gbt_numeric_gt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
30 : : {
5251 tgl@sss.pgh.pa.us 31 : 2180 : return DatumGetBool(DirectFunctionCall2(numeric_gt,
32 : : PointerGetDatum(a),
33 : : PointerGetDatum(b)));
34 : : }
35 : :
36 : : static bool
3091 andrew@dunslane.net 37 : 2193 : gbt_numeric_ge(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
38 : : {
5251 tgl@sss.pgh.pa.us 39 : 2193 : return DatumGetBool(DirectFunctionCall2(numeric_ge,
40 : : PointerGetDatum(a),
41 : : PointerGetDatum(b)));
42 : : }
43 : :
44 : : static bool
3091 andrew@dunslane.net 45 : 568 : gbt_numeric_eq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
46 : : {
5251 tgl@sss.pgh.pa.us 47 : 568 : return DatumGetBool(DirectFunctionCall2(numeric_eq,
48 : : PointerGetDatum(a),
49 : : PointerGetDatum(b)));
50 : : }
51 : :
52 : : static bool
3091 andrew@dunslane.net 53 : 1959 : gbt_numeric_le(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
54 : : {
5251 tgl@sss.pgh.pa.us 55 : 1959 : return DatumGetBool(DirectFunctionCall2(numeric_le,
56 : : PointerGetDatum(a),
57 : : PointerGetDatum(b)));
58 : : }
59 : :
60 : : static bool
3091 andrew@dunslane.net 61 : 1689 : gbt_numeric_lt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
62 : : {
5251 tgl@sss.pgh.pa.us 63 : 1689 : return DatumGetBool(DirectFunctionCall2(numeric_lt,
64 : : PointerGetDatum(a),
65 : : PointerGetDatum(b)));
66 : : }
67 : :
68 : : static int32
3091 andrew@dunslane.net 69 : 43570 : gbt_numeric_cmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
70 : : {
5251 tgl@sss.pgh.pa.us 71 : 43570 : 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 : :
96 : : Datum
7678 bruce@momjian.us 97 : 3151 : gbt_numeric_compress(PG_FUNCTION_ARGS)
98 : : {
99 : 3151 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
100 : :
101 : 3151 : PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo));
102 : : }
103 : :
104 : : Datum
7771 teodor@sigaev.ru 105 : 8705 : gbt_numeric_consistent(PG_FUNCTION_ARGS)
106 : : {
7678 bruce@momjian.us 107 : 8705 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
282 peter@eisentraut.org 108 : 8705 : void *query = DatumGetNumeric(PG_GETARG_DATUM(1));
7678 bruce@momjian.us 109 : 8705 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
110 : :
111 : : /* Oid subtype = PG_GETARG_OID(3); */
6354 tgl@sss.pgh.pa.us 112 : 8705 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
113 : : bool retval;
114 : 8705 : GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
7678 bruce@momjian.us 115 : 8705 : GBT_VARKEY_R r = gbt_var_key_readable(key);
116 : :
117 : : /* All cases served by this function are exact */
6354 tgl@sss.pgh.pa.us 118 : 8705 : *recheck = false;
119 : :
5251 120 : 17410 : retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
3091 andrew@dunslane.net 121 : 8705 : GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
7678 bruce@momjian.us 122 : 8705 : PG_RETURN_BOOL(retval);
123 : : }
124 : :
125 : : Datum
7771 teodor@sigaev.ru 126 : 1859 : gbt_numeric_union(PG_FUNCTION_ARGS)
127 : : {
7678 bruce@momjian.us 128 : 1859 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
129 : 1859 : int32 *size = (int *) PG_GETARG_POINTER(1);
130 : :
5251 tgl@sss.pgh.pa.us 131 : 1859 : PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
132 : : &tinfo, fcinfo->flinfo));
133 : : }
134 : :
135 : : Datum
7771 teodor@sigaev.ru 136 : 1814 : gbt_numeric_same(PG_FUNCTION_ARGS)
137 : : {
7678 bruce@momjian.us 138 : 1814 : Datum d1 = PG_GETARG_DATUM(0);
139 : 1814 : Datum d2 = PG_GETARG_DATUM(1);
140 : 1814 : bool *result = (bool *) PG_GETARG_POINTER(2);
141 : :
3091 andrew@dunslane.net 142 : 1814 : *result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
5251 tgl@sss.pgh.pa.us 143 : 1814 : PG_RETURN_POINTER(result);
144 : : }
145 : :
146 : : Datum
7678 bruce@momjian.us 147 : 3515 : gbt_numeric_penalty(PG_FUNCTION_ARGS)
148 : : {
149 : 3515 : GISTENTRY *o = (GISTENTRY *) PG_GETARG_POINTER(0);
150 : 3515 : GISTENTRY *n = (GISTENTRY *) PG_GETARG_POINTER(1);
151 : 3515 : float *result = (float *) PG_GETARG_POINTER(2);
152 : :
153 : : Numeric us,
154 : : os,
155 : : ds;
156 : :
157 : 3515 : GBT_VARKEY *org = (GBT_VARKEY *) DatumGetPointer(o->key);
158 : 3515 : GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key);
159 : : Datum uni;
160 : : GBT_VARKEY_R rk,
161 : : ok,
162 : : uk;
163 : :
164 : 3515 : rk = gbt_var_key_readable(org);
3817 heikki.linnakangas@i 165 : 3515 : uni = PointerGetDatum(gbt_var_key_copy(&rk));
3091 andrew@dunslane.net 166 : 3515 : gbt_var_bin_union(&uni, newe, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
7678 bruce@momjian.us 167 : 3515 : ok = gbt_var_key_readable(org);
168 : 3515 : uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(uni));
169 : :
2046 alvherre@alvh.no-ip. 170 : 3515 : us = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
171 : : PointerGetDatum(uk.upper),
172 : : PointerGetDatum(uk.lower)));
173 : :
174 : 3515 : os = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
175 : : PointerGetDatum(ok.upper),
176 : : PointerGetDatum(ok.lower)));
177 : :
178 : 3515 : ds = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
179 : : NumericGetDatum(us),
180 : : NumericGetDatum(os)));
181 : :
5517 rhaas@postgresql.org 182 [ - + ]: 3515 : if (numeric_is_nan(us))
183 : : {
5517 rhaas@postgresql.org 184 [ # # ]:UBC 0 : if (numeric_is_nan(os))
7678 bruce@momjian.us 185 : 0 : *result = 0.0;
186 : : else
187 : 0 : *result = 1.0;
188 : : }
189 : : else
190 : : {
1823 peter@eisentraut.org 191 :CBC 3515 : Numeric nul = int64_to_numeric(0);
192 : :
7678 bruce@momjian.us 193 : 3515 : *result = 0.0;
194 : :
29 peter@eisentraut.org 195 [ + + ]:GNC 3515 : if (DatumGetBool(DirectFunctionCall2(numeric_gt, NumericGetDatum(ds), NumericGetDatum(nul))))
196 : : {
7678 bruce@momjian.us 197 :CBC 14 : *result += FLT_MIN;
2046 alvherre@alvh.no-ip. 198 : 14 : os = DatumGetNumeric(DirectFunctionCall2(numeric_div,
199 : : NumericGetDatum(ds),
200 : : NumericGetDatum(us)));
7678 bruce@momjian.us 201 : 14 : *result += (float4) DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow, NumericGetDatum(os)));
202 : : }
203 : : }
204 : :
205 [ + + ]: 3515 : if (*result > 0)
206 : 14 : *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
207 : :
208 : 3515 : PG_RETURN_POINTER(result);
209 : : }
210 : :
211 : : Datum
7771 teodor@sigaev.ru 212 : 24 : gbt_numeric_picksplit(PG_FUNCTION_ARGS)
213 : : {
7678 bruce@momjian.us 214 : 24 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
215 : 24 : GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
216 : :
5251 tgl@sss.pgh.pa.us 217 : 24 : gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
218 : : &tinfo, fcinfo->flinfo);
7678 bruce@momjian.us 219 : 24 : PG_RETURN_POINTER(v);
220 : : }
221 : :
222 : : static int
156 heikki.linnakangas@i 223 : 11619 : gbt_numeric_ssup_cmp(Datum x, Datum y, SortSupport ssup)
224 : : {
225 : 11619 : GBT_VARKEY *key1 = PG_DETOAST_DATUM(x);
226 : 11619 : GBT_VARKEY *key2 = PG_DETOAST_DATUM(y);
227 : :
228 : 11619 : GBT_VARKEY_R arg1 = gbt_var_key_readable(key1);
229 : 11619 : 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 : 11619 : result = DirectFunctionCall2(numeric_cmp,
234 : : PointerGetDatum(arg1.lower),
235 : : PointerGetDatum(arg2.lower));
236 : :
237 [ + + ]: 11619 : GBT_FREE_IF_COPY(key1, x);
238 [ + + ]: 11619 : GBT_FREE_IF_COPY(key2, y);
239 : :
240 : 11619 : return DatumGetInt32(result);
241 : : }
242 : :
243 : : Datum
244 : 2 : gbt_numeric_sortsupport(PG_FUNCTION_ARGS)
245 : : {
246 : 2 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
247 : :
248 : 2 : ssup->comparator = gbt_numeric_ssup_cmp;
249 : 2 : ssup->ssup_extra = NULL;
250 : :
251 : 2 : PG_RETURN_VOID();
252 : : }
|