8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.116 2005/02/28 03:45:21 neilc Exp $
11
+ * $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.117 2005/03/24 21:50:37 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -2193,13 +2193,20 @@ array_set_slice(ArrayType *array,
2193
2193
* or binary-compatible with, the first argument type of fn().
2194
2194
* * retType: OID of element type of output array. This must be the same as,
2195
2195
* or binary-compatible with, the result type of fn().
2196
+ * * amstate: workspace for array_map. Must be zeroed by caller before
2197
+ * first call, and not touched after that.
2198
+ *
2199
+ * It is legitimate to pass a freshly-zeroed ArrayMapState on each call,
2200
+ * but better performance can be had if the state can be preserved across
2201
+ * a series of calls.
2196
2202
*
2197
2203
* NB: caller must assure that input array is not NULL. Currently,
2198
2204
* any additional parameters passed to fn() may not be specified as NULL
2199
2205
* either.
2200
2206
*/
2201
2207
Datum
2202
- array_map (FunctionCallInfo fcinfo , Oid inpType , Oid retType )
2208
+ array_map (FunctionCallInfo fcinfo , Oid inpType , Oid retType ,
2209
+ ArrayMapState * amstate )
2203
2210
{
2204
2211
ArrayType * v ;
2205
2212
ArrayType * result ;
@@ -2217,12 +2224,6 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
2217
2224
bool typbyval ;
2218
2225
char typalign ;
2219
2226
char * s ;
2220
- typedef struct
2221
- {
2222
- ArrayMetaState inp_extra ;
2223
- ArrayMetaState ret_extra ;
2224
- } am_extra ;
2225
- am_extra * my_extra ;
2226
2227
ArrayMetaState * inp_extra ;
2227
2228
ArrayMetaState * ret_extra ;
2228
2229
@@ -2254,22 +2255,8 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
2254
2255
* only once per series of calls, assuming the element type doesn't
2255
2256
* change underneath us.
2256
2257
*/
2257
- my_extra = (am_extra * ) fcinfo -> flinfo -> fn_extra ;
2258
- if (my_extra == NULL )
2259
- {
2260
- fcinfo -> flinfo -> fn_extra = MemoryContextAlloc (fcinfo -> flinfo -> fn_mcxt ,
2261
- sizeof (am_extra ));
2262
- my_extra = (am_extra * ) fcinfo -> flinfo -> fn_extra ;
2263
- inp_extra = & my_extra -> inp_extra ;
2264
- inp_extra -> element_type = InvalidOid ;
2265
- ret_extra = & my_extra -> ret_extra ;
2266
- ret_extra -> element_type = InvalidOid ;
2267
- }
2268
- else
2269
- {
2270
- inp_extra = & my_extra -> inp_extra ;
2271
- ret_extra = & my_extra -> ret_extra ;
2272
- }
2258
+ inp_extra = & amstate -> inp_extra ;
2259
+ ret_extra = & amstate -> ret_extra ;
2273
2260
2274
2261
if (inp_extra -> element_type != inpType )
2275
2262
{
@@ -3101,6 +3088,7 @@ array_type_length_coerce_internal(ArrayType *src,
3101
3088
Oid srctype ;
3102
3089
Oid desttype ;
3103
3090
FmgrInfo coerce_finfo ;
3091
+ ArrayMapState amstate ;
3104
3092
} atc_extra ;
3105
3093
atc_extra * my_extra ;
3106
3094
FunctionCallInfoData locfcinfo ;
@@ -3113,10 +3101,9 @@ array_type_length_coerce_internal(ArrayType *src,
3113
3101
my_extra = (atc_extra * ) fmgr_info -> fn_extra ;
3114
3102
if (my_extra == NULL )
3115
3103
{
3116
- fmgr_info -> fn_extra = MemoryContextAlloc (fmgr_info -> fn_mcxt ,
3117
- sizeof (atc_extra ));
3104
+ fmgr_info -> fn_extra = MemoryContextAllocZero (fmgr_info -> fn_mcxt ,
3105
+ sizeof (atc_extra ));
3118
3106
my_extra = (atc_extra * ) fmgr_info -> fn_extra ;
3119
- my_extra -> srctype = InvalidOid ;
3120
3107
}
3121
3108
3122
3109
if (my_extra -> srctype != src_elem_type )
@@ -3192,7 +3179,8 @@ array_type_length_coerce_internal(ArrayType *src,
3192
3179
locfcinfo .arg [1 ] = Int32GetDatum (desttypmod );
3193
3180
locfcinfo .arg [2 ] = BoolGetDatum (isExplicit );
3194
3181
3195
- return array_map (& locfcinfo , my_extra -> srctype , my_extra -> desttype );
3182
+ return array_map (& locfcinfo , my_extra -> srctype , my_extra -> desttype ,
3183
+ & my_extra -> amstate );
3196
3184
}
3197
3185
3198
3186
/*
@@ -3210,6 +3198,7 @@ array_length_coerce(PG_FUNCTION_ARGS)
3210
3198
{
3211
3199
Oid elemtype ;
3212
3200
FmgrInfo coerce_finfo ;
3201
+ ArrayMapState amstate ;
3213
3202
} alc_extra ;
3214
3203
alc_extra * my_extra ;
3215
3204
FunctionCallInfoData locfcinfo ;
@@ -3226,10 +3215,9 @@ array_length_coerce(PG_FUNCTION_ARGS)
3226
3215
my_extra = (alc_extra * ) fmgr_info -> fn_extra ;
3227
3216
if (my_extra == NULL )
3228
3217
{
3229
- fmgr_info -> fn_extra = MemoryContextAlloc (fmgr_info -> fn_mcxt ,
3230
- sizeof (alc_extra ));
3218
+ fmgr_info -> fn_extra = MemoryContextAllocZero (fmgr_info -> fn_mcxt ,
3219
+ sizeof (alc_extra ));
3231
3220
my_extra = (alc_extra * ) fmgr_info -> fn_extra ;
3232
- my_extra -> elemtype = InvalidOid ;
3233
3221
}
3234
3222
3235
3223
if (my_extra -> elemtype != ARR_ELEMTYPE (v ))
@@ -3265,7 +3253,8 @@ array_length_coerce(PG_FUNCTION_ARGS)
3265
3253
locfcinfo .arg [1 ] = Int32GetDatum (desttypmod );
3266
3254
locfcinfo .arg [2 ] = BoolGetDatum (isExplicit );
3267
3255
3268
- return array_map (& locfcinfo , ARR_ELEMTYPE (v ), ARR_ELEMTYPE (v ));
3256
+ return array_map (& locfcinfo , ARR_ELEMTYPE (v ), ARR_ELEMTYPE (v ),
3257
+ & my_extra -> amstate );
3269
3258
}
3270
3259
3271
3260
/*
0 commit comments