8000 Fixes: · postgrespro/postgres_cluster@94215d5 · GitHub
[go: up one dir, main page]

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
  • test/regress
  • 4 files changed

    +66
    -5
    lines changed

    src/Makefile.global

    Lines changed: 3 additions & 1 deletion
    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

    Lines changed: 15 additions & 1 deletion
    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

    Lines changed: 46 additions & 1 deletion
    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

    Lines changed: 2 additions & 2 deletions
    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)
    0