diff options
Diffstat (limited to 'src/backend/utils/adt')
-rw-r--r-- | src/backend/utils/adt/arrayfuncs.c | 156 | ||||
-rw-r--r-- | src/backend/utils/adt/ruleutils.c | 27 | ||||
-rw-r--r-- | src/backend/utils/adt/varchar.c | 24 |
3 files changed, 192 insertions, 15 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 diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 39ae0632483..4d88413a8e4 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -3,7 +3,7 @@ * out of it's tuple * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.9 1999/04/29 15:52:01 wieck Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.10 1999/05/03 19:10:01 momjian Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -57,6 +57,7 @@ #include "catalog/pg_opclass.h" #include "fmgr.h" +#define BUFSIZE 8192 /* ---------- * Local data types @@ -331,8 +332,8 @@ pg_get_indexdef(Oid indexrelid) int spirc; int len; int keyno; - char buf[8192]; - char keybuf[8192]; + char buf[BUFSIZE]; + char keybuf[BUFSIZE]; char *sep; /* ---------- @@ -603,7 +604,7 @@ make_ruledef(HeapTuple ruletup, TupleDesc rulettc) * Allocate space for the returned rule definition text * ---------- */ - buf = palloc(8192); + buf = palloc(BUFSIZE); /* ---------- * Get the attribute values from the rules tuple @@ -746,7 +747,7 @@ make_ruledef(HeapTuple ruletup, TupleDesc rulettc) static char * make_viewdef(HeapTuple ruletup, TupleDesc rulettc) { - char buf[8192]; + char buf[BUFSIZE]; Query *query; char ev_type; Oid ev_class; @@ -854,7 +855,7 @@ get_query_def(Query *query, QryHier *parentqh) static char * get_select_query_def(Query *query, QryHier *qh) { - char buf[8192]; + char buf[BUFSIZE]; char *sep; TargetEntry *tle; RangeTblEntry *rte; @@ -1024,7 +1025,7 @@ get_select_query_def(Query *query, QryHier *qh) static char * get_insert_query_def(Query *query, QryHier *qh) { - char buf[8192]; + char buf[BUFSIZE]; char *sep; TargetEntry *tle; RangeTblEntry *rte; @@ -1134,7 +1135,7 @@ get_insert_query_def(Query *query, QryHier *qh) static char * get_update_query_def(Query *query, QryHier *qh) { - char buf[8192]; + char buf[BUFSIZE]; char *sep; TargetEntry *tle; RangeTblEntry *rte; @@ -1187,7 +1188,7 @@ get_update_query_def(Query *query, QryHier *qh) static char * get_delete_query_def(Query *query, QryHier *qh) { - char buf[8192]; + char buf[BUFSIZE]; RangeTblEntry *rte; /* ---------- @@ -1221,7 +1222,7 @@ get_delete_query_def(Query *query, QryHier *qh) static char * get_rule_expr(QryHier *qh, int rt_index, Node *node, bool varprefix) { - char buf[8192]; + char buf[BUFSIZE]; if (node == NULL) return pstrdup(""); @@ -1408,7 +1409,7 @@ get_rule_expr(QryHier *qh, int rt_index, Node *node, bool varprefix) static char * get_func_expr(QryHier *qh, int rt_index, Expr *expr, bool varprefix) { - char buf[8192]; + char buf[BUFSIZE]; HeapTuple proctup; Form_pg_proc procStruct; List *l; @@ -1564,7 +1565,7 @@ get_const_expr(Const *constval) FmgrInfo finfo_output; char *extval; bool isnull = FALSE; - char buf[8192]; + char buf[BUFSIZE]; char namebuf[64]; if (constval->constisnull) @@ -1601,7 +1602,7 @@ get_sublink_expr(QryHier *qh, int rt_index, Node *node, bool varprefix) Expr *expr; List *l; char *sep; - char buf[8192]; + char buf[BUFSIZE]; buf[0] = '\0'; diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c index 8a06e6f4fd0..0aa8133b131 100644 --- a/src/backend/utils/adt/varchar.c +++ b/src/backend/utils/adt/varchar.c @@ -7,14 +7,16 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.43 1999/02/13 23:19:35 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.44 1999/05/03 19:10:02 momjian Exp $ * *------------------------------------------------------------------------- */ #include <stdio.h> /* for sprintf() */ #include <string.h> #include "postgres.h" +#include "utils/array.h" #include "utils/builtins.h" +#include "catalog/pg_type.h" #ifdef CYR_RECODE char *convertstr(char *, int, int); @@ -200,6 +202,16 @@ bpchar(char *s, int32 len) return result; } /* bpchar() */ +/* _bpchar() + * Converts an array of char() type to a specific internal length. + * len is the length specified in () plus VARHDRSZ bytes. + */ +ArrayType * +_bpchar(ArrayType *v, int32 len) +{ + return array_map(v, BPCHAROID, bpchar, BPCHAROID, 1, len); +} + /* bpchar_char() * Convert bpchar(1) to char. @@ -396,6 +408,16 @@ varchar(char *s, int32 slen) return result; } /* varchar() */ +/* _varchar() + * Converts an array of varchar() type to the specified size. + * len is the length specified in () plus VARHDRSZ bytes. + */ +ArrayType * +_varchar(ArrayType *v, int32 len) +{ + return array_map(v, VARCHAROID, varchar, VARCHAROID, 1, len); +} + /***************************************************************************** * Comparison Functions used for bpchar |