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