Commit 4e7121c0 authored by unknown's avatar unknown

Bug#16712: group_concat returns odd srting insead of intended result

  when calculating GROUP_CONCAT all blob fields are transformed
  to varchar when making the temp table.
  However a varchar has at max 2 bytes for length. 
  This fix makes the conversion only for blobs whose max length 
  is below that limit. 
  Otherwise blob field is created by make_string_field() call.


mysql-test/r/func_gconcat.result:
  Bug#16712: group_concat returns odd srting insead of intended result
    * testsuite for the bug
mysql-test/t/func_gconcat.test:
  Bug#16712: group_concat returns odd srting insead of intended result
    * testsuite for the bug
sql/item_sum.cc:
  Bug#16712: group_concat returns odd srting insead of intended result
    * force blob->varchar conversion for small enough blobs only
sql/sql_select.cc:
  Bug#16712: group_concat returns odd srting insead of intended result
    * force blob->varchar conversion for small enough blobs only
parent a8fd83d6
...@@ -641,3 +641,16 @@ select charset(group_concat(c1 order by c2)) from t1; ...@@ -641,3 +641,16 @@ select charset(group_concat(c1 order by c2)) from t1;
charset(group_concat(c1 order by c2)) charset(group_concat(c1 order by c2))
latin1 latin1
drop table t1; drop table t1;
CREATE TABLE t1 (a INT(10), b LONGTEXT, PRIMARY KEY (a));
SET GROUP_CONCAT_MAX_LEN = 20000000;
INSERT INTO t1 VALUES (1,REPEAT(CONCAT('A',CAST(CHAR(0) AS BINARY),'B'), 40000));
INSERT INTO t1 SELECT a + 1, b FROM t1;
SELECT a, CHAR_LENGTH(b) FROM t1;
a CHAR_LENGTH(b)
1 120000
2 120000
SELECT CHAR_LENGTH( GROUP_CONCAT(b) ) FROM t1;
CHAR_LENGTH( GROUP_CONCAT(b) )
240001
SET GROUP_CONCAT_MAX_LEN = 1024;
DROP TABLE t1;
...@@ -433,3 +433,17 @@ create table t1 (c1 varchar(10), c2 int); ...@@ -433,3 +433,17 @@ create table t1 (c1 varchar(10), c2 int);
select charset(group_concat(c1 order by c2)) from t1; select charset(group_concat(c1 order by c2)) from t1;
drop table t1; drop table t1;
#
# Bug #16712: group_concat returns odd string instead of intended result
#
CREATE TABLE t1 (a INT(10), b LONGTEXT, PRIMARY KEY (a));
SET GROUP_CONCAT_MAX_LEN = 20000000;
INSERT INTO t1 VALUES (1,REPEAT(CONCAT('A',CAST(CHAR(0) AS BINARY),'B'), 40000));
INSERT INTO t1 SELECT a + 1, b FROM t1;
SELECT a, CHAR_LENGTH(b) FROM t1;
SELECT CHAR_LENGTH( GROUP_CONCAT(b) ) FROM t1;
SET GROUP_CONCAT_MAX_LEN = 1024;
DROP TABLE t1;
...@@ -377,7 +377,13 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table, ...@@ -377,7 +377,13 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table,
case INT_RESULT: case INT_RESULT:
return new Field_longlong(max_length,maybe_null,name,table,unsigned_flag); return new Field_longlong(max_length,maybe_null,name,table,unsigned_flag);
case STRING_RESULT: case STRING_RESULT:
if (max_length/collation.collation->mbmaxlen > 255 && convert_blob_length) /*
Make sure that the blob fits into a Field_varstring which has
2-byte lenght.
*/
if (max_length/collation.collation->mbmaxlen > 255 &&
max_length/collation.collation->mbmaxlen < UINT_MAX16 &&
convert_blob_length)
return new Field_varstring(convert_blob_length, maybe_null, return new Field_varstring(convert_blob_length, maybe_null,
name, table, name, table,
collation.collation); collation.collation);
......
...@@ -8011,7 +8011,12 @@ Field* create_tmp_field_from_field(THD *thd, Field* org_field, ...@@ -8011,7 +8011,12 @@ Field* create_tmp_field_from_field(THD *thd, Field* org_field,
{ {
Field *new_field; Field *new_field;
if (convert_blob_length && (org_field->flags & BLOB_FLAG)) /*
Make sure that the blob fits into a Field_varstring which has
2-byte lenght.
*/
if (convert_blob_length && convert_blob_length < UINT_MAX16 &&
(org_field->flags & BLOB_FLAG))
new_field= new Field_varstring(convert_blob_length, new_field= new Field_varstring(convert_blob_length,
org_field->maybe_null(), org_field->maybe_null(),
org_field->field_name, table, org_field->field_name, table,
...@@ -8087,8 +8092,13 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, ...@@ -8087,8 +8092,13 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
if ((type= item->field_type()) == MYSQL_TYPE_DATETIME || if ((type= item->field_type()) == MYSQL_TYPE_DATETIME ||
type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE) type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE)
new_field= item->tmp_table_field_from_field_type(table); new_field= item->tmp_table_field_from_field_type(table);
/*
Make sure that the blob fits into a Field_varstring which has
2-byte lenght.
*/
else if (item->max_length/item->collation.collation->mbmaxlen > 255 && else if (item->max_length/item->collation.collation->mbmaxlen > 255 &&
convert_blob_length) item->max_length/item->collation.collation->mbmaxlen < UINT_MAX16
&& convert_blob_length)
new_field= new Field_varstring(convert_blob_length, maybe_null, new_field= new Field_varstring(convert_blob_length, maybe_null,
item->name, table, item->name, table,
item->collation.collation); item->collation.collation);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment