to_char: revert cc0d90b73b2e6dd2f301d46818a7265742c41a14
authorBruce Momjian <bruce@momjian.us>
Mon, 23 Mar 2015 02:56:52 +0000 (22:56 -0400)
committerBruce Momjian <bruce@momjian.us>
Mon, 23 Mar 2015 02:56:56 +0000 (22:56 -0400)
Revert "to_char(float4/8):  zero pad to specified length".  There are
too many platform-specific problems, and the proper rounding is missing.
Also revert companion patch 9d61b9953c1489cbb458ca70013cf5fca1bb7710.

src/backend/utils/adt/formatting.c
src/test/regress/expected/numeric.out
src/test/regress/expected/window.out
src/test/regress/sql/numeric.sql

index 25b247ee78de7dbe243852139c08e11536a46c62..40a353f5134cb7766ed567ef9b975bb530b1f6fe 100644 (file)
 #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
@@ -5207,7 +5214,8 @@ int4_to_char(PG_FUNCTION_ARGS)
                /* we can do it easily because float8 won't lose any precision */
                float8          val = (float8) value;
 
-               orgnum = psprintf("%+.*e", Num.post, val);
+               orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
+               snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, val);
 
                /*
                 * Swap a leading positive sign for a space.
@@ -5406,6 +5414,7 @@ float4_to_char(PG_FUNCTION_ARGS)
                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))
                {
                        /*
@@ -5419,29 +5428,15 @@ float4_to_char(PG_FUNCTION_ARGS)
                }
                else
                {
-                       numstr = psprintf("%+.*e", Num.post, value);
-
-                       /* prevent the display of imprecise/junk digits */
-                       if (Num.pre + Num.post > FLT_DIG)
-                       {
-                               int             digits = 0;
-                               char   *numstr_p;
-
-                               for (numstr_p = numstr; *numstr_p && *numstr_p != 'e'; numstr_p++)
-                               {
-                                       if (isdigit(*numstr_p))
-                                       {
-                                               if (++digits > FLT_DIG)
-                                                       *numstr_p = '0';
-                                       }
-                               }
-                       }
+                       snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, value);
 
                        /*
                         * Swap a leading positive sign for a space.
                         */
-                       if (*numstr == '+')
-                               *numstr = ' ';
+                       if (*orgnum == '+')
+                               *orgnum = ' ';
+
+                       numstr = orgnum;
                }
        }
        else
@@ -5457,24 +5452,16 @@ float4_to_char(PG_FUNCTION_ARGS)
                        Num.pre += Num.multi;
                }
 
-               /* let psprintf() do the rounding */
-               orgnum = psprintf("%.*f", Num.post, val);
+               orgnum = (char *) palloc(MAXFLOATWIDTH + 1);
+               snprintf(orgnum, MAXFLOATWIDTH + 1, "%.0f", fabs(val));
+               numstr_pre_len = strlen(orgnum);
 
-               /* prevent the display of imprecise/junk digits */
-               if (Num.pre + Num.post > FLT_DIG)
-               {
-                       int     digits = 0;
-                       char   *orgnum_p;
-
-                       for (orgnum_p = orgnum; *orgnum_p; orgnum_p++)
-                       {
-                               if (isdigit(*orgnum_p))
-                               {
-                                       if (++digits > FLT_DIG)
-                                               *orgnum_p = '0';
-                               }
-                       }
-               }
+               /* 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 */
@@ -5533,6 +5520,7 @@ float8_to_char(PG_FUNCTION_ARGS)
                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))
                {
                        /*
@@ -5546,29 +5534,15 @@ float8_to_char(PG_FUNCTION_ARGS)
                }
                else
                {
-                       numstr = psprintf("%+.*e", Num.post, value);
-
-                       /* prevent the display of imprecise/junk digits */
-                       if (Num.pre + Num.post > DBL_DIG)
-                       {
-                               int             digits = 0;
-                               char   *numstr_p;
-
-                               for (numstr_p = numstr; *numstr_p && *numstr_p != 'e'; numstr_p++)
-                               {
-                                       if (isdigit(*numstr_p))
-                                       {
-                                               if (++digits > DBL_DIG)
-                                                       *numstr_p = '0';
-                                       }
-                               }
-                       }
+                       snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, value);
 
                        /*
                         * Swap a leading positive sign for a space.
                         */
-                       if (*numstr == '+')
-                               *numstr = ' ';
+                       if (*orgnum == '+')
+                               *orgnum = ' ';
+
+                       numstr = orgnum;
                }
        }
        else
@@ -5583,25 +5557,15 @@ float8_to_char(PG_FUNCTION_ARGS)
                        val = value * multi;
                        Num.pre += Num.multi;
                }
-
-               /* let psprintf() do the rounding */
-               orgnum = psprintf("%.*f", Num.post, val);
-
-               /* prevent the display of imprecise/junk digits */
-               if (Num.pre + Num.post > DBL_DIG)
-               {
-                       int     digits = 0;
-                       char   *orgnum_p;
-
-                       for (orgnum_p = orgnum; *orgnum_p; orgnum_p++)
-                       {
-                               if (isdigit(*orgnum_p))
-                               {
-                                       if (++digits > DBL_DIG)
-                                               *orgnum_p = '0';
-                               }
-                       }
-               }
+               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 */
index a4d0161923fdbc44d27f74330aac3775e4220444..9d6814564df961c4dd4e6d449db3d32a9efe0894 100644 (file)
@@ -1499,73 +1499,3 @@ select * from generate_series(1::numeric, 3::numeric) i, generate_series(1,5,i)
  3 | 4
 (10 rows)
 
---
--- Test code path for high-precision output
---
-SELECT to_char(float8 '99999999999', '9999999999999999D99999999');
-          to_char           
-----------------------------
-       99999999999.00000000
-(1 row)
-
-SELECT to_char(float8 '99999999999', '9999999999999999D' || repeat('9', 1000));
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          to_char                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-       99999999999.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.1234567891234500000000000000000000000000000000000000000
-(1 row)
-
-SELECT to_char(float8 '1999999999999999999999999999999999999999999999.123456789123456789',
-       repeat('9', 50) || '.' || repeat('9', 50));
-                                                to_char                                                 
---------------------------------------------------------------------------------------------------------
-      1999999999999990000000000000000000000000000000.00000000000000000000000000000000000000000000000000
-(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)
-
index 79e65f6e6bbe0fc6d8cc898ef41a4734d934ee17..19f909f3d105087c2babcfa62ff3a77d442a3b03 100644 (file)
@@ -1806,7 +1806,7 @@ SELECT to_char(SUM(n::float8) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND 1 FO
   FROM (VALUES(1,1e20),(2,1)) n(i,n);
          to_char          
 --------------------------
-  100000000000000000000.0
+  100000000000000000000
                       1.0
 (2 rows)
 
index 95c2203821a1a4a089c30716bffbf54e6ff07a99..1633e4c375244f35b517d7a699b2a7c8ea7d3225 100644 (file)
@@ -858,20 +858,3 @@ select (i / (10::numeric ^ 131071))::numeric(1,0)
 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 '99999999999', '9999999999999999D99999999');
-SELECT to_char(float8 '99999999999', '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 '1999999999999999999999999999999999999999999999.123456789123456789',
-       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');