PolarDB-for-PostgreSQL
238 строк · 5.5 Кб
1/*
2* contrib/btree_gist/btree_numeric.c
3*/
4#include "postgres.h"5
6#include "btree_gist.h"7
8#include <math.h>9#include <float.h>10
11#include "btree_utils_var.h"12#include "utils/builtins.h"13#include "utils/numeric.h"14#include "utils/rel.h"15
16/*
17** Bytea ops
18*/
19PG_FUNCTION_INFO_V1(gbt_numeric_compress);20PG_FUNCTION_INFO_V1(gbt_numeric_union);21PG_FUNCTION_INFO_V1(gbt_numeric_picksplit);22PG_FUNCTION_INFO_V1(gbt_numeric_consistent);23PG_FUNCTION_INFO_V1(gbt_numeric_penalty);24PG_FUNCTION_INFO_V1(gbt_numeric_same);25
26
27/* define for comparison */
28
29static bool30gbt_numeric_gt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)31{
32return DatumGetBool(DirectFunctionCall2(numeric_gt,33PointerGetDatum(a),34PointerGetDatum(b)));35}
36
37static bool38gbt_numeric_ge(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)39{
40return DatumGetBool(DirectFunctionCall2(numeric_ge,41PointerGetDatum(a),42PointerGetDatum(b)));43}
44
45static bool46gbt_numeric_eq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)47{
48return DatumGetBool(DirectFunctionCall2(numeric_eq,49PointerGetDatum(a),50PointerGetDatum(b)));51}
52
53static bool54gbt_numeric_le(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)55{
56return DatumGetBool(DirectFunctionCall2(numeric_le,57PointerGetDatum(a),58PointerGetDatum(b)));59}
60
61static bool62gbt_numeric_lt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)63{
64return DatumGetBool(DirectFunctionCall2(numeric_lt,65PointerGetDatum(a),66PointerGetDatum(b)));67}
68
69static int3270gbt_numeric_cmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)71{
72return DatumGetInt32(DirectFunctionCall2(numeric_cmp,73PointerGetDatum(a),74PointerGetDatum(b)));75}
76
77
78static const gbtree_vinfo tinfo =79{
80gbt_t_numeric,810,82false,83gbt_numeric_gt,84gbt_numeric_ge,85gbt_numeric_eq,86gbt_numeric_le,87gbt_numeric_lt,88gbt_numeric_cmp,89NULL90};91
92
93/**************************************************
94* Text ops
95**************************************************/
96
97
98Datum
99gbt_numeric_compress(PG_FUNCTION_ARGS)100{
101GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);102
103PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo));104}
105
106
107
108Datum
109gbt_numeric_consistent(PG_FUNCTION_ARGS)110{
111GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);112void *query = (void *) DatumGetNumeric(PG_GETARG_DATUM(1));113StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);114
115/* Oid subtype = PG_GETARG_OID(3); */116bool *recheck = (bool *) PG_GETARG_POINTER(4);117bool retval;118GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);119GBT_VARKEY_R r = gbt_var_key_readable(key);120
121/* All cases served by this function are exact */122*recheck = false;123
124retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),125GIST_LEAF(entry), &tinfo, fcinfo->flinfo);126PG_RETURN_BOOL(retval);127}
128
129
130
131Datum
132gbt_numeric_union(PG_FUNCTION_ARGS)133{
134GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);135int32 *size = (int *) PG_GETARG_POINTER(1);136
137PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),138&tinfo, fcinfo->flinfo));139}
140
141
142Datum
143gbt_numeric_same(PG_FUNCTION_ARGS)144{
145Datum d1 = PG_GETARG_DATUM(0);146Datum d2 = PG_GETARG_DATUM(1);147bool *result = (bool *) PG_GETARG_POINTER(2);148
149*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);150PG_RETURN_POINTER(result);151}
152
153
154Datum
155gbt_numeric_penalty(PG_FUNCTION_ARGS)156{
157GISTENTRY *o = (GISTENTRY *) PG_GETARG_POINTER(0);158GISTENTRY *n = (GISTENTRY *) PG_GETARG_POINTER(1);159float *result = (float *) PG_GETARG_POINTER(2);160
161Numeric us,162os,163ds;164
165GBT_VARKEY *org = (GBT_VARKEY *) DatumGetPointer(o->key);166GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key);167Datum uni;168GBT_VARKEY_R rk,169ok,170uk;171
172rk = gbt_var_key_readable(org);173uni = PointerGetDatum(gbt_var_key_copy(&rk));174gbt_var_bin_union(&uni, newe, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);175ok = gbt_var_key_readable(org);176uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(uni));177
178us = DatumGetNumeric(DirectFunctionCall2(179numeric_sub,180PointerGetDatum(uk.upper),181PointerGetDatum(uk.lower)182));183
184os = DatumGetNumeric(DirectFunctionCall2(185numeric_sub,186PointerGetDatum(ok.upper),187PointerGetDatum(ok.lower)188));189
190ds = DatumGetNumeric(DirectFunctionCall2(191numeric_sub,192NumericGetDatum(us),193NumericGetDatum(os)194));195
196if (numeric_is_nan(us))197{198if (numeric_is_nan(os))199*result = 0.0;200else201*result = 1.0;202}203else204{205Numeric nul = DatumGetNumeric(DirectFunctionCall1(int4_numeric, Int32GetDatum(0)));206
207*result = 0.0;208
209if (DirectFunctionCall2(numeric_gt, NumericGetDatum(ds), NumericGetDatum(nul)))210{211*result += FLT_MIN;212os = DatumGetNumeric(DirectFunctionCall2(213numeric_div,214NumericGetDatum(ds),215NumericGetDatum(us)216));217*result += (float4) DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow, NumericGetDatum(os)));218}219}220
221if (*result > 0)222*result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));223
224PG_RETURN_POINTER(result);225}
226
227
228
229Datum
230gbt_numeric_picksplit(PG_FUNCTION_ARGS)231{
232GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);233GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);234
235gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),236&tinfo, fcinfo->flinfo);237PG_RETURN_POINTER(v);238}
239