From 262ca22b6efd1bd2dc2437bf2c2c83cd71096ccf Mon Sep 17 00:00:00 2001 From: Junwang Zhao Date: Tue, 12 Nov 2024 00:22:00 +0000 Subject: [PATCH v1] int array support multi dim Signed-off-by: Junwang Zhao --- contrib/intarray/_int.h | 12 ++++++++++++ contrib/intarray/_int_op.c | 36 +++++++++++++++++++++++++++++++++--- contrib/intarray/_int_tool.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/contrib/intarray/_int.h b/contrib/intarray/_int.h index 0352cbd368..2b2d6906ae 100644 --- a/contrib/intarray/_int.h +++ b/contrib/intarray/_int.h @@ -188,4 +188,16 @@ int compDESC(const void *a, const void *b); (direction) ? compASC : compDESC ); \ } while(0) + +int compArrayASC(const void *a, const void *b, void *arg); +int compArrayDESC(const void *a, const void *b, void *arg); + +/* sort, either ascending or descending */ +#define QSORT_ARRAY(a, direction, dim0, step) \ + do { \ + if (dim0 > 1) \ + qsort_arg((void*) ARRPTR(a), dim0, sizeof(int32) * step, \ + (direction) ? compArrayASC : compArrayDESC, &step); \ + } while(0) + #endif /* ___INT_H__ */ diff --git a/contrib/intarray/_int_op.c b/contrib/intarray/_int_op.c index 5b164f6788..03f0deea84 100644 --- a/contrib/intarray/_int_op.c +++ b/contrib/intarray/_int_op.c @@ -199,11 +199,21 @@ sort(PG_FUNCTION_ARGS) int32 dc = (dirstr) ? VARSIZE_ANY_EXHDR(dirstr) : 0; char *d = (dirstr) ? VARDATA_ANY(dirstr) : NULL; int dir = -1; + int ndim, + nelems, + step; CHECKARRVALID(a); if (ARRNELEMS(a) < 2) PG_RETURN_POINTER(a); + ndim = ARR_NDIM(a); + if (ndim < 1) + PG_RETURN_POINTER(a); + + nelems = ARRNELEMS(a); + step = nelems / ARR_DIMS(a)[0]; + if (dirstr == NULL || (dc == 3 && (d[0] == 'A' || d[0] == 'a') && (d[1] == 'S' || d[1] == 's') @@ -219,7 +229,7 @@ sort(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("second parameter must be \"ASC\" or \"DESC\""))); - QSORT(a, dir); + QSORT_ARRAY(a, dir, ARR_DIMS(a)[0], step); PG_RETURN_POINTER(a); } @@ -227,9 +237,19 @@ Datum sort_asc(PG_FUNCTION_ARGS) { ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0); + int ndim, + nelems, + step; CHECKARRVALID(a); - QSORT(a, 1); + + ndim = ARR_NDIM(a); + if (ndim < 1) + PG_RETURN_POINTER(a); + + nelems = ARRNELEMS(a); + step = nelems / ARR_DIMS(a)[0]; + QSORT_ARRAY(a, 1, ARR_DIMS(a)[0], step); PG_RETURN_POINTER(a); } @@ -237,9 +257,19 @@ Datum sort_desc(PG_FUNCTION_ARGS) { ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0); + int ndim, + nelems, + step; CHECKARRVALID(a); - QSORT(a, 0); + + ndim = ARR_NDIM(a); + if (ndim < 1) + PG_RETURN_POINTER(a); + + nelems = ARRNELEMS(a); + step = nelems / ARR_DIMS(a)[0]; + QSORT_ARRAY(a, 0, ARR_DIMS(a)[0], step); PG_RETURN_POINTER(a); } diff --git a/contrib/intarray/_int_tool.c b/contrib/intarray/_int_tool.c index c85280c842..cae032d051 100644 --- a/contrib/intarray/_int_tool.c +++ b/contrib/intarray/_int_tool.c @@ -405,3 +405,31 @@ compDESC(const void *a, const void *b) { return pg_cmp_s32(*(const int32 *) b, *(const int32 *) a); } + +int +compArrayASC(const void *a, const void *b, void *arg) +{ + int cnt = *(int*)arg; + for (int i = 0; i < cnt; i++) { + int cmp = pg_cmp_s32(((const int32 *) a)[i], ((const int32 *) b)[i]); + if (cmp == 0) { + continue; + } + return cmp; + } + return 0; +} + +int +compArrayDESC(const void *a, const void *b, void *arg) +{ + int cnt = *(int*)arg; + for (int i = 0; i < cnt; i++) { + int cmp = pg_cmp_s32(((const int32 *) b)[i], ((const int32 *) a)[i]); + if (cmp == 0) { + continue; + } + return cmp; + } + return 0; +} -- 2.39.5