Below is the list of changes that have just been committed into a local
5.0 repository of gluh. When gluh 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@stripped, 2007-10-10 19:55:01+05:00, gluh@stripped +9 -0
Bug#30981 CHAR(0x41 USING ucs2) doesn't add leading zero
Bug#30982 CHAR(..USING..) can return a not-well-formed string
Bug#30986 Character set introducer followed by a HEX string can return bad result
check_well_formed_result moved to Item
fixed Item_func_char::val_str for proper ucs symbols converting
added check for well formed strings for correct conversion of constants with underscore
carset
mysql-test/r/ctype_ucs.result@stripped, 2007-10-10 19:55:00+05:00, gluh@stripped +3 -0
test result
mysql-test/r/ctype_utf8.result@stripped, 2007-10-10 19:55:00+05:00, gluh@stripped +64 -2
test result
mysql-test/t/ctype_ucs.test@stripped, 2007-10-10 19:55:00+05:00, gluh@stripped +5 -0
test case
mysql-test/t/ctype_utf8.test@stripped, 2007-10-10 19:55:00+05:00, gluh@stripped +19 -0
test case
sql/item.cc@stripped, 2007-10-10 19:55:00+05:00, gluh@stripped +35 -0
check_well_formed_result() moved from Item_str_func
sql/item.h@stripped, 2007-10-10 19:55:00+05:00, gluh@stripped +1 -0
check_well_formed_result() moved from Item_str_func
sql/item_strfunc.cc@stripped, 2007-10-10 19:55:00+05:00, gluh@stripped +2 -32
check_well_formed_result moved to Item
fixed Item_func_char::val_str for proper ucs symbols converting
sql/item_strfunc.h@stripped, 2007-10-10 19:55:00+05:00, gluh@stripped +0 -1
check_well_formed_result moved to Item
sql/sql_yacc.yy@stripped, 2007-10-10 19:55:00+05:00, gluh@stripped +9 -3
added check for well formed string
diff -Nrup a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
--- a/mysql-test/r/ctype_ucs.result 2007-08-03 15:57:13 +05:00
+++ b/mysql-test/r/ctype_ucs.result 2007-10-10 19:55:00 +05:00
@@ -922,4 +922,7 @@ ERROR HY000: Illegal mix of collations (
select * from t1 where a=if(b<10,_ucs2 0x0062,_ucs2 0x00C0);
ERROR HY000: Illegal mix of collations (ascii_general_ci,IMPLICIT) and
(ucs2_general_ci,COERCIBLE) for operation '='
drop table t1;
+select hex(char(0x41 using ucs2));
+hex(char(0x41 using ucs2))
+0041
End of 5.0 tests
diff -Nrup a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
--- a/mysql-test/r/ctype_utf8.result 2007-08-03 15:28:37 +05:00
+++ b/mysql-test/r/ctype_utf8.result 2007-10-10 19:55:00 +05:00
@@ -1538,12 +1538,12 @@ char(53647 using utf8)
я
select char(0xff,0x8f using utf8);
char(0xff,0x8f using utf8)
-ÿ
+
Warnings:
Warning 1300 Invalid utf8 character string: 'FF8F'
select convert(char(0xff,0x8f) using utf8);
convert(char(0xff,0x8f) using utf8)
-ÿ
+
Warnings:
Warning 1300 Invalid utf8 character string: 'FF8F'
set sql_mode=traditional;
@@ -1730,3 +1730,65 @@ i
1
н1234567890
DROP TABLE t1, t2;
+set sql_mode=traditional;
+select hex(char(0xFF using utf8));
+hex(char(0xFF using utf8))
+NULL
+Warnings:
+Error 1300 Invalid utf8 character string: 'FF'
+select hex(convert(0xFF using utf8));
+hex(convert(0xFF using utf8))
+NULL
+Warnings:
+Error 1300 Invalid utf8 character string: 'FF'
+select hex(_utf8 0x616263FF);
+hex(_utf8 0x616263FF)
+NULL
+Warnings:
+Error 1300 Invalid utf8 character string: 'FF'
+select hex(_utf8 X'616263FF');
+hex(_utf8 X'616263FF')
+NULL
+Warnings:
+Error 1300 Invalid utf8 character string: 'FF'
+select hex(_utf8 B'001111111111');
+hex(_utf8 B'001111111111')
+NULL
+Warnings:
+Error 1300 Invalid utf8 character string: 'FF'
+select (_utf8 X'616263FF');
+NULL
+NULL
+Warnings:
+Error 1300 Invalid utf8 character string: 'FF'
+set sql_mode=default;
+select hex(char(0xFF using utf8));
+hex(char(0xFF using utf8))
+
+Warnings:
+Warning 1300 Invalid utf8 character string: 'FF'
+select hex(convert(0xFF using utf8));
+hex(convert(0xFF using utf8))
+
+Warnings:
+Warning 1300 Invalid utf8 character string: 'FF'
+select hex(_utf8 0x616263FF);
+hex(_utf8 0x616263FF)
+616263
+Warnings:
+Warning 1300 Invalid utf8 character string: 'FF'
+select hex(_utf8 X'616263FF');
+hex(_utf8 X'616263FF')
+616263
+Warnings:
+Warning 1300 Invalid utf8 character string: 'FF'
+select hex(_utf8 B'001111111111');
+hex(_utf8 B'001111111111')
+03
+Warnings:
+Warning 1300 Invalid utf8 character string: 'FF'
+select (_utf8 X'616263FF');
+abcÿ
+abc
+Warnings:
+Warning 1300 Invalid utf8 character string: 'FF'
diff -Nrup a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
--- a/mysql-test/t/ctype_ucs.test 2007-08-03 15:30:29 +05:00
+++ b/mysql-test/t/ctype_ucs.test 2007-10-10 19:55:00 +05:00
@@ -651,4 +651,9 @@ select * from t1 where a=if(b<10,_ucs2 0
select * from t1 where a=if(b<10,_ucs2 0x0062,_ucs2 0x00C0);
drop table t1;
+#
+# Bug#30981 CHAR(0x41 USING ucs2) doesn't add leading zero
+#
+select hex(char(0x41 using ucs2));
+
--echo End of 5.0 tests
diff -Nrup a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
--- a/mysql-test/t/ctype_utf8.test 2007-08-03 15:28:37 +05:00
+++ b/mysql-test/t/ctype_utf8.test 2007-10-10 19:55:00 +05:00
@@ -1403,3 +1403,22 @@ SELECT b FROM t2 UNION SELECT c FROM t1;
SELECT i FROM t2 UNION SELECT c FROM t1;
DROP TABLE t1, t2;
+
+#
+# Bug#30982: CHAR(..USING..) can return a not-well-formed string
+# Bug #30986: Character set introducer followed by a HEX string can return bad result
+#
+set sql_mode=traditional;
+select hex(char(0xFF using utf8));
+select hex(convert(0xFF using utf8));
+select hex(_utf8 0x616263FF);
+select hex(_utf8 X'616263FF');
+select hex(_utf8 B'001111111111');
+select (_utf8 X'616263FF');
+set sql_mode=default;
+select hex(char(0xFF using utf8));
+select hex(convert(0xFF using utf8));
+select hex(_utf8 0x616263FF);
+select hex(_utf8 X'616263FF');
+select hex(_utf8 B'001111111111');
+select (_utf8 X'616263FF');
diff -Nrup a/sql/item.cc b/sql/item.cc
--- a/sql/item.cc 2007-09-13 18:30:28 +05:00
+++ b/sql/item.cc 2007-10-10 19:55:00 +05:00
@@ -4247,6 +4247,41 @@ bool Item::is_datetime()
}
+String *Item::check_well_formed_result(String *str)
+{
+ /* Check whether we got a well-formed string */
+ CHARSET_INFO *cs= str->charset();
+ int well_formed_error;
+ uint wlen= cs->cset->well_formed_len(cs,
+ str->ptr(), str->ptr() + str->length(),
+ str->length(), &well_formed_error);
+ if (wlen < str->length())
+ {
+ THD *thd= current_thd;
+ char hexbuf[7];
+ enum MYSQL_ERROR::enum_warning_level level;
+ uint diff= str->length() - wlen;
+ set_if_smaller(diff, 3);
+ octet2hex(hexbuf, str->ptr() + wlen, diff);
+ if (thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))
+ {
+ level= MYSQL_ERROR::WARN_LEVEL_ERROR;
+ null_value= 1;
+ str= 0;
+ }
+ else
+ {
+ level= MYSQL_ERROR::WARN_LEVEL_WARN;
+ str->length(wlen);
+ }
+ push_warning_printf(thd, level, ER_INVALID_CHARACTER_STRING,
+ ER(ER_INVALID_CHARACTER_STRING), cs->csname, hexbuf);
+ }
+ return str;
+}
+
+
/*
Create a field to hold a string value from an item
diff -Nrup a/sql/item.h b/sql/item.h
--- a/sql/item.h 2007-08-03 21:59:12 +05:00
+++ b/sql/item.h 2007-10-10 19:55:00 +05:00
@@ -870,6 +870,7 @@ public:
*/
virtual bool result_as_longlong() { return FALSE; }
bool is_datetime();
+ String *check_well_formed_result(String *str);
};
diff -Nrup a/sql/item_strfunc.cc b/sql/item_strfunc.cc
--- a/sql/item_strfunc.cc 2007-08-03 15:28:38 +05:00
+++ b/sql/item_strfunc.cc 2007-10-10 19:55:00 +05:00
@@ -38,36 +38,6 @@ C_MODE_END
String my_empty_string("",default_charset_info);
-String *Item_str_func::check_well_formed_result(String *str)
-{
- /* Check whether we got a well-formed string */
- CHARSET_INFO *cs= str->charset();
- int well_formed_error;
- uint wlen= cs->cset->well_formed_len(cs,
- str->ptr(), str->ptr() + str->length(),
- str->length(), &well_formed_error);
- if (wlen < str->length())
- {
- THD *thd= current_thd;
- char hexbuf[7];
- enum MYSQL_ERROR::enum_warning_level level;
- uint diff= str->length() - wlen;
- set_if_smaller(diff, 3);
- octet2hex(hexbuf, str->ptr() + wlen, diff);
- if (thd->variables.sql_mode &
- (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))
- {
- level= MYSQL_ERROR::WARN_LEVEL_ERROR;
- null_value= 1;
- str= 0;
- }
- else
- level= MYSQL_ERROR::WARN_LEVEL_WARN;
- push_warning_printf(thd, level, ER_INVALID_CHARACTER_STRING,
- ER(ER_INVALID_CHARACTER_STRING), cs->csname, hexbuf);
- }
- return str;
-}
bool Item_str_func::fix_fields(THD *thd, Item **ref)
@@ -2229,6 +2199,7 @@ String *Item_func_char::val_str(String *
{
DBUG_ASSERT(fixed == 1);
str->length(0);
+ str->set_charset(collation.collation);
for (uint i=0 ; i < arg_count ; i++)
{
int32 num=(int32) args[i]->val_int();
@@ -2243,10 +2214,9 @@ String *Item_func_char::val_str(String *
} else if (num&0xFF00L) {
b1: str->append((char)(num>>8));
}
- str->append((char) num);
+ str->append((char*) &num, 1);
}
}
- str->set_charset(collation.collation);
str->realloc(str->length()); // Add end 0 (for Purify)
return check_well_formed_result(str);
}
diff -Nrup a/sql/item_strfunc.h b/sql/item_strfunc.h
--- a/sql/item_strfunc.h 2007-07-27 18:42:24 +05:00
+++ b/sql/item_strfunc.h 2007-10-10 19:55:00 +05:00
@@ -35,7 +35,6 @@ public:
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type () const { return STRING_RESULT; }
void left_right_max_length();
- String *check_well_formed_result(String *str);
bool fix_fields(THD *thd, Item **ref);
};
diff -Nrup a/sql/sql_yacc.yy b/sql/sql_yacc.yy
--- a/sql/sql_yacc.yy 2007-09-12 23:39:32 +05:00
+++ b/sql/sql_yacc.yy 2007-10-10 19:55:00 +05:00
@@ -7720,7 +7720,11 @@ literal:
str ? str->length() : 0,
Lex->underscore_charset);
if ($$)
+ {
((Item_string *) $$)->set_repertoire_from_value();
+ if (!$$->check_well_formed_result(&$$->str_value))
+ $$= new Item_null();
+ }
}
| UNDERSCORE_CHARSET BIN_NUM
{
@@ -7732,9 +7736,11 @@ literal:
String *str= tmp ?
tmp->quick_fix_field(), tmp->val_str((String*) 0) :
(String*) 0;
- $$= new Item_string(str ? str->ptr() : "",
- str ? str->length() : 0,
- Lex->charset);
+ $$= new Item_string(str ? str->ptr() : "",
+ str ? str->length() : 0,
+ Lex->underscore_charset);
+ if ($$ && !$$->check_well_formed_result(&$$->str_value))
+ $$= new Item_null();
}
| DATE_SYM text_literal { $$ = $2; }
| TIME_SYM text_literal { $$ = $2; }
| Thread |
|---|
| • bk commit into 5.0 tree (gluh:1.2536) BUG#30981 | gluh | 10 Oct |