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{
22042211	ArrayType   * v ;
22052212	ArrayType   * result ;
@@ -2217,12 +2224,6 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
22172224	bool 		typbyval ;
22182225	char 		typalign ;
22192226	char 	   * s ;
2220- 	typedef  struct 
2221- 	{
2222- 		ArrayMetaState  inp_extra ;
2223- 		ArrayMetaState  ret_extra ;
2224- 	} am_extra ;
2225- 	am_extra    * my_extra ;
22262227	ArrayMetaState  * inp_extra ;
22272228	ArrayMetaState  * 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
22742261	if  (inp_extra -> element_type  !=  inpType )
22752262	{
@@ -3101,6 +3088,7 @@ array_type_length_coerce_internal(ArrayType *src,
31013088		Oid 			srctype ;
31023089		Oid 			desttype ;
31033090		FmgrInfo 	coerce_finfo ;
3091+ 		ArrayMapState  amstate ;
31043092	} atc_extra ;
31053093	atc_extra   * my_extra ;
31063094	FunctionCallInfoData  locfcinfo ;
@@ -3113,10 +3101,9 @@ array_type_length_coerce_internal(ArrayType *src,
31133101	my_extra  =  (atc_extra  * ) fmgr_info -> fn_extra ;
31143102	if  (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 ));
31183106		my_extra  =  (atc_extra  * ) fmgr_info -> fn_extra ;
3119- 		my_extra -> srctype  =  InvalidOid ;
31203107	}
31213108
31223109	if  (my_extra -> srctype  !=  src_elem_type )
@@ -3192,7 +3179,8 @@ array_type_length_coerce_internal(ArrayType *src,
31923179	locfcinfo .arg [1 ] =  Int32GetDatum (desttypmod );
31933180	locfcinfo .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	{
32113199		Oid 			elemtype ;
32123200		FmgrInfo 	coerce_finfo ;
3201+ 		ArrayMapState  amstate ;
32133202	} alc_extra ;
32143203	alc_extra   * my_extra ;
32153204	FunctionCallInfoData  locfcinfo ;
@@ -3226,10 +3215,9 @@ array_length_coerce(PG_FUNCTION_ARGS)
32263215	my_extra  =  (alc_extra  * ) fmgr_info -> fn_extra ;
32273216	if  (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 ));
32313220		my_extra  =  (alc_extra  * ) fmgr_info -> fn_extra ;
3232- 		my_extra -> elemtype  =  InvalidOid ;
32333221	}
32343222
32353223	if  (my_extra -> elemtype  !=  ARR_ELEMTYPE (v ))
@@ -3265,7 +3253,8 @@ array_length_coerce(PG_FUNCTION_ARGS)
32653253	locfcinfo .arg [1 ] =  Int32GetDatum (desttypmod );
32663254	locfcinfo .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/* 
0 commit comments