Commit ac54aa2a authored by evgen@moonbone.local's avatar evgen@moonbone.local

Fixed bug#14169: type of group_concat() result changed to blob if tmp_table was

used

In a simple queries a result of the GROUP_CONCAT() function was always of 
varchar type.
But if length of GROUP_CONCAT() result is greater than 512 chars and temporary
table is used during select then the result is converted to blob, due to
policy to not to store fields longer than 512 chars in tmp table as varchar
fields.

In order to provide consistent behaviour, result of GROUP_CONCAT() now
will always be converted to blob if it is longer than 512 chars.
Item_func_group_concat::field_type() is modified accordingly.
parent b4980d43
...@@ -604,3 +604,19 @@ count(distinct (f1+1)) ...@@ -604,3 +604,19 @@ count(distinct (f1+1))
1 1
3 3
drop table t1; drop table t1;
create table t1 (f1 int unsigned, f2 varchar(255));
insert into t1 values (1,repeat('a',255)),(2,repeat('b',255));
select f2,group_concat(f1) from t1 group by f2;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t1 t1 f2 f2 253 255 255 Y 0 0 8
def group_concat(f1) 252 400 1 Y 128 0 63
f2 group_concat(f1)
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 2
select f2,group_concat(f1) from t1 group by f2 order by 2;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t1 t1 f2 f2 253 255 255 Y 0 0 8
def group_concat(f1) group_concat(f1) 252 400 1 Y 144 0 63
f2 group_concat(f1)
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 2
...@@ -390,4 +390,14 @@ insert into t1 values(1),(2),(3); ...@@ -390,4 +390,14 @@ insert into t1 values(1),(2),(3);
select f1, group_concat(f1+1) from t1 group by f1 with rollup; select f1, group_concat(f1+1) from t1 group by f1 with rollup;
select count(distinct (f1+1)) from t1 group by f1 with rollup; select count(distinct (f1+1)) from t1 group by f1 with rollup;
drop table t1; drop table t1;
#
# Bug#14169 type of group_concat() result changed to blob if tmp_table was used
#
create table t1 (f1 int unsigned, f2 varchar(255));
insert into t1 values (1,repeat('a',255)),(2,repeat('b',255));
--enable_metadata
select f2,group_concat(f1) from t1 group by f2;
select f2,group_concat(f1) from t1 group by f2 order by 2;
--disable_metadata
# End of 4.1 tests # End of 4.1 tests
...@@ -307,7 +307,7 @@ Field *Item_func::tmp_table_field(TABLE *t_arg) ...@@ -307,7 +307,7 @@ Field *Item_func::tmp_table_field(TABLE *t_arg)
res= new Field_double(max_length, maybe_null, name, t_arg, decimals); res= new Field_double(max_length, maybe_null, name, t_arg, decimals);
break; break;
case STRING_RESULT: case STRING_RESULT:
if (max_length > 255) if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB)
res= new Field_blob(max_length, maybe_null, name, t_arg, collation.collation); res= new Field_blob(max_length, maybe_null, name, t_arg, collation.collation);
else else
res= new Field_string(max_length, maybe_null, name, t_arg, collation.collation); res= new Field_string(max_length, maybe_null, name, t_arg, collation.collation);
......
...@@ -729,6 +729,13 @@ class Item_func_group_concat : public Item_sum ...@@ -729,6 +729,13 @@ class Item_func_group_concat : public Item_sum
enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;} enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;}
const char *func_name() const { return "group_concat"; } const char *func_name() const { return "group_concat"; }
virtual Item_result result_type () const { return STRING_RESULT; } virtual Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const
{
if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB)
return FIELD_TYPE_BLOB;
else
return MYSQL_TYPE_VAR_STRING;
}
void clear(); void clear();
bool add(); bool add();
void reset_field(); void reset_field();
......
...@@ -4925,7 +4925,8 @@ static Field* create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, ...@@ -4925,7 +4925,8 @@ 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);
else if (item->max_length/item->collation.collation->mbmaxlen > 255) else if (item->max_length/item->collation.collation->mbmaxlen >
CONVERT_IF_BIGGER_TO_BLOB)
{ {
if (convert_blob_length) if (convert_blob_length)
new_field= new Field_varstring(convert_blob_length, maybe_null, new_field= new Field_varstring(convert_blob_length, maybe_null,
...@@ -5028,7 +5029,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, ...@@ -5028,7 +5029,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
return new Field_longlong(item_sum->max_length,maybe_null, return new Field_longlong(item_sum->max_length,maybe_null,
item->name,table,item->unsigned_flag); item->name,table,item->unsigned_flag);
case STRING_RESULT: case STRING_RESULT:
if (item_sum->max_length > 255) if (item_sum->max_length/item_sum->collation.collation->mbmaxlen >
CONVERT_IF_BIGGER_TO_BLOB)
{ {
if (convert_blob_length) if (convert_blob_length)
return new Field_varstring(convert_blob_length, maybe_null, return new Field_varstring(convert_blob_length, maybe_null,
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
#define MAX_MBWIDTH 3 /* Max multibyte sequence */ #define MAX_MBWIDTH 3 /* Max multibyte sequence */
#define MAX_FIELD_CHARLENGTH 255 #define MAX_FIELD_CHARLENGTH 255
#define CONVERT_IF_BIGGER_TO_BLOB 255
/* Max column width +1 */ /* Max column width +1 */
#define MAX_FIELD_WIDTH (MAX_FIELD_CHARLENGTH*MAX_MBWIDTH+1) #define MAX_FIELD_WIDTH (MAX_FIELD_CHARLENGTH*MAX_MBWIDTH+1)
......
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