diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index bf952b6..a691905 100644
*** a/src/pl/plpgsql/src/pl_exec.c
--- b/src/pl/plpgsql/src/pl_exec.c
*************** static void exec_move_row(PLpgSQL_execst
*** 188,201 ****
  static HeapTuple make_tuple_from_row(PLpgSQL_execstate *estate,
  					PLpgSQL_row *row,
  					TupleDesc tupdesc);
! static char *convert_value_to_string(Datum value, Oid valtype);
! static Datum exec_cast_value(Datum value, Oid valtype,
  				Oid reqtype,
  				FmgrInfo *reqinput,
  				Oid reqtypioparam,
  				int32 reqtypmod,
  				bool isnull);
! static Datum exec_simple_cast_value(Datum value, Oid valtype,
  					   Oid reqtype, int32 reqtypmod,
  					   bool isnull);
  static void exec_init_tuple_store(PLpgSQL_execstate *estate);
--- 188,204 ----
  static HeapTuple make_tuple_from_row(PLpgSQL_execstate *estate,
  					PLpgSQL_row *row,
  					TupleDesc tupdesc);
! static char *convert_value_to_string(PLpgSQL_execstate *estate,
! 					Datum value, Oid valtype);
! static Datum exec_cast_value(PLpgSQL_execstate *estate,
! 				Datum value, Oid valtype,
  				Oid reqtype,
  				FmgrInfo *reqinput,
  				Oid reqtypioparam,
  				int32 reqtypmod,
  				bool isnull);
! static Datum exec_simple_cast_value(PLpgSQL_execstate *estate,
! 					   Datum value, Oid valtype,
  					   Oid reqtype, int32 reqtypmod,
  					   bool isnull);
  static void exec_init_tuple_store(PLpgSQL_execstate *estate);
*************** plpgsql_exec_function(PLpgSQL_function *
*** 430,436 ****
  		else
  		{
  			/* Cast value to proper type */
! 			estate.retval = exec_cast_value(estate.retval, estate.rettype,
  											func->fn_rettype,
  											&(func->fn_retinput),
  											func->fn_rettypioparam,
--- 433,440 ----
  		else
  		{
  			/* Cast value to proper type */
! 			estate.retval = exec_cast_value(&estate, estate.retval,
! 											estate.rettype,
  											func->fn_rettype,
  											&(func->fn_retinput),
  											func->fn_rettypioparam,
*************** exec_stmt_fori(PLpgSQL_execstate *estate
*** 1757,1763 ****
  	 * Get the value of the lower bound
  	 */
  	value = exec_eval_expr(estate, stmt->lower, &isnull, &valtype);
! 	value = exec_cast_value(value, valtype, var->datatype->typoid,
  							&(var->datatype->typinput),
  							var->datatype->typioparam,
  							var->datatype->atttypmod, isnull);
--- 1761,1767 ----
  	 * Get the value of the lower bound
  	 */
  	value = exec_eval_expr(estate, stmt->lower, &isnull, &valtype);
! 	value = exec_cast_value(estate, value, valtype, var->datatype->typoid,
  							&(var->datatype->typinput),
  							var->datatype->typioparam,
  							var->datatype->atttypmod, isnull);
*************** exec_stmt_fori(PLpgSQL_execstate *estate
*** 1772,1778 ****
  	 * Get the value of the upper bound
  	 */
  	value = exec_eval_expr(estate, stmt->upper, &isnull, &valtype);
! 	value = exec_cast_value(value, valtype, var->datatype->typoid,
  							&(var->datatype->typinput),
  							var->datatype->typioparam,
  							var->datatype->atttypmod, isnull);
--- 1776,1782 ----
  	 * Get the value of the upper bound
  	 */
  	value = exec_eval_expr(estate, stmt->upper, &isnull, &valtype);
! 	value = exec_cast_value(estate, value, valtype, var->datatype->typoid,
  							&(var->datatype->typinput),
  							var->datatype->typioparam,
  							var->datatype->atttypmod, isnull);
*************** exec_stmt_fori(PLpgSQL_execstate *estate
*** 1789,1795 ****
  	if (stmt->step)
  	{
  		value = exec_eval_expr(estate, stmt->step, &isnull, &valtype);
! 		value = exec_cast_value(value, valtype, var->datatype->typoid,
  								&(var->datatype->typinput),
  								var->datatype->typioparam,
  								var->datatype->atttypmod, isnull);
--- 1793,1799 ----
  	if (stmt->step)
  	{
  		value = exec_eval_expr(estate, stmt->step, &isnull, &valtype);
! 		value = exec_cast_value(estate, value, valtype, var->datatype->typoid,
  								&(var->datatype->typinput),
  								var->datatype->typioparam,
  								var->datatype->atttypmod, isnull);
*************** exec_stmt_return_next(PLpgSQL_execstate
*** 2440,2446 ****
  						errmsg("wrong result type supplied in RETURN NEXT")));
  
  					/* coerce type if needed */
! 					retval = exec_simple_cast_value(retval,
  													var->datatype->typoid,
  												 tupdesc->attrs[0]->atttypid,
  												tupdesc->attrs[0]->atttypmod,
--- 2444,2450 ----
  						errmsg("wrong result type supplied in RETURN NEXT")));
  
  					/* coerce type if needed */
! 					retval = exec_simple_cast_value(estate, retval,
  													var->datatype->typoid,
  												 tupdesc->attrs[0]->atttypid,
  												tupdesc->attrs[0]->atttypmod,
*************** exec_stmt_return_next(PLpgSQL_execstate
*** 2511,2517 ****
  								&rettype);
  
  		/* coerce type if needed */
! 		retval = exec_simple_cast_value(retval,
  										rettype,
  										tupdesc->attrs[0]->atttypid,
  										tupdesc->attrs[0]->atttypmod,
--- 2515,2522 ----
  								&rettype);
  
  		/* coerce type if needed */
! 		retval = exec_simple_cast_value(estate,
! 										retval,
  										rettype,
  										tupdesc->attrs[0]->atttypid,
  										tupdesc->attrs[0]->atttypmod,
*************** exec_stmt_raise(PLpgSQL_execstate *estat
*** 2724,2734 ****
  											&paramtypeid);
  
  				if (paramisnull)
! 					extval = "<NULL>";
  				else
! 					extval = convert_value_to_string(paramvalue, paramtypeid);
  				appendStringInfoString(&ds, extval);
  				current_param = lnext(current_param);
  				exec_eval_cleanup(estate);
  			}
  			else
--- 2729,2741 ----
  											&paramtypeid);
  
  				if (paramisnull)
! 					extval = pstrdup("<NULL>");
  				else
! 					extval = convert_value_to_string(estate,
! 												paramvalue, paramtypeid);
  				appendStringInfoString(&ds, extval);
  				current_param = lnext(current_param);
+ 				pfree(extval);
  				exec_eval_cleanup(estate);
  			}
  			else
*************** exec_stmt_raise(PLpgSQL_execstate *estat
*** 2764,2770 ****
  					(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
  					 errmsg("RAISE statement option cannot be null")));
  
! 		extval = convert_value_to_string(optionvalue, optiontypeid);
  
  		switch (opt->opt_type)
  		{
--- 2771,2777 ----
  					(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
  					 errmsg("RAISE statement option cannot be null")));
  
! 		extval = convert_value_to_string(estate, optionvalue, optiontypeid);
  
  		switch (opt->opt_type)
  		{
*************** exec_stmt_dynexecute(PLpgSQL_execstate *
*** 3228,3234 ****
  				 errmsg("query string argument of EXECUTE is null")));
  
  	/* Get the C-String representation */
! 	querystr = convert_value_to_string(query, restype);
  
  	exec_eval_cleanup(estate);
  
--- 3235,3241 ----
  				 errmsg("query string argument of EXECUTE is null")));
  
  	/* Get the C-String representation */
! 	querystr = convert_value_to_string(estate, query, restype);
  
  	exec_eval_cleanup(estate);
  
*************** exec_assign_value(PLpgSQL_execstate *est
*** 3753,3759 ****
  				PLpgSQL_var *var = (PLpgSQL_var *) target;
  				Datum		newvalue;
  
! 				newvalue = exec_cast_value(value, valtype, var->datatype->typoid,
  										   &(var->datatype->typinput),
  										   var->datatype->typioparam,
  										   var->datatype->atttypmod,
--- 3760,3766 ----
  				PLpgSQL_var *var = (PLpgSQL_var *) target;
  				Datum		newvalue;
  
! 				newvalue = exec_cast_value(estate, value, valtype, var->datatype->typoid,
  										   &(var->datatype->typinput),
  										   var->datatype->typioparam,
  										   var->datatype->atttypmod,
*************** exec_assign_value(PLpgSQL_execstate *est
*** 3946,3952 ****
  				atttype = SPI_gettypeid(rec->tupdesc, fno + 1);
  				atttypmod = rec->tupdesc->attrs[fno]->atttypmod;
  				attisnull = *isNull;
! 				values[fno] = exec_simple_cast_value(value,
  													 valtype,
  													 atttype,
  													 atttypmod,
--- 3953,3960 ----
  				atttype = SPI_gettypeid(rec->tupdesc, fno + 1);
  				atttypmod = rec->tupdesc->attrs[fno]->atttypmod;
  				attisnull = *isNull;
! 				values[fno] = exec_simple_cast_value(estate,
! 													 value,
  													 valtype,
  													 atttype,
  													 atttypmod,
*************** exec_assign_value(PLpgSQL_execstate *est
*** 4118,4124 ****
  				estate->eval_tuptable = save_eval_tuptable;
  
  				/* Coerce source value to match array element type. */
! 				coerced_value = exec_simple_cast_value(value,
  													   valtype,
  													   arrayelem->elemtypoid,
  													   arrayelem->arraytypmod,
--- 4126,4133 ----
  				estate->eval_tuptable = save_eval_tuptable;
  
  				/* Coerce source value to match array element type. */
! 				coerced_value = exec_simple_cast_value(estate,
! 													   value,
  													   valtype,
  													   arrayelem->elemtypoid,
  													   arrayelem->arraytypmod,
*************** exec_eval_integer(PLpgSQL_execstate *est
*** 4514,4520 ****
  	Oid			exprtypeid;
  
  	exprdatum = exec_eval_expr(estate, expr, isNull, &exprtypeid);
! 	exprdatum = exec_simple_cast_value(exprdatum, exprtypeid,
  									   INT4OID, -1,
  									   *isNull);
  	return DatumGetInt32(exprdatum);
--- 4523,4529 ----
  	Oid			exprtypeid;
  
  	exprdatum = exec_eval_expr(estate, expr, isNull, &exprtypeid);
! 	exprdatum = exec_simple_cast_value(estate, exprdatum, exprtypeid,
  									   INT4OID, -1,
  									   *isNull);
  	return DatumGetInt32(exprdatum);
*************** exec_eval_boolean(PLpgSQL_execstate *est
*** 4536,4542 ****
  	Oid			exprtypeid;
  
  	exprdatum = exec_eval_expr(estate, expr, isNull, &exprtypeid);
! 	exprdatum = exec_simple_cast_value(exprdatum, exprtypeid,
  									   BOOLOID, -1,
  									   *isNull);
  	return DatumGetBool(exprdatum);
--- 4545,4551 ----
  	Oid			exprtypeid;
  
  	exprdatum = exec_eval_expr(estate, expr, isNull, &exprtypeid);
! 	exprdatum = exec_simple_cast_value(estate, exprdatum, exprtypeid,
  									   BOOLOID, -1,
  									   *isNull);
  	return DatumGetBool(exprdatum);
*************** exec_move_row(PLpgSQL_execstate *estate,
*** 5277,5282 ****
--- 5286,5293 ----
  							  value, valtype, &isnull);
  		}
  
+ 		exec_eval_cleanup(estate);
+ 
  		return;
  	}
  
*************** make_tuple_from_row(PLpgSQL_execstate *e
*** 5339,5357 ****
   * convert_value_to_string			Convert a non-null Datum to C string
   *
   * Note: callers generally assume that the result is a palloc'd string and
!  * should be pfree'd.  This is not all that safe an assumption ...
   *
   * Note: not caching the conversion function lookup is bad for performance.
   * ----------
   */
  static char *
! convert_value_to_string(Datum value, Oid valtype)
  {
! 	Oid			typoutput;
! 	bool		typIsVarlena;
  
  	getTypeOutputInfo(valtype, &typoutput, &typIsVarlena);
! 	return OidOutputFunctionCall(typoutput, value);
  }
  
  /* ----------
--- 5350,5375 ----
   * convert_value_to_string			Convert a non-null Datum to C string
   *
   * Note: callers generally assume that the result is a palloc'd string and
!  * should be pfree'd.
   *
   * Note: not caching the conversion function lookup is bad for performance.
   * ----------
   */
  static char *
! convert_value_to_string(PLpgSQL_execstate *estate, Datum value, Oid valtype)
  {
! 	Oid					 typoutput;
! 	bool				 typIsVarlena;
! 	MemoryContext		 oldcontext;
! 	char				*ret;
  
  	getTypeOutputInfo(valtype, &typoutput, &typIsVarlena);
! 	oldcontext = MemoryContextSwitchTo(
! 		estate->eval_econtext->ecxt_per_tuple_memory);
! 	ret = OidOutputFunctionCall(typoutput, value);
! 	MemoryContextSwitchTo(oldcontext);
! 
! 	return pstrdup(ret);
  }
  
  /* ----------
*************** convert_value_to_string(Datum value, Oid
*** 5359,5365 ****
   * ----------
   */
  static Datum
! exec_cast_value(Datum value, Oid valtype,
  				Oid reqtype,
  				FmgrInfo *reqinput,
  				Oid reqtypioparam,
--- 5377,5384 ----
   * ----------
   */
  static Datum
! exec_cast_value(PLpgSQL_execstate *estate,
! 				Datum value, Oid valtype,
  				Oid reqtype,
  				FmgrInfo *reqinput,
  				Oid reqtypioparam,
*************** exec_cast_value(Datum value, Oid valtype
*** 5376,5382 ****
  		{
  			char	   *extval;
  
! 			extval = convert_value_to_string(value, valtype);
  			value = InputFunctionCall(reqinput, extval,
  									  reqtypioparam, reqtypmod);
  			pfree(extval);
--- 5395,5401 ----
  		{
  			char	   *extval;
  
! 			extval = convert_value_to_string(estate, value, valtype);
  			value = InputFunctionCall(reqinput, extval,
  									  reqtypioparam, reqtypmod);
  			pfree(extval);
*************** exec_cast_value(Datum value, Oid valtype
*** 5400,5406 ****
   * ----------
   */
  static Datum
! exec_simple_cast_value(Datum value, Oid valtype,
  					   Oid reqtype, int32 reqtypmod,
  					   bool isnull)
  {
--- 5419,5425 ----
   * ----------
   */
  static Datum
! exec_simple_cast_value(PLpgSQL_execstate *estate, Datum value, Oid valtype,
  					   Oid reqtype, int32 reqtypmod,
  					   bool isnull)
  {
*************** exec_simple_cast_value(Datum value, Oid
*** 5414,5420 ****
  
  		fmgr_info(typinput, &finfo_input);
  
! 		value = exec_cast_value(value,
  								valtype,
  								reqtype,
  								&finfo_input,
--- 5433,5440 ----
  
  		fmgr_info(typinput, &finfo_input);
  
! 		value = exec_cast_value(estate,
! 								value,
  								valtype,
  								reqtype,
  								&finfo_input,
*************** exec_dynquery_with_params(PLpgSQL_execst
*** 6137,6143 ****
  				 errmsg("query string argument of EXECUTE is null")));
  
  	/* Get the C-String representation */
! 	querystr = convert_value_to_string(query, restype);
  
  	exec_eval_cleanup(estate);
  
--- 6157,6163 ----
  				 errmsg("query string argument of EXECUTE is null")));
  
  	/* Get the C-String representation */
! 	querystr = convert_value_to_string(estate, query, restype);
  
  	exec_eval_cleanup(estate);
  
