Index: src/pl/plpgsql/src/pl_exec.c
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/pl/plpgsql/src/pl_exec.c,v
retrieving revision 1.225
diff -c -r1.225 pl_exec.c
*** src/pl/plpgsql/src/pl_exec.c	20 Nov 2008 15:36:22 -0000	1.225
--- src/pl/plpgsql/src/pl_exec.c	30 Dec 2008 07:31:36 -0000
***************
*** 20,29 ****
--- 20,31 ----
  #include "access/transam.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_type.h"
+ #include "catalog/pg_cast.h"
  #include "executor/spi_priv.h"
  #include "funcapi.h"
  #include "nodes/nodeFuncs.h"
  #include "parser/scansup.h"
+ #include "parser/parse_coerce.h"
  #include "tcop/tcopprot.h"
  #include "utils/array.h"
  #include "utils/builtins.h"
***************
*** 199,204 ****
--- 201,208 ----
  static void free_params_data(PreparedParamsData *ppd);
  static Portal exec_dynquery_with_params(PLpgSQL_execstate *estate,
  										PLpgSQL_expr *query, List *params);
+ static CoercionPathType find_assignment_coercion_pathway(Oid targetTypeId,
+ 											Oid sourceTypeId, Oid *funcid);
  
  
  /* ----------
***************
*** 4732,4750 ****
  	{
  		if (!isnull)
  		{
! 			char	   *extval;
  
! 			extval = convert_value_to_string(value, valtype);
  
! 			/* Allow input function to use SPI ... see notes above */
! 			SPI_push();
  
! 			value = InputFunctionCall(reqinput, extval,
! 									  reqtypioparam, reqtypmod);
  
! 			SPI_pop();
  
! 			pfree(extval);
  		}
  		else
  		{
--- 4736,4779 ----
  	{
  		if (!isnull)
  		{
! 			/*
! 			 * find out if there is a coercion pathway via a function
! 			 */
! 			CoercionPathType pathtype;
! 			Oid				 castfunc;
  
! 			pathtype = find_assignment_coercion_pathway(reqtype, valtype,
! 											 &castfunc);
  
! 			if (pathtype == COERCION_PATH_FUNC)
! 			{
! 				FmgrInfo	cast_func_finfo;
! 
! 				fmgr_info_cxt(castfunc, &cast_func_finfo,
! 							  CurrentMemoryContext);
! 				cast_func_finfo.fn_oid = InvalidOid;
! 			
! 				/* do we need reqtypmod for cast functions? */
! 				value = FunctionCall2(&cast_func_finfo,
! 										 value,
! 										 reqtypmod);
! 			}
! 			else
! 			{
! 				char	   *extval;
  
! 				extval = convert_value_to_string(value, valtype);
  
! 				/* Allow input function to use SPI ... see notes above */
! 				SPI_push();
  
! 				value = InputFunctionCall(reqinput, extval,
! 										  reqtypioparam, reqtypmod);
! 
! 				SPI_pop();
! 
! 				pfree(extval);
! 			}
  		}
  		else
  		{
***************
*** 5456,5458 ****
--- 5485,5513 ----
  
  	return portal;
  }
+ 
+ static CoercionPathType 
+ find_assignment_coercion_pathway(Oid targetTypeId, Oid sourceTypeId, Oid *funcid)
+ {
+ 	CoercionPathType result = COERCION_PATH_NONE;
+ 	HeapTuple	tuple;
+ 
+ 	/* Look in pg_cast */
+ 	tuple = SearchSysCache(CASTSOURCETARGET,
+ 						   ObjectIdGetDatum(sourceTypeId),
+ 						   ObjectIdGetDatum(targetTypeId),
+ 						   0, 0);
+ 
+ 	if (HeapTupleIsValid(tuple))
+ 	{
+ 		Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
+ 
+ 		*funcid = castForm->castfunc;
+ 		ReleaseSysCache(tuple);
+ 	}
+ 
+ 	if (OidIsValid(*funcid))
+ 		result = COERCION_PATH_FUNC;
+ 
+ 	return result;
+ }
