PostgreSQL Source Code: contrib/intarray/_int_op.c Source File

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

AltStyle によって変換されたページ (->オリジナル) /