Peter found bug in the to_char() routine for PL/MI options. This
authorBruce Momjian
Thu, 20 Mar 2003 05:19:26 +0000 (05:19 +0000)
committerBruce Momjian
Thu, 20 Mar 2003 05:19:26 +0000 (05:19 +0000)
 patch fix it -- but this patch doesn't contains tests or docs fixes. I
 will send it later.

 Fixed outputs:

select  to_char(x, '9999.999')  as x,
        to_char(x, 'S9999.999') as s,
        to_char(x, 'SG9999.999') as sg,
        to_char(x, 'MI9999.999') as mi,
        to_char(x, 'PL9999.999') as pl,
        to_char(x, 'PLMI9999.999') as plmi,
        to_char(x, '9999.999SG') as sg2,
        to_char(x, '9999.999PL') as pl2,
        to_char(x, '9999.999MI') as mi2 from num;

Karel Zak

src/backend/utils/adt/formatting.c

index 6a5f0af138ea925473cb400b829055e08975af6c..89671b7f200b0abda355a2b62627bdfb78d23c5a 100644 (file)
@@ -1,7 +1,7 @@
 /* -----------------------------------------------------------------------
  * formatting.c
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.58 2003/03/10 22:28:18 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.59 2003/03/20 05:19:26 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
@@ -1052,6 +1054,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 +1065,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:
@@ -3880,28 +3886,36 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
    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;
+           Np->sign_pos = -1;
        }
-       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 */
+       {
+           if (Np->sign != '-')
+           {
+               if (IS_BRACKET(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;
 
-       Np->sign_pos = -1;
+           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 */
 
-       if (Np->Num->lsign == NUM_LSIGN_PRE && Np->Num->pre == Np->Num->pre_lsign_num)
-           Np->Num->lsign = NUM_LSIGN_POST;
+           Np->sign_pos = -1;
 
-       /* 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,7 +3931,7 @@ 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));
        }
@@ -3946,17 +3960,15 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
            /*
             * terrible Ora format
             */
-           if (!IS_ZERO(Np->Num) && *Np->number == '0' &&
-               !IS_FILLMODE(Np->Num) && Np->Num->post != 0)
+           if (IS_ZERO(Np->Num)==FALSE && *Np->number == '0' &&
+               IS_FILLMODE(Np->Num)==FALSE && Np->Num->post)
            {
 
                ++Np->sign_pos;
 
                if (IS_LSIGN(Np->Num))
                {
-                   if (Np->Num->lsign == NUM_LSIGN_PRE)
-                       ++Np->sign_pos;
-                   else
+                   if (Np->Num->lsign != NUM_LSIGN_PRE)
                        --Np->sign_pos;
                }
            }
@@ -3975,8 +3987,8 @@ 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_POS: %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",
+        Np->sign,
         Np->number,
         Np->Num->pre,
         Np->Num->post,
@@ -3987,8 +3999,11 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
         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"
+   );
 #endif
 
    /*