diff options
author | Alexander Barkov <bar@mysql.com> | 2010-08-20 15:14:11 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mysql.com> | 2010-08-20 15:14:11 +0400 |
commit | 84ee0a9fa40f13eaeec66ce2c9d3b8dcf2b9c67d (patch) | |
tree | 898cfdb055d0628299db2ec24858e41d693242ee /sql/item_strfunc.cc | |
parent | 02863b41804352f1371407ccdc9e1cb51b9e20e3 (diff) | |
download | mariadb-git-84ee0a9fa40f13eaeec66ce2c9d3b8dcf2b9c67d.tar.gz |
Bug#55912 FORMAT with locale set fails for numbers < 1000
Problems:
- dot character was always printed as decimal point
instead of localized decimal point for short
numbers without thousands
- Item_func_format::val_str always returned values in ASCII
format,
regargless of @@character_set_connection, which in case of utf32
led to crash in debug build, or to incorrect values in release build.
Fix:
- Adding a piece of code to replace dot character to
localized decimal point in short numbers.
- Changing parent class for Item_func_format to
Item_str_ascii_func, because its val_str() implementation is heavily ASCII oriented.
Diffstat (limited to 'sql/item_strfunc.cc')
-rw-r--r-- | sql/item_strfunc.cc | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 1a772950303..6d3514bf356 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2217,7 +2217,7 @@ const int FORMAT_MAX_DECIMALS= 30; MY_LOCALE *Item_func_format::get_locale(Item *item) { DBUG_ASSERT(arg_count == 3); - String tmp, *locale_name= args[2]->val_str(&tmp); + String tmp, *locale_name= args[2]->val_str_ascii(&tmp); MY_LOCALE *lc; if (!locale_name || !(lc= my_locale_by_name(locale_name->c_ptr_safe()))) @@ -2250,7 +2250,7 @@ void Item_func_format::fix_length_and_dec() are stored in more than one byte */ -String *Item_func_format::val_str(String *str) +String *Item_func_format::val_str_ascii(String *str) { uint32 str_length; /* Number of decimal digits */ @@ -2290,8 +2290,7 @@ String *Item_func_format::val_str(String *str) if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ nr= my_double_round(nr, (longlong) dec, FALSE, FALSE); - /* Here default_charset() is right as this is not an automatic conversion */ - str->set_real(nr, dec, default_charset()); + str->set_real(nr, dec, &my_charset_numeric); if (isnan(nr)) return str; str_length=str->length(); @@ -2341,6 +2340,14 @@ String *Item_func_format::val_str(String *str) /* Put the rest of the integer part without grouping */ str->copy(dst, buf + sizeof(buf) - dst, &my_charset_latin1); } + else if (dec_length && lc->decimal_point != '.') + { + /* + For short values without thousands (<1000) + replace decimal point to localized value. + */ + ((char*) str->ptr())[str_length - dec_length]= lc->decimal_point; + } return str; } |