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 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); }
Datum g_int_union(PG_FUNCTION_ARGS) { GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); int *size = (int *) PG_GETARG_POINTER(1); int4 i; ArrayType *res; int totlen = 0, *ptr; for (i = 0; i < entryvec->n; i++) totlen += ARRNELEMS(GETENTRY(entryvec, i)); res = new_intArrayType(totlen); ptr = ARRPTR(res); for (i = 0; i < entryvec->n; i++) { memcpy(ptr, ARRPTR(GETENTRY(entryvec, i)), ARRNELEMS(GETENTRY(entryvec, i)) * sizeof(int4)); ptr += ARRNELEMS(GETENTRY(entryvec, i)); } QSORT(res, 1); res = _int_unique(res); *size = VARSIZE(res); PG_RETURN_POINTER(res); }
Datum g_int_union(PG_FUNCTION_ARGS) { bytea *entryvec = (bytea *) PG_GETARG_POINTER(0); int *size = (int *) PG_GETARG_POINTER(1); int4 i, len = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY); ArrayType *res; int totlen = 0, *ptr; for (i = 0; i < len; i++) totlen += ARRNELEMS(GETENTRY(entryvec, i)); res = new_intArrayType(totlen); ptr = ARRPTR(res); for (i = 0; i < len; i++) { memcpy(ptr, ARRPTR(GETENTRY(entryvec, i)), ARRNELEMS(GETENTRY(entryvec, i)) * sizeof(int4)); ptr += ARRNELEMS(GETENTRY(entryvec, i)); } QSORT(res, 1); res = _int_unique(res); *size = VARSIZE(res); PG_RETURN_POINTER(res); }
ArrayType * inner_int_inter(ArrayType *a, ArrayType *b) { ArrayType *r; int na, nb; int *da, *db, *dr; int i, j, k; if (ARRISEMPTY(a) || ARRISEMPTY(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 = k = 0; while (i < na && j < nb) { if (da[i] < db[j]) i++; else if (da[i] == db[j]) { if (k == 0 || dr[k - 1] != db[j]) dr[k++] = db[j]; i++; j++; } else j++; } if (k == 0) { pfree(r); return new_intArrayType(0); } else return resize_intArrayType(r, k); }
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)); }
ArrayType * copy_intArrayType(ArrayType *a) { ArrayType *r; r = new_intArrayType(ARRNELEMS(a)); memmove(r, a, VARSIZE(r)); return r; }
ArrayType * copy_intArrayType(ArrayType *a) { ArrayType *r; int n = ARRNELEMS(a); r = new_intArrayType(n); memcpy(ARRPTR(r), ARRPTR(a), n * sizeof(int4)); return r; }
ArrayType * int_to_intset(int32 n) { ArrayType *result; int32 *aa; result = new_intArrayType(1); aa = ARRPTR(result); aa[0] = n; return result; }
Datum g_int_decompress(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); GISTENTRY *retval; ArrayType *r; int *dr, lenr; ArrayType *in; int lenin; int *din; int i, j; in = (ArrayType *) PG_DETOAST_DATUM(entry->key); if (ARRISVOID(in)) PG_RETURN_POINTER(entry); lenin = ARRNELEMS(in); if (lenin < 2 * MAXNUMRANGE || ISLEAFKEY(in)) { /* not compressed value */ if (in != (ArrayType *) DatumGetPointer(entry->key)) { retval = palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(in), entry->rel, entry->page, entry->offset, VARSIZE(in), FALSE); PG_RETURN_POINTER(retval); } PG_RETURN_POINTER(entry); } din = ARRPTR(in); lenr = internal_size(din, lenin); r = new_intArrayType(lenr); dr = ARRPTR(r); for (i = 0; i < lenin; i += 2) for (j = din[i]; j <= din[i + 1]; j++) if ((!i) || *(dr - 1) != j) *dr++ = j; if (in != (ArrayType *) DatumGetPointer(entry->key)) pfree(in); retval = palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE); PG_RETURN_POINTER(retval); }
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; }
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; }
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 _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 g_int_union(PG_FUNCTION_ARGS) { GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); int *size = (int *) PG_GETARG_POINTER(1); int4 i, *ptr; ArrayType *res; int totlen = 0; for (i = 0; i < entryvec->n; i++) { ArrayType *ent = GETENTRY(entryvec, i); CHECKARRVALID(ent); totlen += ARRNELEMS(ent); } res = new_intArrayType(totlen); ptr = ARRPTR(res); for (i = 0; i < entryvec->n; i++) { ArrayType *ent = GETENTRY(entryvec, i); int nel; nel = ARRNELEMS(ent); memcpy(ptr, ARRPTR(ent), nel * sizeof(int4)); ptr += nel; } QSORT(res, 1); res = _int_unique(res); *size = VARSIZE(res); PG_RETURN_POINTER(res); }