3
3
* procedural language
4
4
*
5
5
* 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 $
7
7
*
8
8
* This software is copyrighted by Jan Wieck - Hamburg.
9
9
*
@@ -3069,11 +3069,13 @@ exec_assign_value(PLpgSQL_execstate *estate,
3069
3069
oldarrayisnull ;
3070
3070
Oid arraytypeid ,
3071
3071
arrayelemtypeid ;
3072
- int16 elemtyplen ;
3072
+ int16 arraytyplen ,
3073
+ elemtyplen ;
3073
3074
bool elemtypbyval ;
3074
3075
char elemtypalign ;
3075
- Datum oldarrayval ,
3076
+ Datum oldarraydatum ,
3076
3077
coerced_value ;
3078
+ ArrayType * oldarrayval ;
3077
3079
ArrayType * newarrayval ;
3078
3080
3079
3081
/*
@@ -3102,14 +3104,20 @@ exec_assign_value(PLpgSQL_execstate *estate,
3102
3104
3103
3105
/* Fetch current value of array datum */
3104
3106
exec_eval_datum (estate , target , InvalidOid ,
3105
- & arraytypeid , & oldarrayval , & oldarrayisnull );
3107
+ & arraytypeid , & oldarraydatum , & oldarrayisnull );
3106
3108
3107
3109
arrayelemtypeid = get_element_type (arraytypeid );
3108
3110
if (!OidIsValid (arrayelemtypeid ))
3109
3111
ereport (ERROR ,
3110
3112
(errcode (ERRCODE_DATATYPE_MISMATCH ),
3111
3113
errmsg ("subscripted object is not an array" )));
3112
3114
3115
+ get_typlenbyvalalign (arrayelemtypeid ,
3116
+ & elemtyplen ,
3117
+ & elemtypbyval ,
3118
+ & elemtypalign );
3119
+ arraytyplen = get_typlen (arraytypeid );
3120
+
3113
3121
/*
3114
3122
* Evaluate the subscripts, switch into left-to-right
3115
3123
* order
@@ -3127,14 +3135,36 @@ exec_assign_value(PLpgSQL_execstate *estate,
3127
3135
}
3128
3136
3129
3137
/*
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().
3134
3141
*/
3135
- if (oldarrayisnull || havenullsubscript || * isNull )
3142
+ if (havenullsubscript || * isNull )
3136
3143
return ;
3137
3144
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
+
3138
3168
/* Coerce source value to match array element type. */
3139
3169
coerced_value = exec_simple_cast_value (value ,
3140
3170
valtype ,
@@ -3145,16 +3175,11 @@ exec_assign_value(PLpgSQL_execstate *estate,
3145
3175
/*
3146
3176
* Build the modified array value.
3147
3177
*/
3148
- get_typlenbyvalalign (arrayelemtypeid ,
3149
- & elemtyplen ,
3150
- & elemtypbyval ,
3151
- & elemtypalign );
3152
-
3153
- newarrayval = array_set ((ArrayType * ) DatumGetPointer (oldarrayval ),
3178
+ newarrayval = array_set (oldarrayval ,
3154
3179
nsubscripts ,
3155
3180
subscriptvals ,
3156
3181
coerced_value ,
3157
- get_typlen ( arraytypeid ) ,
3182
+ arraytyplen ,
3158
3183
elemtyplen ,
3159
3184
elemtypbyval ,
3160
3185
elemtypalign ,
0 commit comments