mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-12 18:34:36 +08:00
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
This commit is contained in:
parent
8000fdd462
commit
94701fb24b
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------
|
/* -----------------------------------------------------------------------
|
||||||
* formatting.c
|
* 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
|
* Portions Copyright (c) 1999-2002, PostgreSQL Global Development Group
|
||||||
@ -276,17 +276,19 @@ typedef struct
|
|||||||
* Flags for NUMBER version
|
* Flags for NUMBER version
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
#define NUM_F_DECIMAL 0x01
|
#define NUM_F_DECIMAL 1 << 1
|
||||||
#define NUM_F_LDECIMAL 0x02
|
#define NUM_F_LDECIMAL 1 << 2
|
||||||
#define NUM_F_ZERO 0x04
|
#define NUM_F_ZERO 1 << 3
|
||||||
#define NUM_F_BLANK 0x08
|
#define NUM_F_BLANK 1 << 4
|
||||||
#define NUM_F_FILLMODE 0x10
|
#define NUM_F_FILLMODE 1 << 5
|
||||||
#define NUM_F_LSIGN 0x20
|
#define NUM_F_LSIGN 1 << 6
|
||||||
#define NUM_F_BRACKET 0x40
|
#define NUM_F_BRACKET 1 << 7
|
||||||
#define NUM_F_MINUS 0x80
|
#define NUM_F_MINUS 1 << 8
|
||||||
#define NUM_F_PLUS 0x100
|
#define NUM_F_PLUS 1 << 9
|
||||||
#define NUM_F_ROMAN 0x200
|
#define NUM_F_ROMAN 1 << 10
|
||||||
#define NUM_F_MULTI 0x400
|
#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_PRE -1
|
||||||
#define NUM_LSIGN_POST 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.");
|
elog(ERROR, "to_char/to_number(): can't use 'S' and 'MI' together.");
|
||||||
}
|
}
|
||||||
num->flag |= NUM_F_MINUS;
|
num->flag |= NUM_F_MINUS;
|
||||||
|
if (IS_DECIMAL(num))
|
||||||
|
num->flag |= NUM_F_MINUS_POST;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NUM_PL:
|
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.");
|
elog(ERROR, "to_char/to_number(): can't use 'S' and 'PL' together.");
|
||||||
}
|
}
|
||||||
num->flag |= NUM_F_PLUS;
|
num->flag |= NUM_F_PLUS;
|
||||||
|
if (IS_DECIMAL(num))
|
||||||
|
num->flag |= NUM_F_PLUS_POST;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NUM_SG:
|
case NUM_SG:
|
||||||
@ -3880,28 +3886,36 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Np->sign = sign;
|
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 */
|
/* MI/PL/SG - write sign itself and not in number */
|
||||||
if (IS_PLUS(Np->Num) || IS_MINUS(Np->Num))
|
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))
|
if (IS_DECIMAL(Np->Num))
|
||||||
Np->last_relevant = get_last_relevant_decnum(
|
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) ?
|
||||||
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
|
* terrible Ora format
|
||||||
*/
|
*/
|
||||||
if (!IS_ZERO(Np->Num) && *Np->number == '0' &&
|
if (IS_ZERO(Np->Num)==FALSE && *Np->number == '0' &&
|
||||||
!IS_FILLMODE(Np->Num) && Np->Num->post != 0)
|
IS_FILLMODE(Np->Num)==FALSE && Np->Num->post)
|
||||||
{
|
{
|
||||||
|
|
||||||
++Np->sign_pos;
|
++Np->sign_pos;
|
||||||
|
|
||||||
if (IS_LSIGN(Np->Num))
|
if (IS_LSIGN(Np->Num))
|
||||||
{
|
{
|
||||||
if (Np->Num->lsign == NUM_LSIGN_PRE)
|
if (Np->Num->lsign != NUM_LSIGN_PRE)
|
||||||
++Np->sign_pos;
|
|
||||||
else
|
|
||||||
--Np->sign_pos;
|
--Np->sign_pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3975,8 +3987,8 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
|
|||||||
|
|
||||||
#ifdef DEBUG_TO_FROM_CHAR
|
#ifdef DEBUG_TO_FROM_CHAR
|
||||||
elog(DEBUG_elog_output,
|
elog(DEBUG_elog_output,
|
||||||
|
"\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",
|
||||||
"\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",
|
Np->sign,
|
||||||
Np->number,
|
Np->number,
|
||||||
Np->Num->pre,
|
Np->Num->pre,
|
||||||
Np->Num->post,
|
Np->Num->post,
|
||||||
@ -3987,8 +3999,11 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
|
|||||||
IS_ZERO(Np->Num) ? "Yes" : "No",
|
IS_ZERO(Np->Num) ? "Yes" : "No",
|
||||||
Np->Num->zero_start,
|
Np->Num->zero_start,
|
||||||
Np->Num->zero_end,
|
Np->Num->zero_end,
|
||||||
Np->last_relevant ? Np->last_relevant : "<not set>"
|
Np->last_relevant ? Np->last_relevant : "<not set>",
|
||||||
);
|
IS_BRACKET(Np->Num) ? "Yes" : "No",
|
||||||
|
IS_PLUS(Np->Num) ? "Yes" : "No",
|
||||||
|
IS_MINUS(Np->Num) ? "Yes" : "No"
|
||||||
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user