88 *
99 *
1010 * 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 $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -2193,13 +2193,20 @@ array_set_slice(ArrayType *array,
21932193 * or binary-compatible with, the first argument type of fn().
21942194 * * retType: OID of element type of output array.This must be the same as,
21952195 * 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.
21962202 *
21972203 * NB: caller must assure that input array is not NULL. Currently,
21982204 * any additional parameters passed to fn() may not be specified as NULL
21992205 * either.
22002206 */
22012207Datum
2202- array_map (FunctionCallInfo fcinfo ,Oid inpType ,Oid retType )
2208+ array_map (FunctionCallInfo fcinfo ,Oid inpType ,Oid retType ,
2209+ ArrayMapState * amstate )
22032210{
22042211ArrayType * v ;
22052212ArrayType * result ;
@@ -2217,12 +2224,6 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
22172224bool typbyval ;
22182225char typalign ;
22192226char * s ;
2220- typedef struct
2221- {
2222- ArrayMetaState inp_extra ;
2223- ArrayMetaState ret_extra ;
2224- }am_extra ;
2225- am_extra * my_extra ;
22262227ArrayMetaState * inp_extra ;
22272228ArrayMetaState * ret_extra ;
22282229
@@ -2254,22 +2255,8 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
22542255 * only once per series of calls, assuming the element type doesn't
22552256 * change underneath us.
22562257 */
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 ;
22732260
22742261if (inp_extra -> element_type != inpType )
22752262{
@@ -3101,6 +3088,7 @@ array_type_length_coerce_internal(ArrayType *src,
31013088Oid srctype ;
31023089Oid desttype ;
31033090FmgrInfo coerce_finfo ;
3091+ ArrayMapState amstate ;
31043092}atc_extra ;
31053093atc_extra * my_extra ;
31063094FunctionCallInfoData locfcinfo ;
@@ -3113,10 +3101,9 @@ array_type_length_coerce_internal(ArrayType *src,
31133101my_extra = (atc_extra * )fmgr_info -> fn_extra ;
31143102if (my_extra == NULL )
31153103{
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 ));
31183106my_extra = (atc_extra * )fmgr_info -> fn_extra ;
3119- my_extra -> srctype = InvalidOid ;
31203107}
31213108
31223109if (my_extra -> srctype != src_elem_type )
@@ -3192,7 +3179,8 @@ array_type_length_coerce_internal(ArrayType *src,
31923179locfcinfo .arg [1 ]= Int32GetDatum (desttypmod );
31933180locfcinfo .arg [2 ]= BoolGetDatum (isExplicit );
31943181
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 );
31963184}
31973185
31983186/*
@@ -3210,6 +3198,7 @@ array_length_coerce(PG_FUNCTION_ARGS)
32103198{
32113199Oid elemtype ;
32123200FmgrInfo coerce_finfo ;
3201+ ArrayMapState amstate ;
32133202}alc_extra ;
32143203alc_extra * my_extra ;
32153204FunctionCallInfoData locfcinfo ;
@@ -3226,10 +3215,9 @@ array_length_coerce(PG_FUNCTION_ARGS)
32263215my_extra = (alc_extra * )fmgr_info -> fn_extra ;
32273216if (my_extra == NULL )
32283217{
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 ));
32313220my_extra = (alc_extra * )fmgr_info -> fn_extra ;
3232- my_extra -> elemtype = InvalidOid ;
32333221}
32343222
32353223if (my_extra -> elemtype != ARR_ELEMTYPE (v ))
@@ -3265,7 +3253,8 @@ array_length_coerce(PG_FUNCTION_ARGS)
32653253locfcinfo .arg [1 ]= Int32GetDatum (desttypmod );
32663254locfcinfo .arg [2 ]= BoolGetDatum (isExplicit );
32673255
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 );
32693258}
32703259
32713260/*