summaryrefslogtreecommitdiff
path: root/sql/item_sum.cc
diff options
context:
space:
mode:
authorunknown <bar@mysql.com/bar.intranet.mysql.r18.ru>2006-11-07 12:45:48 +0400
committerunknown <bar@mysql.com/bar.intranet.mysql.r18.ru>2006-11-07 12:45:48 +0400
commitd9360eae3b57c7ef4b1a14b270d06c8423df3bfb (patch)
tree7efe124c16c347e163ec9064f07a8ccfaae1341c /sql/item_sum.cc
parent2ab335a5b8bb3a25796824aa14325c777ce07a86 (diff)
downloadmariadb-git-d9360eae3b57c7ef4b1a14b270d06c8423df3bfb.tar.gz
Bug#23451 GROUP_CONCAT truncates a multibyte utf8 character
Problem: GROUP_CONCAT on a multi-byte column can truncate in the middle of a multibyte character when applying group_concat_max_len limit. It produces an invalid multi-byte character in the result string. The second, easier version - reusing old "warning_for_row" flag, instead of introducing of "result_is_full" - which was added in the previous commit. mysql-test/r/func_gconcat.result: Adding test case mysql-test/t/func_gconcat.test: Adding test case sql/item_sum.cc: Adding well_formed_len() call not to cut in the middle of a multi-byte character.
Diffstat (limited to 'sql/item_sum.cc')
-rw-r--r--sql/item_sum.cc20
1 files changed, 17 insertions, 3 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 0b9b10d05d4..4c346357240 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1664,6 +1664,7 @@ int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
{
char buff[MAX_FIELD_WIDTH];
String tmp((char *)&buff,sizeof(buff),default_charset_info), tmp2;
+ uint old_length= item->result.length();
if (item->no_appended)
item->no_appended= FALSE;
@@ -1702,8 +1703,22 @@ int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
/* stop if length of result more than group_concat_max_len */
if (item->result.length() > item->group_concat_max_len)
{
+ int well_formed_error;
+ CHARSET_INFO *cs= item->collation.collation;
+ const char *ptr= item->result.ptr();
+ uint add_length;
+ /*
+ It's ok to use item->result.length() as the fourth argument
+ as this is never used to limit the length of the data.
+ Cut is done with the third argument.
+ */
+ add_length= cs->cset->well_formed_len(cs,
+ ptr + old_length,
+ ptr + item->group_concat_max_len,
+ item->result.length(),
+ &well_formed_error);
+ item->result.length(old_length + add_length);
item->count_cut_values++;
- item->result.length(item->group_concat_max_len);
item->warning_for_row= TRUE;
return 1;
}
@@ -1893,8 +1908,7 @@ bool Item_func_group_concat::add()
we can dump the row here in case of GROUP_CONCAT(DISTINCT...)
instead of doing tree traverse later.
*/
- if (result.length() <= group_concat_max_len &&
- !warning_for_row &&
+ if (!warning_for_row &&
(!tree_mode || (el->count == 1 && distinct && !arg_count_order)))
dump_leaf_key(table->record[0], 1, this);