--- mysql-5.0.bk-orig/sql/sql_yacc.yy Thu Jun 7 10:53:14 2007 +++ mysql-5.0.bk-ucs/sql/sql_yacc.yy Thu Jun 7 11:57:09 2007 @@ -1043,7 +1043,7 @@ opt_constraint constraint ident_or_empty %type - text_string opt_gconcat_separator + text_string %type type int_type real_type order_dir lock_option @@ -1072,7 +1072,7 @@ expr_or_default set_expr_or_default interval_expr param_marker geometry_function signed_literal now_or_signed_literal opt_escape - sp_opt_default + sp_opt_default opt_gconcat_separator simple_ident_nospvar simple_ident_q field_or_var limit_option @@ -5420,8 +5420,8 @@ |DISTINCT { $$ = 1; }; opt_gconcat_separator: - /* empty */ { $$ = new (YYTHD->mem_root) String(",",1,default_charset_info); } - |SEPARATOR_SYM text_string { $$ = $2; }; + /* empty */ { $$ = NULL; } + |SEPARATOR_SYM text_literal { $$ = $2; }; opt_gorder_clause: --- mysql-5.0.bk-orig/sql/item_sum.h Thu Mar 22 21:48:00 2007 +++ mysql-5.0.bk-ucs/sql/item_sum.h Thu Jun 7 15:30:16 2007 @@ -1163,7 +1163,8 @@ TMP_TABLE_PARAM *tmp_table_param; MYSQL_ERROR *warning; String result; - String *separator; + Item *separator; + bool separator_is_default; TREE tree_base; TREE *tree; TABLE *table; @@ -1197,7 +1198,7 @@ public: Item_func_group_concat(Name_resolution_context *context_arg, bool is_distinct, List *is_select, - SQL_LIST *is_order, String *is_separator); + SQL_LIST *is_order, Item *is_separator); Item_func_group_concat(THD *thd, Item_func_group_concat *item); ~Item_func_group_concat() {} --- mysql-5.0.bk-orig/sql/item_sum.cc Wed Jun 6 14:10:50 2007 +++ mysql-5.0.bk-ucs/sql/item_sum.cc Thu Jun 7 15:54:05 2007 @@ -2934,7 +2934,11 @@ if (item->no_appended) item->no_appended= FALSE; else - result->append(*item->separator); + { + String *res; + res= item->separator->val_str(&tmp2); + result->append(*res); + } tmp.length(0); @@ -2998,7 +3002,7 @@ Item_func_group_concat:: Item_func_group_concat(Name_resolution_context *context_arg, bool distinct_arg, List *select_list, - SQL_LIST *order_list, String *separator_arg) + SQL_LIST *order_list, Item *separator_arg) :tmp_table_param(0), warning(0), separator(separator_arg), tree(0), table(0), order(0), context(context_arg), @@ -3012,17 +3016,26 @@ Item *item_select; Item **arg_ptr; + if (!separator_arg) + { + separator= new Item_string(",", 1, &my_charset_latin1); + separator_is_default= TRUE; + } + else + separator_is_default= FALSE; + quick_group= FALSE; - arg_count= arg_count_field + arg_count_order; + arg_count= arg_count_field + 1 + arg_count_order; /* We need to allocate: - args - arg_count_field+arg_count_order + args - arg_count_field+arg_count_order+the_seperator (for possible order items in temporare tables) order - arg_count_order */ if (!(args= (Item**) sql_alloc(sizeof(Item*) * arg_count + - sizeof(ORDER*)*arg_count_order))) + sizeof(ORDER*)*arg_count_order + + 1))) return; order= (ORDER**)(args + arg_count); @@ -3033,6 +3046,9 @@ for (arg_ptr=args ; (item_select= li++) ; arg_ptr++) *arg_ptr= item_select; + *arg_ptr= separator; + arg_ptr++; + if (arg_count_order) { ORDER **order_ptr= order; @@ -3200,10 +3216,24 @@ if (agg_item_charsets(collation, func_name(), args, /* skip charset aggregation for order columns */ - arg_count - arg_count_order, + arg_count - arg_count_order - + (separator_is_default ? 1 : 0), MY_COLL_ALLOW_CONV, 1)) return 1; + if (separator_is_default) + { + Item* conv; + if (conv= separator->safe_charset_converter(collation.collation)) + { + thd->change_item_tree(&separator, conv); + conv->fix_fields(thd, &separator); + } + else DBUG_ASSERT(FALSE); // default separator should always be convertable + } + else + separator= args[arg_count_field]; // fix the pointer on the this Item + result.set_charset(collation.collation); result_field= 0; null_value= 1; @@ -3366,6 +3396,8 @@ void Item_func_group_concat::print(String *str) { + String *res; + String tmp; str->append(STRING_WITH_LEN("group_concat(")); if (distinct) str->append(STRING_WITH_LEN("distinct ")); @@ -3390,6 +3422,7 @@ } } str->append(STRING_WITH_LEN(" separator \'")); - str->append(*separator); + res= separator->val_str(&tmp); + str->append(*res); str->append(STRING_WITH_LEN("\')")); } --- mysql-5.0.bk-orig/mysql-test/t/func_gconcat.test Wed Jun 6 14:10:49 2007 +++ mysql-5.0.bk-ucs/mysql-test/t/func_gconcat.test Thu Jun 7 15:50:04 2007 @@ -552,3 +552,26 @@ DROP TABLE t1, t2, t3; --echo End of 5.0 tests + +set names latin1; +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; + +select hex(group_concat('b' SEPARATOR _utf8 ',')) from t1; +select collation(group_concat('b' SEPARATOR _utf8 ',')) from t1; + +select hex(group_concat('b' SEPARATOR _ucs2 ',')) from t1; +select collation(group_concat('b' SEPARATOR _ucs2 ',')) 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; +drop table t1; + --- mysql-5.0.bk-orig/mysql-test/r/func_gconcat.result Wed Jun 6 14:10:49 2007 +++ mysql-5.0.bk-ucs/mysql-test/r/func_gconcat.result Thu Jun 7 15:50:12 2007 @@ -811,3 +811,33 @@ SET group_concat_max_len= DEFAULT; DROP TABLE t1, t2, t3; End of 5.0 tests +set names latin1; +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 +select hex(group_concat('b' SEPARATOR _utf8 ',')) from t1; +hex(group_concat('b' SEPARATOR _utf8 ',')) +622C622C62 +select collation(group_concat('b' SEPARATOR _utf8 ',')) from t1; +collation(group_concat('b' SEPARATOR _utf8 ',')) +utf8_general_ci +select hex(group_concat('b' SEPARATOR _ucs2 ',')) from t1; +hex(group_concat('b' SEPARATOR _ucs2 ',')) +0062002C0062002C0062 +select collation(group_concat('b' SEPARATOR _ucs2 ',')) from t1; +collation(group_concat('b' SEPARATOR _ucs2 ',')) +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 +drop table t1;