From 94701fb24b4397a4fc1a8441980ed499a8cc991c Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Thu, 20 Mar 2003 05:19:26 +0000 Subject: [PATCH] Peter found bug in the to_char() routine for PL/MI options. This 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 | 99 +++++++++++++++++------------- 1 file changed, 57 insertions(+), 42 deletions(-) diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c index 6a5f0af138..89671b7f20 100644 --- a/src/backend/utils/adt/formatting.c +++ b/src/backend/utils/adt/formatting.c @@ -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 != '-') - { - Np->Num->flag &= ~NUM_F_BRACKET; - Np->Num->flag &= ~NUM_F_MINUS; - } - 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->Num->lsign == NUM_LSIGN_PRE && Np->Num->pre == Np->Num->pre_lsign_num) - Np->Num->lsign = NUM_LSIGN_POST; - + /* 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 (IS_PLUS(Np->Num) && IS_MINUS(Np->Num)==FALSE) + Np->sign_wrote = FALSE; + Np->sign_pos = -1; + } + else + { + 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; + + 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->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 /*