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

Skip to content

Commit 98d8c75

Browse files
committed
Further fix for psql's code for locale-aware formatting of numeric output.
(Third time's the charm, I hope.) Additional testing disclosed that this code could mangle already-localized output from the "money" datatype. We can't very easily skip applying it to "money" values, because the logic is tied to column right-justification and people expect "money" output to be right-justified. Short of decoupling that, we can fix it in what should be a safe enough way by testing to make sure the string doesn't contain any characters that would not be expected in plain numeric output.
1 parent 71763ec commit 98d8c75

File tree

1 file changed

+23
-7
lines changed

1 file changed

+23
-7
lines changed

src/bin/psql/print.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -185,18 +185,34 @@ additional_numeric_locale_len(const char *my_str)
185185
}
186186

187187
/*
188+
* Format a numeric value per current LC_NUMERIC locale setting
189+
*
188190
* Returns the appropriately formatted string in a new allocated block,
189-
* caller must free
191+
* caller must free.
192+
*
193+
* setDecimalLocale() must have been called earlier.
190194
*/
191195
static char *
192196
format_numeric_locale(const char *my_str)
193197
{
194-
int new_len = strlen(my_str) + additional_numeric_locale_len(my_str);
195-
char *new_str = pg_local_malloc(new_len + 1);
196-
int int_len = integer_digits(my_str);
197-
int i,
198-
leading_digits;
199-
int new_str_pos = 0;
198+
char *new_str;
199+
int new_len,
200+
int_len,
201+
leading_digits,
202+
i,
203+
new_str_pos;
204+
205+
/*
206+
* If the string doesn't look like a number, return it unchanged. This
207+
* check is essential to avoid mangling already-localized "money" values.
208+
*/
209+
if (strspn(my_str, "0123456789+-.eE") != strlen(my_str))
210+
return pg_strdup(my_str);
211+
212+
new_len = strlen(my_str) + additional_numeric_locale_len(my_str);
213+
new_str = pg_local_malloc(new_len + 1);
214+
new_str_pos = 0;
215+
int_len = integer_digits(my_str);
200216

201217
/* number of digits in first thousands group */
202218
leading_digits = int_len % groupdigits;

0 commit comments

Comments
 (0)
0