to_char fixes, Karel Zak
authorBruce Momjian
Thu, 27 Mar 2003 16:35:31 +0000 (16:35 +0000)
committerBruce Momjian
Thu, 27 Mar 2003 16:35:31 +0000 (16:35 +0000)
doc/src/sgml/func.sgml
src/backend/utils/adt/formatting.c
src/test/regress/expected/int8.out
src/test/regress/expected/numeric.out

index 25db8b37c100377e4721b608e15e88a350809330..c8f242ca0003a80916869b8b8e86524a32042a40 100644 (file)
@@ -1,5 +1,5 @@
 
 
@@ -4365,7 +4365,7 @@ substring('foobar' from 'o(.)b')   o
                  
        
         to_char(-0.1, '99.99')
-        ' -.10'
+         -.10'
        
        
         to_char(-0.1, 'FM9.99')
@@ -4381,7 +4381,7 @@ substring('foobar' from 'o(.)b')   o
        
        
         to_char(12, 'FM9990999.9')
-        '0012'
+        '0012.'
        
        
         to_char(485, '999')
@@ -4405,8 +4405,18 @@ substring('foobar' from 'o(.)b')   o
        
        
         to_char(148.5, '999.999')
-        ' 148.500'
+        ' 148.500'
        
+       
+        to_char(148.5, 'FM999.999')
+        '148.5'
+       
+       
+       
+        to_char(148.5, 'FM999.990')
+        '148.500'
+       
+       
        
         to_char(148.5, '999D999')
         ' 148,500'   
@@ -4425,6 +4435,10 @@ substring('foobar' from 'o(.)b')   o
        
        
         to_char(485, '999MI')
+        '485 '      
+       
+       
+        to_char(485, 'FM999MI')
         '485'        
        
        
index 0b97519d4310e282103092c29b632bbbdf4fb468..3e5ab791518310debd27dcc0c9271bd583e17c53 100644 (file)
@@ -1,7 +1,7 @@
 /* -----------------------------------------------------------------------
  * formatting.c
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.60 2003/03/22 02:12:24 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.61 2003/03/27 16:35:30 momjian Exp $
  *
  *
  *  Portions Copyright (c) 1999-2002, PostgreSQL Global Development Group
@@ -276,17 +276,19 @@ typedef struct
  * Flags for NUMBER version
  * ----------
  */
-#define NUM_F_DECIMAL  0x01
-#define NUM_F_LDECIMAL 0x02
-#define NUM_F_ZERO 0x04
-#define NUM_F_BLANK 0x08
-#define NUM_F_FILLMODE 0x10
-#define NUM_F_LSIGN 0x20
-#define NUM_F_BRACKET  0x40
-#define NUM_F_MINUS 0x80
-#define NUM_F_PLUS 0x100
-#define NUM_F_ROMAN 0x200
-#define NUM_F_MULTI 0x400
+#define NUM_F_DECIMAL      (1 << 1)
+#define NUM_F_LDECIMAL     (1 << 2)
+#define NUM_F_ZERO     (1 << 3)
+#define NUM_F_BLANK        (1 << 4)
+#define NUM_F_FILLMODE     (1 << 5)
+#define NUM_F_LSIGN        (1 << 6)
+#define NUM_F_BRACKET      (1 << 7)
+#define NUM_F_MINUS        (1 << 8)
+#define NUM_F_PLUS     (1 << 9)
+#define NUM_F_ROMAN        (1 << 10)
+#define NUM_F_MULTI        (1 << 11)
+#define NUM_F_PLUS_POST    (1 << 12)
+#define NUM_F_MINUS_POST   (1 << 13)
 
 #define NUM_LSIGN_PRE  -1
 #define NUM_LSIGN_POST 1
@@ -828,7 +830,6 @@ typedef struct NUMProc
 
    int         sign,           /* '-' or '+'           */
                sign_wrote,     /* was sign write       */
-               sign_pos,       /* pre number sign position */
                num_count,      /* number of write digits   */
                num_in,         /* is inside number     */
                num_curr,       /* current position in number   */
@@ -1052,6 +1053,8 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
                elog(ERROR, "to_char/to_number(): can't use 'S' and 'MI' together.");
            }
            num->flag |= NUM_F_MINUS;
+           if (IS_DECIMAL(num))
+               num->flag |= NUM_F_MINUS_POST;
            break;
 
        case NUM_PL:
@@ -1061,6 +1064,8 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
                elog(ERROR, "to_char/to_number(): can't use 'S' and 'PL' together.");
            }
            num->flag |= NUM_F_PLUS;
+           if (IS_DECIMAL(num))
+               num->flag |= NUM_F_PLUS_POST;
            break;
 
        case NUM_SG:
@@ -3556,7 +3561,7 @@ NUM_numpart_from_char(NUMProc *Np, int id, int plen)
         * simple + - < >
         */
        if (*Np->inout_p == '-' || (IS_BRACKET(Np->Num) &&
-                                   *Np->inout_p == '<'))
+           *Np->inout_p == '<'))
        {
 
            *Np->number = '-';  /* set - */
@@ -3629,6 +3634,12 @@ NUM_numpart_from_char(NUMProc *Np, int id, int plen)
    }
 }
 
+#define IS_PREDEC_SPACE(_n) \
+       (IS_ZERO((_n)->Num)==FALSE && \
+        (_n)->number == (_n)->number_p && \
+        *(_n)->number == '0' && \
+                 (_n)->Num->post != 0)
+
 /* ----------
  * Add digit or sign to number-string
  * ----------
@@ -3658,67 +3669,54 @@ NUM_numpart_to_char(NUMProc *Np, int id)
    Np->num_in = FALSE;
 
    /*
-    * Write sign
+    * Write sign if real number will write to output
+    * Note: IS_PREDEC_SPACE() handle "9.9" --> " .1"
     */
-   if (Np->num_curr == Np->sign_pos && Np->sign_wrote == FALSE)
-   {
-
-#ifdef DEBUG_TO_FROM_CHAR
-       elog(DEBUG_elog_output, "Writing sign to position: %d", Np->num_curr);
-#endif
+   if (Np->sign_wrote == FALSE && 
+       (Np->num_curr >= Np->num_pre || (IS_ZERO(Np->Num) && Np->Num->zero_start == Np->num_curr )) && 
+       (IS_PREDEC_SPACE(Np)==FALSE || (Np->last_relevant && *Np->last_relevant == '.')))
+   {   
        if (IS_LSIGN(Np->Num))
        {
-           /*
-            * Write locale SIGN
-            */
-           if (Np->sign == '-')
-               strcpy(Np->inout_p, Np->L_negative_sign);
-           else
-               strcpy(Np->inout_p, Np->L_positive_sign);
-           Np->inout_p += strlen(Np->inout_p);
-
+           if (Np->Num->lsign == NUM_LSIGN_PRE)
+           {
+               if (Np->sign == '-')
+                   strcpy(Np->inout_p, Np->L_negative_sign);
+               else
+                   strcpy(Np->inout_p, Np->L_positive_sign);
+               Np->inout_p += strlen(Np->inout_p);
+               Np->sign_wrote = TRUE;
+           }
        }
        else if (IS_BRACKET(Np->Num))
        {
-           *Np->inout_p = '<'; /* Write < */
+           *Np->inout_p = Np->sign == '+' ? ' ' : '<';
            ++Np->inout_p;
-
+           Np->sign_wrote = TRUE;
        }
        else if (Np->sign == '+')
        {
-           *Np->inout_p = ' '; /* Write + */
-           ++Np->inout_p;
-
+           if (!IS_FILLMODE(Np->Num))
+           {
+               *Np->inout_p = ' '; /* Write + */
+               ++Np->inout_p;
+           }
+           Np->sign_wrote = TRUE;
        }
        else if (Np->sign == '-')
        {                       /* Write - */
            *Np->inout_p = '-';
            ++Np->inout_p;
+           Np->sign_wrote = TRUE;
        }
-       Np->sign_wrote = TRUE;
-
    }
-   else if (Np->sign_wrote && IS_BRACKET(Np->Num) &&
-            (Np->num_curr == Np->num_count + (Np->num_pre ? 1 : 0)
-             + (IS_DECIMAL(Np->Num) ? 1 : 0)))
-   {
-       /*
-        * Write close BRACKET
-        */
-#ifdef DEBUG_TO_FROM_CHAR
-       elog(DEBUG_elog_output, "Writing bracket to position %d", Np->num_curr);
-#endif
-       *Np->inout_p = '>';     /* Write '>' */
-       ++Np->inout_p;
-   }
-
+    
+   
    /*
     * digits / FM / Zero / Dec. point
     */
-   if (id == NUM_9 || id == NUM_0 || id == NUM_D || id == NUM_DEC ||
-       (id == NUM_S && Np->num_curr < Np->num_pre))
+   if (id == NUM_9 || id == NUM_0 || id == NUM_D || id == NUM_DEC)
    {
-
        if (Np->num_curr < Np->num_pre &&
            (Np->Num->zero_start > Np->num_curr || !IS_ZERO(Np->Num)))
        {
@@ -3727,9 +3725,6 @@ NUM_numpart_to_char(NUMProc *Np, int id)
             */
            if (!IS_FILLMODE(Np->Num))
            {
-#ifdef DEBUG_TO_FROM_CHAR
-               elog(DEBUG_elog_output, "Writing blank space to position %d", Np->num_curr);
-#endif
                *Np->inout_p = ' ';     /* Write ' ' */
                ++Np->inout_p;
            }
@@ -3742,9 +3737,6 @@ NUM_numpart_to_char(NUMProc *Np, int id)
            /*
             * Write ZERO
             */
-#ifdef DEBUG_TO_FROM_CHAR
-           elog(DEBUG_elog_output, "Writing zero to position %d", Np->num_curr);
-#endif
            *Np->inout_p = '0'; /* Write '0' */
            ++Np->inout_p;
            Np->num_in = TRUE;
@@ -3760,12 +3752,8 @@ NUM_numpart_to_char(NUMProc *Np, int id)
 
                if (!Np->last_relevant || *Np->last_relevant != '.')
                {
-#ifdef DEBUG_TO_FROM_CHAR
-                   elog(DEBUG_elog_output, "Writing decimal point to position %d", Np->num_curr);
-#endif
                    strcpy(Np->inout_p, Np->decimal);   /* Write DEC/D */
                    Np->inout_p += strlen(Np->inout_p);
-
                }
                /*
                 * Ora 'n' -- FM9.9 --> 'n.'
@@ -3788,10 +3776,9 @@ NUM_numpart_to_char(NUMProc *Np, int id)
                    id != NUM_0)
                    ;
                /*
-                * terrible Ora format: '0.1' -- 9.9 --> '  .1'
+                * '0.1' -- 9.9 --> '  .1'
                 */
-               else if (!IS_ZERO(Np->Num) && *Np->number == '0' &&
-                        Np->number == Np->number_p && Np->Num->post != 0)
+               else if (IS_PREDEC_SPACE(Np))
                {
                    if (!IS_FILLMODE(Np->Num))
                    {
@@ -3799,7 +3786,7 @@ NUM_numpart_to_char(NUMProc *Np, int id)
                        ++Np->inout_p;
                    }
                    /*
-                    * total terrible Ora: '0' -- FM9.9 --> '0.'
+                    * '0' -- FM9.9 --> '0.'
                     */
                    else if (Np->last_relevant && *Np->last_relevant == '.')
                    {
@@ -3809,10 +3796,6 @@ NUM_numpart_to_char(NUMProc *Np, int id)
                }
                else
                {
-#ifdef DEBUG_TO_FROM_CHAR
-                   elog(DEBUG_elog_output, "Writing digit '%c' to position %d",
-                        *Np->number_p, Np->num_curr);
-#endif
                    *Np->inout_p = *Np->number_p;       /* Write DIGIT */
                    ++Np->inout_p;
                    Np->num_in = TRUE;
@@ -3820,6 +3803,28 @@ NUM_numpart_to_char(NUMProc *Np, int id)
            }
            ++Np->number_p;
        }
+
+       int end = Np->num_count + (Np->num_pre ? 1 : 0) + (IS_DECIMAL(Np->Num) ? 1 : 0);
+       
+       if (Np->last_relevant && Np->last_relevant == Np->number_p)
+           end = Np->num_curr;
+       
+       if (Np->num_curr+1 == end)
+       {
+           if (Np->sign_wrote == TRUE && IS_BRACKET(Np->Num))
+           {
+               *Np->inout_p = Np->sign == '+' ? ' ' : '>';
+               ++Np->inout_p;
+           }
+           else if (IS_LSIGN(Np->Num) && Np->Num->lsign == NUM_LSIGN_POST)
+           {
+               if (Np->sign == '-')
+                   strcpy(Np->inout_p, Np->L_negative_sign);
+               else
+                   strcpy(Np->inout_p, Np->L_positive_sign);
+               Np->inout_p += strlen(Np->inout_p);
+           }
+       }
    }
 
    ++Np->num_curr;
@@ -3847,7 +3852,7 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
 
    if (Np->Num->zero_start)
        --Np->Num->zero_start;
-
+   
    /*
     * Roman correction
     */
@@ -3875,33 +3880,37 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
    if (type == FROM_CHAR)
    {
        Np->sign = FALSE;
-       Np->sign_pos = -1;
    }
    else
    {
        Np->sign = sign;
-
-       if (Np->sign != '-')
+       
+       /* MI/PL/SG - write sign itself and not in number */
+       if (IS_PLUS(Np->Num) || IS_MINUS(Np->Num))
        {
-           Np->Num->flag &= ~NUM_F_BRACKET;
-           Np->Num->flag &= ~NUM_F_MINUS;
+           if (IS_PLUS(Np->Num) && IS_MINUS(Np->Num)==FALSE)
+               Np->sign_wrote = FALSE;
        }
-       else if (Np->sign != '+')
-           Np->Num->flag &= ~NUM_F_PLUS;
-
-       if (Np->sign == '+' && IS_FILLMODE(Np->Num) && !IS_LSIGN(Np->Num))
-           Np->sign_wrote = TRUE;      /* needn't sign */
        else
-           Np->sign_wrote = FALSE;     /* need sign */
-
-       Np->sign_pos = -1;
+       {
+           if (Np->sign != '-')
+           {
+               if (IS_BRACKET(Np->Num) && IS_FILLMODE(Np->Num))
+                   Np->Num->flag &= ~NUM_F_BRACKET;
+               if (IS_MINUS(Np->Num))
+                   Np->Num->flag &= ~NUM_F_MINUS;
+           }
+           else if (Np->sign != '+' && IS_PLUS(Np->Num))
+               Np->Num->flag &= ~NUM_F_PLUS;
 
-       if (Np->Num->lsign == NUM_LSIGN_PRE && Np->Num->pre == Np->Num->pre_lsign_num)
-           Np->Num->lsign = NUM_LSIGN_POST;
+           if (Np->sign == '+' && IS_FILLMODE(Np->Num) && IS_LSIGN(Np->Num)==FALSE)
+               Np->sign_wrote = TRUE;      /* needn't sign */
+           else
+               Np->sign_wrote = FALSE;     /* need sign */
 
-       /* MI/PL/SG - write sign itself and not in number */
-       if (IS_PLUS(Np->Num) || IS_MINUS(Np->Num))
-           Np->sign_wrote = TRUE;      /* needn't sign */
+           if (Np->Num->lsign == NUM_LSIGN_PRE && Np->Num->pre == Np->Num->pre_lsign_num)
+               Np->Num->lsign = NUM_LSIGN_POST;
+       }
    }
 
    /*
@@ -3917,51 +3926,13 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
        {
            if (IS_DECIMAL(Np->Num))
                Np->last_relevant = get_last_relevant_decnum(
-                                                            Np->number +
+                                Np->number +
                                 ((Np->Num->zero_end - Np->num_pre > 0) ?
                                  Np->Num->zero_end - Np->num_pre : 0));
        }
 
-       if (!Np->sign_wrote && Np->num_pre == 0)
+       if (Np->sign_wrote==FALSE && Np->num_pre == 0)
            ++Np->num_count;
-
-       if (!Np->sign_wrote)
-       {
-           /*
-            * Set SING position
-            */
-           if (Np->Num->lsign == NUM_LSIGN_POST)
-           {
-               Np->sign_pos = Np->num_count + (Np->num_pre ? 1 : 0);
-
-               if (IS_DECIMAL(Np->Num))        /* decimal point correction */
-                   ++Np->sign_pos;
-           }
-           else if (IS_ZERO(Np->Num) && Np->num_pre > Np->Num->zero_start)
-               Np->sign_pos = Np->Num->zero_start ? Np->Num->zero_start : 0;
-
-           else
-               Np->sign_pos = Np->num_pre && !IS_FILLMODE(Np->Num) ? Np->num_pre : 0;
-
-           /*
-            * terrible Ora format
-            */
-           if (!IS_ZERO(Np->Num) && *Np->number == '0' &&
-               !IS_FILLMODE(Np->Num) && Np->Num->post != 0)
-           {
-
-               ++Np->sign_pos;
-
-               if (IS_LSIGN(Np->Num))
-               {
-                   if (Np->Num->lsign == NUM_LSIGN_PRE)
-                       ++Np->sign_pos;
-                   else
-                       --Np->sign_pos;
-               }
-           }
-       }
-
    }
    else
    {
@@ -3975,20 +3946,24 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
 
 #ifdef DEBUG_TO_FROM_CHAR
    elog(DEBUG_elog_output,
-
-        "\n\tNUM: '%s'\n\tPRE: %d\n\tPOST: %d\n\tNUM_COUNT: %d\n\tNUM_PRE: %d\n\tSIGN_POS: %d\n\tSIGN_WROTE: %s\n\tZERO: %s\n\tZERO_START: %d\n\tZERO_END: %d\n\tLAST_RELEVANT: %s",
+        "\n\tSIGN: '%c'\n\tNUM: '%s'\n\tPRE: %d\n\tPOST: %d\n\tNUM_COUNT: %d\n\tNUM_PRE: %d\n\tSIGN_WROTE: %s\n\tZERO: %s\n\tZERO_START: %d\n\tZERO_END: %d\n\tLAST_RELEVANT: %s\n\tBRACKET: %s\n\tPLUS: %s\n\tMINUS: %s\n\tFILLMODE: %s\n\tROMAN: %s",
+        Np->sign,
         Np->number,
         Np->Num->pre,
         Np->Num->post,
         Np->num_count,
         Np->num_pre,
-        Np->sign_pos,
         Np->sign_wrote ? "Yes" : "No",
         IS_ZERO(Np->Num) ? "Yes" : "No",
         Np->Num->zero_start,
         Np->Num->zero_end,
-        Np->last_relevant ? Np->last_relevant : ""
-       );
+        Np->last_relevant ? Np->last_relevant : "",
+        IS_BRACKET(Np->Num) ? "Yes" : "No",
+        IS_PLUS(Np->Num) ? "Yes" : "No",
+        IS_MINUS(Np->Num) ? "Yes" : "No",
+        IS_FILLMODE(Np->Num) ? "Yes" : "No",
+        IS_ROMAN(Np->Num) ? "Yes" : "No"
+   );
 #endif
 
    /*
@@ -4031,8 +4006,6 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
                case NUM_0:
                case NUM_DEC:
                case NUM_D:
-               case NUM_S:
-               case NUM_PR:
                    if (Np->type == TO_CHAR)
                    {
                        NUM_numpart_to_char(Np, n->key->id);
@@ -4163,6 +4136,8 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
                    {
                        if (Np->sign == '-')
                            *Np->inout_p = '-';
+                       else if (IS_FILLMODE(Np->Num))
+                           continue;
                        else
                            *Np->inout_p = ' ';
 
@@ -4179,6 +4154,8 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
                    {
                        if (Np->sign == '+')
                            *Np->inout_p = '+';
+                       else if (IS_FILLMODE(Np->Num))
+                           continue;
                        else
                            *Np->inout_p = ' ';
 
@@ -4262,6 +4239,7 @@ do { \
    if (len <= 0)                           \
        return DirectFunctionCall1(textin, CStringGetDatum(""));    \
    result  = (text *) palloc( (len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ); \
+   memset(result, 0,  (len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ ); \
    format  = NUM_cache(len, &Num, VARDATA(fmt), &shouldFree);      \
 } while (0)
 
index e05bdc89714ea6b276b2b23a8b38378a4d17690a..931889c4ad96595a6481987532799736fe40639f 100644 (file)
@@ -139,7 +139,7 @@ SELECT '' AS to_char_3, to_char( (q1 * -1), '9999999999999999PR'), to_char( (q2
            |              <123> | <4567890123456789.000>
            | <4567890123456789> |              <123.000>
            | <4567890123456789> | <4567890123456789.000>
-           | <4567890123456789> |  4567890123456789.000
+           | <4567890123456789> |  4567890123456789.000 
 (5 rows)
 
 SELECT '' AS to_char_4, to_char( (q1 * -1), '9999999999999999S'), to_char( (q2 * -1), 'S9999999999999999') 
@@ -154,12 +154,12 @@ SELECT '' AS to_char_4, to_char( (q1 * -1), '9999999999999999S'), to_char( (q2 *
 (5 rows)
 
 SELECT '' AS to_char_5,  to_char(q2, 'MI9999999999999999')     FROM INT8_TBL;  
- to_char_5 |      to_char       
------------+--------------------
-           |                456
-           |   4567890123456789
-           |                123
-           |   4567890123456789
+ to_char_5 |      to_char      
+-----------+-------------------
+           |               456
+           |  4567890123456789
+           |               123
+           |  4567890123456789
            | -4567890123456789
 (5 rows)
 
@@ -256,11 +256,11 @@ SELECT '' AS to_char_14, to_char(q2, 'FM9999999999999999.999') FROM INT8_TBL;
 SELECT '' AS to_char_15, to_char(q2, 'S 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9') FROM INT8_TBL;
  to_char_15 |                  to_char                  
 ------------+-------------------------------------------
-            |                           +4 5 6 . 0 0 0 
-            | 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
-            |                           +1 2 3 . 0 0 0 
-            | 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
-            | 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
+            |                            +4 5 6 . 0 0 0
+            |  +4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
+            |                            +1 2 3 . 0 0 0
+            |  +4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
+            |  -4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
 (5 rows)
 
 SELECT '' AS to_char_16, to_char(q2, '99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM INT8_TBL;
index 50730edcf8ff95ac8292c6cc69198b8bef3825b6..cdbef0da4c2b12e5a356115279de1415f6af7170 100644 (file)
@@ -732,15 +732,15 @@ SELECT '' AS to_char_3, to_char(val, '9999999999999999.999999999999999PR')
    FROM num_data;
  to_char_3 |              to_char               
 -----------+------------------------------------
-           |                  .000000000000000
-           |                  .000000000000000
+           |                  .000000000000000 
+           |                  .000000000000000 
            |         <34338492.215397047000000>
-           |                 4.310000000000000
-           |           7799461.411900000000000
-           |             16397.038491000000000
-           |             93901.577630260000000
+           |                 4.310000000000000 
+           |           7799461.411900000000000 
+           |             16397.038491000000000 
+           |             93901.577630260000000 
            |         <83028485.000000000000000>
-           |             74881.000000000000000
+           |             74881.000000000000000 
            |         <24926804.045047420000000>
 (10 rows)
 
@@ -761,17 +761,17 @@ SELECT '' AS to_char_4, to_char(val, '9999999999999999.999999999999999S')
 (10 rows)
 
 SELECT '' AS to_char_5,  to_char(val, 'MI9999999999999999.999999999999999')     FROM num_data; 
- to_char_5 |              to_char               
------------+------------------------------------
-           |                   .000000000000000
-           |                   .000000000000000
+ to_char_5 |              to_char              
+-----------+-----------------------------------
+           |                  .000000000000000
+           |                  .000000000000000
            | -        34338492.215397047000000
-           |                  4.310000000000000
-           |            7799461.411900000000000
-           |              16397.038491000000000
-           |              93901.577630260000000
+           |                 4.310000000000000
+           |           7799461.411900000000000
+           |             16397.038491000000000
+           |             93901.577630260000000
            | -        83028485.000000000000000
-           |              74881.000000000000000
+           |             74881.000000000000000
            | -        24926804.045047420000000
 (10 rows)
 
@@ -958,31 +958,31 @@ SELECT '' AS to_char_17, to_char(val, 'FM9999999999999999.99999999999999')    FROM
 SELECT '' AS to_char_18, to_char(val, 'S 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9') FROM num_data;
  to_char_18 |                                to_char                                
 ------------+-----------------------------------------------------------------------
-            |                                 . +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
-            |                                 . +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
-            |                 -3 4 3 3 8 4 9 2 . 2 1 5 3 9 7 0 4 7 0 0 0 0 0 0 0 0 
-            |                               +4 . 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
-            |                   +7 7 9 9 4 6 1 . 4 1 1 9 0 0 0 0 0 0 0 0 0 0 0 0 0 
-            |                       +1 6 3 9 7 . 0 3 8 4 9 1 0 0 0 0 0 0 0 0 0 0 0 
-            |                       +9 3 9 0 1 . 5 7 7 6 3 0 2 6 0 0 0 0 0 0 0 0 0 
-            |                 -8 3 0 2 8 4 8 5 . 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
-            |                       +7 4 8 8 1 . 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
-            |                 -2 4 9 2 6 8 0 4 . 0 4 5 0 4 7 4 2 0 0 0 0 0 0 0 0 0 
+            |                                  +. 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+            |                                  +. 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+            |                  -3 4 3 3 8 4 9 2 . 2 1 5 3 9 7 0 4 7 0 0 0 0 0 0 0 0
+            |                                +4 . 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+            |                    +7 7 9 9 4 6 1 . 4 1 1 9 0 0 0 0 0 0 0 0 0 0 0 0 0
+            |                        +1 6 3 9 7 . 0 3 8 4 9 1 0 0 0 0 0 0 0 0 0 0 0
+            |                        +9 3 9 0 1 . 5 7 7 6 3 0 2 6 0 0 0 0 0 0 0 0 0
+            |                  -8 3 0 2 8 4 8 5 . 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+            |                        +7 4 8 8 1 . 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+            |                  -2 4 9 2 6 8 0 4 . 0 4 5 0 4 7 4 2 0 0 0 0 0 0 0 0 0
 (10 rows)
 
 SELECT '' AS to_char_19, to_char(val, 'FMS 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9') FROM num_data;
  to_char_19 |                        to_char                        
 ------------+-------------------------------------------------------
-            | +               0 .                  
-            | +               0 .                  
-            | -        3 4 3 3 8 4 9 2 . 2 1 5 3 9 7 0 4 7         
-            | +               4 . 3 1                
-            | +         7 7 9 9 4 6 1 . 4 1 1 9              
-            | +           1 6 3 9 7 . 0 3 8 4 9 1            
-            | +           9 3 9 0 1 . 5 7 7 6 3 0 2 6          
-            | -        8 3 0 2 8 4 8 5 .                  
-            | +           7 4 8 8 1 .                  
-            | -        2 4 9 2 6 8 0 4 . 0 4 5 0 4 7 4 2          
+            |                 +0 .                 
+            |                 +0 .                 
+            |          -3 4 3 3 8 4 9 2 . 2 1 5 3 9 7 0 4 7        
+            |                 +4 . 3 1               
+            |           +7 7 9 9 4 6 1 . 4 1 1 9             
+            |             +1 6 3 9 7 . 0 3 8 4 9 1           
+            |             +9 3 9 0 1 . 5 7 7 6 3 0 2 6         
+            |          -8 3 0 2 8 4 8 5 .                 
+            |             +7 4 8 8 1 .                 
+            |          -2 4 9 2 6 8 0 4 . 0 4 5 0 4 7 4 2         
 (10 rows)
 
 SELECT '' AS to_char_20, to_char(val, '99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM num_data;