PolarDB-for-PostgreSQL
437 строк · 7.6 Кб
1/*
2* contrib/intarray/_int_op.c
3*/
4#include "postgres.h"5
6
7#include "_int.h"8
9PG_MODULE_MAGIC;10
11PG_FUNCTION_INFO_V1(_int_different);12PG_FUNCTION_INFO_V1(_int_same);13PG_FUNCTION_INFO_V1(_int_contains);14PG_FUNCTION_INFO_V1(_int_contained);15PG_FUNCTION_INFO_V1(_int_overlap);16PG_FUNCTION_INFO_V1(_int_union);17PG_FUNCTION_INFO_V1(_int_inter);18
19Datum
20_int_contained(PG_FUNCTION_ARGS)21{
22/* just reverse the operands and call _int_contains */23return DirectFunctionCall2(_int_contains,24PG_GETARG_DATUM(1),25PG_GETARG_DATUM(0));26}
27
28Datum
29_int_contains(PG_FUNCTION_ARGS)30{
31/* Force copy so we can modify the arrays in-place */32ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);33ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);34bool res;35
36CHECKARRVALID(a);37CHECKARRVALID(b);38PREPAREARR(a);39PREPAREARR(b);40res = inner_int_contains(a, b);41pfree(a);42pfree(b);43PG_RETURN_BOOL(res);44}
45
46Datum
47_int_different(PG_FUNCTION_ARGS)48{
49PG_RETURN_BOOL(!DatumGetBool(50DirectFunctionCall2(51_int_same,52PointerGetDatum(PG_GETARG_POINTER(0)),53PointerGetDatum(PG_GETARG_POINTER(1))54)55));56}
57
58Datum
59_int_same(PG_FUNCTION_ARGS)60{
61ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);62ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);63int na,64nb;65int n;66int *da,67*db;68bool result;69
70CHECKARRVALID(a);71CHECKARRVALID(b);72na = ARRNELEMS(a);73nb = ARRNELEMS(b);74da = ARRPTR(a);75db = ARRPTR(b);76
77result = false;78
79if (na == nb)80{81SORT(a);82SORT(b);83result = true;84
85for (n = 0; n < na; n++)86{87if (da[n] != db[n])88{89result = false;90break;91}92}93}94
95pfree(a);96pfree(b);97
98PG_RETURN_BOOL(result);99}
100
101/* _int_overlap -- does a overlap b?
102*/
103Datum
104_int_overlap(PG_FUNCTION_ARGS)105{
106ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);107ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);108bool result;109
110CHECKARRVALID(a);111CHECKARRVALID(b);112if (ARRISEMPTY(a) || ARRISEMPTY(b))113return false;114
115SORT(a);116SORT(b);117
118result = inner_int_overlap(a, b);119
120pfree(a);121pfree(b);122
123PG_RETURN_BOOL(result);124}
125
126Datum
127_int_union(PG_FUNCTION_ARGS)128{
129ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);130ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);131ArrayType *result;132
133CHECKARRVALID(a);134CHECKARRVALID(b);135
136SORT(a);137SORT(b);138
139result = inner_int_union(a, b);140
141pfree(a);142pfree(b);143
144PG_RETURN_POINTER(result);145}
146
147Datum
148_int_inter(PG_FUNCTION_ARGS)149{
150ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);151ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);152ArrayType *result;153
154CHECKARRVALID(a);155CHECKARRVALID(b);156
157SORT(a);158SORT(b);159
160result = inner_int_inter(a, b);161
162pfree(a);163pfree(b);164
165PG_RETURN_POINTER(result);166}
167
168
169PG_FUNCTION_INFO_V1(intset);170PG_FUNCTION_INFO_V1(icount);171PG_FUNCTION_INFO_V1(sort);172PG_FUNCTION_INFO_V1(sort_asc);173PG_FUNCTION_INFO_V1(sort_desc);174PG_FUNCTION_INFO_V1(uniq);175PG_FUNCTION_INFO_V1(idx);176PG_FUNCTION_INFO_V1(subarray);177PG_FUNCTION_INFO_V1(intarray_push_elem);178PG_FUNCTION_INFO_V1(intarray_push_array);179PG_FUNCTION_INFO_V1(intarray_del_elem);180PG_FUNCTION_INFO_V1(intset_union_elem);181PG_FUNCTION_INFO_V1(intset_subtract);182
183Datum
184intset(PG_FUNCTION_ARGS)185{
186PG_RETURN_POINTER(int_to_intset(PG_GETARG_INT32(0)));187}
188
189Datum
190icount(PG_FUNCTION_ARGS)191{
192ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);193int32 count = ARRNELEMS(a);194
195PG_FREE_IF_COPY(a, 0);196PG_RETURN_INT32(count);197}
198
199Datum
200sort(PG_FUNCTION_ARGS)201{
202ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);203text *dirstr = (fcinfo->nargs == 2) ? PG_GETARG_TEXT_PP(1) : NULL;204int32 dc = (dirstr) ? VARSIZE_ANY_EXHDR(dirstr) : 0;205char *d = (dirstr) ? VARDATA_ANY(dirstr) : NULL;206int dir = -1;207
208CHECKARRVALID(a);209if (ARRNELEMS(a) < 2)210PG_RETURN_POINTER(a);211
212if (dirstr == NULL || (dc == 3213&& (d[0] == 'A' || d[0] == 'a')214&& (d[1] == 'S' || d[1] == 's')215&& (d[2] == 'C' || d[2] == 'c')))216dir = 1;217else if (dc == 4218&& (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'))222dir = 0;223if (dir == -1)224ereport(ERROR,225(errcode(ERRCODE_INVALID_PARAMETER_VALUE),226errmsg("second parameter must be \"ASC\" or \"DESC\"")));227QSORT(a, dir);228PG_RETURN_POINTER(a);229}
230
231Datum
232sort_asc(PG_FUNCTION_ARGS)233{
234ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);235
236CHECKARRVALID(a);237QSORT(a, 1);238PG_RETURN_POINTER(a);239}
240
241Datum
242sort_desc(PG_FUNCTION_ARGS)243{
244ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);245
246CHECKARRVALID(a);247QSORT(a, 0);248PG_RETURN_POINTER(a);249}
250
251Datum
252uniq(PG_FUNCTION_ARGS)253{
254ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);255
256CHECKARRVALID(a);257if (ARRNELEMS(a) < 2)258PG_RETURN_POINTER(a);259a = _int_unique(a);260PG_RETURN_POINTER(a);261}
262
263Datum
264idx(PG_FUNCTION_ARGS)265{
266ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);267int32 result;268
269CHECKARRVALID(a);270result = ARRNELEMS(a);271if (result)272result = intarray_match_first(a, PG_GETARG_INT32(1));273PG_FREE_IF_COPY(a, 0);274PG_RETURN_INT32(result);275}
276
277Datum
278subarray(PG_FUNCTION_ARGS)279{
280ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);281int32 start = PG_GETARG_INT32(1);282int32 len = (fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0;283int32 end = 0;284int32 c;285ArrayType *result;286
287start = (start > 0) ? start - 1 : start;288
289CHECKARRVALID(a);290if (ARRISEMPTY(a))291{292PG_FREE_IF_COPY(a, 0);293PG_RETURN_POINTER(new_intArrayType(0));294}295
296c = ARRNELEMS(a);297
298if (start < 0)299start = c + start;300
301if (len < 0)302end = c + len;303else if (len == 0)304end = c;305else306end = start + len;307
308if (end > c)309end = c;310
311if (start < 0)312start = 0;313
314if (start >= end || end <= 0)315{316PG_FREE_IF_COPY(a, 0);317PG_RETURN_POINTER(new_intArrayType(0));318}319
320result = new_intArrayType(end - start);321if (end - start > 0)322memcpy(ARRPTR(result), ARRPTR(a) + start, (end - start) * sizeof(int32));323PG_FREE_IF_COPY(a, 0);324PG_RETURN_POINTER(result);325}
326
327Datum
328intarray_push_elem(PG_FUNCTION_ARGS)329{
330ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);331ArrayType *result;332
333result = intarray_add_elem(a, PG_GETARG_INT32(1));334PG_FREE_IF_COPY(a, 0);335PG_RETURN_POINTER(result);336}
337
338Datum
339intarray_push_array(PG_FUNCTION_ARGS)340{
341ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);342ArrayType *b = PG_GETARG_ARRAYTYPE_P(1);343ArrayType *result;344
345result = intarray_concat_arrays(a, b);346PG_FREE_IF_COPY(a, 0);347PG_FREE_IF_COPY(b, 1);348PG_RETURN_POINTER(result);349}
350
351Datum
352intarray_del_elem(PG_FUNCTION_ARGS)353{
354ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);355int32 elem = PG_GETARG_INT32(1);356int32 c;357int32 *aa;358int32 n = 0,359i;360
361CHECKARRVALID(a);362if (!ARRISEMPTY(a))363{364c = ARRNELEMS(a);365aa = ARRPTR(a);366for (i = 0; i < c; i++)367{368if (aa[i] != elem)369{370if (i > n)371aa[n++] = aa[i];372else373n++;374}375}376a = resize_intArrayType(a, n);377}378PG_RETURN_POINTER(a);379}
380
381Datum
382intset_union_elem(PG_FUNCTION_ARGS)383{
384ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);385ArrayType *result;386
387result = intarray_add_elem(a, PG_GETARG_INT32(1));388PG_FREE_IF_COPY(a, 0);389QSORT(result, 1);390PG_RETURN_POINTER(_int_unique(result));391}
392
393Datum
394intset_subtract(PG_FUNCTION_ARGS)395{
396ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);397ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);398ArrayType *result;399int32 ca;400int32 cb;401int32 *aa,402*bb,403*r;404int32 n = 0,405i = 0,406k = 0;407
408CHECKARRVALID(a);409CHECKARRVALID(b);410
411QSORT(a, 1);412a = _int_unique(a);413ca = ARRNELEMS(a);414QSORT(b, 1);415b = _int_unique(b);416cb = ARRNELEMS(b);417result = new_intArrayType(ca);418aa = ARRPTR(a);419bb = ARRPTR(b);420r = ARRPTR(result);421while (i < ca)422{423if (k == cb || aa[i] < bb[k])424r[n++] = aa[i++];425else if (aa[i] == bb[k])426{427i++;428k++;429}430else431k++;432}433result = resize_intArrayType(result, n);434pfree(a);435pfree(b);436PG_RETURN_POINTER(result);437}
438