PolarDB-for-PostgreSQL

Форк
0
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
*/
19
PG_FUNCTION_INFO_V1(gbt_numeric_compress);
20
PG_FUNCTION_INFO_V1(gbt_numeric_union);
21
PG_FUNCTION_INFO_V1(gbt_numeric_picksplit);
22
PG_FUNCTION_INFO_V1(gbt_numeric_consistent);
23
PG_FUNCTION_INFO_V1(gbt_numeric_penalty);
24
PG_FUNCTION_INFO_V1(gbt_numeric_same);
25

26

27
/* define for comparison */
28

29
static bool
30
gbt_numeric_gt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
31
{
32
	return DatumGetBool(DirectFunctionCall2(numeric_gt,
33
											PointerGetDatum(a),
34
											PointerGetDatum(b)));
35
}
36

37
static bool
38
gbt_numeric_ge(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
39
{
40
	return DatumGetBool(DirectFunctionCall2(numeric_ge,
41
											PointerGetDatum(a),
42
											PointerGetDatum(b)));
43
}
44

45
static bool
46
gbt_numeric_eq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
47
{
48
	return DatumGetBool(DirectFunctionCall2(numeric_eq,
49
											PointerGetDatum(a),
50
											PointerGetDatum(b)));
51
}
52

53
static bool
54
gbt_numeric_le(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
55
{
56
	return DatumGetBool(DirectFunctionCall2(numeric_le,
57
											PointerGetDatum(a),
58
											PointerGetDatum(b)));
59
}
60

61
static bool
62
gbt_numeric_lt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
63
{
64
	return DatumGetBool(DirectFunctionCall2(numeric_lt,
65
											PointerGetDatum(a),
66
											PointerGetDatum(b)));
67
}
68

69
static int32
70
gbt_numeric_cmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
71
{
72
	return DatumGetInt32(DirectFunctionCall2(numeric_cmp,
73
											 PointerGetDatum(a),
74
											 PointerGetDatum(b)));
75
}
76

77

78
static const gbtree_vinfo tinfo =
79
{
80
	gbt_t_numeric,
81
	0,
82
	false,
83
	gbt_numeric_gt,
84
	gbt_numeric_ge,
85
	gbt_numeric_eq,
86
	gbt_numeric_le,
87
	gbt_numeric_lt,
88
	gbt_numeric_cmp,
89
	NULL
90
};
91

92

93
/**************************************************
94
 * Text ops
95
 **************************************************/
96

97

98
Datum
99
gbt_numeric_compress(PG_FUNCTION_ARGS)
100
{
101
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
102

103
	PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo));
104
}
105

106

107

108
Datum
109
gbt_numeric_consistent(PG_FUNCTION_ARGS)
110
{
111
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
112
	void	   *query = (void *) DatumGetNumeric(PG_GETARG_DATUM(1));
113
	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
114

115
	/* Oid		subtype = PG_GETARG_OID(3); */
116
	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
117
	bool		retval;
118
	GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
119
	GBT_VARKEY_R r = gbt_var_key_readable(key);
120

121
	/* All cases served by this function are exact */
122
	*recheck = false;
123

124
	retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
125
								GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
126
	PG_RETURN_BOOL(retval);
127
}
128

129

130

131
Datum
132
gbt_numeric_union(PG_FUNCTION_ARGS)
133
{
134
	GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
135
	int32	   *size = (int *) PG_GETARG_POINTER(1);
136

137
	PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
138
									&tinfo, fcinfo->flinfo));
139
}
140

141

142
Datum
143
gbt_numeric_same(PG_FUNCTION_ARGS)
144
{
145
	Datum		d1 = PG_GETARG_DATUM(0);
146
	Datum		d2 = PG_GETARG_DATUM(1);
147
	bool	   *result = (bool *) PG_GETARG_POINTER(2);
148

149
	*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
150
	PG_RETURN_POINTER(result);
151
}
152

153

154
Datum
155
gbt_numeric_penalty(PG_FUNCTION_ARGS)
156
{
157
	GISTENTRY  *o = (GISTENTRY *) PG_GETARG_POINTER(0);
158
	GISTENTRY  *n = (GISTENTRY *) PG_GETARG_POINTER(1);
159
	float	   *result = (float *) PG_GETARG_POINTER(2);
160

161
	Numeric		us,
162
				os,
163
				ds;
164

165
	GBT_VARKEY *org = (GBT_VARKEY *) DatumGetPointer(o->key);
166
	GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key);
167
	Datum		uni;
168
	GBT_VARKEY_R rk,
169
				ok,
170
				uk;
171

172
	rk = gbt_var_key_readable(org);
173
	uni = PointerGetDatum(gbt_var_key_copy(&rk));
174
	gbt_var_bin_union(&uni, newe, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
175
	ok = gbt_var_key_readable(org);
176
	uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(uni));
177

178
	us = DatumGetNumeric(DirectFunctionCall2(
179
											 numeric_sub,
180
											 PointerGetDatum(uk.upper),
181
											 PointerGetDatum(uk.lower)
182
											 ));
183

184
	os = DatumGetNumeric(DirectFunctionCall2(
185
											 numeric_sub,
186
											 PointerGetDatum(ok.upper),
187
											 PointerGetDatum(ok.lower)
188
											 ));
189

190
	ds = DatumGetNumeric(DirectFunctionCall2(
191
											 numeric_sub,
192
											 NumericGetDatum(us),
193
											 NumericGetDatum(os)
194
											 ));
195

196
	if (numeric_is_nan(us))
197
	{
198
		if (numeric_is_nan(os))
199
			*result = 0.0;
200
		else
201
			*result = 1.0;
202
	}
203
	else
204
	{
205
		Numeric		nul = DatumGetNumeric(DirectFunctionCall1(int4_numeric, Int32GetDatum(0)));
206

207
		*result = 0.0;
208

209
		if (DirectFunctionCall2(numeric_gt, NumericGetDatum(ds), NumericGetDatum(nul)))
210
		{
211
			*result += FLT_MIN;
212
			os = DatumGetNumeric(DirectFunctionCall2(
213
													 numeric_div,
214
													 NumericGetDatum(ds),
215
													 NumericGetDatum(us)
216
													 ));
217
			*result += (float4) DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow, NumericGetDatum(os)));
218
		}
219
	}
220

221
	if (*result > 0)
222
		*result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
223

224
	PG_RETURN_POINTER(result);
225
}
226

227

228

229
Datum
230
gbt_numeric_picksplit(PG_FUNCTION_ARGS)
231
{
232
	GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
233
	GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
234

235
	gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
236
					  &tinfo, fcinfo->flinfo);
237
	PG_RETURN_POINTER(v);
238
}
239

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.