On Wed, Apr  1, 2015 at 11:48:37AM -0400, Bruce Momjian wrote:
> This should return something like 15555600000000.000... (per Oracle
> output at the URL above, float4 has 6 significant digits on my compiler)
> but I can't seem to figure how to get printf() to round non-fractional
> parts.  I am afraid the only solution is to use printf's %e format and
> place the decimal point myself.

Hearing nothing, I went with the %e approach;  patch attached.  The new
output looks right:

        test=> SELECT to_char(float4 
'15555555555555.912345678912345678900000000000000000000000',
                  repeat('9', 50) || '.' || repeat('9', 50));
                                                        to_char
        
--------------------------------------------------------------------------------------------------------
                                              
15555600000000.00000000000000000000000000000000000000000000000000
        (1 row)

> The fact I still don't have a complete solution suggests this is 9.6
> material but I still want to work on it so it is ready.

I will keep this patch for 9.6 unless I hear otherwise.

-- 
  Bruce Momjian  <br...@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + Everyone has their own god. +
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
new file mode 100644
index 40a353f..d283cd2
*** a/src/backend/utils/adt/formatting.c
--- b/src/backend/utils/adt/formatting.c
***************
*** 113,125 ****
  #define DCH_MAX_ITEM_SIZ	   12		/* max localized day name		*/
  #define NUM_MAX_ITEM_SIZ		8		/* roman number (RN has 15 chars)	*/
  
- /* ----------
-  * More is in float.c
-  * ----------
-  */
- #define MAXFLOATWIDTH	60
- #define MAXDOUBLEWIDTH	500
- 
  
  /* ----------
   * Format parser structs
--- 113,118 ----
*************** static DCHCacheEntry *DCH_cache_getnew(c
*** 989,994 ****
--- 982,989 ----
  static NUMCacheEntry *NUM_cache_search(char *str);
  static NUMCacheEntry *NUM_cache_getnew(char *str);
  static void NUM_cache_remove(NUMCacheEntry *ent);
+ static char *add_pre_zero_padding(char *num_str, int decimal_shift);
+ static char *add_post_zero_padding(char *num_str, int pad_digits);
  
  
  /* ----------
*************** do { \
*** 5016,5021 ****
--- 5011,5103 ----
  	SET_VARSIZE(result, len + VARHDRSZ); \
  } while (0)
  
+ /*
+  * add_pre_zero_padding
+  *
+  * printf() can only round non-fractional parts of a number if the number
+  * is in exponential format, so this function takes a number in that format
+  * and adds pre-decimal zero padding.
+  */
+ static char *
+ add_pre_zero_padding(char *num_str, int decimal_shift)
+ {
+ 	/* one for decimal point, one for trailing null byte */
+ 	char *out = palloc(strlen(num_str) + decimal_shift + 1 + 1), *out_p = out;
+ 	char *num_str_p = num_str;
+ 	bool decimal_found = false;
+ 
+ 	/* copy the number before 'e' and shift the decimal point */
+ 	while (*num_str_p && *num_str_p != 'e')
+ 	{
+ 		if (*num_str_p == '.')
+ 		{
+ 			num_str_p++;
+ 			decimal_found = true;
+ 		}
+ 		else
+ 		{
+ 			*(out_p++) = *(num_str_p++);
+ 			if (decimal_found)
+ 				decimal_shift--;
+ 		}
+ 	}
+ 
+ 	/* add zero pad digits */
+ 	while (decimal_shift-- > 0)
+ 		*(out_p++) = '0';
+ 
+ 	*(out_p++) = '\0';
+ 
+ 	pfree(num_str);
+ 	return out;
+ }
+ 
+ /*
+  * add_post_zero_padding
+  *
+  * Some sprintf() implementations have a 512-digit precision limit, and we
+  * need sprintf() to round to the internal precision, so this function adds
+  * zero padding between the mantissa and exponent of an exponential-format
+  * number, or after the supplied string for non-exponent strings.
+  */
+ static char *
+ add_post_zero_padding(char *num_str, int pad_digits)
+ {
+ 	/* one for decimal point, one for trailing null byte */
+ 	char *out = palloc(strlen(num_str) + pad_digits + 1 + 1), *out_p = out;
+ 	char *num_str_p = num_str;
+ 	bool decimal_found = false;
+ 
+ 	/* copy the number before 'e', or the entire string if no 'e' */
+ 	while (*num_str_p && *num_str_p != 'e')
+ 	{
+ 		if (*num_str_p == '.')
+ 			decimal_found = true;
+ 		*(out_p++) = *(num_str_p++);
+ 	}
+ 
+ 	/* add zero pad digits */
+ 	while (pad_digits-- > 0)
+ 	{
+ 		if (!decimal_found)
+ 		{
+ 			*(out_p++) = '.';
+ 			decimal_found = true;
+ 		}
+ 
+ 		*(out_p++) = '0';
+ 	}
+ 
+ 	/* copy 'e' and everything after */
+ 	while (*num_str_p)
+ 		*(out_p++) = *(num_str_p++);
+ 
+ 	*(out_p++) = '\0';
+ 
+ 	pfree(num_str);
+ 	return out;	
+ }
+ 
  /* -------------------
   * NUMERIC to_number() (convert string to numeric)
   * -------------------
*************** int4_to_char(PG_FUNCTION_ARGS)
*** 5214,5221 ****
  		/* we can do it easily because float8 won't lose any precision */
  		float8		val = (float8) value;
  
! 		orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
! 		snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, val);
  
  		/*
  		 * Swap a leading positive sign for a space.
--- 5296,5307 ----
  		/* we can do it easily because float8 won't lose any precision */
  		float8		val = (float8) value;
  
! 		/* Use '1' if there is any Num.post, so we get a decimal point */
! 		orgnum = psprintf("%+.0e", val);
! 
! 		/* Add any additional zeros */
! 		if (Num.post > 0)
! 			orgnum = add_post_zero_padding(orgnum, Num.post);
  
  		/*
  		 * Swap a leading positive sign for a space.
*************** int4_to_char(PG_FUNCTION_ARGS)
*** 5253,5265 ****
  
  		/* post-decimal digits?  Pad out with zeros. */
  		if (Num.post)
! 		{
! 			numstr = (char *) palloc(numstr_pre_len + Num.post + 2);
! 			strcpy(numstr, orgnum);
! 			*(numstr + numstr_pre_len) = '.';
! 			memset(numstr + numstr_pre_len + 1, '0', Num.post);
! 			*(numstr + numstr_pre_len + Num.post + 1) = '\0';
! 		}
  		else
  			numstr = orgnum;
  
--- 5339,5345 ----
  
  		/* post-decimal digits?  Pad out with zeros. */
  		if (Num.post)
! 			numstr = add_post_zero_padding(pstrdup(orgnum), Num.post);
  		else
  			numstr = orgnum;
  
*************** int8_to_char(PG_FUNCTION_ARGS)
*** 5363,5375 ****
  
  		/* post-decimal digits?  Pad out with zeros. */
  		if (Num.post)
! 		{
! 			numstr = (char *) palloc(numstr_pre_len + Num.post + 2);
! 			strcpy(numstr, orgnum);
! 			*(numstr + numstr_pre_len) = '.';
! 			memset(numstr + numstr_pre_len + 1, '0', Num.post);
! 			*(numstr + numstr_pre_len + Num.post + 1) = '\0';
! 		}
  		else
  			numstr = orgnum;
  
--- 5443,5449 ----
  
  		/* post-decimal digits?  Pad out with zeros. */
  		if (Num.post)
! 			numstr = add_post_zero_padding(pstrdup(orgnum), Num.post);
  		else
  			numstr = orgnum;
  
*************** float4_to_char(PG_FUNCTION_ARGS)
*** 5414,5420 ****
  		numstr = orgnum = int_to_roman((int) rint(value));
  	else if (IS_EEEE(&Num))
  	{
- 		numstr = orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
  		if (isnan(value) || is_infinite(value))
  		{
  			/*
--- 5488,5493 ----
*************** float4_to_char(PG_FUNCTION_ARGS)
*** 5428,5448 ****
  		}
  		else
  		{
! 			snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, value);
  
  			/*
  			 * Swap a leading positive sign for a space.
  			 */
! 			if (*orgnum == '+')
! 				*orgnum = ' ';
! 
! 			numstr = orgnum;
  		}
  	}
  	else
  	{
  		float4		val = value;
! 		int			numstr_pre_len;
  
  		if (IS_MULTI(&Num))
  		{
--- 5501,5526 ----
  		}
  		else
  		{
! 			/* We already have one decimal digit before the decimal point. */
! 			numstr = psprintf("%+.*e",
! 						Min(Num.post, FLT_DIG + extra_float_digits - 1), value);
! 
! 			if (Num.post > FLT_DIG + extra_float_digits - 1)
! 				numstr = add_post_zero_padding(numstr,
! 							Num.post - FLT_DIG - extra_float_digits + 1);
  
  			/*
  			 * Swap a leading positive sign for a space.
  			 */
! 			if (*numstr == '+')
! 				*numstr = ' ';
  		}
  	}
  	else
  	{
  		float4		val = value;
! 		int			numstr_pre_len, val_exp = 0;
! 		char		*exp_buf;
  
  		if (IS_MULTI(&Num))
  		{
*************** float4_to_char(PG_FUNCTION_ARGS)
*** 5452,5467 ****
  			Num.pre += Num.multi;
  		}
  
! 		orgnum = (char *) palloc(MAXFLOATWIDTH + 1);
! 		snprintf(orgnum, MAXFLOATWIDTH + 1, "%.0f", fabs(val));
! 		numstr_pre_len = strlen(orgnum);
! 
! 		/* adjust post digits to fit max float digits */
! 		if (numstr_pre_len >= FLT_DIG)
! 			Num.post = 0;
! 		else if (numstr_pre_len + Num.post > FLT_DIG)
! 			Num.post = FLT_DIG - numstr_pre_len;
! 		snprintf(orgnum, MAXFLOATWIDTH + 1, "%.*f", Num.post, val);
  
  		if (*orgnum == '-')
  		{						/* < 0 */
--- 5530,5566 ----
  			Num.pre += Num.multi;
  		}
  
! 		/* Generate string with padding */
! 		exp_buf = psprintf("%.*e", FLT_DIG + extra_float_digits - 1, val);
! 		if (strchr(exp_buf, 'e') != NULL)
! 		{
! 			val_exp = atoi(strchr(exp_buf, 'e') + 1);
! 			/*
! 			 * Is the number larger than our precision?  If so, we need
! 			 * round the non-fractional part of the number.  To do that,
! 			 * we use %e so we can round the value, shift the decimal point
! 			 * and add zeros before the decimal point.
! 			 */
! 			/* exp assumes one digit before the decimal point */
! 			if (val_exp + 1 > FLT_DIG + extra_float_digits)
! 			{
! 				orgnum = add_pre_zero_padding(exp_buf, val_exp);
! 				if (Num.post > 0)
! 					orgnum = add_post_zero_padding(orgnum, Num.post);
! 			}
! 			else
! 			{
! 				/* We might have significant fractional digits */
! 				pfree(exp_buf);
! 				orgnum = psprintf("%.*f", Min(Num.post, FLT_DIG +
! 								  extra_float_digits - val_exp - 1), val);
! 				if (Num.post > FLT_DIG + extra_float_digits - val_exp - 1)
! 					orgnum = add_post_zero_padding(orgnum, Num.post - FLT_DIG -
! 											extra_float_digits + val_exp + 1);
! 			}
! 		}
! 		else
! 			orgnum = exp_buf;
  
  		if (*orgnum == '-')
  		{						/* < 0 */
*************** float8_to_char(PG_FUNCTION_ARGS)
*** 5520,5526 ****
  		numstr = orgnum = int_to_roman((int) rint(value));
  	else if (IS_EEEE(&Num))
  	{
- 		numstr = orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
  		if (isnan(value) || is_infinite(value))
  		{
  			/*
--- 5619,5624 ----
*************** float8_to_char(PG_FUNCTION_ARGS)
*** 5534,5554 ****
  		}
  		else
  		{
! 			snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, value);
  
  			/*
  			 * Swap a leading positive sign for a space.
  			 */
! 			if (*orgnum == '+')
! 				*orgnum = ' ';
! 
! 			numstr = orgnum;
  		}
  	}
  	else
  	{
  		float8		val = value;
! 		int			numstr_pre_len;
  
  		if (IS_MULTI(&Num))
  		{
--- 5632,5657 ----
  		}
  		else
  		{
! 			/* We already have one decimal digit before the decimal point. */
! 			numstr = psprintf("%+.*e",
! 						Min(Num.post, DBL_DIG + extra_float_digits - 1), value);
! 
! 			if (Num.post > DBL_DIG + extra_float_digits - 1)
! 				numstr = add_post_zero_padding(numstr,
! 							Num.post - DBL_DIG - extra_float_digits + 1);
  
  			/*
  			 * Swap a leading positive sign for a space.
  			 */
! 			if (*numstr == '+')
! 				*numstr = ' ';
  		}
  	}
  	else
  	{
  		float8		val = value;
! 		int			numstr_pre_len, val_exp = 0;
! 		char		*exp_buf;
  
  		if (IS_MULTI(&Num))
  		{
*************** float8_to_char(PG_FUNCTION_ARGS)
*** 5557,5571 ****
  			val = value * multi;
  			Num.pre += Num.multi;
  		}
- 		orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
- 		numstr_pre_len = snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.0f", fabs(val));
  
! 		/* adjust post digits to fit max double digits */
! 		if (numstr_pre_len >= DBL_DIG)
! 			Num.post = 0;
! 		else if (numstr_pre_len + Num.post > DBL_DIG)
! 			Num.post = DBL_DIG - numstr_pre_len;
! 		snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.*f", Num.post, val);
  
  		if (*orgnum == '-')
  		{						/* < 0 */
--- 5660,5697 ----
  			val = value * multi;
  			Num.pre += Num.multi;
  		}
  
! 		/* Generate string with padding */
! 		exp_buf = psprintf("%.*e", DBL_DIG + extra_float_digits - 1, val);
! 		if (strchr(exp_buf, 'e') != NULL)
! 		{
! 			val_exp = atoi(strchr(exp_buf, 'e') + 1);
! 			/*
! 			 * Is the number larger than our precision?  If so, we need
! 			 * round the non-fractional part of the number.  To do that,
! 			 * we use %e so we can round the value, shift the decimal point
! 			 * and add zeros before the decimal point.
! 			 */
! 			/* exp assumes one digit before the decimal point */
! 			if (val_exp + 1 > DBL_DIG + extra_float_digits)
! 			{
! 				orgnum = add_pre_zero_padding(exp_buf, val_exp);
! 				if (Num.post > 0)
! 					orgnum = add_post_zero_padding(orgnum, Num.post);
! 			}
! 			else
! 			{
! 				/* We might have significant fractional digits */
! 				pfree(exp_buf);
! 				orgnum = psprintf("%.*f", Min(Num.post, DBL_DIG +
! 								  extra_float_digits - val_exp - 1), val);
! 				if (Num.post > DBL_DIG + extra_float_digits - val_exp - 1)
! 					orgnum = add_post_zero_padding(orgnum, Num.post - DBL_DIG -
! 											extra_float_digits + val_exp + 1);
! 			}
! 		}
! 		else
! 			orgnum = exp_buf;
  
  		if (*orgnum == '-')
  		{						/* < 0 */
diff --git a/src/test/regress/expected/numeric.out b/src/test/regress/expected/numeric.out
new file mode 100644
index 9d68145..ac30bd2
*** a/src/test/regress/expected/numeric.out
--- b/src/test/regress/expected/numeric.out
*************** select * from generate_series(1::numeric
*** 1499,1501 ****
--- 1499,1585 ----
   3 | 4
  (10 rows)
  
+ --
+ -- Test code path for high-precision output
+ --
+ SELECT to_char(float8 '55555555555', '9999999999999999D99999999');
+           to_char           
+ ----------------------------
+        55555555555.00000000
+ (1 row)
+ 
+ SELECT to_char(float8 '55555555555', '9999999999999999D' || repeat('9', 1000));
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           to_char                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
+ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+        55555555555.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+ (1 row)
+ 
+ SELECT to_char(float8 '1e9','999999999999999999999D9');
+          to_char          
+ --------------------------
+              1000000000.0
+ (1 row)
+ 
+ SELECT to_char(float8 '1e20','999999999999999999999D9');
+          to_char          
+ --------------------------
+   100000000000000000000.0
+ (1 row)
+ 
+ SELECT to_char(1e20, '999999999999999999999D9');
+          to_char          
+ --------------------------
+   100000000000000000000.0
+ (1 row)
+ 
+ SELECT to_char(float8 '1.123456789123456789', '9.' || repeat('9', 55));
+                           to_char                           
+ ------------------------------------------------------------
+   1.1234567891234600000000000000000000000000000000000000000
+ (1 row)
+ 
+ SELECT to_char(float8 '1555555555555555555555555555555555555555555555.123456789123456789',
+         repeat('9', 50) || '.' || repeat('9', 50));
+                                                 to_char                                                 
+ --------------------------------------------------------------------------------------------------------
+       1555555555555560000000000000000000000000000000.00000000000000000000000000000000000000000000000000
+ (1 row)
+ 
+ SELECT to_char(float8 '1555555.55555555555555555555555555555555555555',
+         repeat('9', 50) || '.' || repeat('9', 50));
+                                                 to_char                                                 
+ --------------------------------------------------------------------------------------------------------
+                                              1555555.55555556000000000000000000000000000000000000000000
+ (1 row)
+ 
+ SELECT to_char(float8 '0.00000000000000000000015555555555555555555555',
+         repeat('9', 50) || '.' || repeat('9', 50));
+                                                 to_char                                                 
+ --------------------------------------------------------------------------------------------------------
+                                                     .00000000000000000000015555555555555600000000000000
+ (1 row)
+ 
+ SELECT to_char(float8 '0.1', '9D' || repeat('9', 1000));
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    to_char                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
+ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+    .1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+ (1 row)
+ 
+ SELECT to_char(int4 '1', '9D' || repeat('9', 1000) || 'EEEE');
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      to_char                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
+ -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+   1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00
+ (1 row)
+ 
+ SELECT to_char(float4 '1', '9D' || repeat('9', 1000) || 'EEEE');
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      to_char                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
+ -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+   1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00
+ (1 row)
+ 
+ SELECT to_char(float8 '1', '9D' || repeat('9', 1000) || 'EEEE');
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      to_char                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
+ -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+   1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00
+ (1 row)
+ 
diff --git a/src/test/regress/expected/window.out b/src/test/regress/expected/window.out
new file mode 100644
index 19f909f..79e65f6
*** a/src/test/regress/expected/window.out
--- b/src/test/regress/expected/window.out
*************** SELECT to_char(SUM(n::float8) OVER (ORDE
*** 1806,1812 ****
    FROM (VALUES(1,1e20),(2,1)) n(i,n);
           to_char          
  --------------------------
!   100000000000000000000
                        1.0
  (2 rows)
  
--- 1806,1812 ----
    FROM (VALUES(1,1e20),(2,1)) n(i,n);
           to_char          
  --------------------------
!   100000000000000000000.0
                        1.0
  (2 rows)
  
diff --git a/src/test/regress/sql/numeric.sql b/src/test/regress/sql/numeric.sql
new file mode 100644
index 1633e4c..a47c1bb
*** a/src/test/regress/sql/numeric.sql
--- b/src/test/regress/sql/numeric.sql
*************** select (i / (10::numeric ^ 131071))::num
*** 858,860 ****
--- 858,881 ----
  select * from generate_series(1::numeric, 3::numeric) i, generate_series(i,3) j;
  select * from generate_series(1::numeric, 3::numeric) i, generate_series(1,i) j;
  select * from generate_series(1::numeric, 3::numeric) i, generate_series(1,5,i) j;
+ 
+ --
+ -- Test code path for high-precision output
+ --
+ 
+ SELECT to_char(float8 '55555555555', '9999999999999999D99999999');
+ SELECT to_char(float8 '55555555555', '9999999999999999D' || repeat('9', 1000));
+ SELECT to_char(float8 '1e9','999999999999999999999D9');
+ SELECT to_char(float8 '1e20','999999999999999999999D9');
+ SELECT to_char(1e20, '999999999999999999999D9');
+ SELECT to_char(float8 '1.123456789123456789', '9.' || repeat('9', 55));
+ SELECT to_char(float8 '1555555555555555555555555555555555555555555555.123456789123456789',
+         repeat('9', 50) || '.' || repeat('9', 50));
+ SELECT to_char(float8 '1555555.55555555555555555555555555555555555555',
+         repeat('9', 50) || '.' || repeat('9', 50));
+ SELECT to_char(float8 '0.00000000000000000000015555555555555555555555',
+         repeat('9', 50) || '.' || repeat('9', 50));
+ SELECT to_char(float8 '0.1', '9D' || repeat('9', 1000));
+ SELECT to_char(int4 '1', '9D' || repeat('9', 1000) || 'EEEE');
+ SELECT to_char(float4 '1', '9D' || repeat('9', 1000) || 'EEEE');
+ SELECT to_char(float8 '1', '9D' || repeat('9', 1000) || 'EEEE');
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to