8000 Further fix for psql's code for locale-aware formatting of numeric ou… · yinrcode/postgres@71763ec · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit 71763ec

Browse files
committed
Further fix for psql's code for locale-aware formatting of numeric output.
On closer inspection, those seemingly redundant atoi() calls were not so much inefficient as just plain wrong: the author of this code either had not read, or had not understood, the POSIX specification for localeconv(). The grouping field is *not* a textual digit string but separate integers encoded as chars. We'll follow the existing code as well as the backend's cash.c in only honoring the first group width, but let's at least honor it correctly. This doesn't actually result in any behavioral change in any of the locales I have installed on my Linux box, which may explain why nobody's complained; grouping width 3 is close enough to universal that it's barely worth considering other cases. 10000 Still, wrong is wrong, so back-patch.
1 parent c2d6ef1 commit 71763ec

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

src/bin/psql/print.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2455,16 +2455,24 @@ setDecimalLocale(void)
24552455

24562456
extlconv = localeconv();
24572457

2458+
/* Don't accept an empty decimal_point string */
24582459
if (*extlconv->decimal_point)
24592460
decimal_point = pg_strdup(extlconv->decimal_point);
24602461
else
24612462
decimal_point = "."; /* SQL output standard */
24622463

2463-
if (*extlconv->grouping && atoi(extlconv->grouping) > 0)
2464-
groupdigits = atoi(extlconv->grouping);
2465-
else
2464+
/*
2465+
* Although the Open Group standard allows locales to supply more than one
2466+
* group width, we consider only the first one, and we ignore any attempt
2467+
* to suppress grouping by specifying CHAR_MAX. As in the backend's
2468+
* cash.c, we must apply a range check to avoid being fooled by variant
2469+
* CHAR_MAX values.
2470+
*/
2471+
groupdigits = *extlconv->grouping;
2472+
if (groupdigits <= 0 || groupdigits > 6)
24662473
groupdigits = 3; /* most common */
24672474

2475+
/* Don't accept an empty thousands_sep string, either */
24682476
/* similar code exists in formatting.c */
43D4
24692477
if (*extlconv->thousands_sep)
24702478
thousands_sep = pg_strdup(extlconv->thousands_sep);

0 commit comments

Comments
 (0)
0