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