Below is the list of changes that have just been committed into a local
4.1 repository of bar. When bar does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.2459 06/04/13 10:55:48 bar@stripped +4 -0
Bug#18691: Converting number to UNICODE string returns invalid result.
Conversion from int and real numbers to UCS2 didn't work fine:
CONVERT(100, CHAR(50) UNICODE)
CONVERT(103.9, CHAR(50) UNICODE)
The problem appeared because numbers have binary charset, so,
simple charset recast binary->ucs2 was performed
instead of real conversion.
Fixed to make numbers pretend to be non-binary.
sql/item_timefunc.h
1.56 06/04/13 10:55:41 bar@stripped +1 -1
Adding new member from_cs, to replace my_charset_bin
to a non-binary charset when converting from numbers to UCS2
sql/item_timefunc.cc
1.98 06/04/13 10:55:41 bar@stripped +23 -5
Adding new member from_cs, to replace my_charset_bin
to a non-binary charset when converting from numbers to UCS2
mysql-test/t/ctype_ucs.test
1.29 06/04/13 10:55:41 bar@stripped +8 -0
Adding test case
mysql-test/r/ctype_ucs.result
1.29 06/04/13 10:55:41 bar@stripped +12 -0
Adding test case
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: bar
# Host: bar.intranet.mysql.r18.ru
# Root: /usr/home/bar/mysql-4.1.b18691
--- 1.97/sql/item_timefunc.cc 2006-01-16 18:44:53 +04:00
+++ 1.98/sql/item_timefunc.cc 2006-04-13 10:55:41 +05:00
@@ -2221,8 +2221,8 @@ String *Item_char_typecast::val_str(Stri
// Convert character set if differ
uint dummy_errors;
if (!(res= args[0]->val_str(&tmp_value)) ||
- str->copy(res->ptr(), res->length(), res->charset(),
- cast_cs, &dummy_errors))
+ str->copy(res->ptr(), res->length(), from_cs,
+ cast_cs, &dummy_errors))
{
null_value= 1;
return 0;
@@ -2261,14 +2261,32 @@ void Item_char_typecast::fix_length_and_
For single-byte character sets we allow just to copy
from the argument. A single-byte character sets string
is always well-formed.
+
+ There is a special trick to convert form a number to ucs2.
+ As numbers have my_charset_bin as their character set,
+ it wouldn't do conversion to ucs2 without an additional action.
+ To force conversion, we should pretend to be non-binary.
+ Let's choose from_cs this way:
+ - If the argument in a number and cast_cs is ucs2 (i.e. mbminlen > 1),
+ then from_cs is set to latin1, to perform latin1 -> ucs2 conversion.
+ - If the argument is a number and cast_cs is ASCII-compatible
+ (i.e. mbminlen == 1), then from_cs is set to cast_cs,
+ which allows just to take over the args[0]->val_str() result
+ and thus avoid unnecessary character set conversion.
+ - If the argument is not a number, then from_cs is set to
+ the argument's charset.
*/
+ from_cs= (args[0]->result_type() == INT_RESULT ||
+ args[0]->result_type() == REAL_RESULT) ?
+ (cast_cs->mbminlen == 1 ? cast_cs : &my_charset_latin1) :
+ args[0]->collation.collation;
charset_conversion= (cast_cs->mbmaxlen > 1) ||
- !my_charset_same(args[0]->collation.collation, cast_cs)
&&
- args[0]->collation.collation != &my_charset_bin &&
+ !my_charset_same(from_cs, cast_cs) &&
+ from_cs != &my_charset_bin &&
cast_cs != &my_charset_bin;
collation.set(cast_cs, DERIVATION_IMPLICIT);
char_length= (cast_length >= 0) ? cast_length :
- args[0]->max_length/args[0]->collation.collation->mbmaxlen;
+ args[0]->max_length/from_cs->mbmaxlen;
max_length= char_length * cast_cs->mbmaxlen;
}
--- 1.55/sql/item_timefunc.h 2005-11-10 18:12:18 +04:00
+++ 1.56/sql/item_timefunc.h 2006-04-13 10:55:41 +05:00
@@ -681,7 +681,7 @@ public:
class Item_char_typecast :public Item_typecast
{
int cast_length;
- CHARSET_INFO *cast_cs;
+ CHARSET_INFO *cast_cs, *from_cs;
bool charset_conversion;
String tmp_value;
public:
--- 1.28/mysql-test/r/ctype_ucs.result 2006-01-17 02:02:57 +04:00
+++ 1.29/mysql-test/r/ctype_ucs.result 2006-04-13 10:55:41 +05:00
@@ -666,6 +666,18 @@ Warnings:
Warning 1265 Data truncated for column 'Field1' at row 1
DROP TABLE t1;
SET NAMES latin1;
+SELECT CONVERT(103, CHAR(50) UNICODE);
+CONVERT(103, CHAR(50) UNICODE)
+103
+SELECT CONVERT(103.0, CHAR(50) UNICODE);
+CONVERT(103.0, CHAR(50) UNICODE)
+103.0
+SELECT CONVERT(-103, CHAR(50) UNICODE);
+CONVERT(-103, CHAR(50) UNICODE)
+-103
+SELECT CONVERT(-103.0, CHAR(50) UNICODE);
+CONVERT(-103.0, CHAR(50) UNICODE)
+-103.0
CREATE TABLE t1 (
a varchar(255) NOT NULL default '',
KEY a (a)
--- 1.28/mysql-test/t/ctype_ucs.test 2006-01-24 16:54:30 +04:00
+++ 1.29/mysql-test/t/ctype_ucs.test 2006-04-13 10:55:41 +05:00
@@ -408,6 +408,14 @@ DROP TABLE t1;
SET NAMES latin1;
#
+# Bug#18691 Converting number to UNICODE string returns invalid result
+#
+SELECT CONVERT(103, CHAR(50) UNICODE);
+SELECT CONVERT(103.0, CHAR(50) UNICODE);
+SELECT CONVERT(-103, CHAR(50) UNICODE);
+SELECT CONVERT(-103.0, CHAR(50) UNICODE);
+
+#
# Bug#9557 MyISAM utf8 table crash
#
CREATE TABLE t1 (
| Thread |
|---|
| • bk commit into 4.1 tree (bar:1.2459) BUG#18691 | bar | 13 Apr |