postgresql/contrib/intarray/_int_op.c
Alvaro Herrera c9d2977519 Clean up newlines following left parentheses
We used to strategically place newlines after some function call left
parentheses to make pgindent move the argument list a few chars to the
left, so that the whole line would fit under 80 chars.  However,
pgindent no longer does that, so the newlines just made the code
vertically longer for no reason.  Remove those newlines, and reflow some
of those lines for some extra naturality.

Reviewed-by: Michael Paquier, Tom Lane
Discussion: https://postgr.es/m/20200129200401.GA6303@alvherre.pgsql
2020-01-30 13:42:14 -03:00

433 lines
7.6 KiB
C

/*
* contrib/intarray/_int_op.c
*/
#include "postgres.h"
#include "_int.h"
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(_int_different);
PG_FUNCTION_INFO_V1(_int_same);
PG_FUNCTION_INFO_V1(_int_contains);
PG_FUNCTION_INFO_V1(_int_contained);
PG_FUNCTION_INFO_V1(_int_overlap);
PG_FUNCTION_INFO_V1(_int_union);
PG_FUNCTION_INFO_V1(_int_inter);
Datum
_int_contained(PG_FUNCTION_ARGS)
{
/* just reverse the operands and call _int_contains */
return DirectFunctionCall2(_int_contains,
PG_GETARG_DATUM(1),
PG_GETARG_DATUM(0));
}
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
_int_different(PG_FUNCTION_ARGS)
{
PG_RETURN_BOOL(!DatumGetBool(DirectFunctionCall2(_int_same,
PointerGetDatum(PG_GETARG_POINTER(0)),
PointerGetDatum(PG_GETARG_POINTER(1)))));
}
Datum
_int_same(PG_FUNCTION_ARGS)
{
ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
ArrayType *b = 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);
}
/* _int_overlap -- does a overlap b?
*/
Datum
_int_overlap(PG_FUNCTION_ARGS)
{
ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
ArrayType *b = 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);
}
Datum
_int_union(PG_FUNCTION_ARGS)
{
ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
ArrayType *result;
CHECKARRVALID(a);
CHECKARRVALID(b);
SORT(a);
SORT(b);
result = inner_int_union(a, b);
pfree(a);
pfree(b);
PG_RETURN_POINTER(result);
}
Datum
_int_inter(PG_FUNCTION_ARGS)
{
ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
ArrayType *b = 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);
}
PG_FUNCTION_INFO_V1(intset);
PG_FUNCTION_INFO_V1(icount);
PG_FUNCTION_INFO_V1(sort);
PG_FUNCTION_INFO_V1(sort_asc);
PG_FUNCTION_INFO_V1(sort_desc);
PG_FUNCTION_INFO_V1(uniq);
PG_FUNCTION_INFO_V1(idx);
PG_FUNCTION_INFO_V1(subarray);
PG_FUNCTION_INFO_V1(intarray_push_elem);
PG_FUNCTION_INFO_V1(intarray_push_array);
PG_FUNCTION_INFO_V1(intarray_del_elem);
PG_FUNCTION_INFO_V1(intset_union_elem);
PG_FUNCTION_INFO_V1(intset_subtract);
Datum
intset(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(int_to_intset(PG_GETARG_INT32(0)));
}
Datum
icount(PG_FUNCTION_ARGS)
{
ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
int32 count = ARRNELEMS(a);
PG_FREE_IF_COPY(a, 0);
PG_RETURN_INT32(count);
}
Datum
sort(PG_FUNCTION_ARGS)
{
ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
text *dirstr = (fcinfo->nargs == 2) ? PG_GETARG_TEXT_PP(1) : NULL;
int32 dc = (dirstr) ? VARSIZE_ANY_EXHDR(dirstr) : 0;
char *d = (dirstr) ? VARDATA_ANY(dirstr) : NULL;
int dir = -1;
CHECKARRVALID(a);
if (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
sort_asc(PG_FUNCTION_ARGS)
{
ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
CHECKARRVALID(a);
QSORT(a, 1);
PG_RETURN_POINTER(a);
}
Datum
sort_desc(PG_FUNCTION_ARGS)
{
ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
CHECKARRVALID(a);
QSORT(a, 0);
PG_RETURN_POINTER(a);
}
Datum
uniq(PG_FUNCTION_ARGS)
{
ArrayType *a = 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
idx(PG_FUNCTION_ARGS)
{
ArrayType *a = 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
subarray(PG_FUNCTION_ARGS)
{
ArrayType *a = 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
intarray_push_elem(PG_FUNCTION_ARGS)
{
ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
ArrayType *result;
result = intarray_add_elem(a, PG_GETARG_INT32(1));
PG_FREE_IF_COPY(a, 0);
PG_RETURN_POINTER(result);
}
Datum
intarray_push_array(PG_FUNCTION_ARGS)
{
ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
ArrayType *b = PG_GETARG_ARRAYTYPE_P(1);
ArrayType *result;
result = intarray_concat_arrays(a, b);
PG_FREE_IF_COPY(a, 0);
PG_FREE_IF_COPY(b, 1);
PG_RETURN_POINTER(result);
}
Datum
intarray_del_elem(PG_FUNCTION_ARGS)
{
ArrayType *a = 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);
}
Datum
intset_union_elem(PG_FUNCTION_ARGS)
{
ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
ArrayType *result;
result = intarray_add_elem(a, PG_GETARG_INT32(1));
PG_FREE_IF_COPY(a, 0);
QSORT(result, 1);
PG_RETURN_POINTER(_int_unique(result));
}
Datum
intset_subtract(PG_FUNCTION_ARGS)
{
ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
ArrayType *b = PG_GETARG_ARRAYTYPE_P_COPY(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);
}