PolarDB-for-PostgreSQL

Форк
0
437 строк · 7.6 Кб
1
/*
2
 * contrib/intarray/_int_op.c
3
 */
4
#include "postgres.h"
5

6

7
#include "_int.h"
8

9
PG_MODULE_MAGIC;
10

11
PG_FUNCTION_INFO_V1(_int_different);
12
PG_FUNCTION_INFO_V1(_int_same);
13
PG_FUNCTION_INFO_V1(_int_contains);
14
PG_FUNCTION_INFO_V1(_int_contained);
15
PG_FUNCTION_INFO_V1(_int_overlap);
16
PG_FUNCTION_INFO_V1(_int_union);
17
PG_FUNCTION_INFO_V1(_int_inter);
18

19
Datum
20
_int_contained(PG_FUNCTION_ARGS)
21
{
22
	/* just reverse the operands and call _int_contains */
23
	return DirectFunctionCall2(_int_contains,
24
							   PG_GETARG_DATUM(1),
25
							   PG_GETARG_DATUM(0));
26
}
27

28
Datum
29
_int_contains(PG_FUNCTION_ARGS)
30
{
31
	/* Force copy so we can modify the arrays in-place */
32
	ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
33
	ArrayType  *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
34
	bool		res;
35

36
	CHECKARRVALID(a);
37
	CHECKARRVALID(b);
38
	PREPAREARR(a);
39
	PREPAREARR(b);
40
	res = inner_int_contains(a, b);
41
	pfree(a);
42
	pfree(b);
43
	PG_RETURN_BOOL(res);
44
}
45

46
Datum
47
_int_different(PG_FUNCTION_ARGS)
48
{
49
	PG_RETURN_BOOL(!DatumGetBool(
50
								 DirectFunctionCall2(
51
													 _int_same,
52
													 PointerGetDatum(PG_GETARG_POINTER(0)),
53
													 PointerGetDatum(PG_GETARG_POINTER(1))
54
													 )
55
								 ));
56
}
57

58
Datum
59
_int_same(PG_FUNCTION_ARGS)
60
{
61
	ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
62
	ArrayType  *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
63
	int			na,
64
				nb;
65
	int			n;
66
	int		   *da,
67
			   *db;
68
	bool		result;
69

70
	CHECKARRVALID(a);
71
	CHECKARRVALID(b);
72
	na = ARRNELEMS(a);
73
	nb = ARRNELEMS(b);
74
	da = ARRPTR(a);
75
	db = ARRPTR(b);
76

77
	result = false;
78

79
	if (na == nb)
80
	{
81
		SORT(a);
82
		SORT(b);
83
		result = true;
84

85
		for (n = 0; n < na; n++)
86
		{
87
			if (da[n] != db[n])
88
			{
89
				result = false;
90
				break;
91
			}
92
		}
93
	}
94

95
	pfree(a);
96
	pfree(b);
97

98
	PG_RETURN_BOOL(result);
99
}
100

101
/*	_int_overlap -- does a overlap b?
102
 */
103
Datum
104
_int_overlap(PG_FUNCTION_ARGS)
105
{
106
	ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
107
	ArrayType  *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
108
	bool		result;
109

110
	CHECKARRVALID(a);
111
	CHECKARRVALID(b);
112
	if (ARRISEMPTY(a) || ARRISEMPTY(b))
113
		return false;
114

115
	SORT(a);
116
	SORT(b);
117

118
	result = inner_int_overlap(a, b);
119

120
	pfree(a);
121
	pfree(b);
122

123
	PG_RETURN_BOOL(result);
124
}
125

126
Datum
127
_int_union(PG_FUNCTION_ARGS)
128
{
129
	ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
130
	ArrayType  *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
131
	ArrayType  *result;
132

133
	CHECKARRVALID(a);
134
	CHECKARRVALID(b);
135

136
	SORT(a);
137
	SORT(b);
138

139
	result = inner_int_union(a, b);
140

141
	pfree(a);
142
	pfree(b);
143

144
	PG_RETURN_POINTER(result);
145
}
146

147
Datum
148
_int_inter(PG_FUNCTION_ARGS)
149
{
150
	ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
151
	ArrayType  *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
152
	ArrayType  *result;
153

154
	CHECKARRVALID(a);
155
	CHECKARRVALID(b);
156

157
	SORT(a);
158
	SORT(b);
159

160
	result = inner_int_inter(a, b);
161

162
	pfree(a);
163
	pfree(b);
164

165
	PG_RETURN_POINTER(result);
166
}
167

168

169
PG_FUNCTION_INFO_V1(intset);
170
PG_FUNCTION_INFO_V1(icount);
171
PG_FUNCTION_INFO_V1(sort);
172
PG_FUNCTION_INFO_V1(sort_asc);
173
PG_FUNCTION_INFO_V1(sort_desc);
174
PG_FUNCTION_INFO_V1(uniq);
175
PG_FUNCTION_INFO_V1(idx);
176
PG_FUNCTION_INFO_V1(subarray);
177
PG_FUNCTION_INFO_V1(intarray_push_elem);
178
PG_FUNCTION_INFO_V1(intarray_push_array);
179
PG_FUNCTION_INFO_V1(intarray_del_elem);
180
PG_FUNCTION_INFO_V1(intset_union_elem);
181
PG_FUNCTION_INFO_V1(intset_subtract);
182

183
Datum
184
intset(PG_FUNCTION_ARGS)
185
{
186
	PG_RETURN_POINTER(int_to_intset(PG_GETARG_INT32(0)));
187
}
188

189
Datum
190
icount(PG_FUNCTION_ARGS)
191
{
192
	ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
193
	int32		count = ARRNELEMS(a);
194

195
	PG_FREE_IF_COPY(a, 0);
196
	PG_RETURN_INT32(count);
197
}
198

199
Datum
200
sort(PG_FUNCTION_ARGS)
201
{
202
	ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
203
	text	   *dirstr = (fcinfo->nargs == 2) ? PG_GETARG_TEXT_PP(1) : NULL;
204
	int32		dc = (dirstr) ? VARSIZE_ANY_EXHDR(dirstr) : 0;
205
	char	   *d = (dirstr) ? VARDATA_ANY(dirstr) : NULL;
206
	int			dir = -1;
207

208
	CHECKARRVALID(a);
209
	if (ARRNELEMS(a) < 2)
210
		PG_RETURN_POINTER(a);
211

212
	if (dirstr == NULL || (dc == 3
213
						   && (d[0] == 'A' || d[0] == 'a')
214
						   && (d[1] == 'S' || d[1] == 's')
215
						   && (d[2] == 'C' || d[2] == 'c')))
216
		dir = 1;
217
	else if (dc == 4
218
			 && (d[0] == 'D' || d[0] == 'd')
219
			 && (d[1] == 'E' || d[1] == 'e')
220
			 && (d[2] == 'S' || d[2] == 's')
221
			 && (d[3] == 'C' || d[3] == 'c'))
222
		dir = 0;
223
	if (dir == -1)
224
		ereport(ERROR,
225
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
226
				 errmsg("second parameter must be \"ASC\" or \"DESC\"")));
227
	QSORT(a, dir);
228
	PG_RETURN_POINTER(a);
229
}
230

231
Datum
232
sort_asc(PG_FUNCTION_ARGS)
233
{
234
	ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
235

236
	CHECKARRVALID(a);
237
	QSORT(a, 1);
238
	PG_RETURN_POINTER(a);
239
}
240

241
Datum
242
sort_desc(PG_FUNCTION_ARGS)
243
{
244
	ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
245

246
	CHECKARRVALID(a);
247
	QSORT(a, 0);
248
	PG_RETURN_POINTER(a);
249
}
250

251
Datum
252
uniq(PG_FUNCTION_ARGS)
253
{
254
	ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
255

256
	CHECKARRVALID(a);
257
	if (ARRNELEMS(a) < 2)
258
		PG_RETURN_POINTER(a);
259
	a = _int_unique(a);
260
	PG_RETURN_POINTER(a);
261
}
262

263
Datum
264
idx(PG_FUNCTION_ARGS)
265
{
266
	ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
267
	int32		result;
268

269
	CHECKARRVALID(a);
270
	result = ARRNELEMS(a);
271
	if (result)
272
		result = intarray_match_first(a, PG_GETARG_INT32(1));
273
	PG_FREE_IF_COPY(a, 0);
274
	PG_RETURN_INT32(result);
275
}
276

277
Datum
278
subarray(PG_FUNCTION_ARGS)
279
{
280
	ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
281
	int32		start = PG_GETARG_INT32(1);
282
	int32		len = (fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0;
283
	int32		end = 0;
284
	int32		c;
285
	ArrayType  *result;
286

287
	start = (start > 0) ? start - 1 : start;
288

289
	CHECKARRVALID(a);
290
	if (ARRISEMPTY(a))
291
	{
292
		PG_FREE_IF_COPY(a, 0);
293
		PG_RETURN_POINTER(new_intArrayType(0));
294
	}
295

296
	c = ARRNELEMS(a);
297

298
	if (start < 0)
299
		start = c + start;
300

301
	if (len < 0)
302
		end = c + len;
303
	else if (len == 0)
304
		end = c;
305
	else
306
		end = start + len;
307

308
	if (end > c)
309
		end = c;
310

311
	if (start < 0)
312
		start = 0;
313

314
	if (start >= end || end <= 0)
315
	{
316
		PG_FREE_IF_COPY(a, 0);
317
		PG_RETURN_POINTER(new_intArrayType(0));
318
	}
319

320
	result = new_intArrayType(end - start);
321
	if (end - start > 0)
322
		memcpy(ARRPTR(result), ARRPTR(a) + start, (end - start) * sizeof(int32));
323
	PG_FREE_IF_COPY(a, 0);
324
	PG_RETURN_POINTER(result);
325
}
326

327
Datum
328
intarray_push_elem(PG_FUNCTION_ARGS)
329
{
330
	ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
331
	ArrayType  *result;
332

333
	result = intarray_add_elem(a, PG_GETARG_INT32(1));
334
	PG_FREE_IF_COPY(a, 0);
335
	PG_RETURN_POINTER(result);
336
}
337

338
Datum
339
intarray_push_array(PG_FUNCTION_ARGS)
340
{
341
	ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
342
	ArrayType  *b = PG_GETARG_ARRAYTYPE_P(1);
343
	ArrayType  *result;
344

345
	result = intarray_concat_arrays(a, b);
346
	PG_FREE_IF_COPY(a, 0);
347
	PG_FREE_IF_COPY(b, 1);
348
	PG_RETURN_POINTER(result);
349
}
350

351
Datum
352
intarray_del_elem(PG_FUNCTION_ARGS)
353
{
354
	ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
355
	int32		elem = PG_GETARG_INT32(1);
356
	int32		c;
357
	int32	   *aa;
358
	int32		n = 0,
359
				i;
360

361
	CHECKARRVALID(a);
362
	if (!ARRISEMPTY(a))
363
	{
364
		c = ARRNELEMS(a);
365
		aa = ARRPTR(a);
366
		for (i = 0; i < c; i++)
367
		{
368
			if (aa[i] != elem)
369
			{
370
				if (i > n)
371
					aa[n++] = aa[i];
372
				else
373
					n++;
374
			}
375
		}
376
		a = resize_intArrayType(a, n);
377
	}
378
	PG_RETURN_POINTER(a);
379
}
380

381
Datum
382
intset_union_elem(PG_FUNCTION_ARGS)
383
{
384
	ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
385
	ArrayType  *result;
386

387
	result = intarray_add_elem(a, PG_GETARG_INT32(1));
388
	PG_FREE_IF_COPY(a, 0);
389
	QSORT(result, 1);
390
	PG_RETURN_POINTER(_int_unique(result));
391
}
392

393
Datum
394
intset_subtract(PG_FUNCTION_ARGS)
395
{
396
	ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
397
	ArrayType  *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
398
	ArrayType  *result;
399
	int32		ca;
400
	int32		cb;
401
	int32	   *aa,
402
			   *bb,
403
			   *r;
404
	int32		n = 0,
405
				i = 0,
406
				k = 0;
407

408
	CHECKARRVALID(a);
409
	CHECKARRVALID(b);
410

411
	QSORT(a, 1);
412
	a = _int_unique(a);
413
	ca = ARRNELEMS(a);
414
	QSORT(b, 1);
415
	b = _int_unique(b);
416
	cb = ARRNELEMS(b);
417
	result = new_intArrayType(ca);
418
	aa = ARRPTR(a);
419
	bb = ARRPTR(b);
420
	r = ARRPTR(result);
421
	while (i < ca)
422
	{
423
		if (k == cb || aa[i] < bb[k])
424
			r[n++] = aa[i++];
425
		else if (aa[i] == bb[k])
426
		{
427
			i++;
428
			k++;
429
		}
430
		else
431
			k++;
432
	}
433
	result = resize_intArrayType(result, n);
434
	pfree(a);
435
	pfree(b);
436
	PG_RETURN_POINTER(result);
437
}
438

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

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

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

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