2 * contrib/btree_gist/btree_numeric.c
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"
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 */
29 gbt_numeric_gt(const void *a
, const void *b
, Oid collation
, FmgrInfo
*flinfo
)
31 return DatumGetBool(DirectFunctionCall2(numeric_gt
,
37 gbt_numeric_ge(const void *a
, const void *b
, Oid collation
, FmgrInfo
*flinfo
)
39 return DatumGetBool(DirectFunctionCall2(numeric_ge
,
45 gbt_numeric_eq(const void *a
, const void *b
, Oid collation
, FmgrInfo
*flinfo
)
47 return DatumGetBool(DirectFunctionCall2(numeric_eq
,
53 gbt_numeric_le(const void *a
, const void *b
, Oid collation
, FmgrInfo
*flinfo
)
55 return DatumGetBool(DirectFunctionCall2(numeric_le
,
61 gbt_numeric_lt(const void *a
, const void *b
, Oid collation
, FmgrInfo
*flinfo
)
63 return DatumGetBool(DirectFunctionCall2(numeric_lt
,
69 gbt_numeric_cmp(const void *a
, const void *b
, Oid collation
, FmgrInfo
*flinfo
)
71 return DatumGetInt32(DirectFunctionCall2(numeric_cmp
,
77 static const gbtree_vinfo tinfo
=
92 /**************************************************
94 **************************************************/
98 gbt_numeric_compress(PG_FUNCTION_ARGS
)
100 GISTENTRY
*entry
= (GISTENTRY
*) PG_GETARG_POINTER(0);
102 PG_RETURN_POINTER(gbt_var_compress(entry
, &tinfo
));
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);
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 */
123 retval
= gbt_var_consistent(&r
, query
, strategy
, PG_GET_COLLATION(),
124 GIST_LEAF(entry
), &tinfo
, fcinfo
->flinfo
);
125 PG_RETURN_BOOL(retval
);
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
));
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
);
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);
164 GBT_VARKEY
*org
= (GBT_VARKEY
*) DatumGetPointer(o
->key
);
165 GBT_VARKEY
*newe
= (GBT_VARKEY
*) DatumGetPointer(n
->key
);
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
,
187 NumericGetDatum(os
)));
189 if (numeric_is_nan(us
))
191 if (numeric_is_nan(os
))
198 Numeric nul
= DatumGetNumeric(DirectFunctionCall1(int4_numeric
, Int32GetDatum(0)));
202 if (DirectFunctionCall2(numeric_gt
, NumericGetDatum(ds
), NumericGetDatum(nul
)))
205 os
= DatumGetNumeric(DirectFunctionCall2(numeric_div
,
207 NumericGetDatum(us
)));
208 *result
+= (float4
) DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow
, NumericGetDatum(os
)));
213 *result
*= (FLT_MAX
/ (((GISTENTRY
*) PG_GETARG_POINTER(0))->rel
->rd_att
->natts
+ 1));
215 PG_RETURN_POINTER(result
);
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
);