to_char fixes, Karel Zak

This commit is contained in:
Bruce Momjian 2003-03-27 16:35:31 +00:00
parent bf576cc014
commit 7a3e7b64ac
4 changed files with 185 additions and 193 deletions

View File

@ -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
-->
@ -4365,7 +4365,7 @@ substring('foobar' from 'o(.)b') <lineannotation>o</lineannotation>
</row>
<row>
<entry><literal>to_char(-0.1, '99.99')</literal></entry>
<entry><literal>'&nbsp;-.10'</literal></entry>
<entry><literal>'&nbsp;&nbsp;-.10'</literal></entry>
</row>
<row>
<entry><literal>to_char(-0.1, 'FM9.99')</literal></entry>
@ -4381,7 +4381,7 @@ substring('foobar' from 'o(.)b') <lineannotation>o</lineannotation>
</row>
<row>
<entry><literal>to_char(12, 'FM9990999.9')</literal></entry>
<entry><literal>'0012'</literal></entry>
<entry><literal>'0012.'</literal></entry>
</row>
<row>
<entry><literal>to_char(485, '999')</literal></entry>
@ -4405,8 +4405,18 @@ substring('foobar' from 'o(.)b') <lineannotation>o</lineannotation>
</row>
<row>
<entry><literal>to_char(148.5, '999.999')</literal></entry>
<entry><literal>' 148.500'</literal></entry>
<entry><literal>'&nbsp;148.500'</literal></entry>
</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>
<entry><literal>to_char(148.5, '999D999')</literal></entry>
<entry><literal>'&nbsp;148,500'</literal></entry>
@ -4425,6 +4435,10 @@ substring('foobar' from 'o(.)b') <lineannotation>o</lineannotation>
</row>
<row>
<entry><literal>to_char(485, '999MI')</literal></entry>
<entry><literal>'485&nbsp;'</literal></entry>
</row>
<row>
<entry><literal>to_char(485, 'FM999MI')</literal></entry>
<entry><literal>'485'</literal></entry>
</row>
<row>

View 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 != '-')
{
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;
}
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))
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 : "<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
/*
@ -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)

View 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;

View 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;