Commit cc0061a1 authored by ramil@mysql.com's avatar ramil@mysql.com

a fix (bug #7405: group_concat with distinct and rollup => ignores distinct in some rows).

parent e8a6fa42
...@@ -469,3 +469,26 @@ x (select group_concat(x) from r2) ...@@ -469,3 +469,26 @@ x (select group_concat(x) from r2)
1 1,1 1 1,1
2 2,2 2 2,2
drop table r2; drop table r2;
create table t1 (d int, a int, b int, c int);
insert into t1(a,b) values (1,3), (1,4), (1,2), (2,7), (1,1), (1,2), (2,3), (2,3);
select a, group_concat(b) from t1 group by a with rollup;
a group_concat(b)
1 3,4,2,1,2
2 7,3,3
NULL 3,4,2,1,2,7,3,3
select a, group_concat(distinct b) from t1 group by a with rollup;
a group_concat(distinct b)
1 3,4,2,1
2 7,3
NULL 3,4,2,1,7
select a, group_concat(b order by b) from t1 group by a with rollup;
a group_concat(b order by b)
1 1,2,2,3,4
2 3,3,7
NULL 1,2,2,3,3,3,4,7
select a, group_concat(distinct b order by b) from t1 group by a with rollup;
a group_concat(distinct b order by b)
1 1,2,3,4
2 3,7
NULL 1,2,3,4,7
drop table t1;
...@@ -292,3 +292,15 @@ create table r2 (a int, b int); ...@@ -292,3 +292,15 @@ create table r2 (a int, b int);
insert into r2 values (1,1), (2,2); insert into r2 values (1,1), (2,2);
select b x, (select group_concat(x) from r2) from r2; select b x, (select group_concat(x) from r2) from r2;
drop table r2; drop table r2;
#
# Bug #7405: problems with rollup
#
create table t1 (d int, a int, b int, c int);
insert into t1(a,b) values (1,3), (1,4), (1,2), (2,7), (1,1), (1,2), (2,3), (2,3);
select a, group_concat(b) from t1 group by a with rollup;
select a, group_concat(distinct b) from t1 group by a with rollup;
select a, group_concat(b order by b) from t1 group by a with rollup;
select a, group_concat(distinct b order by b) from t1 group by a with rollup;
drop table t1;
...@@ -1566,7 +1566,6 @@ int group_concat_key_cmp_with_distinct(void* arg, byte* key1, ...@@ -1566,7 +1566,6 @@ int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
{ {
Item_func_group_concat* grp_item= (Item_func_group_concat*)arg; Item_func_group_concat* grp_item= (Item_func_group_concat*)arg;
Item **field_item, **end; Item **field_item, **end;
char *record= (char*) grp_item->table->record[0];
for (field_item= grp_item->args, end= field_item + grp_item->arg_count_field; for (field_item= grp_item->args, end= field_item + grp_item->arg_count_field;
field_item < end; field_item < end;
...@@ -1581,7 +1580,7 @@ int group_concat_key_cmp_with_distinct(void* arg, byte* key1, ...@@ -1581,7 +1580,7 @@ int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
if (field) if (field)
{ {
int res; int res;
uint offset= (uint) (field->ptr - record); uint offset= field->offset();
if ((res= field->key_cmp(key1 + offset, key2 + offset))) if ((res= field->key_cmp(key1 + offset, key2 + offset)))
return res; return res;
} }
...@@ -1599,7 +1598,6 @@ int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2) ...@@ -1599,7 +1598,6 @@ int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2)
{ {
Item_func_group_concat* grp_item= (Item_func_group_concat*) arg; Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
ORDER **order_item, **end; ORDER **order_item, **end;
char *record= (char*) grp_item->table->record[0];
for (order_item= grp_item->order, end=order_item+ grp_item->arg_count_order; for (order_item= grp_item->order, end=order_item+ grp_item->arg_count_order;
order_item < end; order_item < end;
...@@ -1615,7 +1613,7 @@ int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2) ...@@ -1615,7 +1613,7 @@ int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2)
if (field) if (field)
{ {
int res; int res;
uint offset= (uint) (field->ptr - record); uint offset= field->offset();
if ((res= field->key_cmp(key1 + offset, key2 + offset))) if ((res= field->key_cmp(key1 + offset, key2 + offset)))
return (*order_item)->asc ? res : -res; return (*order_item)->asc ? res : -res;
} }
...@@ -1657,7 +1655,6 @@ int dump_leaf_key(byte* key, uint32 count __attribute__((unused)), ...@@ -1657,7 +1655,6 @@ int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
{ {
char buff[MAX_FIELD_WIDTH]; char buff[MAX_FIELD_WIDTH];
String tmp((char *)&buff,sizeof(buff),default_charset_info), tmp2; String tmp((char *)&buff,sizeof(buff),default_charset_info), tmp2;
char *record= (char*) item->table->record[0];
if (item->result.length()) if (item->result.length())
item->result.append(*item->separator); item->result.append(*item->separator);
...@@ -1677,9 +1674,8 @@ int dump_leaf_key(byte* key, uint32 count __attribute__((unused)), ...@@ -1677,9 +1674,8 @@ int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
Field *field= show_item->get_tmp_table_field(); Field *field= show_item->get_tmp_table_field();
String *res; String *res;
char *save_ptr= field->ptr; char *save_ptr= field->ptr;
uint offset= (uint) (save_ptr - record); DBUG_ASSERT(field->offset() < item->table->reclength);
DBUG_ASSERT(offset < item->table->reclength); field->ptr= (char *) key + field->offset();
field->ptr= (char *) key + offset;
res= field->val_str(&tmp,&tmp2); res= field->val_str(&tmp,&tmp2);
item->result.append(*res); item->result.append(*res);
field->ptr= save_ptr; field->ptr= save_ptr;
...@@ -1852,12 +1848,6 @@ void Item_func_group_concat::clear() ...@@ -1852,12 +1848,6 @@ void Item_func_group_concat::clear()
result.copy(); result.copy();
null_value= TRUE; null_value= TRUE;
warning_for_row= FALSE; warning_for_row= FALSE;
if (table)
{
table->file->extra(HA_EXTRA_NO_CACHE);
table->file->delete_all_rows();
table->file->extra(HA_EXTRA_WRITE_CACHE);
}
if (tree_mode) if (tree_mode)
reset_tree(tree); reset_tree(tree);
} }
...@@ -1870,19 +1860,13 @@ bool Item_func_group_concat::add() ...@@ -1870,19 +1860,13 @@ bool Item_func_group_concat::add()
copy_fields(tmp_table_param); copy_fields(tmp_table_param);
copy_funcs(tmp_table_param->items_to_copy); copy_funcs(tmp_table_param->items_to_copy);
for (uint i= 0; i < arg_count_field; i++) for (Item **arg= args, **arg_end= args + arg_count_field;
arg < arg_end; arg++)
{ {
Item *show_item= args[i]; if (!(*arg)->const_item() &&
if (!show_item->const_item()) (*arg)->get_tmp_table_field()->is_null_in_record(
{ (const uchar*) table->record[0]))
/*
Here we use real_item as we want the original field data that should
be written to table->record[0]
*/
Field *f= show_item->real_item()->get_tmp_table_field();
if (f->is_null())
return 0; // Skip row if it contains null return 0; // Skip row if it contains null
}
} }
null_value= FALSE; null_value= FALSE;
...@@ -1945,10 +1929,6 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -1945,10 +1929,6 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
null_value= 1; null_value= 1;
max_length= group_concat_max_len; max_length= group_concat_max_len;
thd->allow_sum_func= 1; thd->allow_sum_func= 1;
if (!(tmp_table_param= new TMP_TABLE_PARAM))
return 1;
/* We'll convert all blobs to varchar fields in the temporary table */
tmp_table_param->convert_blob_length= group_concat_max_len;
tables_list= tables; tables_list= tables;
fixed= 1; fixed= 1;
return 0; return 0;
...@@ -1967,6 +1947,11 @@ bool Item_func_group_concat::setup(THD *thd) ...@@ -1967,6 +1947,11 @@ bool Item_func_group_concat::setup(THD *thd)
if (select_lex->linkage == GLOBAL_OPTIONS_TYPE) if (select_lex->linkage == GLOBAL_OPTIONS_TYPE)
DBUG_RETURN(1); DBUG_RETURN(1);
if (!(tmp_table_param= new TMP_TABLE_PARAM))
return 1;
/* We'll convert all blobs to varchar fields in the temporary table */
tmp_table_param->convert_blob_length= group_concat_max_len;
/* /*
push all not constant fields to list and create temp table push all not constant fields to list and create temp table
*/ */
......
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