Datum g_int_same(PG_FUNCTION_ARGS) { ArrayType *a = PG_GETARG_ARRAYTYPE_P(0); ArrayType *b = PG_GETARG_ARRAYTYPE_P(1); bool *result = (bool *) PG_GETARG_POINTER(2); int32 n = ARRNELEMS(a); int32 *da, *db; CHECKARRVALID(a); CHECKARRVALID(b); if (n != ARRNELEMS(b)) { *result = false; PG_RETURN_POINTER(result); } *result = TRUE; da = ARRPTR(a); db = ARRPTR(b); while (n--) { if (*da++ != *db++) { *result = FALSE; break; } } PG_RETURN_POINTER(result); }
bool inner_int_overlap(ArrayType *a, ArrayType *b) { int na, nb; int i, j; int *da, *db; CHECKARRVALID(a); CHECKARRVALID(b); if (ARRISVOID(a) || ARRISVOID(b)) return FALSE; na = ARRNELEMS(a); nb = ARRNELEMS(b); da = ARRPTR(a); db = ARRPTR(b); i = j = 0; while (i < na && j < nb) if (da[i] < db[j]) i++; else if (da[i] == db[j]) return TRUE; else j++; return FALSE; }
Datum g_int_same(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) PointerGetDatum(PG_GETARG_POINTER(0)); ArrayType *b = (ArrayType *) PointerGetDatum(PG_GETARG_POINTER(1)); bool *result = (bool *) PG_GETARG_POINTER(2); int4 n = ARRNELEMS(a); int4 *da, *db; CHECKARRVALID(a); CHECKARRVALID(b); if (n != ARRNELEMS(b)) { *result = false; PG_RETURN_POINTER(result); } *result = TRUE; da = ARRPTR(a); db = ARRPTR(b); while (n--) if (*da++ != *db++) { *result = FALSE; break; } PG_RETURN_POINTER(result); }
ArrayType * inner_int_union(ArrayType *a, ArrayType *b) { ArrayType *r = NULL; CHECKARRVALID(a); CHECKARRVALID(b); if (ARRISEMPTY(a) && ARRISEMPTY(b)) return new_intArrayType(0); if (ARRISEMPTY(a)) r = copy_intArrayType(b); if (ARRISEMPTY(b)) r = copy_intArrayType(a); if (!r) { int na = ARRNELEMS(a), nb = ARRNELEMS(b); int *da = ARRPTR(a), *db = ARRPTR(b); int i, j, *dr; r = new_intArrayType(na + nb); dr = ARRPTR(r); /* union */ i = j = 0; while (i < na && j < nb) { if (da[i] == db[j]) { *dr++ = da[i++]; j++; } else if (da[i] < db[j]) *dr++ = da[i++]; else *dr++ = db[j++]; } while (i < na) *dr++ = da[i++]; while (j < nb) *dr++ = db[j++]; r = resize_intArrayType(r, dr - ARRPTR(r)); } if (ARRNELEMS(r) > 1) r = _int_unique(r); return r; }
Datum sort(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0))); text *dirstr = (fcinfo->nargs == 2) ? PG_GETARG_TEXT_P(1) : NULL; int32 dc = (dirstr) ? VARSIZE(dirstr) - VARHDRSZ : 0; char *d = (dirstr) ? VARDATA(dirstr) : NULL; int dir = -1; CHECKARRVALID(a); if (ARRISVOID(a) || ARRNELEMS(a) < 2) PG_RETURN_POINTER(a); if (dirstr == NULL || (dc == 3 && (d[0] == 'A' || d[0] == 'a') && (d[1] == 'S' || d[1] == 's') && (d[2] == 'C' || d[2] == 'c'))) dir = 1; else if (dc == 4 && (d[0] == 'D' || d[0] == 'd') && (d[1] == 'E' || d[1] == 'e') && (d[2] == 'S' || d[2] == 's') && (d[3] == 'C' || d[3] == 'c')) dir = 0; if (dir == -1) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("second parameter must be \"ASC\" or \"DESC\""))); QSORT(a, dir); PG_RETURN_POINTER(a); }
Datum intarray_del_elem(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0))); int32 elem = PG_GETARG_INT32(1); int32 c; int32 *aa; int32 n = 0, i; CHECKARRVALID(a); if (!ARRISVOID(a)) { c = ARRNELEMS(a); aa = ARRPTR(a); for (i = 0; i < c; i++) { if (aa[i] != elem) { if (i > n) aa[n++] = aa[i]; else n++; } } a = resize_intArrayType(a, n); } PG_RETURN_POINTER(a); }
Datum intarray_del_elem(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) PG_GETARG_ARRAYTYPE_P_COPY(0); int32 elem = PG_GETARG_INT32(1); int32 c; int32 *aa; int32 n = 0, i; CHECKARRVALID(a); if (!ARRISEMPTY(a)) { c = ARRNELEMS(a); aa = ARRPTR(a); for (i = 0; i < c; i++) { if (aa[i] != elem) { if (i > n) aa[n++] = aa[i]; else n++; } } a = resize_intArrayType(a, n); } PG_RETURN_POINTER(a); }
ArrayType * intarray_concat_arrays(ArrayType *a, ArrayType *b) { ArrayType *result; int32 ac = ARRNELEMS(a); int32 bc = ARRNELEMS(b); CHECKARRVALID(a); CHECKARRVALID(b); result = new_intArrayType(ac + bc); if (ac) memcpy(ARRPTR(result), ARRPTR(a), ac * sizeof(int32)); if (bc) memcpy(ARRPTR(result) + ac, ARRPTR(b), bc * sizeof(int32)); return result; }
Datum boolop(PG_FUNCTION_ARGS) { ArrayType *val = (ArrayType *) PG_DETOAST_DATUM_COPY(PG_GETARG_POINTER(0)); QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_POINTER(1)); CHKVAL chkval; bool result; CHECKARRVALID(val); if (ARRISVOID(val)) { pfree(val); PG_FREE_IF_COPY(query, 1); PG_RETURN_BOOL(false); } PREPAREARR(val); chkval.arrb = ARRPTR(val); chkval.arre = chkval.arrb + ARRNELEMS(val); result = execute( GETQUERY(query) + query->size - 1, &chkval, true, checkcondition_arr ); pfree(val); PG_FREE_IF_COPY(query, 1); PG_RETURN_BOOL(result); }
ArrayType * inner_int_inter(ArrayType *a, ArrayType *b) { ArrayType *r; int na, nb; int *da, *db, *dr; int i, j; CHECKARRVALID(a); CHECKARRVALID(b); if (ARRISVOID(a) || ARRISVOID(b)) return new_intArrayType(0); na = ARRNELEMS(a); nb = ARRNELEMS(b); da = ARRPTR(a); db = ARRPTR(b); r = new_intArrayType(Min(na, nb)); dr = ARRPTR(r); i = j = 0; while (i < na && j < nb) if (da[i] < db[j]) i++; else if (da[i] == db[j]) { if (i + j == 0 || (i + j > 0 && *(dr - 1) != db[j])) *dr++ = db[j]; i++; j++; } else j++; if ((dr - ARRPTR(r)) == 0) { pfree(r); return new_intArrayType(0); } else return resize_intArrayType(r, dr - ARRPTR(r)); }
Datum _int_same(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0))); ArrayType *b = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1))); int na, nb; int n; int *da, *db; bool result; bool avoid; bool bvoid; CHECKARRVALID(a); CHECKARRVALID(b); avoid = ARRISVOID(a); bvoid = ARRISVOID(b); if (avoid || bvoid) return (avoid && bvoid) ? TRUE : FALSE; na = ARRNELEMS(a); nb = ARRNELEMS(b); da = ARRPTR(a); db = ARRPTR(b); result = FALSE; if (na == nb) { SORT(a); SORT(b); result = TRUE; for (n = 0; n < na; n++) if (da[n] != db[n]) { result = FALSE; break; } } pfree(a); pfree(b); PG_RETURN_BOOL(result); }
Datum _int_contains(PG_FUNCTION_ARGS) { /* Force copy so we can modify the arrays in-place */ ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0); ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1); bool res; CHECKARRVALID(a); CHECKARRVALID(b); PREPAREARR(a); PREPAREARR(b); res = inner_int_contains(a, b); pfree(a); pfree(b); PG_RETURN_BOOL(res); }
Datum intset_subtract(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0))); ArrayType *b = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1))); ArrayType *result; int32 ca; int32 cb; int32 *aa, *bb, *r; int32 n = 0, i = 0, k = 0; CHECKARRVALID(a); CHECKARRVALID(b); QSORT(a, 1); a = _int_unique(a); ca = ARRNELEMS(a); QSORT(b, 1); b = _int_unique(b); cb = ARRNELEMS(b); result = new_intArrayType(ca); aa = ARRPTR(a); bb = ARRPTR(b); r = ARRPTR(result); while (i < ca) { if (k == cb || aa[i] < bb[k]) r[n++] = aa[i++]; else if (aa[i] == bb[k]) { i++; k++; } else k++; } result = resize_intArrayType(result, n); pfree(a); pfree(b); PG_RETURN_POINTER(result); }
Datum sort_desc(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) PG_GETARG_ARRAYTYPE_P_COPY(0); CHECKARRVALID(a); QSORT(a, 0); PG_RETURN_POINTER(a); }
Datum _int_same(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) PG_GETARG_ARRAYTYPE_P_COPY(0); ArrayType *b = (ArrayType *) PG_GETARG_ARRAYTYPE_P_COPY(1); int na, nb; int n; int *da, *db; bool result; CHECKARRVALID(a); CHECKARRVALID(b); na = ARRNELEMS(a); nb = ARRNELEMS(b); da = ARRPTR(a); db = ARRPTR(b); result = FALSE; if (na == nb) { SORT(a); SORT(b); result = TRUE; for (n = 0; n < na; n++) { if (da[n] != db[n]) { result = FALSE; break; } } } pfree(a); pfree(b); PG_RETURN_BOOL(result); }
Datum _int_contains(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0))); ArrayType *b = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1))); bool res; CHECKARRVALID(a); CHECKARRVALID(b); if (ARRISVOID(a) || ARRISVOID(b)) return FALSE; PREPAREARR(a); PREPAREARR(b); res = inner_int_contains(a, b); pfree(a); pfree(b); PG_RETURN_BOOL(res); }
Datum uniq(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0))); CHECKARRVALID(a); if (ARRISVOID(a) || ARRNELEMS(a) < 2) PG_RETURN_POINTER(a); a = _int_unique(a); PG_RETURN_POINTER(a); }
Datum _int_inter(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) PG_GETARG_ARRAYTYPE_P_COPY(0); ArrayType *b = (ArrayType *) PG_GETARG_ARRAYTYPE_P_COPY(1); ArrayType *result; CHECKARRVALID(a); CHECKARRVALID(b); SORT(a); SORT(b); result = inner_int_inter(a, b); pfree(a); pfree(b); PG_RETURN_POINTER(result); }
Datum uniq(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) PG_GETARG_ARRAYTYPE_P_COPY(0); CHECKARRVALID(a); if (ARRNELEMS(a) < 2) PG_RETURN_POINTER(a); a = _int_unique(a); PG_RETURN_POINTER(a); }
Datum sort_desc(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0))); CHECKARRVALID(a); if (ARRISVOID(a)) PG_RETURN_POINTER(a); QSORT(a, 0); PG_RETURN_POINTER(a); }
/* Array must be sorted! */ bool execconsistent(QUERYTYPE *query, ArrayType *array, bool calcnot) { CHKVAL chkval; CHECKARRVALID(array); chkval.arrb = ARRPTR(array); chkval.arre = chkval.arrb + ARRNELEMS(array); return execute(GETQUERY(query) + query->size - 1, (void *) &chkval, calcnot, checkcondition_arr); }
Datum idx(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) PG_GETARG_ARRAYTYPE_P(0); int32 result; CHECKARRVALID(a); result = ARRNELEMS(a); if (result) result = intarray_match_first(a, PG_GETARG_INT32(1)); PG_FREE_IF_COPY(a, 0); PG_RETURN_INT32(result); }
Datum _int_inter(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0))); ArrayType *b = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1))); ArrayType *result; CHECKARRVALID(a); CHECKARRVALID(b); if (ARRISVOID(a) || ARRISVOID(b)) PG_RETURN_POINTER(new_intArrayType(0)); SORT(a); SORT(b); result = inner_int_inter(a, b); pfree(a); pfree(b); PG_RETURN_POINTER(result); }
Datum idx(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); int32 result; CHECKARRVALID(a); result = (ARRISVOID(a)) ? 0 : ARRNELEMS(a); if (result) result = intarray_match_first(a, PG_GETARG_INT32(1)); PG_FREE_IF_COPY(a, 0); PG_RETURN_INT32(result); }
/* _int_overlap -- does a overlap b? */ Datum _int_overlap(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) PG_GETARG_ARRAYTYPE_P_COPY(0); ArrayType *b = (ArrayType *) PG_GETARG_ARRAYTYPE_P_COPY(1); bool result; CHECKARRVALID(a); CHECKARRVALID(b); if (ARRISEMPTY(a) || ARRISEMPTY(b)) return FALSE; SORT(a); SORT(b); result = inner_int_overlap(a, b); pfree(a); pfree(b); PG_RETURN_BOOL(result); }
/* _int_overlap -- does a overlap b? */ Datum _int_overlap(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0))); ArrayType *b = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1))); bool result; CHECKARRVALID(a); CHECKARRVALID(b); if (ARRISVOID(a) || ARRISVOID(b)) return FALSE; SORT(a); SORT(b); result = inner_int_overlap(a, b); pfree(a); pfree(b); PG_RETURN_BOOL(result); }
bool inner_int_contains(ArrayType *a, ArrayType *b) { int na, nb; int i, j, n; int *da, *db; CHECKARRVALID(a); CHECKARRVALID(b); if (ARRISVOID(a) || ARRISVOID(b)) return FALSE; na = ARRNELEMS(a); nb = ARRNELEMS(b); da = ARRPTR(a); db = ARRPTR(b); i = j = n = 0; while (i < na && j < nb) if (da[i] < db[j]) i++; else if (da[i] == db[j]) { n++; i++; j++; } else break; return (n == nb) ? TRUE : FALSE; }
Datum subarray(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) PG_GETARG_ARRAYTYPE_P(0); int32 start = PG_GETARG_INT32(1); int32 len = (fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0; int32 end = 0; int32 c; ArrayType *result; start = (start > 0) ? start - 1 : start; CHECKARRVALID(a); if (ARRISEMPTY(a)) { PG_FREE_IF_COPY(a, 0); PG_RETURN_POINTER(new_intArrayType(0)); } c = ARRNELEMS(a); if (start < 0) start = c + start; if (len < 0) end = c + len; else if (len == 0) end = c; else end = start + len; if (end > c) end = c; if (start < 0) start = 0; if (start >= end || end <= 0) { PG_FREE_IF_COPY(a, 0); PG_RETURN_POINTER(new_intArrayType(0)); } result = new_intArrayType(end - start); if (end - start > 0) memcpy(ARRPTR(result), ARRPTR(a) + start, (end - start) * sizeof(int32)); PG_FREE_IF_COPY(a, 0); PG_RETURN_POINTER(result); }
int32 intarray_match_first(ArrayType *a, int32 elem) { int32 *aa, c, i; CHECKARRVALID(a); c = ARRNELEMS(a); aa = ARRPTR(a); for (i = 0; i < c; i++) if (aa[i] == elem) return (i + 1); return 0; }
ArrayType * intarray_add_elem(ArrayType *a, int32 elem) { ArrayType *result; int32 *r; int32 c; CHECKARRVALID(a); c = ARRNELEMS(a); result = new_intArrayType(c + 1); r = ARRPTR(result); if (c > 0) memcpy(r, ARRPTR(a), c * sizeof(int32)); r[c] = elem; return result; }