diff options
author | Sergey Glukhov <sergey.glukhov@oracle.com> | 2011-10-12 17:41:25 +0400 |
---|---|---|
committer | Sergey Glukhov <sergey.glukhov@oracle.com> | 2011-10-12 17:41:25 +0400 |
commit | b195e6f9433d7d293faadd834af6edee79133278 (patch) | |
tree | 63ffa1d7dfd4b57de72d08e5439fdf0770a3ed84 /sql/item_sum.cc | |
parent | 9de021c753566259c0e0b2923c6b149a2d1e8734 (diff) | |
download | mariadb-git-b195e6f9433d7d293faadd834af6edee79133278.tar.gz |
Bug#11750518 41090: ORDER BY TRUNCATES GROUP_CONCAT RESULT
When temporary tables is used for result sorting
result field for gconcat function is created using
group_concat_max_len size. It leads to result truncation
when character_set_results is multi-byte character set due
to insufficient tmp table field size.
The fix is to increase temporary table field size for
gconcat. Method make_string_field() is overloaded
for Item_func_group_concat class and uses
max_characters * collation.collation->mbmaxlen size for
result field. max_characters is maximum number of characters
what can fit into max_length size.
Diffstat (limited to 'sql/item_sum.cc')
-rw-r--r-- | sql/item_sum.cc | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 161c8c8eacf..d9e634f8c16 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3128,6 +3128,31 @@ void Item_func_group_concat::cleanup() } +Field *Item_func_group_concat::make_string_field(TABLE *table) +{ + Field *field; + DBUG_ASSERT(collation.collation); + /* + max_characters is maximum number of characters + what can fit into max_length size. It's necessary + to use field size what allows to store group_concat + result without truncation. For this purpose we use + max_characters * CS->mbmaxlen. + */ + const uint32 max_characters= max_length / collation.collation->mbminlen; + if (max_characters > CONVERT_IF_BIGGER_TO_BLOB) + field= new Field_blob(max_characters * collation.collation->mbmaxlen, + maybe_null, name, collation.collation, TRUE); + else + field= new Field_varstring(max_characters * collation.collation->mbmaxlen, + maybe_null, name, table->s, collation.collation); + + if (field) + field->init(table); + return field; +} + + Item *Item_func_group_concat::copy_or_same(THD* thd) { return new (thd->mem_root) Item_func_group_concat(thd, this); |