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