Commit a83c4b68 authored by svoj@april.(none)'s avatar svoj@april.(none)

Merge april.(none):/home/svoj/devel/mysql/merge/mysql-5.0

into  april.(none):/home/svoj/devel/mysql/merge/mysql-5.1-new
parents b2c810e8 a9e30921
...@@ -674,6 +674,18 @@ Warnings: ...@@ -674,6 +674,18 @@ Warnings:
Warning 1264 Out of range value for column 'Field1' at row 1 Warning 1264 Out of range value for column 'Field1' at row 1
DROP TABLE t1; DROP TABLE t1;
SET NAMES latin1; 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 ( CREATE TABLE t1 (
a varchar(255) NOT NULL default '', a varchar(255) NOT NULL default '',
KEY a (a) KEY a (a)
......
...@@ -409,6 +409,14 @@ INSERT INTO t1 VALUES ('-1'); ...@@ -409,6 +409,14 @@ INSERT INTO t1 VALUES ('-1');
DROP TABLE t1; DROP TABLE t1;
SET NAMES latin1; 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 # Bug#9557 MyISAM utf8 table crash
# #
......
...@@ -2255,7 +2255,7 @@ String *Item_char_typecast::val_str(String *str) ...@@ -2255,7 +2255,7 @@ String *Item_char_typecast::val_str(String *str)
// Convert character set if differ // Convert character set if differ
uint dummy_errors; uint dummy_errors;
if (!(res= args[0]->val_str(&tmp_value)) || if (!(res= args[0]->val_str(&tmp_value)) ||
str->copy(res->ptr(), res->length(), res->charset(), str->copy(res->ptr(), res->length(), from_cs,
cast_cs, &dummy_errors)) cast_cs, &dummy_errors))
{ {
null_value= 1; null_value= 1;
...@@ -2312,20 +2312,39 @@ void Item_char_typecast::fix_length_and_dec() ...@@ -2312,20 +2312,39 @@ void Item_char_typecast::fix_length_and_dec()
{ {
uint32 char_length; uint32 char_length;
/* /*
We always force character set conversion if cast_cs is a We always force character set conversion if cast_cs
multi-byte character set. It garantees that the result of CAST is is a multi-byte character set. It garantees that the
a well-formed string. For single-byte character sets we allow result of CAST is a well-formed string.
just to copy from the argument. A single-byte character sets For single-byte character sets we allow just to copy
string is always well-formed. 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.
*/ */
charset_conversion= ((cast_cs->mbmaxlen > 1) || from_cs= (args[0]->result_type() == INT_RESULT ||
!my_charset_same(args[0]->collation.collation, args[0]->result_type() == DECIMAL_RESULT ||
cast_cs) && args[0]->result_type() == REAL_RESULT) ?
args[0]->collation.collation != &my_charset_bin && (cast_cs->mbminlen == 1 ? cast_cs : &my_charset_latin1) :
cast_cs != &my_charset_bin); args[0]->collation.collation;
charset_conversion= (cast_cs->mbmaxlen > 1) ||
!my_charset_same(from_cs, cast_cs) &&
from_cs != &my_charset_bin &&
cast_cs != &my_charset_bin;
collation.set(cast_cs, DERIVATION_IMPLICIT); collation.set(cast_cs, DERIVATION_IMPLICIT);
char_length= (cast_length >= 0) ? cast_length : 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; max_length= char_length * cast_cs->mbmaxlen;
} }
......
...@@ -708,7 +708,7 @@ class Item_typecast_maybe_null :public Item_typecast ...@@ -708,7 +708,7 @@ class Item_typecast_maybe_null :public Item_typecast
class Item_char_typecast :public Item_typecast class Item_char_typecast :public Item_typecast
{ {
int cast_length; int cast_length;
CHARSET_INFO *cast_cs; CHARSET_INFO *cast_cs, *from_cs;
bool charset_conversion; bool charset_conversion;
String tmp_value; String tmp_value;
public: public:
......
...@@ -5931,7 +5931,7 @@ The minimum value for this variable is 4096.", ...@@ -5931,7 +5931,7 @@ The minimum value for this variable is 4096.",
(gptr*) &max_system_variables.max_length_for_sort_data, 0, GET_ULONG, (gptr*) &max_system_variables.max_length_for_sort_data, 0, GET_ULONG,
REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0}, REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
{"max_prepared_stmt_count", OPT_MAX_PREPARED_STMT_COUNT, {"max_prepared_stmt_count", OPT_MAX_PREPARED_STMT_COUNT,
"Maximum numbrer of prepared statements in the server.", "Maximum number of prepared statements in the server.",
(gptr*) &max_prepared_stmt_count, (gptr*) &max_prepared_stmt_count, (gptr*) &max_prepared_stmt_count, (gptr*) &max_prepared_stmt_count,
0, GET_ULONG, REQUIRED_ARG, 16382, 0, 1*1024*1024, 0, 1, 0}, 0, GET_ULONG, REQUIRED_ARG, 16382, 0, 1*1024*1024, 0, 1, 0},
{"max_relay_log_size", OPT_MAX_RELAY_LOG_SIZE, {"max_relay_log_size", OPT_MAX_RELAY_LOG_SIZE,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment