aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2015-09-25 12:20:45 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2015-09-25 12:20:45 -0400
commit5eb7024379ec0701ce2fae242ae90d7d56ee72bb (patch)
tree39d5746ca3dd4bb93b580bb16eb8a45156d7dc2e /src
parentda4af91cefaabe493577f1d6d17ee78f2e66389c (diff)
downloadpostgresql-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.c30
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;