diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index eadf41f..cf65b5e 100644
*** a/src/backend/catalog/pg_aggregate.c
--- b/src/backend/catalog/pg_aggregate.c
***************
*** 34,40 ****
  #include "utils/syscache.h"
  
  
! static Oid lookup_agg_function(List *fnName, int nargs, Oid *input_types,
  					Oid *rettype);
  
  
--- 34,40 ----
  #include "utils/syscache.h"
  
  
! extern Oid lookup_agg_function(List *fnName, int nargs, Oid *input_types,
  					Oid *rettype);
  
  
*************** AggregateCreate(const char *aggName,
*** 298,304 ****
  /*
   * lookup_agg_function -- common code for finding both transfn and finalfn
   */
! static Oid
  lookup_agg_function(List *fnName,
  					int nargs,
  					Oid *input_types,
--- 298,304 ----
  /*
   * lookup_agg_function -- common code for finding both transfn and finalfn
   */
! Oid
  lookup_agg_function(List *fnName,
  					int nargs,
  					Oid *input_types,
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index ee83e2f..b324b48 100644
*** a/src/backend/utils/adt/varlena.c
--- b/src/backend/utils/adt/varlena.c
***************
*** 22,27 ****
--- 22,28 ----
  #include "libpq/md5.h"
  #include "libpq/pqformat.h"
  #include "miscadmin.h"
+ #include "parser/parser.h"
  #include "parser/scansup.h"
  #include "regex/regex.h"
  #include "utils/builtins.h"
*************** text_format(PG_FUNCTION_ARGS)
*** 3820,3825 ****
--- 3821,3915 ----
  		isNull = PG_ARGISNULL(arg);
  		typid = get_fn_expr_argtype(fcinfo->flinfo, arg);
  
+ 		if (*cp == '{')
+ 		{
+ 			const char *format = cp + 1;
+ 
+ 			/* search right parensis */
+ 			for (; cp < end_ptr && *cp != '}'; cp++)
+ 			{
+ 				/* XXX: Should we supply a method to escape '}' ? */
+ 			}
+ 			if (cp >= end_ptr)
+ 				ereport(ERROR,
+ 						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ 							errmsg("conversion format is incomplete")));
+ 
+ 			/* format the value with to_char function */
+ 			if (!isNull)
+ 			{
+ 				Oid		fnOid;
+ 				Oid		rettype;
+ 				Datum	formatDatum;
+ 
+ #define enable_dynamic_to_char_lookup		0
+ 
+ 				if (enable_dynamic_to_char_lookup)
+ 				{
+ 					Oid		input_types[2];
+ 
+ extern Oid lookup_agg_function(List *fnName, int nargs, Oid *input_types,
+ 					Oid *rettype);
+ 
+ 					/*
+ 					 * Only lookup pg_catalog.to_char() and avoid searching
+ 					 * functions in search_path so that it should not be a
+ 					 * security hole.
+ 					 */
+ 					input_types[0] = typid;
+ 					input_types[1] = TEXTOID;
+ 					fnOid = lookup_agg_function(SystemFuncName("to_char"),
+ 								2, input_types, &rettype);
+ 				}
+ 				else
+ 				{
+ 					rettype = TEXTOID;
+ 
+ 					switch (typid)
+ 					{
+ 						case INT4OID:
+ 							fnOid = 1773;
+ 							break;
+ 						case INT8OID:
+ 							fnOid = 1774;
+ 							break;
+ 						case FLOAT4OID:
+ 							fnOid = 1775;
+ 							break;
+ 						case FLOAT8OID:
+ 							fnOid = 1776;
+ 							break;
+ 						case NUMERICOID:
+ 							fnOid = 1772;
+ 							break;
+ 						case TIMESTAMPTZOID:
+ 							fnOid = 1770;
+ 							break;
+ 						case TIMESTAMPOID:
+ 							fnOid = 2049;
+ 							break;
+ 						case INTERVALOID:
+ 							fnOid = 1768;
+ 							break;
+ 						default:
+ 							elog(ERROR, "unsupported type oid: %u", typid);
+ 							fnOid = rettype = InvalidOid;	/* keep compiler quiet */
+ 					}
+ 				}
+ 
+ 				formatDatum = PointerGetDatum(
+ 					cstring_to_text_with_len(format, cp - format));
+ 				value = OidFunctionCall2(fnOid, value, formatDatum);
+ 				typid = rettype;
+ 			}
+ 
+ 			/* Did we run off the end of the string? */
+ 			if (++cp >= end_ptr)
+ 				ereport(ERROR,
+ 						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ 						 errmsg("unterminated conversion specifier")));
+ 		}
+ 
  		switch (*cp)
  		{
  			case 's':
