Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 94215d5

Browse files
committed
Fixes:
The updating of array fields is broken in Postgres95-1.01, An array can be only replaced with a new array but not have some elements modified. This is caused by two bugs in the parser and in the array utilities. Furthermore it is not possible to update array with a base type of variable length. - submitted by: Massimo Dal Zotto <dz@cs.unitn.it>
1 parent baeb3aa commit 94215d5

File tree

4 files changed

+66
-5
lines changed

4 files changed

+66
-5
lines changed

src/Makefile.global

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#
88
#
99
# IDENTIFICATION
10-
# $Header: /cvsroot/pgsql/src/Attic/Makefile.global,v 1.6 1996/07/20 07:29:33 scrappy Exp $
10+
# $Header: /cvsroot/pgsql/src/Attic/Makefile.global,v 1.7 1996/07/20 07:57:49 scrappy Exp $
1111
#
1212
# NOTES
1313
# This is seen by any Makefiles that include mk/postgres.mk. To
@@ -287,6 +287,8 @@ CFLAGS+= $(CFLAGS_BE)
287287
LDADD+= $(LDADD_BE)
288288
LDFLAGS+= $(LDFLAGS_BE)
289289

290+
# enable patches to array update code
291+
CFLAGS += -DARRAY_PATCH
290292

291293
##############################################################################
292294
#

src/backend/parser/analyze.c

+15-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.2 1996/07/19 07:24:06 scrappy Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.3 1996/07/20 07:58:04 scrappy Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -1386,6 +1386,16 @@ make_targetlist_expr(ParseState *pstate,
13861386
if (attrtype != type_id) {
13871387
if (IsA(expr,Const)) {
13881388
/* try to cast the constant */
1389+
#ifdef ARRAY_PATCH
1390+
if (arrayRef && !(((A_Indices *)lfirst(arrayRef))->lidx)) {
1391+
/* updating a single item */
1392+
Oid typelem = get_typelem(attrtype);
1393+
expr = (Node*)parser_typecast2(expr,
1394+
type_id,
1395+
get_id_type((long)typelem),
1396+
attrlen);
1397+
} else
1398+
#endif
13891399
expr = (Node*)parser_typecast2(expr,
13901400
type_id,
13911401
get_id_type((long)attrtype),
@@ -1418,7 +1428,11 @@ make_targetlist_expr(ParseState *pstate,
14181428
&pstate->p_last_resno);
14191429
while(ar!=NIL) {
14201430
A_Indices *ind = lfirst(ar);
1431+
#ifdef ARRAY_PATCH
1432+
if (lowerIndexpr || (!upperIndexpr && ind->lidx)) {
1433+
#else
14211434
if (lowerIndexpr) {
1435+
#endif
14221436
/* XXX assume all lowerIndexpr is non-null in
14231437
* this case
14241438
*/

src/backend/utils/adt/arrayfuncs.c

+46-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.1.1.1 1996/07/09 06:22:03 scrappy Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.2 1996/07/20 07:58:44 scrappy Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -877,7 +877,11 @@ array_set(ArrayType *array,
877877
* fixed length arrays -- these are assumed to be 1-d
878878
*/
879879
if (indx[0]*elmlen > arraylen)
880+
#ifdef ARRAY_PATCH
880881
elog(WARN, "array_ref: array bound exceeded");
882+
#else
883+
elog(WARN, "array_set: array bound exceeded");
884+
#endif
881885
pos = (char *)array + indx[0]*elmlen;
882886
ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, pos);
883887
return((char *)array);
@@ -888,7 +892,14 @@ array_set(ArrayType *array,
888892
nbytes = (* (int32 *) array) - ARR_OVERHEAD(ndim);
889893

890894
if (!SanityCheckInput(ndim, n, dim, lb, indx))
895+
#ifdef ARRAY_PATCH
896+
{
897+
elog(WARN, "array_set: array bound exceeded");
898+
return((char *)array);
899+
}
900+
#else
891901
return((char *)array);
902+
#endif
892903
offset = GetOffset( n, dim, lb, indx);
893904

894905
if (ARR_IS_LO(array)) {
@@ -924,7 +935,41 @@ array_set(ArrayType *array,
924935
if (nbytes - offset < 1) return((char *)array);
925936
pos = ARR_DATA_PTR (array) + offset;
926937
} else {
938+
#ifdef ARRAY_PATCH
939+
ArrayType *newarray;
940+
char *elt_ptr;
941+
int oldsize, newsize, oldlen, newlen, lth0, lth1, lth2;
942+
943+
elt_ptr = array_seek(ARR_DATA_PTR(array), -1, offset);
944+
oldlen = INTALIGN(*(int32 *)elt_ptr);
945+
newlen = INTALIGN(*(int32 *)dataPtr);
946+
947+
if (oldlen == newlen) {
948+
/* new element with same size, overwrite old data */
949+
ArrayCastAndSet(dataPtr, (bool)reftype, elmlen, elt_ptr);
950+
return((char *)array);
951+
}
952+
953+
/* new element with different size, reallocate the array */
954+
oldsize = array->size;
955+
lth0 = ARR_OVERHEAD(n);
956+
lth1 = (int)(elt_ptr - ARR_DATA_PTR(array));
957+
lth2 = (int)(oldsize - lth0 - lth1 - oldlen);
958+
newsize = lth0 + lth1 + newlen + lth2;
959+
960+
newarray = (ArrayType *)palloc(newsize);
961+
memmove((char *)newarray, (char *)array, lth0+lth1);
962+
newarray->size = newsize;
963+
newlen = ArrayCastAndSet(dataPtr, (bool)reftype, elmlen,
964+
(char *)newarray+lth0+lth1);
965+
memmove((char *)newarray+lth0+lth1+newlen,
966+
(char *)array+lth0+lth1+oldlen, lth2);
967+
968+
/* ??? who should free this storage ??? */
969+
return((char *)newarray);
970+
#else
927971
elog(WARN, "array_set: update of variable length fields not supported");
972+
#endif
928973
}
929974
ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, pos);
930975
return((char *)array);

src/test/regress/create.source

+2-2
Original file line numberDiff line numberDiff line change
@@ -555,9 +555,9 @@ COPY bt_f8_heap FROM '_CWD_/data/hash.data';
555555
INSERT INTO arrtest (a[5], b[2][1][2], c, d)
556556
VALUES ('{1,2,3,4,5}', '{{{},{1,2}}}', '{}', '{}');
557557

558-
-- UPDATE arrtest SET e[0] = '1.1';
558+
UPDATE arrtest SET e[0] = '1.1';
559559

560-
-- UPDATE arrtest SET e[1] = '2.2';
560+
UPDATE arrtest SET e[1] = '2.2';
561561

562562
INSERT INTO arrtest (a, b[2][2][1], c, d, e)
563563
VALUES ('{11,12,23}', '{{3,4},{4,5}}', '{"foobar"}',

0 commit comments

Comments
 (0)