PolarDB-for-PostgreSQL

Форк
0
190 строк · 4.3 Кб
1
/*
2
 * contrib/btree_gist/btree_inet.c
3
 */
4
#include "postgres.h"
5

6
#include "btree_gist.h"
7
#include "btree_utils_num.h"
8
#include "utils/builtins.h"
9
#include "utils/inet.h"
10
#include "catalog/pg_type.h"
11

12
typedef struct inetkey
13
{
14
	double		lower;
15
	double		upper;
16
} inetKEY;
17

18
/*
19
** inet ops
20
*/
21
PG_FUNCTION_INFO_V1(gbt_inet_compress);
22
PG_FUNCTION_INFO_V1(gbt_inet_union);
23
PG_FUNCTION_INFO_V1(gbt_inet_picksplit);
24
PG_FUNCTION_INFO_V1(gbt_inet_consistent);
25
PG_FUNCTION_INFO_V1(gbt_inet_penalty);
26
PG_FUNCTION_INFO_V1(gbt_inet_same);
27

28

29
static bool
30
gbt_inetgt(const void *a, const void *b, FmgrInfo *flinfo)
31
{
32
	return (*((const double *) a) > *((const double *) b));
33
}
34
static bool
35
gbt_inetge(const void *a, const void *b, FmgrInfo *flinfo)
36
{
37
	return (*((const double *) a) >= *((const double *) b));
38
}
39
static bool
40
gbt_ineteq(const void *a, const void *b, FmgrInfo *flinfo)
41
{
42
	return (*((const double *) a) == *((const double *) b));
43
}
44
static bool
45
gbt_inetle(const void *a, const void *b, FmgrInfo *flinfo)
46
{
47
	return (*((const double *) a) <= *((const double *) b));
48
}
49
static bool
50
gbt_inetlt(const void *a, const void *b, FmgrInfo *flinfo)
51
{
52
	return (*((const double *) a) < *((const double *) b));
53
}
54

55
static int
56
gbt_inetkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
57
{
58
	inetKEY    *ia = (inetKEY *) (((const Nsrt *) a)->t);
59
	inetKEY    *ib = (inetKEY *) (((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

73
static const gbtree_ninfo tinfo =
74
{
75
	gbt_t_inet,
76
	sizeof(double),
77
	16,							/* sizeof(gbtreekey16) */
78
	gbt_inetgt,
79
	gbt_inetge,
80
	gbt_ineteq,
81
	gbt_inetle,
82
	gbt_inetlt,
83
	gbt_inetkey_cmp,
84
	NULL
85
};
86

87

88
/**************************************************
89
 * inet ops
90
 **************************************************/
91

92

93
Datum
94
gbt_inet_compress(PG_FUNCTION_ARGS)
95
{
96
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
97
	GISTENTRY  *retval;
98

99
	if (entry->leafkey)
100
	{
101
		inetKEY    *r = (inetKEY *) palloc(sizeof(inetKEY));
102
		bool		failure = false;
103

104
		retval = palloc(sizeof(GISTENTRY));
105
		r->lower = convert_network_to_scalar(entry->key, INETOID, &failure);
106
		Assert(!failure);
107
		r->upper = r->lower;
108
		gistentryinit(*retval, PointerGetDatum(r),
109
					  entry->rel, entry->page,
110
					  entry->offset, false);
111
	}
112
	else
113
		retval = entry;
114

115
	PG_RETURN_POINTER(retval);
116
}
117

118

119
Datum
120
gbt_inet_consistent(PG_FUNCTION_ARGS)
121
{
122
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
123
	Datum		dquery = PG_GETARG_DATUM(1);
124
	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
125

126
	/* Oid		subtype = PG_GETARG_OID(3); */
127
	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
128
	inetKEY    *kkk = (inetKEY *) DatumGetPointer(entry->key);
129
	GBT_NUMKEY_R key;
130
	double		query;
131
	bool		failure = false;
132

133
	query = convert_network_to_scalar(dquery, INETOID, &failure);
134
	Assert(!failure);
135

136
	/* All cases served by this function are inexact */
137
	*recheck = true;
138

139
	key.lower = (GBT_NUMKEY *) &kkk->lower;
140
	key.upper = (GBT_NUMKEY *) &kkk->upper;
141

142
	PG_RETURN_BOOL(gbt_num_consistent(&key, (void *) &query,
143
									  &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
144
}
145

146

147
Datum
148
gbt_inet_union(PG_FUNCTION_ARGS)
149
{
150
	GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
151
	void	   *out = palloc(sizeof(inetKEY));
152

153
	*(int *) PG_GETARG_POINTER(1) = sizeof(inetKEY);
154
	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
155
}
156

157

158
Datum
159
gbt_inet_penalty(PG_FUNCTION_ARGS)
160
{
161
	inetKEY    *origentry = (inetKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
162
	inetKEY    *newentry = (inetKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
163
	float	   *result = (float *) PG_GETARG_POINTER(2);
164

165
	penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
166

167
	PG_RETURN_POINTER(result);
168

169
}
170

171
Datum
172
gbt_inet_picksplit(PG_FUNCTION_ARGS)
173
{
174
	PG_RETURN_POINTER(gbt_num_picksplit(
175
										(GistEntryVector *) PG_GETARG_POINTER(0),
176
										(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
177
										&tinfo, fcinfo->flinfo
178
										));
179
}
180

181
Datum
182
gbt_inet_same(PG_FUNCTION_ARGS)
183
{
184
	inetKEY    *b1 = (inetKEY *) PG_GETARG_POINTER(0);
185
	inetKEY    *b2 = (inetKEY *) PG_GETARG_POINTER(1);
186
	bool	   *result = (bool *) PG_GETARG_POINTER(2);
187

188
	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
189
	PG_RETURN_POINTER(result);
190
}
191

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

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

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

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