Fix xslt_process() to ensure that it inserts a NULL terminator after the
[PostgreSQL.git] / contrib / btree_gist / btree_numeric.c
blob373d12eedb37dd0f03099ac08b8fb385f3fc045b
1 /*
2 * $PostgreSQL$
3 */
4 #include "btree_gist.h"
6 #include <math.h>
7 #include <float.h>
9 #include "btree_utils_var.h"
10 #include "utils/builtins.h"
11 #include "utils/numeric.h"
12 #include "utils/rel.h"
15 ** Bytea ops
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);
24 Datum gbt_numeric_compress(PG_FUNCTION_ARGS);
25 Datum gbt_numeric_union(PG_FUNCTION_ARGS);
26 Datum gbt_numeric_picksplit(PG_FUNCTION_ARGS);
27 Datum gbt_numeric_consistent(PG_FUNCTION_ARGS);
28 Datum gbt_numeric_penalty(PG_FUNCTION_ARGS);
29 Datum gbt_numeric_same(PG_FUNCTION_ARGS);
32 /* define for comparison */
34 static bool
35 gbt_numeric_gt(const void *a, const void *b)
37 return (DatumGetBool(DirectFunctionCall2(numeric_gt, PointerGetDatum(a), PointerGetDatum(b))));
40 static bool
41 gbt_numeric_ge(const void *a, const void *b)
43 return (DatumGetBool(DirectFunctionCall2(numeric_ge, PointerGetDatum(a), PointerGetDatum(b))));
46 static bool
47 gbt_numeric_eq(const void *a, const void *b)
49 return (DatumGetBool(DirectFunctionCall2(numeric_eq, PointerGetDatum(a), PointerGetDatum(b))));
52 static bool
53 gbt_numeric_le(const void *a, const void *b)
55 return (DatumGetBool(DirectFunctionCall2(numeric_le, PointerGetDatum(a), PointerGetDatum(b))));
58 static bool
59 gbt_numeric_lt(const void *a, const void *b)
61 return (DatumGetBool(DirectFunctionCall2(numeric_lt, PointerGetDatum(a), PointerGetDatum(b))));
65 static int32
66 gbt_numeric_cmp(const bytea *a, const bytea *b)
68 return
69 (DatumGetInt32(DirectFunctionCall2(numeric_cmp, PointerGetDatum(a), PointerGetDatum(b))));
73 static const gbtree_vinfo tinfo =
75 gbt_t_numeric,
77 FALSE,
78 gbt_numeric_gt,
79 gbt_numeric_ge,
80 gbt_numeric_eq,
81 gbt_numeric_le,
82 gbt_numeric_lt,
83 gbt_numeric_cmp,
84 NULL
88 /**************************************************
89 * Text ops
90 **************************************************/
93 Datum
94 gbt_numeric_compress(PG_FUNCTION_ARGS)
96 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
98 PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo));
103 Datum
104 gbt_numeric_consistent(PG_FUNCTION_ARGS)
106 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
107 void *query = (void *) DatumGetNumeric(PG_GETARG_DATUM(1));
108 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
110 /* Oid subtype = PG_GETARG_OID(3); */
111 bool *recheck = (bool *) PG_GETARG_POINTER(4);
112 bool retval;
113 GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
114 GBT_VARKEY_R r = gbt_var_key_readable(key);
116 /* All cases served by this function are exact */
117 *recheck = false;
119 retval = gbt_var_consistent(&r, query, &strategy, GIST_LEAF(entry), &tinfo);
120 PG_RETURN_BOOL(retval);
125 Datum
126 gbt_numeric_union(PG_FUNCTION_ARGS)
128 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
129 int32 *size = (int *) PG_GETARG_POINTER(1);
131 PG_RETURN_POINTER(gbt_var_union(entryvec, size, &tinfo));
135 Datum
136 gbt_numeric_same(PG_FUNCTION_ARGS)
138 Datum d1 = PG_GETARG_DATUM(0);
139 Datum d2 = PG_GETARG_DATUM(1);
140 bool *result = (bool *) PG_GETARG_POINTER(2);
142 PG_RETURN_POINTER(gbt_var_same(result, d1, d2, &tinfo));
146 Datum
147 gbt_numeric_penalty(PG_FUNCTION_ARGS)
149 GISTENTRY *o = (GISTENTRY *) PG_GETARG_POINTER(0);
150 GISTENTRY *n = (GISTENTRY *) PG_GETARG_POINTER(1);
151 float *result = (float *) PG_GETARG_POINTER(2);
153 Numeric us,
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,
164 rk = gbt_var_key_readable(org);
165 uni = PointerGetDatum(gbt_var_key_copy(&rk, TRUE));
166 gbt_var_bin_union(&uni, newe, &tinfo);
167 ok = gbt_var_key_readable(org);
168 uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(uni));
170 us = DatumGetNumeric(DirectFunctionCall2(
171 numeric_sub,
172 PointerGetDatum(uk.upper),
173 PointerGetDatum(uk.lower)
176 os = DatumGetNumeric(DirectFunctionCall2(
177 numeric_sub,
178 PointerGetDatum(ok.upper),
179 PointerGetDatum(ok.lower)
182 ds = DatumGetNumeric(DirectFunctionCall2(
183 numeric_sub,
184 NumericGetDatum(us),
185 NumericGetDatum(os)
188 if (NUMERIC_IS_NAN(us))
190 if (NUMERIC_IS_NAN(os))
191 *result = 0.0;
192 else
193 *result = 1.0;
195 else
197 Numeric nul = DatumGetNumeric(DirectFunctionCall1(int4_numeric, Int32GetDatum(0)));
199 *result = 0.0;
201 if (DirectFunctionCall2(numeric_gt, NumericGetDatum(ds), NumericGetDatum(nul)))
203 *result += FLT_MIN;
204 os = DatumGetNumeric(DirectFunctionCall2(
205 numeric_div,
206 NumericGetDatum(ds),
207 NumericGetDatum(us)
209 *result += (float4) DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow, NumericGetDatum(os)));
213 if (*result > 0)
214 *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
216 PG_RETURN_POINTER(result);
221 Datum
222 gbt_numeric_picksplit(PG_FUNCTION_ARGS)
224 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
225 GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
227 gbt_var_picksplit(entryvec, v, &tinfo);
228 PG_RETURN_POINTER(v);