*           procedural language
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.127 2005/01/13 23:07:34 tgl Exp $
+ *   $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.128 2005/02/01 19:35:14 tgl Exp $
  *
  *   This software is copyrighted by Jan Wieck - Hamburg.
  *
                            oldarrayisnull;
                Oid         arraytypeid,
                            arrayelemtypeid;
-               int16       elemtyplen;
+               int16       arraytyplen,
+                           elemtyplen;
                bool        elemtypbyval;
                char        elemtypalign;
-               Datum       oldarrayval,
+               Datum       oldarraydatum,
                            coerced_value;
+               ArrayType  *oldarrayval;
                ArrayType  *newarrayval;
 
                /*
 
                /* Fetch current value of array datum */
                exec_eval_datum(estate, target, InvalidOid,
-                           &arraytypeid, &oldarrayval, &oldarrayisnull);
+                               &arraytypeid, &oldarraydatum, &oldarrayisnull);
 
                arrayelemtypeid = get_element_type(arraytypeid);
                if (!OidIsValid(arrayelemtypeid))
                            (errcode(ERRCODE_DATATYPE_MISMATCH),
                          errmsg("subscripted object is not an array")));
 
+               get_typlenbyvalalign(arrayelemtypeid,
+                                    &elemtyplen,
+                                    &elemtypbyval,
+                                    &elemtypalign);
+               arraytyplen = get_typlen(arraytypeid);
+
                /*
                 * Evaluate the subscripts, switch into left-to-right
                 * order
                }
 
                /*
-                * Skip the assignment if we have any nulls, either in the
-                * original array value, the subscripts, or the righthand
-                * side. This is pretty bogus but it corresponds to the
-                * current behavior of ExecEvalArrayRef().
+                * Skip the assignment if we have any nulls in the subscripts
+                * or the righthand side. This is pretty bogus but it
+                * corresponds to the current behavior of ExecEvalArrayRef().
                 */
-               if (oldarrayisnull || havenullsubscript || *isNull)
+               if (havenullsubscript || *isNull)
                    return;
 
+               /*
+                * If the original array is null, cons up an empty array
+                * so that the assignment can proceed; we'll end with a
+                * one-element array containing just the assigned-to
+                * subscript.  This only works for varlena arrays, though;
+                * for fixed-length array types we skip the assignment.
+                * Again, this corresponds to the current behavior of
+                * ExecEvalArrayRef().
+                */
+               if (oldarrayisnull)
+               {
+                   if (arraytyplen > 0)        /* fixed-length array? */
+                       return;
+
+                   oldarrayval = construct_md_array(NULL, 0, NULL, NULL,
+                                                    arrayelemtypeid,
+                                                    elemtyplen,
+                                                    elemtypbyval,
+                                                    elemtypalign);
+               }
+               else
+                   oldarrayval = (ArrayType *) DatumGetPointer(oldarraydatum);
+
                /* Coerce source value to match array element type. */
                coerced_value = exec_simple_cast_value(value,
                                                       valtype,
                /*
                 * Build the modified array value.
                 */
-               get_typlenbyvalalign(arrayelemtypeid,
-                                    &elemtyplen,
-                                    &elemtypbyval,
-                                    &elemtypalign);
-
-               newarrayval = array_set((ArrayType *) DatumGetPointer(oldarrayval),
+               newarrayval = array_set(oldarrayval,
                                        nsubscripts,
                                        subscriptvals,
                                        coerced_value,
-                                       get_typlen(arraytypeid),
+                                       arraytyplen,
                                        elemtyplen,
                                        elemtypbyval,
                                        elemtypalign,