to_char fixes, Karel Zak
This commit is contained in:
parent
bf576cc014
commit
7a3e7b64ac
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.148 2003/03/25 16:15:36 petere Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.149 2003/03/27 16:35:30 momjian Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -4365,7 +4365,7 @@ substring('foobar' from 'o(.)b') <lineannotation>o</lineannotation>
|
|||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>to_char(-0.1, '99.99')</literal></entry>
|
<entry><literal>to_char(-0.1, '99.99')</literal></entry>
|
||||||
<entry><literal>' -.10'</literal></entry>
|
<entry><literal>' -.10'</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>to_char(-0.1, 'FM9.99')</literal></entry>
|
<entry><literal>to_char(-0.1, 'FM9.99')</literal></entry>
|
||||||
@ -4381,7 +4381,7 @@ substring('foobar' from 'o(.)b') <lineannotation>o</lineannotation>
|
|||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>to_char(12, 'FM9990999.9')</literal></entry>
|
<entry><literal>to_char(12, 'FM9990999.9')</literal></entry>
|
||||||
<entry><literal>'0012'</literal></entry>
|
<entry><literal>'0012.'</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>to_char(485, '999')</literal></entry>
|
<entry><literal>to_char(485, '999')</literal></entry>
|
||||||
@ -4405,8 +4405,18 @@ substring('foobar' from 'o(.)b') <lineannotation>o</lineannotation>
|
|||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>to_char(148.5, '999.999')</literal></entry>
|
<entry><literal>to_char(148.5, '999.999')</literal></entry>
|
||||||
<entry><literal>' 148.500'</literal></entry>
|
<entry><literal>' 148.500'</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><literal>to_char(148.5, 'FM999.999')</literal></entry>
|
||||||
|
<entry><literal>'148.5'</literal></entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<row>
|
||||||
|
<entry><literal>to_char(148.5, 'FM999.990')</literal></entry>
|
||||||
|
<entry><literal>'148.500'</literal></entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>to_char(148.5, '999D999')</literal></entry>
|
<entry><literal>to_char(148.5, '999D999')</literal></entry>
|
||||||
<entry><literal>' 148,500'</literal></entry>
|
<entry><literal>' 148,500'</literal></entry>
|
||||||
@ -4425,6 +4435,10 @@ substring('foobar' from 'o(.)b') <lineannotation>o</lineannotation>
|
|||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>to_char(485, '999MI')</literal></entry>
|
<entry><literal>to_char(485, '999MI')</literal></entry>
|
||||||
|
<entry><literal>'485 '</literal></entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><literal>to_char(485, 'FM999MI')</literal></entry>
|
||||||
<entry><literal>'485'</literal></entry>
|
<entry><literal>'485'</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------
|
/* -----------------------------------------------------------------------
|
||||||
* formatting.c
|
* 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
|
* 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
|
||||||
@ -828,7 +830,6 @@ typedef struct NUMProc
|
|||||||
|
|
||||||
int sign, /* '-' or '+' */
|
int sign, /* '-' or '+' */
|
||||||
sign_wrote, /* was sign write */
|
sign_wrote, /* was sign write */
|
||||||
sign_pos, /* pre number sign position */
|
|
||||||
num_count, /* number of write digits */
|
num_count, /* number of write digits */
|
||||||
num_in, /* is inside number */
|
num_in, /* is inside number */
|
||||||
num_curr, /* current position in 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.");
|
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 +1064,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:
|
||||||
@ -3556,7 +3561,7 @@ NUM_numpart_from_char(NUMProc *Np, int id, int plen)
|
|||||||
* simple + - < >
|
* simple + - < >
|
||||||
*/
|
*/
|
||||||
if (*Np->inout_p == '-' || (IS_BRACKET(Np->Num) &&
|
if (*Np->inout_p == '-' || (IS_BRACKET(Np->Num) &&
|
||||||
*Np->inout_p == '<'))
|
*Np->inout_p == '<'))
|
||||||
{
|
{
|
||||||
|
|
||||||
*Np->number = '-'; /* set - */
|
*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
|
* Add digit or sign to number-string
|
||||||
* ----------
|
* ----------
|
||||||
@ -3658,67 +3669,54 @@ NUM_numpart_to_char(NUMProc *Np, int id)
|
|||||||
Np->num_in = FALSE;
|
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)
|
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 == '.')))
|
||||||
#ifdef DEBUG_TO_FROM_CHAR
|
{
|
||||||
elog(DEBUG_elog_output, "Writing sign to position: %d", Np->num_curr);
|
|
||||||
#endif
|
|
||||||
if (IS_LSIGN(Np->Num))
|
if (IS_LSIGN(Np->Num))
|
||||||
{
|
{
|
||||||
/*
|
if (Np->Num->lsign == NUM_LSIGN_PRE)
|
||||||
* Write locale SIGN
|
{
|
||||||
*/
|
if (Np->sign == '-')
|
||||||
if (Np->sign == '-')
|
strcpy(Np->inout_p, Np->L_negative_sign);
|
||||||
strcpy(Np->inout_p, Np->L_negative_sign);
|
else
|
||||||
else
|
strcpy(Np->inout_p, Np->L_positive_sign);
|
||||||
strcpy(Np->inout_p, Np->L_positive_sign);
|
Np->inout_p += strlen(Np->inout_p);
|
||||||
Np->inout_p += strlen(Np->inout_p);
|
Np->sign_wrote = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (IS_BRACKET(Np->Num))
|
else if (IS_BRACKET(Np->Num))
|
||||||
{
|
{
|
||||||
*Np->inout_p = '<'; /* Write < */
|
*Np->inout_p = Np->sign == '+' ? ' ' : '<';
|
||||||
++Np->inout_p;
|
++Np->inout_p;
|
||||||
|
Np->sign_wrote = TRUE;
|
||||||
}
|
}
|
||||||
else if (Np->sign == '+')
|
else if (Np->sign == '+')
|
||||||
{
|
{
|
||||||
*Np->inout_p = ' '; /* Write + */
|
if (!IS_FILLMODE(Np->Num))
|
||||||
++Np->inout_p;
|
{
|
||||||
|
*Np->inout_p = ' '; /* Write + */
|
||||||
|
++Np->inout_p;
|
||||||
|
}
|
||||||
|
Np->sign_wrote = TRUE;
|
||||||
}
|
}
|
||||||
else if (Np->sign == '-')
|
else if (Np->sign == '-')
|
||||||
{ /* Write - */
|
{ /* Write - */
|
||||||
*Np->inout_p = '-';
|
*Np->inout_p = '-';
|
||||||
++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
|
* digits / FM / Zero / Dec. point
|
||||||
*/
|
*/
|
||||||
if (id == NUM_9 || id == NUM_0 || id == NUM_D || id == NUM_DEC ||
|
if (id == NUM_9 || id == NUM_0 || id == NUM_D || id == NUM_DEC)
|
||||||
(id == NUM_S && Np->num_curr < Np->num_pre))
|
|
||||||
{
|
{
|
||||||
|
|
||||||
if (Np->num_curr < Np->num_pre &&
|
if (Np->num_curr < Np->num_pre &&
|
||||||
(Np->Num->zero_start > Np->num_curr || !IS_ZERO(Np->Num)))
|
(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))
|
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 = ' '; /* Write ' ' */
|
||||||
++Np->inout_p;
|
++Np->inout_p;
|
||||||
}
|
}
|
||||||
@ -3742,9 +3737,6 @@ NUM_numpart_to_char(NUMProc *Np, int id)
|
|||||||
/*
|
/*
|
||||||
* Write ZERO
|
* 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 = '0'; /* Write '0' */
|
||||||
++Np->inout_p;
|
++Np->inout_p;
|
||||||
Np->num_in = TRUE;
|
Np->num_in = TRUE;
|
||||||
@ -3760,12 +3752,8 @@ NUM_numpart_to_char(NUMProc *Np, int id)
|
|||||||
|
|
||||||
if (!Np->last_relevant || *Np->last_relevant != '.')
|
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 */
|
strcpy(Np->inout_p, Np->decimal); /* Write DEC/D */
|
||||||
Np->inout_p += strlen(Np->inout_p);
|
Np->inout_p += strlen(Np->inout_p);
|
||||||
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Ora 'n' -- FM9.9 --> 'n.'
|
* Ora 'n' -- FM9.9 --> 'n.'
|
||||||
@ -3788,10 +3776,9 @@ NUM_numpart_to_char(NUMProc *Np, int id)
|
|||||||
id != NUM_0)
|
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' &&
|
else if (IS_PREDEC_SPACE(Np))
|
||||||
Np->number == Np->number_p && Np->Num->post != 0)
|
|
||||||
{
|
{
|
||||||
if (!IS_FILLMODE(Np->Num))
|
if (!IS_FILLMODE(Np->Num))
|
||||||
{
|
{
|
||||||
@ -3799,7 +3786,7 @@ NUM_numpart_to_char(NUMProc *Np, int id)
|
|||||||
++Np->inout_p;
|
++Np->inout_p;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* total terrible Ora: '0' -- FM9.9 --> '0.'
|
* '0' -- FM9.9 --> '0.'
|
||||||
*/
|
*/
|
||||||
else if (Np->last_relevant && *Np->last_relevant == '.')
|
else if (Np->last_relevant && *Np->last_relevant == '.')
|
||||||
{
|
{
|
||||||
@ -3809,10 +3796,6 @@ NUM_numpart_to_char(NUMProc *Np, int id)
|
|||||||
}
|
}
|
||||||
else
|
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->number_p; /* Write DIGIT */
|
||||||
++Np->inout_p;
|
++Np->inout_p;
|
||||||
Np->num_in = TRUE;
|
Np->num_in = TRUE;
|
||||||
@ -3820,6 +3803,28 @@ NUM_numpart_to_char(NUMProc *Np, int id)
|
|||||||
}
|
}
|
||||||
++Np->number_p;
|
++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;
|
++Np->num_curr;
|
||||||
@ -3847,7 +3852,7 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
|
|||||||
|
|
||||||
if (Np->Num->zero_start)
|
if (Np->Num->zero_start)
|
||||||
--Np->Num->zero_start;
|
--Np->Num->zero_start;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Roman correction
|
* Roman correction
|
||||||
*/
|
*/
|
||||||
@ -3875,33 +3880,37 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
|
|||||||
if (type == FROM_CHAR)
|
if (type == FROM_CHAR)
|
||||||
{
|
{
|
||||||
Np->sign = FALSE;
|
Np->sign = FALSE;
|
||||||
Np->sign_pos = -1;
|
|
||||||
}
|
}
|
||||||
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;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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->sign == '+' && IS_FILLMODE(Np->Num) && IS_LSIGN(Np->Num)==FALSE)
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3917,51 +3926,13 @@ 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Np->sign_wrote && Np->num_pre == 0)
|
if (Np->sign_wrote==FALSE && Np->num_pre == 0)
|
||||||
++Np->num_count;
|
++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
|
else
|
||||||
{
|
{
|
||||||
@ -3975,20 +3946,24 @@ 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_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",
|
||||||
"\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,
|
||||||
Np->num_count,
|
Np->num_count,
|
||||||
Np->num_pre,
|
Np->num_pre,
|
||||||
Np->sign_pos,
|
|
||||||
Np->sign_wrote ? "Yes" : "No",
|
Np->sign_wrote ? "Yes" : "No",
|
||||||
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",
|
||||||
|
IS_FILLMODE(Np->Num) ? "Yes" : "No",
|
||||||
|
IS_ROMAN(Np->Num) ? "Yes" : "No"
|
||||||
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4031,8 +4006,6 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
|
|||||||
case NUM_0:
|
case NUM_0:
|
||||||
case NUM_DEC:
|
case NUM_DEC:
|
||||||
case NUM_D:
|
case NUM_D:
|
||||||
case NUM_S:
|
|
||||||
case NUM_PR:
|
|
||||||
if (Np->type == TO_CHAR)
|
if (Np->type == TO_CHAR)
|
||||||
{
|
{
|
||||||
NUM_numpart_to_char(Np, n->key->id);
|
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 == '-')
|
if (Np->sign == '-')
|
||||||
*Np->inout_p = '-';
|
*Np->inout_p = '-';
|
||||||
|
else if (IS_FILLMODE(Np->Num))
|
||||||
|
continue;
|
||||||
else
|
else
|
||||||
*Np->inout_p = ' ';
|
*Np->inout_p = ' ';
|
||||||
|
|
||||||
@ -4179,6 +4154,8 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
|
|||||||
{
|
{
|
||||||
if (Np->sign == '+')
|
if (Np->sign == '+')
|
||||||
*Np->inout_p = '+';
|
*Np->inout_p = '+';
|
||||||
|
else if (IS_FILLMODE(Np->Num))
|
||||||
|
continue;
|
||||||
else
|
else
|
||||||
*Np->inout_p = ' ';
|
*Np->inout_p = ' ';
|
||||||
|
|
||||||
@ -4262,6 +4239,7 @@ do { \
|
|||||||
if (len <= 0) \
|
if (len <= 0) \
|
||||||
return DirectFunctionCall1(textin, CStringGetDatum("")); \
|
return DirectFunctionCall1(textin, CStringGetDatum("")); \
|
||||||
result = (text *) palloc( (len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ); \
|
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); \
|
format = NUM_cache(len, &Num, VARDATA(fmt), &shouldFree); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ SELECT '' AS to_char_3, to_char( (q1 * -1), '9999999999999999PR'), to_char( (q2
|
|||||||
| <123> | <4567890123456789.000>
|
| <123> | <4567890123456789.000>
|
||||||
| <4567890123456789> | <123.000>
|
| <4567890123456789> | <123.000>
|
||||||
| <4567890123456789> | <4567890123456789.000>
|
| <4567890123456789> | <4567890123456789.000>
|
||||||
| <4567890123456789> | 4567890123456789.000
|
| <4567890123456789> | 4567890123456789.000
|
||||||
(5 rows)
|
(5 rows)
|
||||||
|
|
||||||
SELECT '' AS to_char_4, to_char( (q1 * -1), '9999999999999999S'), to_char( (q2 * -1), 'S9999999999999999')
|
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)
|
(5 rows)
|
||||||
|
|
||||||
SELECT '' AS to_char_5, to_char(q2, 'MI9999999999999999') FROM INT8_TBL;
|
SELECT '' AS to_char_5, to_char(q2, 'MI9999999999999999') FROM INT8_TBL;
|
||||||
to_char_5 | to_char
|
to_char_5 | to_char
|
||||||
-----------+--------------------
|
-----------+-------------------
|
||||||
| 456
|
| 456
|
||||||
| 4567890123456789
|
| 4567890123456789
|
||||||
| 123
|
| 123
|
||||||
| 4567890123456789
|
| 4567890123456789
|
||||||
| -4567890123456789
|
| -4567890123456789
|
||||||
(5 rows)
|
(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;
|
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
|
to_char_15 | to_char
|
||||||
------------+-------------------------------------------
|
------------+-------------------------------------------
|
||||||
| +4 5 6 . 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
|
| +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
|
| +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 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)
|
(5 rows)
|
||||||
|
|
||||||
SELECT '' AS to_char_16, to_char(q2, '99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM INT8_TBL;
|
SELECT '' AS to_char_16, to_char(q2, '99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM INT8_TBL;
|
||||||
|
@ -732,15 +732,15 @@ SELECT '' AS to_char_3, to_char(val, '9999999999999999.999999999999999PR')
|
|||||||
FROM num_data;
|
FROM num_data;
|
||||||
to_char_3 | to_char
|
to_char_3 | to_char
|
||||||
-----------+------------------------------------
|
-----------+------------------------------------
|
||||||
| .000000000000000
|
| .000000000000000
|
||||||
| .000000000000000
|
| .000000000000000
|
||||||
| <34338492.215397047000000>
|
| <34338492.215397047000000>
|
||||||
| 4.310000000000000
|
| 4.310000000000000
|
||||||
| 7799461.411900000000000
|
| 7799461.411900000000000
|
||||||
| 16397.038491000000000
|
| 16397.038491000000000
|
||||||
| 93901.577630260000000
|
| 93901.577630260000000
|
||||||
| <83028485.000000000000000>
|
| <83028485.000000000000000>
|
||||||
| 74881.000000000000000
|
| 74881.000000000000000
|
||||||
| <24926804.045047420000000>
|
| <24926804.045047420000000>
|
||||||
(10 rows)
|
(10 rows)
|
||||||
|
|
||||||
@ -761,17 +761,17 @@ SELECT '' AS to_char_4, to_char(val, '9999999999999999.999999999999999S')
|
|||||||
(10 rows)
|
(10 rows)
|
||||||
|
|
||||||
SELECT '' AS to_char_5, to_char(val, 'MI9999999999999999.999999999999999') FROM num_data;
|
SELECT '' AS to_char_5, to_char(val, 'MI9999999999999999.999999999999999') FROM num_data;
|
||||||
to_char_5 | to_char
|
to_char_5 | to_char
|
||||||
-----------+------------------------------------
|
-----------+-----------------------------------
|
||||||
| .000000000000000
|
| .000000000000000
|
||||||
| .000000000000000
|
| .000000000000000
|
||||||
| - 34338492.215397047000000
|
| - 34338492.215397047000000
|
||||||
| 4.310000000000000
|
| 4.310000000000000
|
||||||
| 7799461.411900000000000
|
| 7799461.411900000000000
|
||||||
| 16397.038491000000000
|
| 16397.038491000000000
|
||||||
| 93901.577630260000000
|
| 93901.577630260000000
|
||||||
| - 83028485.000000000000000
|
| - 83028485.000000000000000
|
||||||
| 74881.000000000000000
|
| 74881.000000000000000
|
||||||
| - 24926804.045047420000000
|
| - 24926804.045047420000000
|
||||||
(10 rows)
|
(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;
|
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
|
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
|
||||||
| . +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
|
| -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
|
| +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
|
| +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
|
| +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
|
| +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
|
| -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
|
| +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
|
| -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)
|
(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;
|
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
|
to_char_19 | to_char
|
||||||
------------+-------------------------------------------------------
|
------------+-------------------------------------------------------
|
||||||
| + 0 .
|
| +0 .
|
||||||
| + 0 .
|
| +0 .
|
||||||
| - 3 4 3 3 8 4 9 2 . 2 1 5 3 9 7 0 4 7
|
| -3 4 3 3 8 4 9 2 . 2 1 5 3 9 7 0 4 7
|
||||||
| + 4 . 3 1
|
| +4 . 3 1
|
||||||
| + 7 7 9 9 4 6 1 . 4 1 1 9
|
| +7 7 9 9 4 6 1 . 4 1 1 9
|
||||||
| + 1 6 3 9 7 . 0 3 8 4 9 1
|
| +1 6 3 9 7 . 0 3 8 4 9 1
|
||||||
| + 9 3 9 0 1 . 5 7 7 6 3 0 2 6
|
| +9 3 9 0 1 . 5 7 7 6 3 0 2 6
|
||||||
| - 8 3 0 2 8 4 8 5 .
|
| -8 3 0 2 8 4 8 5 .
|
||||||
| + 7 4 8 8 1 .
|
| +7 4 8 8 1 .
|
||||||
| - 2 4 9 2 6 8 0 4 . 0 4 5 0 4 7 4 2
|
| -2 4 9 2 6 8 0 4 . 0 4 5 0 4 7 4 2
|
||||||
(10 rows)
|
(10 rows)
|
||||||
|
|
||||||
SELECT '' AS to_char_20, to_char(val, '99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM num_data;
|
SELECT '' AS to_char_20, to_char(val, '99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM num_data;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user