Fix minor nbtree page deletion buffer lock issue.
[pgsql.git] / contrib / btree_gist / btree_numeric.c
blobd66901680e3366c73d6a52ddd5eb730b3ca059fa
1 /*
2 * contrib/btree_gist/btree_numeric.c
3 */
4 #include "postgres.h"
6 #include <math.h>
7 #include <float.h>
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"
16 ** Bytea ops
18 PG_FUNCTION_INFO_V1(gbt_numeric_compress);
19 PG_FUNCTION_INFO_V1(gbt_numeric_union);
20 PG_FUNCTION_INFO_V1(gbt_numeric_picksplit);
21 PG_FUNCTION_INFO_V1(gbt_numeric_consistent);
22 PG_FUNCTION_INFO_V1(gbt_numeric_penalty);
23 PG_FUNCTION_INFO_V1(gbt_numeric_same);
26 /* define for comparison */
28 static bool
29 gbt_numeric_gt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
31 return DatumGetBool(DirectFunctionCall2(numeric_gt,
32 PointerGetDatum(a),
33 PointerGetDatum(b)));
36 static bool
37 gbt_numeric_ge(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
39 return DatumGetBool(DirectFunctionCall2(numeric_ge,
40 PointerGetDatum(a),
41 PointerGetDatum(b)));
44 static bool
45 gbt_numeric_eq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
47 return DatumGetBool(DirectFunctionCall2(numeric_eq,
48 PointerGetDatum(a),
49 PointerGetDatum(b)));
52 static bool
53 gbt_numeric_le(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
55 return DatumGetBool(DirectFunctionCall2(numeric_le,
56 PointerGetDatum(a),
57 PointerGetDatum(b)));
60 static bool
61 gbt_numeric_lt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
63 return DatumGetBool(DirectFunctionCall2(numeric_lt,
64 PointerGetDatum(a),
65 PointerGetDatum(b)));
68 static int32
69 gbt_numeric_cmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
71 return DatumGetInt32(DirectFunctionCall2(numeric_cmp,
72 PointerGetDatum(a),
73 PointerGetDatum(b)));
77 static const gbtree_vinfo tinfo =
79 gbt_t_numeric,
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
92 /**************************************************
93 * Text ops
94 **************************************************/
97 Datum
98 gbt_numeric_compress(PG_FUNCTION_ARGS)
100 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
102 PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo));
107 Datum
108 gbt_numeric_consistent(PG_FUNCTION_ARGS)
110 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
111 void *query = (void *) DatumGetNumeric(PG_GETARG_DATUM(1));
112 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
114 /* Oid subtype = PG_GETARG_OID(3); */
115 bool *recheck = (bool *) PG_GETARG_POINTER(4);
116 bool retval;
117 GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
118 GBT_VARKEY_R r = gbt_var_key_readable(key);
120 /* All cases served by this function are exact */
121 *recheck = false;
123 retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
124 GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
125 PG_RETURN_BOOL(retval);
130 Datum
131 gbt_numeric_union(PG_FUNCTION_ARGS)
133 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
134 int32 *size = (int *) PG_GETARG_POINTER(1);
136 PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
137 &tinfo, fcinfo->flinfo));
141 Datum
142 gbt_numeric_same(PG_FUNCTION_ARGS)
144 Datum d1 = PG_GETARG_DATUM(0);
145 Datum d2 = PG_GETARG_DATUM(1);
146 bool *result = (bool *) PG_GETARG_POINTER(2);
148 *result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
149 PG_RETURN_POINTER(result);
153 Datum
154 gbt_numeric_penalty(PG_FUNCTION_ARGS)
156 GISTENTRY *o = (GISTENTRY *) PG_GETARG_POINTER(0);
157 GISTENTRY *n = (GISTENTRY *) PG_GETARG_POINTER(1);
158 float *result = (float *) PG_GETARG_POINTER(2);
160 Numeric us,
164 GBT_VARKEY *org = (GBT_VARKEY *) DatumGetPointer(o->key);
165 GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key);
166 Datum uni;
167 GBT_VARKEY_R rk,
171 rk = gbt_var_key_readable(org);
172 uni = PointerGetDatum(gbt_var_key_copy(&rk));
173 gbt_var_bin_union(&uni, newe, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
174 ok = gbt_var_key_readable(org);
175 uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(uni));
177 us = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
178 PointerGetDatum(uk.upper),
179 PointerGetDatum(uk.lower)));
181 os = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
182 PointerGetDatum(ok.upper),
183 PointerGetDatum(ok.lower)));
185 ds = DatumGetNumeric(DirectFunctionCall2(numeric_sub,
186 NumericGetDatum(us),
187 NumericGetDatum(os)));
189 if (numeric_is_nan(us))
191 if (numeric_is_nan(os))
192 *result = 0.0;
193 else
194 *result = 1.0;
196 else
198 Numeric nul = DatumGetNumeric(DirectFunctionCall1(int4_numeric, Int32GetDatum(0)));
200 *result = 0.0;
202 if (DirectFunctionCall2(numeric_gt, NumericGetDatum(ds), NumericGetDatum(nul)))
204 *result += FLT_MIN;
205 os = DatumGetNumeric(DirectFunctionCall2(numeric_div,
206 NumericGetDatum(ds),
207 NumericGetDatum(us)));
208 *result += (float4) DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow, NumericGetDatum(os)));
212 if (*result > 0)
213 *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
215 PG_RETURN_POINTER(result);
220 Datum
221 gbt_numeric_picksplit(PG_FUNCTION_ARGS)
223 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
224 GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
226 gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
227 &tinfo, fcinfo->flinfo);
228 PG_RETURN_POINTER(v);