PolarDB-for-PostgreSQL

Форк
0
221 строка · 4.9 Кб
1
/*
2
 * contrib/btree_gist/btree_int8.c
3
 */
4
#include "postgres.h"
5

6
#include "btree_gist.h"
7
#include "btree_utils_num.h"
8
#include "common/int.h"
9

10
typedef struct int64key
11
{
12
	int64		lower;
13
	int64		upper;
14
} int64KEY;
15

16
/*
17
** int64 ops
18
*/
19
PG_FUNCTION_INFO_V1(gbt_int8_compress);
20
PG_FUNCTION_INFO_V1(gbt_int8_fetch);
21
PG_FUNCTION_INFO_V1(gbt_int8_union);
22
PG_FUNCTION_INFO_V1(gbt_int8_picksplit);
23
PG_FUNCTION_INFO_V1(gbt_int8_consistent);
24
PG_FUNCTION_INFO_V1(gbt_int8_distance);
25
PG_FUNCTION_INFO_V1(gbt_int8_penalty);
26
PG_FUNCTION_INFO_V1(gbt_int8_same);
27

28

29
static bool
30
gbt_int8gt(const void *a, const void *b, FmgrInfo *flinfo)
31
{
32
	return (*((const int64 *) a) > *((const int64 *) b));
33
}
34
static bool
35
gbt_int8ge(const void *a, const void *b, FmgrInfo *flinfo)
36
{
37
	return (*((const int64 *) a) >= *((const int64 *) b));
38
}
39
static bool
40
gbt_int8eq(const void *a, const void *b, FmgrInfo *flinfo)
41
{
42
	return (*((const int64 *) a) == *((const int64 *) b));
43
}
44
static bool
45
gbt_int8le(const void *a, const void *b, FmgrInfo *flinfo)
46
{
47
	return (*((const int64 *) a) <= *((const int64 *) b));
48
}
49
static bool
50
gbt_int8lt(const void *a, const void *b, FmgrInfo *flinfo)
51
{
52
	return (*((const int64 *) a) < *((const int64 *) b));
53
}
54

55
static int
56
gbt_int8key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
57
{
58
	int64KEY   *ia = (int64KEY *) (((const Nsrt *) a)->t);
59
	int64KEY   *ib = (int64KEY *) (((const Nsrt *) b)->t);
60

61
	if (ia->lower == ib->lower)
62
	{
63
		if (ia->upper == ib->upper)
64
			return 0;
65

66
		return (ia->upper > ib->upper) ? 1 : -1;
67
	}
68

69
	return (ia->lower > ib->lower) ? 1 : -1;
70
}
71

72
static float8
73
gbt_int8_dist(const void *a, const void *b, FmgrInfo *flinfo)
74
{
75
	return GET_FLOAT_DISTANCE(int64, a, b);
76
}
77

78

79
static const gbtree_ninfo tinfo =
80
{
81
	gbt_t_int8,
82
	sizeof(int64),
83
	16,							/* sizeof(gbtreekey16) */
84
	gbt_int8gt,
85
	gbt_int8ge,
86
	gbt_int8eq,
87
	gbt_int8le,
88
	gbt_int8lt,
89
	gbt_int8key_cmp,
90
	gbt_int8_dist
91
};
92

93

94
PG_FUNCTION_INFO_V1(int8_dist);
95
Datum
96
int8_dist(PG_FUNCTION_ARGS)
97
{
98
	int64		a = PG_GETARG_INT64(0);
99
	int64		b = PG_GETARG_INT64(1);
100
	int64		r;
101
	int64		ra;
102

103
	if (pg_sub_s64_overflow(a, b, &r) ||
104
		r == PG_INT64_MIN)
105
		ereport(ERROR,
106
				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
107
				 errmsg("bigint out of range")));
108

109
	ra = Abs(r);
110

111
	PG_RETURN_INT64(ra);
112
}
113

114

115
/**************************************************
116
 * int64 ops
117
 **************************************************/
118

119

120
Datum
121
gbt_int8_compress(PG_FUNCTION_ARGS)
122
{
123
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
124

125
	PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
126
}
127

128
Datum
129
gbt_int8_fetch(PG_FUNCTION_ARGS)
130
{
131
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
132

133
	PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
134
}
135

136
Datum
137
gbt_int8_consistent(PG_FUNCTION_ARGS)
138
{
139
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
140
	int64		query = PG_GETARG_INT64(1);
141
	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
142

143
	/* Oid		subtype = PG_GETARG_OID(3); */
144
	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
145
	int64KEY   *kkk = (int64KEY *) DatumGetPointer(entry->key);
146
	GBT_NUMKEY_R key;
147

148
	/* All cases served by this function are exact */
149
	*recheck = false;
150

151
	key.lower = (GBT_NUMKEY *) &kkk->lower;
152
	key.upper = (GBT_NUMKEY *) &kkk->upper;
153

154
	PG_RETURN_BOOL(
155
				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
156
		);
157
}
158

159

160
Datum
161
gbt_int8_distance(PG_FUNCTION_ARGS)
162
{
163
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
164
	int64		query = PG_GETARG_INT64(1);
165

166
	/* Oid		subtype = PG_GETARG_OID(3); */
167
	int64KEY   *kkk = (int64KEY *) DatumGetPointer(entry->key);
168
	GBT_NUMKEY_R key;
169

170
	key.lower = (GBT_NUMKEY *) &kkk->lower;
171
	key.upper = (GBT_NUMKEY *) &kkk->upper;
172

173
	PG_RETURN_FLOAT8(
174
					 gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
175
		);
176
}
177

178

179
Datum
180
gbt_int8_union(PG_FUNCTION_ARGS)
181
{
182
	GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
183
	void	   *out = palloc(sizeof(int64KEY));
184

185
	*(int *) PG_GETARG_POINTER(1) = sizeof(int64KEY);
186
	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
187
}
188

189

190
Datum
191
gbt_int8_penalty(PG_FUNCTION_ARGS)
192
{
193
	int64KEY   *origentry = (int64KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
194
	int64KEY   *newentry = (int64KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
195
	float	   *result = (float *) PG_GETARG_POINTER(2);
196

197
	penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
198

199
	PG_RETURN_POINTER(result);
200
}
201

202
Datum
203
gbt_int8_picksplit(PG_FUNCTION_ARGS)
204
{
205
	PG_RETURN_POINTER(gbt_num_picksplit(
206
										(GistEntryVector *) PG_GETARG_POINTER(0),
207
										(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
208
										&tinfo, fcinfo->flinfo
209
										));
210
}
211

212
Datum
213
gbt_int8_same(PG_FUNCTION_ARGS)
214
{
215
	int64KEY   *b1 = (int64KEY *) PG_GETARG_POINTER(0);
216
	int64KEY   *b2 = (int64KEY *) PG_GETARG_POINTER(1);
217
	bool	   *result = (bool *) PG_GETARG_POINTER(2);
218

219
	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
220
	PG_RETURN_POINTER(result);
221
}
222

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

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

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

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