Consistently use "superuser" instead of "super user"
[pgsql.git] / contrib / intarray / _int_op.c
blob5b164f6788fb43a97e5318c3d870f3082c8baf48
1 /*
2 * contrib/intarray/_int_op.c
3 */
4 #include "postgres.h"
6 #include "_int.h"
8 PG_MODULE_MAGIC;
10 PG_FUNCTION_INFO_V1(_int_different);
11 PG_FUNCTION_INFO_V1(_int_same);
12 PG_FUNCTION_INFO_V1(_int_contains);
13 PG_FUNCTION_INFO_V1(_int_contained);
14 PG_FUNCTION_INFO_V1(_int_overlap);
15 PG_FUNCTION_INFO_V1(_int_union);
16 PG_FUNCTION_INFO_V1(_int_inter);
18 Datum
19 _int_contained(PG_FUNCTION_ARGS)
21 /* just reverse the operands and call _int_contains */
22 return DirectFunctionCall2(_int_contains,
23 PG_GETARG_DATUM(1),
24 PG_GETARG_DATUM(0));
27 Datum
28 _int_contains(PG_FUNCTION_ARGS)
30 /* Force copy so we can modify the arrays in-place */
31 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
32 ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
33 bool res;
35 CHECKARRVALID(a);
36 CHECKARRVALID(b);
37 PREPAREARR(a);
38 PREPAREARR(b);
39 res = inner_int_contains(a, b);
40 pfree(a);
41 pfree(b);
42 PG_RETURN_BOOL(res);
45 Datum
46 _int_different(PG_FUNCTION_ARGS)
48 PG_RETURN_BOOL(!DatumGetBool(DirectFunctionCall2(_int_same,
49 PointerGetDatum(PG_GETARG_POINTER(0)),
50 PointerGetDatum(PG_GETARG_POINTER(1)))));
53 Datum
54 _int_same(PG_FUNCTION_ARGS)
56 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
57 ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
58 int na,
59 nb;
60 int n;
61 int *da,
62 *db;
63 bool result;
65 CHECKARRVALID(a);
66 CHECKARRVALID(b);
67 na = ARRNELEMS(a);
68 nb = ARRNELEMS(b);
69 da = ARRPTR(a);
70 db = ARRPTR(b);
72 result = false;
74 if (na == nb)
76 SORT(a);
77 SORT(b);
78 result = true;
80 for (n = 0; n < na; n++)
82 if (da[n] != db[n])
84 result = false;
85 break;
90 pfree(a);
91 pfree(b);
93 PG_RETURN_BOOL(result);
96 /* _int_overlap -- does a overlap b?
98 Datum
99 _int_overlap(PG_FUNCTION_ARGS)
101 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
102 ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
103 bool result;
105 CHECKARRVALID(a);
106 CHECKARRVALID(b);
107 if (ARRISEMPTY(a) || ARRISEMPTY(b))
108 return false;
110 SORT(a);
111 SORT(b);
113 result = inner_int_overlap(a, b);
115 pfree(a);
116 pfree(b);
118 PG_RETURN_BOOL(result);
121 Datum
122 _int_union(PG_FUNCTION_ARGS)
124 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
125 ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
126 ArrayType *result;
128 CHECKARRVALID(a);
129 CHECKARRVALID(b);
131 SORT(a);
132 SORT(b);
134 result = inner_int_union(a, b);
136 pfree(a);
137 pfree(b);
139 PG_RETURN_POINTER(result);
142 Datum
143 _int_inter(PG_FUNCTION_ARGS)
145 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
146 ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
147 ArrayType *result;
149 CHECKARRVALID(a);
150 CHECKARRVALID(b);
152 SORT(a);
153 SORT(b);
155 result = inner_int_inter(a, b);
157 pfree(a);
158 pfree(b);
160 PG_RETURN_POINTER(result);
164 PG_FUNCTION_INFO_V1(intset);
165 PG_FUNCTION_INFO_V1(icount);
166 PG_FUNCTION_INFO_V1(sort);
167 PG_FUNCTION_INFO_V1(sort_asc);
168 PG_FUNCTION_INFO_V1(sort_desc);
169 PG_FUNCTION_INFO_V1(uniq);
170 PG_FUNCTION_INFO_V1(idx);
171 PG_FUNCTION_INFO_V1(subarray);
172 PG_FUNCTION_INFO_V1(intarray_push_elem);
173 PG_FUNCTION_INFO_V1(intarray_push_array);
174 PG_FUNCTION_INFO_V1(intarray_del_elem);
175 PG_FUNCTION_INFO_V1(intset_union_elem);
176 PG_FUNCTION_INFO_V1(intset_subtract);
178 Datum
179 intset(PG_FUNCTION_ARGS)
181 PG_RETURN_POINTER(int_to_intset(PG_GETARG_INT32(0)));
184 Datum
185 icount(PG_FUNCTION_ARGS)
187 ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
188 int32 count = ARRNELEMS(a);
190 PG_FREE_IF_COPY(a, 0);
191 PG_RETURN_INT32(count);
194 Datum
195 sort(PG_FUNCTION_ARGS)
197 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
198 text *dirstr = (fcinfo->nargs == 2) ? PG_GETARG_TEXT_PP(1) : NULL;
199 int32 dc = (dirstr) ? VARSIZE_ANY_EXHDR(dirstr) : 0;
200 char *d = (dirstr) ? VARDATA_ANY(dirstr) : NULL;
201 int dir = -1;
203 CHECKARRVALID(a);
204 if (ARRNELEMS(a) < 2)
205 PG_RETURN_POINTER(a);
207 if (dirstr == NULL || (dc == 3
208 && (d[0] == 'A' || d[0] == 'a')
209 && (d[1] == 'S' || d[1] == 's')
210 && (d[2] == 'C' || d[2] == 'c')))
211 dir = 1;
212 else if (dc == 4
213 && (d[0] == 'D' || d[0] == 'd')
214 && (d[1] == 'E' || d[1] == 'e')
215 && (d[2] == 'S' || d[2] == 's')
216 && (d[3] == 'C' || d[3] == 'c'))
217 dir = 0;
218 if (dir == -1)
219 ereport(ERROR,
220 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
221 errmsg("second parameter must be \"ASC\" or \"DESC\"")));
222 QSORT(a, dir);
223 PG_RETURN_POINTER(a);
226 Datum
227 sort_asc(PG_FUNCTION_ARGS)
229 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
231 CHECKARRVALID(a);
232 QSORT(a, 1);
233 PG_RETURN_POINTER(a);
236 Datum
237 sort_desc(PG_FUNCTION_ARGS)
239 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
241 CHECKARRVALID(a);
242 QSORT(a, 0);
243 PG_RETURN_POINTER(a);
246 Datum
247 uniq(PG_FUNCTION_ARGS)
249 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
251 CHECKARRVALID(a);
252 if (ARRNELEMS(a) < 2)
253 PG_RETURN_POINTER(a);
254 a = _int_unique(a);
255 PG_RETURN_POINTER(a);
258 Datum
259 idx(PG_FUNCTION_ARGS)
261 ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
262 int32 result;
264 CHECKARRVALID(a);
265 result = ARRNELEMS(a);
266 if (result)
267 result = intarray_match_first(a, PG_GETARG_INT32(1));
268 PG_FREE_IF_COPY(a, 0);
269 PG_RETURN_INT32(result);
272 Datum
273 subarray(PG_FUNCTION_ARGS)
275 ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
276 int32 start = PG_GETARG_INT32(1);
277 int32 len = (fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0;
278 int32 end = 0;
279 int32 c;
280 ArrayType *result;
282 start = (start > 0) ? start - 1 : start;
284 CHECKARRVALID(a);
285 if (ARRISEMPTY(a))
287 PG_FREE_IF_COPY(a, 0);
288 PG_RETURN_POINTER(new_intArrayType(0));
291 c = ARRNELEMS(a);
293 if (start < 0)
294 start = c + start;
296 if (len < 0)
297 end = c + len;
298 else if (len == 0)
299 end = c;
300 else
301 end = start + len;
303 if (end > c)
304 end = c;
306 if (start < 0)
307 start = 0;
309 if (start >= end || end <= 0)
311 PG_FREE_IF_COPY(a, 0);
312 PG_RETURN_POINTER(new_intArrayType(0));
315 result = new_intArrayType(end - start);
316 if (end - start > 0)
317 memcpy(ARRPTR(result), ARRPTR(a) + start, (end - start) * sizeof(int32));
318 PG_FREE_IF_COPY(a, 0);
319 PG_RETURN_POINTER(result);
322 Datum
323 intarray_push_elem(PG_FUNCTION_ARGS)
325 ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
326 ArrayType *result;
328 result = intarray_add_elem(a, PG_GETARG_INT32(1));
329 PG_FREE_IF_COPY(a, 0);
330 PG_RETURN_POINTER(result);
333 Datum
334 intarray_push_array(PG_FUNCTION_ARGS)
336 ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
337 ArrayType *b = PG_GETARG_ARRAYTYPE_P(1);
338 ArrayType *result;
340 result = intarray_concat_arrays(a, b);
341 PG_FREE_IF_COPY(a, 0);
342 PG_FREE_IF_COPY(b, 1);
343 PG_RETURN_POINTER(result);
346 Datum
347 intarray_del_elem(PG_FUNCTION_ARGS)
349 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
350 int32 elem = PG_GETARG_INT32(1);
351 int32 c;
352 int32 *aa;
353 int32 n = 0,
356 CHECKARRVALID(a);
357 if (!ARRISEMPTY(a))
359 c = ARRNELEMS(a);
360 aa = ARRPTR(a);
361 for (i = 0; i < c; i++)
363 if (aa[i] != elem)
365 if (i > n)
366 aa[n++] = aa[i];
367 else
368 n++;
371 a = resize_intArrayType(a, n);
373 PG_RETURN_POINTER(a);
376 Datum
377 intset_union_elem(PG_FUNCTION_ARGS)
379 ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
380 ArrayType *result;
382 result = intarray_add_elem(a, PG_GETARG_INT32(1));
383 PG_FREE_IF_COPY(a, 0);
384 QSORT(result, 1);
385 PG_RETURN_POINTER(_int_unique(result));
388 Datum
389 intset_subtract(PG_FUNCTION_ARGS)
391 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
392 ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
393 ArrayType *result;
394 int32 ca;
395 int32 cb;
396 int32 *aa,
397 *bb,
399 int32 n = 0,
400 i = 0,
401 k = 0;
403 CHECKARRVALID(a);
404 CHECKARRVALID(b);
406 QSORT(a, 1);
407 a = _int_unique(a);
408 ca = ARRNELEMS(a);
409 QSORT(b, 1);
410 b = _int_unique(b);
411 cb = ARRNELEMS(b);
412 result = new_intArrayType(ca);
413 aa = ARRPTR(a);
414 bb = ARRPTR(b);
415 r = ARRPTR(result);
416 while (i < ca)
418 if (k == cb || aa[i] < bb[k])
419 r[n++] = aa[i++];
420 else if (aa[i] == bb[k])
422 i++;
423 k++;
425 else
426 k++;
428 result = resize_intArrayType(result, n);
429 pfree(a);
430 pfree(b);
431 PG_RETURN_POINTER(result);