diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2015-09-25 12:20:45 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2015-09-25 12:20:45 -0400 |
commit | 5eb7024379ec0701ce2fae242ae90d7d56ee72bb (patch) | |
tree | 39d5746ca3dd4bb93b580bb16eb8a45156d7dc2e /src | |
parent | da4af91cefaabe493577f1d6d17ee78f2e66389c (diff) | |
download | postgresql-5eb7024379ec0701ce2fae242ae90d7d56ee72bb.tar.gz postgresql-5eb7024379ec0701ce2fae242ae90d7d56ee72bb.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/psql/print.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c index 725ce8b34c4..74298cfe441 100644 --- a/src/bin/psql/print.c +++ b/src/bin/psql/print.c @@ -227,18 +227,34 @@ additional_numeric_locale_len(const char *my_str) } /* + * Format a numeric value per current LC_NUMERIC locale setting + * * Returns the appropriately formatted string in a new allocated block, - * caller must free + * caller must free. + * + * setDecimalLocale() must have been called earlier. */ static char * format_numeric_locale(const char *my_str) { - int new_len = strlen(my_str) + additional_numeric_locale_len(my_str); - char *new_str = pg_malloc(new_len + 1); - int int_len = integer_digits(my_str); - int i, - leading_digits; - int new_str_pos = 0; + char *new_str; + int new_len, + int_len, + leading_digits, + i, + new_str_pos; + + /* + * If the string doesn't look like a number, return it unchanged. This + * check is essential to avoid mangling already-localized "money" values. + */ + if (strspn(my_str, "0123456789+-.eE") != strlen(my_str)) + return pg_strdup(my_str); + + new_len = strlen(my_str) + additional_numeric_locale_len(my_str); + new_str = pg_malloc(new_len + 1); + new_str_pos = 0; + int_len = integer_digits(my_str); /* number of digits in first thousands group */ leading_digits = int_len % groupdigits; |