Go to the documentation of this file.00001
00002
00003
00004 #include "postgres.h"
00005
00006
00007 #include "_int.h"
00008
00009
00010 PG_MODULE_MAGIC;
00011
00012 PG_FUNCTION_INFO_V1(_int_different);
00013 PG_FUNCTION_INFO_V1(_int_same);
00014 PG_FUNCTION_INFO_V1(_int_contains);
00015 PG_FUNCTION_INFO_V1(_int_contained);
00016 PG_FUNCTION_INFO_V1(_int_overlap);
00017 PG_FUNCTION_INFO_V1(_int_union);
00018 PG_FUNCTION_INFO_V1(_int_inter);
00019
00020 Datum _int_different(PG_FUNCTION_ARGS);
00021 Datum _int_same(PG_FUNCTION_ARGS);
00022 Datum _int_contains(PG_FUNCTION_ARGS);
00023 Datum _int_contained(PG_FUNCTION_ARGS);
00024 Datum _int_overlap(PG_FUNCTION_ARGS);
00025 Datum _int_union(PG_FUNCTION_ARGS);
00026 Datum _int_inter(PG_FUNCTION_ARGS);
00027
00028 Datum
00029 _int_contained(PG_FUNCTION_ARGS)
00030 {
00031
00032 return DirectFunctionCall2(_int_contains,
00033 PG_GETARG_DATUM(1),
00034 PG_GETARG_DATUM(0));
00035 }
00036
00037 Datum
00038 _int_contains(PG_FUNCTION_ARGS)
00039 {
00040
00041 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
00042 ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
00043 bool res;
00044
00045 CHECKARRVALID(a);
00046 CHECKARRVALID(b);
00047 PREPAREARR(a);
00048 PREPAREARR(b);
00049 res = inner_int_contains(a, b);
00050 pfree(a);
00051 pfree(b);
00052 PG_RETURN_BOOL(res);
00053 }
00054
00055 Datum
00056 _int_different(PG_FUNCTION_ARGS)
00057 {
00058 PG_RETURN_BOOL(!DatumGetBool(
00059 DirectFunctionCall2(
00060 _int_same,
00061 PointerGetDatum(PG_GETARG_POINTER(0)),
00062 PointerGetDatum(PG_GETARG_POINTER(1))
00063 )
00064 ));
00065 }
00066
00067 Datum
00068 _int_same(PG_FUNCTION_ARGS)
00069 {
00070 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
00071 ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
00072 int na,
00073 nb;
00074 int n;
00075 int *da,
00076 *db;
00077 bool result;
00078
00079 CHECKARRVALID(a);
00080 CHECKARRVALID(b);
00081 na = ARRNELEMS(a);
00082 nb = ARRNELEMS(b);
00083 da = ARRPTR(a);
00084 db = ARRPTR(b);
00085
00086 result = FALSE;
00087
00088 if (na == nb)
00089 {
00090 SORT(a);
00091 SORT(b);
00092 result = TRUE;
00093
00094 for (n = 0; n < na; n++)
00095 {
00096 if (da[n] != db[n])
00097 {
00098 result = FALSE;
00099 break;
00100 }
00101 }
00102 }
00103
00104 pfree(a);
00105 pfree(b);
00106
00107 PG_RETURN_BOOL(result);
00108 }
00109
00110
00111
00112 Datum
00113 _int_overlap(PG_FUNCTION_ARGS)
00114 {
00115 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
00116 ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
00117 bool result;
00118
00119 CHECKARRVALID(a);
00120 CHECKARRVALID(b);
00121 if (ARRISEMPTY(a) || ARRISEMPTY(b))
00122 return FALSE;
00123
00124 SORT(a);
00125 SORT(b);
00126
00127 result = inner_int_overlap(a, b);
00128
00129 pfree(a);
00130 pfree(b);
00131
00132 PG_RETURN_BOOL(result);
00133 }
00134
00135 Datum
00136 _int_union(PG_FUNCTION_ARGS)
00137 {
00138 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
00139 ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
00140 ArrayType *result;
00141
00142 CHECKARRVALID(a);
00143 CHECKARRVALID(b);
00144
00145 SORT(a);
00146 SORT(b);
00147
00148 result = inner_int_union(a, b);
00149
00150 pfree(a);
00151 pfree(b);
00152
00153 PG_RETURN_POINTER(result);
00154 }
00155
00156 Datum
00157 _int_inter(PG_FUNCTION_ARGS)
00158 {
00159 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
00160 ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
00161 ArrayType *result;
00162
00163 CHECKARRVALID(a);
00164 CHECKARRVALID(b);
00165
00166 SORT(a);
00167 SORT(b);
00168
00169 result = inner_int_inter(a, b);
00170
00171 pfree(a);
00172 pfree(b);
00173
00174 PG_RETURN_POINTER(result);
00175 }
00176
00177
00178 PG_FUNCTION_INFO_V1(intset);
00179 PG_FUNCTION_INFO_V1(icount);
00180 PG_FUNCTION_INFO_V1(sort);
00181 PG_FUNCTION_INFO_V1(sort_asc);
00182 PG_FUNCTION_INFO_V1(sort_desc);
00183 PG_FUNCTION_INFO_V1(uniq);
00184 PG_FUNCTION_INFO_V1(idx);
00185 PG_FUNCTION_INFO_V1(subarray);
00186 PG_FUNCTION_INFO_V1(intarray_push_elem);
00187 PG_FUNCTION_INFO_V1(intarray_push_array);
00188 PG_FUNCTION_INFO_V1(intarray_del_elem);
00189 PG_FUNCTION_INFO_V1(intset_union_elem);
00190 PG_FUNCTION_INFO_V1(intset_subtract);
00191 Datum intset(PG_FUNCTION_ARGS);
00192 Datum icount(PG_FUNCTION_ARGS);
00193 Datum sort(PG_FUNCTION_ARGS);
00194 Datum sort_asc(PG_FUNCTION_ARGS);
00195 Datum sort_desc(PG_FUNCTION_ARGS);
00196 Datum uniq(PG_FUNCTION_ARGS);
00197 Datum idx(PG_FUNCTION_ARGS);
00198 Datum subarray(PG_FUNCTION_ARGS);
00199 Datum intarray_push_elem(PG_FUNCTION_ARGS);
00200 Datum intarray_push_array(PG_FUNCTION_ARGS);
00201 Datum intarray_del_elem(PG_FUNCTION_ARGS);
00202 Datum intset_union_elem(PG_FUNCTION_ARGS);
00203 Datum intset_subtract(PG_FUNCTION_ARGS);
00204
00205 Datum
00206 intset(PG_FUNCTION_ARGS)
00207 {
00208 PG_RETURN_POINTER(int_to_intset(PG_GETARG_INT32(0)));
00209 }
00210
00211 Datum
00212 icount(PG_FUNCTION_ARGS)
00213 {
00214 ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
00215 int32 count = ARRNELEMS(a);
00216
00217 PG_FREE_IF_COPY(a, 0);
00218 PG_RETURN_INT32(count);
00219 }
00220
00221 Datum
00222 sort(PG_FUNCTION_ARGS)
00223 {
00224 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
00225 text *dirstr = (fcinfo->nargs == 2) ? PG_GETARG_TEXT_P(1) : NULL;
00226 int32 dc = (dirstr) ? VARSIZE(dirstr) - VARHDRSZ : 0;
00227 char *d = (dirstr) ? VARDATA(dirstr) : NULL;
00228 int dir = -1;
00229
00230 CHECKARRVALID(a);
00231 if (ARRNELEMS(a) < 2)
00232 PG_RETURN_POINTER(a);
00233
00234 if (dirstr == NULL || (dc == 3
00235 && (d[0] == 'A' || d[0] == 'a')
00236 && (d[1] == 'S' || d[1] == 's')
00237 && (d[2] == 'C' || d[2] == 'c')))
00238 dir = 1;
00239 else if (dc == 4
00240 && (d[0] == 'D' || d[0] == 'd')
00241 && (d[1] == 'E' || d[1] == 'e')
00242 && (d[2] == 'S' || d[2] == 's')
00243 && (d[3] == 'C' || d[3] == 'c'))
00244 dir = 0;
00245 if (dir == -1)
00246 ereport(ERROR,
00247 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00248 errmsg("second parameter must be \"ASC\" or \"DESC\"")));
00249 QSORT(a, dir);
00250 PG_RETURN_POINTER(a);
00251 }
00252
00253 Datum
00254 sort_asc(PG_FUNCTION_ARGS)
00255 {
00256 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
00257
00258 CHECKARRVALID(a);
00259 QSORT(a, 1);
00260 PG_RETURN_POINTER(a);
00261 }
00262
00263 Datum
00264 sort_desc(PG_FUNCTION_ARGS)
00265 {
00266 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
00267
00268 CHECKARRVALID(a);
00269 QSORT(a, 0);
00270 PG_RETURN_POINTER(a);
00271 }
00272
00273 Datum
00274 uniq(PG_FUNCTION_ARGS)
00275 {
00276 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
00277
00278 CHECKARRVALID(a);
00279 if (ARRNELEMS(a) < 2)
00280 PG_RETURN_POINTER(a);
00281 a = _int_unique(a);
00282 PG_RETURN_POINTER(a);
00283 }
00284
00285 Datum
00286 idx(PG_FUNCTION_ARGS)
00287 {
00288 ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
00289 int32 result;
00290
00291 CHECKARRVALID(a);
00292 result = ARRNELEMS(a);
00293 if (result)
00294 result = intarray_match_first(a, PG_GETARG_INT32(1));
00295 PG_FREE_IF_COPY(a, 0);
00296 PG_RETURN_INT32(result);
00297 }
00298
00299 Datum
00300 subarray(PG_FUNCTION_ARGS)
00301 {
00302 ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
00303 int32 start = PG_GETARG_INT32(1);
00304 int32 len = (fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0;
00305 int32 end = 0;
00306 int32 c;
00307 ArrayType *result;
00308
00309 start = (start > 0) ? start - 1 : start;
00310
00311 CHECKARRVALID(a);
00312 if (ARRISEMPTY(a))
00313 {
00314 PG_FREE_IF_COPY(a, 0);
00315 PG_RETURN_POINTER(new_intArrayType(0));
00316 }
00317
00318 c = ARRNELEMS(a);
00319
00320 if (start < 0)
00321 start = c + start;
00322
00323 if (len < 0)
00324 end = c + len;
00325 else if (len == 0)
00326 end = c;
00327 else
00328 end = start + len;
00329
00330 if (end > c)
00331 end = c;
00332
00333 if (start < 0)
00334 start = 0;
00335
00336 if (start >= end || end <= 0)
00337 {
00338 PG_FREE_IF_COPY(a, 0);
00339 PG_RETURN_POINTER(new_intArrayType(0));
00340 }
00341
00342 result = new_intArrayType(end - start);
00343 if (end - start > 0)
00344 memcpy(ARRPTR(result), ARRPTR(a) + start, (end - start) * sizeof(int32));
00345 PG_FREE_IF_COPY(a, 0);
00346 PG_RETURN_POINTER(result);
00347 }
00348
00349 Datum
00350 intarray_push_elem(PG_FUNCTION_ARGS)
00351 {
00352 ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
00353 ArrayType *result;
00354
00355 result = intarray_add_elem(a, PG_GETARG_INT32(1));
00356 PG_FREE_IF_COPY(a, 0);
00357 PG_RETURN_POINTER(result);
00358 }
00359
00360 Datum
00361 intarray_push_array(PG_FUNCTION_ARGS)
00362 {
00363 ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
00364 ArrayType *b = PG_GETARG_ARRAYTYPE_P(1);
00365 ArrayType *result;
00366
00367 result = intarray_concat_arrays(a, b);
00368 PG_FREE_IF_COPY(a, 0);
00369 PG_FREE_IF_COPY(b, 1);
00370 PG_RETURN_POINTER(result);
00371 }
00372
00373 Datum
00374 intarray_del_elem(PG_FUNCTION_ARGS)
00375 {
00376 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
00377 int32 elem = PG_GETARG_INT32(1);
00378 int32 c;
00379 int32 *aa;
00380 int32 n = 0,
00381 i;
00382
00383 CHECKARRVALID(a);
00384 if (!ARRISEMPTY(a))
00385 {
00386 c = ARRNELEMS(a);
00387 aa = ARRPTR(a);
00388 for (i = 0; i < c; i++)
00389 {
00390 if (aa[i] != elem)
00391 {
00392 if (i > n)
00393 aa[n++] = aa[i];
00394 else
00395 n++;
00396 }
00397 }
00398 a = resize_intArrayType(a, n);
00399 }
00400 PG_RETURN_POINTER(a);
00401 }
00402
00403 Datum
00404 intset_union_elem(PG_FUNCTION_ARGS)
00405 {
00406 ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
00407 ArrayType *result;
00408
00409 result = intarray_add_elem(a, PG_GETARG_INT32(1));
00410 PG_FREE_IF_COPY(a, 0);
00411 QSORT(result, 1);
00412 PG_RETURN_POINTER(_int_unique(result));
00413 }
00414
00415 Datum
00416 intset_subtract(PG_FUNCTION_ARGS)
00417 {
00418 ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
00419 ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
00420 ArrayType *result;
00421 int32 ca;
00422 int32 cb;
00423 int32 *aa,
00424 *bb,
00425 *r;
00426 int32 n = 0,
00427 i = 0,
00428 k = 0;
00429
00430 CHECKARRVALID(a);
00431 CHECKARRVALID(b);
00432
00433 QSORT(a, 1);
00434 a = _int_unique(a);
00435 ca = ARRNELEMS(a);
00436 QSORT(b, 1);
00437 b = _int_unique(b);
00438 cb = ARRNELEMS(b);
00439 result = new_intArrayType(ca);
00440 aa = ARRPTR(a);
00441 bb = ARRPTR(b);
00442 r = ARRPTR(result);
00443 while (i < ca)
00444 {
00445 if (k == cb || aa[i] < bb[k])
00446 r[n++] = aa[i++];
00447 else if (aa[i] == bb[k])
00448 {
00449 i++;
00450 k++;
00451 }
00452 else
00453 k++;
00454 }
00455 result = resize_intArrayType(result, n);
00456 pfree(a);
00457 pfree(b);
00458 PG_RETURN_POINTER(result);
00459 }