summaryrefslogtreecommitdiff
path: root/sql/item_sum.cc
diff options
context:
space:
mode:
authorSergey Glukhov <sergey.glukhov@oracle.com>2011-10-12 17:41:25 +0400
committerSergey Glukhov <sergey.glukhov@oracle.com>2011-10-12 17:41:25 +0400
commitbd4785a6b71f794fcc82b6c52761015e497498ce (patch)
tree63ffa1d7dfd4b57de72d08e5439fdf0770a3ed84 /sql/item_sum.cc
parentb7a4918fe8e1ace2c3ef21a4a4b2ad737d3ccf69 (diff)
downloadmariadb-git-bd4785a6b71f794fcc82b6c52761015e497498ce.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. mysql-test/r/ctype_utf16.result: test result mysql-test/r/ctype_utf32.result: test result mysql-test/r/ctype_utf8.result: test result mysql-test/t/ctype_utf16.test: test case mysql-test/t/ctype_utf32.test: test case mysql-test/t/ctype_utf8.test: test case sql/item.h: make Item::make_string_field() virtual sql/item_sum.cc: added Item_func_group_concat::make_string_field(TABLE *table) method which uses max_characters * collation.collation->mbmaxlen size for result item. max_characters is maximum number of characters what can fit into max_length size. sql/item_sum.h: added Item_func_group_concat::make_string_field(TABLE *table) method
Diffstat (limited to 'sql/item_sum.cc')
-rw-r--r--sql/item_sum.cc25
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);