aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/arrayfuncs.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>1999-05-03 19:10:48 +0000
committerBruce Momjian <bruce@momjian.us>1999-05-03 19:10:48 +0000
commit210055ad614ae845686fdf9f8fc6b60301689cc8 (patch)
tree0410cff48a92bc3c95aea12877046d4ab25aaedb /src/backend/utils/adt/arrayfuncs.c
parentda5f1dd7227bd507cc8d5b088fd3f5e53e932722 (diff)
downloadpostgresql-210055ad614ae845686fdf9f8fc6b60301689cc8.tar.gz
postgresql-210055ad614ae845686fdf9f8fc6b60301689cc8.zip
here are some patches for 6.5.0 which I already submitted but have never
been applied. The patches are in the .tar.gz attachment at the end: varchar-array.patch this patch adds support for arrays of bpchar() and varchar(), which where always missing from postgres. These datatypes can be used to replace the _char4, _char8, etc., which were dropped some time ago. block-size.patch this patch fixes many errors in the parser and other program which happen with very large query statements (> 8K) when using a page size larger than 8192. This patch is needed if you want to submit queries larger than 8K. Postgres supports tuples up to 32K but you can't insert them because you can't submit queries larger than 8K. My patch fixes this problem. The patch also replaces all the occurrences of `8192' and `1<<13' in the sources with the proper constants defined in include files. You should now never find 8192 hardwired in C code, just to make code clearer. -- Massimo Dal Zotto
Diffstat (limited to 'src/backend/utils/adt/arrayfuncs.c')
-rw-r--r--src/backend/utils/adt/arrayfuncs.c156
1 files changed, 155 insertions, 1 deletions
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index a4f1842e5f9..f8fe7e42229 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.38 1999/02/13 23:19:00 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.39 1999/05/03 19:09:59 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,6 +15,7 @@
#include <ctype.h>
#include <stdio.h>
#include <string.h>
+#include <stdarg.h>
#include "postgres.h"
@@ -26,6 +27,7 @@
#include "storage/fd.h"
#include "fmgr.h"
#include "utils/array.h"
+#include "utils/elog.h"
#include "libpq/libpq-fs.h"
#include "libpq/be-fsstubs.h"
@@ -614,7 +616,9 @@ array_out(ArrayType *v, Oid element_type)
i,
j,
k,
+#ifndef TCL_ARRAYS
l,
+#endif
indx[MAXDIM];
bool dummy_bool;
int ndim,
@@ -1274,6 +1278,156 @@ array_assgn(ArrayType *array,
return (char *) array;
}
+/*
+ * array_map()
+ *
+ * Map an arbitrary function to an array and return a new array with
+ * same dimensions and the source elements transformed by fn().
+ */
+ArrayType *
+array_map(ArrayType *v,
+ Oid type,
+ char *(fn)(char *p, ...),
+ Oid retType,
+ int nargs,
+ ...)
+{
+ ArrayType *result;
+ void *args[4];
+ char **values;
+ char *elt;
+ int *dim;
+ int ndim;
+ int nitems;
+ int i;
+ int nbytes = 0;
+ int inp_typlen;
+ bool inp_typbyval;
+ int typlen;
+ bool typbyval;
+ char typdelim;
+ Oid typelem;
+ Oid proc;
+ char typalign;
+ char *s;
+ char *p;
+ va_list ap;
+
+ /* Large objects not yet supported */
+ if (ARR_IS_LO(v) == true) {
+ elog(ERROR, "array_map: large objects not supported");
+ }
+
+ /* Check nargs */
+ if ((nargs < 0) || (nargs > 4)) {
+ elog(ERROR, "array_map: invalid nargs: %d", nargs);
+ }
+
+ /* Copy extra args to local variable */
+ va_start(ap, nargs);
+ for (i=0; i<nargs; i++) {
+ args[i] = (void *) va_arg(ap, char *);
+ }
+ va_end(ap);
+
+ /* Lookup source and result types. Unneeded variables are reused. */
+ system_cache_lookup(type, false, &inp_typlen, &inp_typbyval,
+ &typdelim, &typelem, &proc, &typalign);
+ system_cache_lookup(retType, false, &typlen, &typbyval,
+ &typdelim, &typelem, &proc, &typalign);
+
+ /* Allocate temporary array for new values */
+ ndim = ARR_NDIM(v);
+ dim = ARR_DIMS(v);
+ nitems = getNitems(ndim, dim);
+ values = (char **) palloc(nitems * sizeof(char *));
+ MemSet(values, 0, nitems * sizeof(char *));
+
+ /* Loop over source data */
+ s = (char *) ARR_DATA_PTR(v);
+ for (i=0; i<nitems; i++) {
+ /* Get source element */
+ if (inp_typbyval) {
+ switch (inp_typlen) {
+ case 1:
+ elt = (char *) ((int) (*(char *) s));
+ break;
+ case 2:
+ elt = (char *) ((int) (*(int16 *) s));
+ break;
+ case 3:
+ case 4:
+ default:
+ elt = (char *) (*(int32 *) s);
+ break;
+ }
+ s += inp_typlen;
+ } else {
+ elt = s;
+ if (inp_typlen > 0) {
+ s += inp_typlen;
+ } else {
+ s += INTALIGN(*(int32 *) s);
+ }
+ }
+
+ /*
+ * Apply the given function to source elt and extra args.
+ * nargs is the number of extra args taken by fn().
+ */
+ switch (nargs) {
+ case 0:
+ p = (char *) (*fn) (elt);
+ break;
+ case 1:
+ p = (char *) (*fn) (elt, args[0]);
+ break;
+ case 2:
+ p = (char *) (*fn) (elt, args[0], args[1]);
+ break;
+ case 3:
+ p = (char *) (*fn) (elt, args[0], args[1], args[2]);
+ break;
+ case 4:
+ default:
+ p = (char *) (*fn) (elt, args[0], args[1], args[2], args[3]);
+ break;
+ }
+
+ /* Update values and total result size */
+ if (typbyval) {
+ values[i] = (char *) p;
+ nbytes += typlen;
+ } else {
+ int len;
+ len = ((typlen > 0) ? typlen : INTALIGN(*(int32 *) p));
+ /* Needed because _CopyArrayEls tries to pfree items */
+ if (p == elt) {
+ p = (char *) palloc(len);
+ memcpy(p, elt, len);
+ }
+ values[i] = (char *) p;
+ nbytes += len;
+ }
+ }
+
+ /* Allocate and initialize the result array */
+ nbytes += ARR_OVERHEAD(ndim);
+ result = (ArrayType *) palloc(nbytes);
+ MemSet(result, 0, nbytes);
+
+ memcpy((char *) result, (char *) &nbytes, sizeof(int));
+ memcpy((char *) ARR_NDIM_PTR(result), (char *) &ndim, sizeof(int));
+ memcpy((char *) ARR_DIMS(result), ARR_DIMS(v), 2 * ndim * sizeof(int));
+
+ /* Copy new values into the result array. values is pfreed. */
+ _CopyArrayEls((char **) values,
+ ARR_DATA_PTR(result), nitems,
+ typlen, typalign, typbyval);
+
+ return result;
+}
+
/*-----------------------------------------------------------------------------
* array_eq :
* compares two arrays for equality