Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6e7a3c3

Browse files
committed
Fix corner case bug in numeric to_char().
Trailing-zero stripping applied by the FM specifier could strip zeroesto the left of the decimal point, for a format with no digit positionsafter the decimal point (such as "FM999.").Reported and diagnosed by Marti Raudsepp, though I didn't use his patch.
1 parentc3106a3 commit6e7a3c3

File tree

3 files changed

+42
-7
lines changed

3 files changed

+42
-7
lines changed

‎src/backend/utils/adt/formatting.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3673,6 +3673,9 @@ NUM_prepare_locale(NUMProc *Np)
36733673
/* ----------
36743674
* Return pointer of last relevant number after decimal point
36753675
*12.0500 --> last relevant is '5'
3676+
*12.0000 --> last relevant is '.'
3677+
* If there is no decimal point, return NULL (which will result in same
3678+
* behavior as if FM hadn't been specified).
36763679
* ----------
36773680
*/
36783681
staticchar*
@@ -3686,7 +3689,8 @@ get_last_relevant_decnum(char *num)
36863689
#endif
36873690

36883691
if (!p)
3689-
p=num;
3692+
returnNULL;
3693+
36903694
result=p;
36913695

36923696
while (*(++p))
@@ -4223,13 +4227,22 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
42234227
{
42244228
Np->num_pre=plen;
42254229

4226-
if (IS_FILLMODE(Np->Num))
4230+
if (IS_FILLMODE(Np->Num)&&IS_DECIMAL(Np->Num))
42274231
{
4228-
if (IS_DECIMAL(Np->Num))
4229-
Np->last_relevant=get_last_relevant_decnum(
4230-
Np->number+
4231-
((Np->Num->zero_end-Np->num_pre>0) ?
4232-
Np->Num->zero_end-Np->num_pre :0));
4232+
Np->last_relevant=get_last_relevant_decnum(Np->number);
4233+
4234+
/*
4235+
* If any '0' specifiers are present, make sure we don't strip
4236+
* those digits.
4237+
*/
4238+
if (Np->last_relevant&&Np->Num->zero_end>Np->num_pre)
4239+
{
4240+
char*last_zero;
4241+
4242+
last_zero=Np->number+ (Np->Num->zero_end-Np->num_pre);
4243+
if (Np->last_relevant<last_zero)
4244+
Np->last_relevant=last_zero;
4245+
}
42334246
}
42344247

42354248
if (Np->sign_wrote== FALSE&&Np->num_pre==0)

‎src/test/regress/expected/numeric.out

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,24 @@ SELECT '' AS to_char_23, to_char(val, '9.999EEEE')FROM num_data;
11541154
| -2.493e+07
11551155
(10 rows)
11561156

1157+
SELECT '' AS to_char_24, to_char('100'::numeric, 'FM999.9');
1158+
to_char_24 | to_char
1159+
------------+---------
1160+
| 100.
1161+
(1 row)
1162+
1163+
SELECT '' AS to_char_25, to_char('100'::numeric, 'FM999.');
1164+
to_char_25 | to_char
1165+
------------+---------
1166+
| 100
1167+
(1 row)
1168+
1169+
SELECT '' AS to_char_26, to_char('100'::numeric, 'FM999');
1170+
to_char_26 | to_char
1171+
------------+---------
1172+
| 100
1173+
(1 row)
1174+
11571175
-- TO_NUMBER()
11581176
--
11591177
SELECT '' AS to_number_1, to_number('-34,338,492', '99G999G999');

‎src/test/regress/sql/numeric.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,10 @@ SELECT '' AS to_char_21, to_char(val, '999999SG9999999999')FROM num_data;
764764
SELECT''AS to_char_22, to_char(val,'FM9999999999999999.999999999999999')FROM num_data;
765765
SELECT''AS to_char_23, to_char(val,'9.999EEEE')FROM num_data;
766766

767+
SELECT''AS to_char_24, to_char('100'::numeric,'FM999.9');
768+
SELECT''AS to_char_25, to_char('100'::numeric,'FM999.');
769+
SELECT''AS to_char_26, to_char('100'::numeric,'FM999');
770+
767771
-- TO_NUMBER()
768772
--
769773
SELECT''AS to_number_1, to_number('-34,338,492','99G999G999');

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp