Age Owner Branch data TLA Line data Source code
1 : : /*
2 : : * contrib/intarray/_int_op.c
3 : : */
4 : : #include "postgres.h"
5 : :
6 : : #include "_int.h"
7 : :
6529 tgl@sss.pgh.pa.us 8 :CBC 1 : PG_MODULE_MAGIC;
9 : :
7613 bruce@momjian.us 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 : 41160 : _int_contained(PG_FUNCTION_ARGS)
20 : : {
21 : : /* just reverse the operands and call _int_contains */
4844 tgl@sss.pgh.pa.us 22 : 41160 : return DirectFunctionCall2(_int_contains,
23 : : PG_GETARG_DATUM(1),
24 : : PG_GETARG_DATUM(0));
25 : : }
26 : :
27 : : Datum
7613 bruce@momjian.us 28 : 68284 : _int_contains(PG_FUNCTION_ARGS)
29 : : {
30 : : /* Force copy so we can modify the arrays in-place */
4844 tgl@sss.pgh.pa.us 31 : 68284 : ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
32 : 68284 : ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
33 : : bool res;
34 : :
6721 35 [ - + - - : 68284 : CHECKARRVALID(a);
- - ]
36 [ - + - - : 68284 : CHECKARRVALID(b);
- - ]
7613 bruce@momjian.us 37 [ + + - + : 68284 : PREPAREARR(a);
+ + ]
38 [ + + - + : 68284 : PREPAREARR(b);
+ + ]
39 : 68284 : res = inner_int_contains(a, b);
40 : 68284 : pfree(a);
41 : 68284 : pfree(b);
42 : 68284 : PG_RETURN_BOOL(res);
43 : : }
44 : :
45 : : Datum
7613 bruce@momjian.us 46 :UBC 0 : _int_different(PG_FUNCTION_ARGS)
47 : : {
1536 alvherre@alvh.no-ip. 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
7613 bruce@momjian.us 54 : 0 : _int_same(PG_FUNCTION_ARGS)
55 : : {
4844 tgl@sss.pgh.pa.us 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 : :
6721 65 [ # # # # : 0 : CHECKARRVALID(a);
# # ]
66 [ # # # # : 0 : CHECKARRVALID(b);
# # ]
7613 bruce@momjian.us 67 : 0 : na = ARRNELEMS(a);
68 : 0 : nb = ARRNELEMS(b);
69 [ # # ]: 0 : da = ARRPTR(a);
70 [ # # ]: 0 : db = ARRPTR(b);
71 : :
2433 peter_e@gmx.net 72 : 0 : result = false;
73 : :
7613 bruce@momjian.us 74 [ # # ]: 0 : if (na == nb)
75 : : {
6549 teodor@sigaev.ru 76 [ # # # # ]: 0 : SORT(a);
77 [ # # # # ]: 0 : SORT(b);
2433 peter_e@gmx.net 78 : 0 : result = true;
79 : :
7613 bruce@momjian.us 80 [ # # ]: 0 : for (n = 0; n < na; n++)
81 : : {
82 [ # # ]: 0 : if (da[n] != db[n])
83 : : {
2433 peter_e@gmx.net 84 : 0 : result = false;
7613 bruce@momjian.us 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
7613 bruce@momjian.us 99 :CBC 7563 : _int_overlap(PG_FUNCTION_ARGS)
100 : : {
4844 tgl@sss.pgh.pa.us 101 : 7563 : ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
102 : 7563 : ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
103 : : bool result;
104 : :
6721 105 [ - + - - : 7563 : CHECKARRVALID(a);
- - ]
106 [ - + - - : 7563 : CHECKARRVALID(b);
- - ]
4844 107 [ + + - + ]: 7563 : if (ARRISEMPTY(a) || ARRISEMPTY(b))
2433 peter_e@gmx.net 108 : 9 : return false;
109 : :
7613 bruce@momjian.us 110 [ + - - + ]: 7554 : SORT(a);
111 [ + - - + ]: 7554 : SORT(b);
112 : :
113 : 7554 : result = inner_int_overlap(a, b);
114 : :
115 : 7554 : pfree(a);
116 : 7554 : pfree(b);
117 : :
118 : 7554 : PG_RETURN_BOOL(result);
119 : : }
120 : :
121 : : Datum
122 : 1 : _int_union(PG_FUNCTION_ARGS)
123 : : {
4844 tgl@sss.pgh.pa.us 124 : 1 : ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
125 : 1 : ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
126 : : ArrayType *result;
127 : :
6721 128 [ - + - - : 1 : CHECKARRVALID(a);
- - ]
129 [ - + - - : 1 : CHECKARRVALID(b);
- - ]
130 : :
4844 131 [ + - - + ]: 1 : SORT(a);
132 [ + - - + ]: 1 : SORT(b);
133 : :
7613 bruce@momjian.us 134 : 1 : result = inner_int_union(a, b);
135 : :
4844 tgl@sss.pgh.pa.us 136 : 1 : pfree(a);
137 : 1 : pfree(b);
138 : :
7613 bruce@momjian.us 139 : 1 : PG_RETURN_POINTER(result);
140 : : }
141 : :
142 : : Datum
143 : 6 : _int_inter(PG_FUNCTION_ARGS)
144 : : {
4844 tgl@sss.pgh.pa.us 145 : 6 : ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
146 : 6 : ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
147 : : ArrayType *result;
148 : :
6721 149 [ - + - - : 6 : CHECKARRVALID(a);
- - ]
150 [ - + - - : 6 : CHECKARRVALID(b);
- - ]
151 : :
7613 bruce@momjian.us 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 : : {
4844 tgl@sss.pgh.pa.us 187 : 2 : ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
6721 188 : 2 : int32 count = ARRNELEMS(a);
189 : :
7613 bruce@momjian.us 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 : : {
4844 tgl@sss.pgh.pa.us 197 : 3 : ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
2590 noah@leadboat.com 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;
7613 bruce@momjian.us 201 : 3 : int dir = -1;
202 : :
6721 tgl@sss.pgh.pa.us 203 [ - + - - : 3 : CHECKARRVALID(a);
- - ]
4844 204 [ - + ]: 3 : if (ARRNELEMS(a) < 2)
7613 bruce@momjian.us 205 :UBC 0 : PG_RETURN_POINTER(a);
206 : :
7613 bruce@momjian.us 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)
7570 tgl@sss.pgh.pa.us 219 [ # # ]:UBC 0 : ereport(ERROR,
220 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
221 : : errmsg("second parameter must be \"ASC\" or \"DESC\"")));
7613 bruce@momjian.us 222 [ + - + + :CBC 3 : QSORT(a, dir);
- + ]
223 : 3 : PG_RETURN_POINTER(a);
224 : : }
225 : :
226 : : Datum
227 : 2 : sort_asc(PG_FUNCTION_ARGS)
228 : : {
4844 tgl@sss.pgh.pa.us 229 : 2 : ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
230 : :
6721 231 [ - + - - : 2 : CHECKARRVALID(a);
- - ]
7613 bruce@momjian.us 232 [ + - - + ]: 2 : QSORT(a, 1);
233 : 2 : PG_RETURN_POINTER(a);
234 : : }
235 : :
236 : : Datum
237 : 1 : sort_desc(PG_FUNCTION_ARGS)
238 : : {
4844 tgl@sss.pgh.pa.us 239 : 1 : ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
240 : :
6721 241 [ - + - - : 1 : CHECKARRVALID(a);
- - ]
7613 bruce@momjian.us 242 [ + - - + ]: 1 : QSORT(a, 0);
243 : 1 : PG_RETURN_POINTER(a);
244 : : }
245 : :
246 : : Datum
247 : 2 : uniq(PG_FUNCTION_ARGS)
248 : : {
4844 tgl@sss.pgh.pa.us 249 : 2 : ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
250 : :
6721 251 [ - + - - : 2 : CHECKARRVALID(a);
- - ]
4844 252 [ - + ]: 2 : if (ARRNELEMS(a) < 2)
7613 bruce@momjian.us 253 :UBC 0 : PG_RETURN_POINTER(a);
7613 bruce@momjian.us 254 :CBC 2 : a = _int_unique(a);
255 : 2 : PG_RETURN_POINTER(a);
256 : : }
257 : :
258 : : Datum
259 : 1 : idx(PG_FUNCTION_ARGS)
260 : : {
4844 tgl@sss.pgh.pa.us 261 : 1 : ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
262 : : int32 result;
263 : :
6721 264 [ - + - - : 1 : CHECKARRVALID(a);
- - ]
4844 265 : 1 : result = ARRNELEMS(a);
7613 bruce@momjian.us 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 : : {
4844 tgl@sss.pgh.pa.us 275 : 3 : ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
276 : 3 : int32 start = PG_GETARG_INT32(1);
7613 bruce@momjian.us 277 [ + - ]: 3 : int32 len = (fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0;
278 : 3 : int32 end = 0;
279 : : int32 c;
280 : : ArrayType *result;
281 : :
4844 tgl@sss.pgh.pa.us 282 [ + + ]: 3 : start = (start > 0) ? start - 1 : start;
283 : :
6721 284 [ - + - - : 3 : CHECKARRVALID(a);
- - ]
4844 285 [ - + ]: 3 : if (ARRISEMPTY(a))
286 : : {
7613 bruce@momjian.us 287 [ # # ]:UBC 0 : PG_FREE_IF_COPY(a, 0);
288 : 0 : PG_RETURN_POINTER(new_intArrayType(0));
289 : : }
290 : :
7613 bruce@momjian.us 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)
7613 bruce@momjian.us 299 :UBC 0 : end = c;
300 : : else
7613 bruce@momjian.us 301 :CBC 2 : end = start + len;
302 : :
303 [ - + ]: 3 : if (end > c)
7613 bruce@momjian.us 304 :UBC 0 : end = c;
305 : :
7613 bruce@momjian.us 306 [ - + ]:CBC 3 : if (start < 0)
7613 bruce@momjian.us 307 :UBC 0 : start = 0;
308 : :
7613 bruce@momjian.us 309 [ + - - + ]:CBC 3 : if (start >= end || end <= 0)
310 : : {
7613 bruce@momjian.us 311 [ # # ]:UBC 0 : PG_FREE_IF_COPY(a, 0);
312 : 0 : PG_RETURN_POINTER(new_intArrayType(0));
313 : : }
314 : :
7613 bruce@momjian.us 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 : : {
4844 tgl@sss.pgh.pa.us 325 : 2 : ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
326 : : ArrayType *result;
327 : :
7613 bruce@momjian.us 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 : : {
4844 tgl@sss.pgh.pa.us 336 : 1 : ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
337 : 1 : ArrayType *b = PG_GETARG_ARRAYTYPE_P(1);
338 : : ArrayType *result;
339 : :
7613 bruce@momjian.us 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 : : {
4844 tgl@sss.pgh.pa.us 349 : 1 : ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
6721 350 : 1 : int32 elem = PG_GETARG_INT32(1);
351 : : int32 c;
352 : : int32 *aa;
7613 bruce@momjian.us 353 : 1 : int32 n = 0,
354 : : i;
355 : :
6721 tgl@sss.pgh.pa.us 356 [ - + - - : 1 : CHECKARRVALID(a);
- - ]
4844 357 [ + - ]: 1 : if (!ARRISEMPTY(a))
358 : : {
6721 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 : : }
7613 bruce@momjian.us 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 : : {
4844 tgl@sss.pgh.pa.us 379 : 2 : ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
380 : : ArrayType *result;
381 : :
7613 bruce@momjian.us 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 : : {
4844 tgl@sss.pgh.pa.us 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;
7613 bruce@momjian.us 399 : 1 : int32 n = 0,
400 : 1 : i = 0,
401 : 1 : k = 0;
402 : :
6721 tgl@sss.pgh.pa.us 403 [ - + - - : 1 : CHECKARRVALID(a);
- - ]
404 [ - + - - : 1 : CHECKARRVALID(b);
- - ]
405 : :
7613 bruce@momjian.us 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
7613 bruce@momjian.us 426 :UBC 0 : k++;
427 : : }
7613 bruce@momjian.us 428 :CBC 1 : result = resize_intArrayType(result, n);
429 : 1 : pfree(a);
430 : 1 : pfree(b);
431 : 1 : PG_RETURN_POINTER(result);
432 : : }
|