diff --git a/src/Makefile.global b/src/Makefile.global index 19ad705c33..b09925c6ab 100644 --- a/src/Makefile.global +++ b/src/Makefile.global @@ -7,7 +7,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/Attic/Makefile.global,v 1.6 1996/07/20 07:29:33 scrappy Exp $ +# $Header: /cvsroot/pgsql/src/Attic/Makefile.global,v 1.7 1996/07/20 07:57:49 scrappy Exp $ # # NOTES # This is seen by any Makefiles that include mk/postgres.mk. To @@ -287,6 +287,8 @@ CFLAGS+= $(CFLAGS_BE) LDADD+= $(LDADD_BE) LDFLAGS+= $(LDFLAGS_BE) +# enable patches to array update code +CFLAGS += -DARRAY_PATCH ############################################################################## # diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 3f44037ca7..cba2e21199 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.2 1996/07/19 07:24:06 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.3 1996/07/20 07:58:04 scrappy Exp $ * *------------------------------------------------------------------------- */ @@ -1386,6 +1386,16 @@ make_targetlist_expr(ParseState *pstate, if (attrtype != type_id) { if (IsA(expr,Const)) { /* try to cast the constant */ +#ifdef ARRAY_PATCH + if (arrayRef && !(((A_Indices *)lfirst(arrayRef))->lidx)) { + /* updating a single item */ + Oid typelem = get_typelem(attrtype); + expr = (Node*)parser_typecast2(expr, + type_id, + get_id_type((long)typelem), + attrlen); + } else +#endif expr = (Node*)parser_typecast2(expr, type_id, get_id_type((long)attrtype), @@ -1418,7 +1428,11 @@ make_targetlist_expr(ParseState *pstate, &pstate->p_last_resno); while(ar!=NIL) { A_Indices *ind = lfirst(ar); +#ifdef ARRAY_PATCH + if (lowerIndexpr || (!upperIndexpr && ind->lidx)) { +#else if (lowerIndexpr) { +#endif /* XXX assume all lowerIndexpr is non-null in * this case */ diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c index 2e780fb03b..8a2b0fd291 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.1.1.1 1996/07/09 06:22:03 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.2 1996/07/20 07:58:44 scrappy Exp $ * *------------------------------------------------------------------------- */ @@ -877,7 +877,11 @@ array_set(ArrayType *array, * fixed length arrays -- these are assumed to be 1-d */ if (indx[0]*elmlen > arraylen) +#ifdef ARRAY_PATCH elog(WARN, "array_ref: array bound exceeded"); +#else + elog(WARN, "array_set: array bound exceeded"); +#endif pos = (char *)array + indx[0]*elmlen; ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, pos); return((char *)array); @@ -888,7 +892,14 @@ array_set(ArrayType *array, nbytes = (* (int32 *) array) - ARR_OVERHEAD(ndim); if (!SanityCheckInput(ndim, n, dim, lb, indx)) +#ifdef ARRAY_PATCH + { + elog(WARN, "array_set: array bound exceeded"); return((char *)array); + } +#else + return((char *)array); +#endif offset = GetOffset( n, dim, lb, indx); if (ARR_IS_LO(array)) { @@ -924,7 +935,41 @@ array_set(ArrayType *array, if (nbytes - offset < 1) return((char *)array); pos = ARR_DATA_PTR (array) + offset; } else { +#ifdef ARRAY_PATCH + ArrayType *newarray; + char *elt_ptr; + int oldsize, newsize, oldlen, newlen, lth0, lth1, lth2; + + elt_ptr = array_seek(ARR_DATA_PTR(array), -1, offset); + oldlen = INTALIGN(*(int32 *)elt_ptr); + newlen = INTALIGN(*(int32 *)dataPtr); + + if (oldlen == newlen) { + /* new element with same size, overwrite old data */ + ArrayCastAndSet(dataPtr, (bool)reftype, elmlen, elt_ptr); + return((char *)array); + } + + /* new element with different size, reallocate the array */ + oldsize = array->size; + lth0 = ARR_OVERHEAD(n); + lth1 = (int)(elt_ptr - ARR_DATA_PTR(array)); + lth2 = (int)(oldsize - lth0 - lth1 - oldlen); + newsize = lth0 + lth1 + newlen + lth2; + + newarray = (ArrayType *)palloc(newsize); + memmove((char *)newarray, (char *)array, lth0+lth1); + newarray->size = newsize; + newlen = ArrayCastAndSet(dataPtr, (bool)reftype, elmlen, + (char *)newarray+lth0+lth1); + memmove((char *)newarray+lth0+lth1+newlen, + (char *)array+lth0+lth1+oldlen, lth2); + + /* ??? who should free this storage ??? */ + return((char *)newarray); +#else elog(WARN, "array_set: update of variable length fields not supported"); +#endif } ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, pos); return((char *)array); diff --git a/src/test/regress/create.source b/src/test/regress/create.source index f3fb711dc7..050c9a86a6 100644 --- a/src/test/regress/create.source +++ b/src/test/regress/create.source @@ -555,9 +555,9 @@ COPY bt_f8_heap FROM '_CWD_/data/hash.data'; INSERT INTO arrtest (a[5], b[2][1][2], c, d) VALUES ('{1,2,3,4,5}', '{{{},{1,2}}}', '{}', '{}'); --- UPDATE arrtest SET e[0] = '1.1'; +UPDATE arrtest SET e[0] = '1.1'; --- UPDATE arrtest SET e[1] = '2.2'; +UPDATE arrtest SET e[1] = '2.2'; INSERT INTO arrtest (a, b[2][2][1], c, d, e) VALUES ('{11,12,23}', '{{3,4},{4,5}}', '{"foobar"}',