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

Commit 2a88748

Browse files
committed
Adjust plpgsql to allow assignment to an element of an array that is
initially NULL. For 8.0 we changed the main executor to have this behavior in an UPDATE of an array column, but plpgsql's equivalent case was overlooked. Per report from Sven Willenberger.
1 parent 68b0e29 commit 2a88748

File tree

1 file changed

+41
-16
lines changed

1 file changed

+41
-16
lines changed

src/pl/plpgsql/src/pl_exec.c

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.127 2005/01/13 23:07:34 tgl Exp $
6+
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.128 2005/02/01 19:35:14 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -3069,11 +3069,13 @@ exec_assign_value(PLpgSQL_execstate *estate,
30693069
oldarrayisnull;
30703070
Oid arraytypeid,
30713071
arrayelemtypeid;
3072-
int16 elemtyplen;
3072+
int16 arraytyplen,
3073+
elemtyplen;
30733074
bool elemtypbyval;
30743075
char elemtypalign;
3075-
Datum oldarrayval,
3076+
Datum oldarraydatum,
30763077
coerced_value;
3078+
ArrayType *oldarrayval;
30773079
ArrayType *newarrayval;
30783080

30793081
/*
@@ -3102,14 +3104,20 @@ exec_assign_value(PLpgSQL_execstate *estate,
31023104

31033105
/* Fetch current value of array datum */
31043106
exec_eval_datum(estate, target, InvalidOid,
3105-
&arraytypeid, &oldarrayval, &oldarrayisnull);
3107+
&arraytypeid, &oldarraydatum, &oldarrayisnull);
31063108

31073109
arrayelemtypeid = get_element_type(arraytypeid);
31083110
if (!OidIsValid(arrayelemtypeid))
31093111
ereport(ERROR,
31103112
(errcode(ERRCODE_DATATYPE_MISMATCH),
31113113
errmsg("subscripted object is not an array")));
31123114

3115+
get_typlenbyvalalign(arrayelemtypeid,
3116+
&elemtyplen,
3117+
&elemtypbyval,
3118+
&elemtypalign);
3119+
arraytyplen = get_typlen(arraytypeid);
3120+
31133121
/*
31143122
* Evaluate the subscripts, switch into left-to-right
31153123
* order
@@ -3127,14 +3135,36 @@ exec_assign_value(PLpgSQL_execstate *estate,
31273135
}
31283136

31293137
/*
3130-
* Skip the assignment if we have any nulls, either in the
3131-
* original array value, the subscripts, or the righthand
3132-
* side. This is pretty bogus but it corresponds to the
3133-
* current behavior of ExecEvalArrayRef().
3138+
* Skip the assignment if we have any nulls in the subscripts
3139+
* or the righthand side. This is pretty bogus but it
3140+
* corresponds to the current behavior of ExecEvalArrayRef().
31343141
*/
3135-
if (oldarrayisnull || havenullsubscript || *isNull)
3142+
if (havenullsubscript || *isNull)
31363143
return;
31373144

3145+
/*
3146+
* If the original array is null, cons up an empty array
3147+
* so that the assignment can proceed; we'll end with a
3148+
* one-element array containing just the assigned-to
3149+
* subscript. This only works for varlena arrays, though;
3150+
* for fixed-length array types we skip the assignment.
3151+
* Again, this corresponds to the current behavior of
3152+
* ExecEvalArrayRef().
3153+
*/
3154+
if (oldarrayisnull)
3155+
{
3156+
if (arraytyplen > 0) /* fixed-length array? */
3157+
return;
3158+
3159+
oldarrayval = construct_md_array(NULL, 0, NULL, NULL,
3160+
arrayelemtypeid,
3161+
elemtyplen,
3162+
elemtypbyval,
3163+
elemtypalign);
3164+
}
3165+
else
3166+
oldarrayval = (ArrayType *) DatumGetPointer(oldarraydatum);
3167+
31383168
/* Coerce source value to match array element type. */
31393169
coerced_value = exec_simple_cast_value(value,
31403170
valtype,
@@ -3145,16 +3175,11 @@ exec_assign_value(PLpgSQL_execstate *estate,
31453175
/*
31463176
* Build the modified array value.
31473177
*/
3148-
get_typlenbyvalalign(arrayelemtypeid,
3149-
&elemtyplen,
3150-
&elemtypbyval,
3151-
&elemtypalign);
3152-
3153-
newarrayval = array_set((ArrayType *) DatumGetPointer(oldarrayval),
3178+
newarrayval = array_set(oldarrayval,
31543179
nsubscripts,
31553180
subscriptvals,
31563181
coerced_value,
3157-
get_typlen(arraytypeid),
3182+
arraytyplen,
31583183
elemtyplen,
31593184
elemtypbyval,
31603185
elemtypalign,

0 commit comments

Comments
 (0)