From 46c3d7b87d27c1e2a2507b1faa7a1ee26d74715b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 22 Jun 2007 17:18:40 +0500 Subject: [PATCH] Bug#28925 GROUP_CONCAT inserts wrong separators for a ucs2 column Problem: separator was not converted to the result character set, so the result was a mixture of two different character sets, which was especially bad for UCS2. Fix: convert separator to the result character set. mysql-test/r/ctype_ucs.result: Adding test case mysql-test/r/ctype_ucs2_def.result: Adding test case mysql-test/t/ctype_ucs.test: Adding test case mysql-test/t/ctype_ucs2_def.test: Adding test case sql/item_sum.cc: Adding conversion of separator to the result character set sql/sql_yacc.yy: Fixing GROUPC_CONCAT problems when "mysqld --default-character-set=ucs2". --- mysql-test/r/ctype_ucs.result | 21 +++++++++++++++++++++ mysql-test/r/ctype_ucs2_def.result | 8 ++++++++ mysql-test/t/ctype_ucs.test | 18 ++++++++++++++++++ mysql-test/t/ctype_ucs2_def.test | 13 +++++++++++++ sql/item_sum.cc | 21 +++++++++++++++++++++ sql/sql_yacc.yy | 7 +++++-- 6 files changed, 86 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 960953b3c5e..0183a0c5c4b 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -865,4 +865,25 @@ blob 65535 65535 text 65535 65535 text 65535 32767 drop table t1; +create table t1 (a char(1) character set ucs2); +insert into t1 values ('a'),('b'),('c'); +select hex(group_concat(a)) from t1; +hex(group_concat(a)) +0061002C0062002C0063 +select collation(group_concat(a)) from t1; +collation(group_concat(a)) +ucs2_general_ci +drop table t1; +set names latin1; +create table t1 (a char(1) character set latin1); +insert into t1 values ('a'),('b'),('c'); +set character_set_connection=ucs2; +select hex(group_concat(a separator ',')) from t1; +hex(group_concat(a separator ',')) +612C622C63 +select collation(group_concat(a separator ',')) from t1; +collation(group_concat(a separator ',')) +latin1_swedish_ci +drop table t1; +set names latin1; End of 5.0 tests diff --git a/mysql-test/r/ctype_ucs2_def.result b/mysql-test/r/ctype_ucs2_def.result index 2f9dc4ae616..8a62970e528 100644 --- a/mysql-test/r/ctype_ucs2_def.result +++ b/mysql-test/r/ctype_ucs2_def.result @@ -7,3 +7,11 @@ character_set_server ucs2 DROP TABLE IF EXISTS t1; create table t1 (a int); drop table t1; +End of 4.1 tests +create table t1 (a char(1) character set latin1); +insert into t1 values ('a'),('b'),('c'); +select hex(group_concat(a)) from t1; +hex(group_concat(a)) +612C622C63 +drop table t1; +End of 5.0 tests diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index c3320159c41..8828cd10eec 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -594,4 +594,22 @@ select data_type, character_octet_length, character_maximum_length from information_schema.columns where table_name='t1'; drop table t1; +# +# Bug#28925 GROUP_CONCAT inserts wrong separators for a ucs2 column +# +create table t1 (a char(1) character set ucs2); +insert into t1 values ('a'),('b'),('c'); +select hex(group_concat(a)) from t1; +select collation(group_concat(a)) from t1; +drop table t1; + +set names latin1; +create table t1 (a char(1) character set latin1); +insert into t1 values ('a'),('b'),('c'); +set character_set_connection=ucs2; +select hex(group_concat(a separator ',')) from t1; +select collation(group_concat(a separator ',')) from t1; +drop table t1; +set names latin1; + --echo End of 5.0 tests diff --git a/mysql-test/t/ctype_ucs2_def.test b/mysql-test/t/ctype_ucs2_def.test index e435d1fb07d..60d6966584d 100644 --- a/mysql-test/t/ctype_ucs2_def.test +++ b/mysql-test/t/ctype_ucs2_def.test @@ -14,3 +14,16 @@ DROP TABLE IF EXISTS t1; --enable_warnings create table t1 (a int); drop table t1; + +--echo End of 4.1 tests + +# +# Bug #28925 GROUP_CONCAT inserts wrong separators for a ucs2 column +# Check that GROUP_CONCAT works fine with --default-character-set=ucs2 +# +create table t1 (a char(1) character set latin1); +insert into t1 values ('a'),('b'),('c'); +select hex(group_concat(a)) from t1; +drop table t1; + +--echo End of 5.0 tests diff --git a/sql/item_sum.cc b/sql/item_sum.cc index ea2a14ffb63..be1946b4677 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3209,6 +3209,27 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref) null_value= 1; max_length= thd->variables.group_concat_max_len; + uint32 offset; + if (separator->needs_conversion(separator->length(), separator->charset(), + collation.collation, &offset)) + { + uint32 buflen= collation.collation->mbmaxlen * separator->length(); + uint errors, conv_length; + char *buf; + String *new_separator; + + if (!(buf= thd->stmt_arena->alloc(buflen)) || + !(new_separator= new(thd->stmt_arena->mem_root) + String(buf, buflen, collation.collation))) + return TRUE; + + conv_length= copy_and_convert(buf, buflen, collation.collation, + separator->ptr(), separator->length(), + separator->charset(), &errors); + new_separator->length(conv_length); + separator= new_separator; + } + if (check_sum_func(thd, ref)) return TRUE; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 5ae2f6db581..f1657d2b1fa 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5420,8 +5420,11 @@ opt_distinct: |DISTINCT { $$ = 1; }; opt_gconcat_separator: - /* empty */ { $$ = new (YYTHD->mem_root) String(",",1,default_charset_info); } - |SEPARATOR_SYM text_string { $$ = $2; }; + /* empty */ + { + $$= new (YYTHD->mem_root) String(",", 1, &my_charset_latin1); + } + | SEPARATOR_SYM text_string { $$ = $2; }; opt_gorder_clause: