diff options
author | unknown <wax@kishkin.ru> | 2003-05-31 15:44:19 +0600 |
---|---|---|
committer | unknown <wax@kishkin.ru> | 2003-05-31 15:44:19 +0600 |
commit | e0c9de6e62a199ec48ac1c910de4bcad28425c76 (patch) | |
tree | 879ead6061bc1bdc807a16f5c29c0fd10acc4404 /sql/item_sum.cc | |
parent | c121cb748d9432561664ad020c3c48431fe2a48c (diff) | |
download | mariadb-git-e0c9de6e62a199ec48ac1c910de4bcad28425c76.tar.gz |
URGENT
SCRUM
BUG
correct wrong code in group_concat
mysql-test/r/func_gconcat.result:
add new tests
mysql-test/t/func_gconcat.test:
add new tests
sql/field.cc:
add new variable for group_concat
sql/field.h:
add new variable for group_concat
sql/item_sum.cc:
correct wrong code
sql/item_sum.h:
correct wrong code
Diffstat (limited to 'sql/item_sum.cc')
-rw-r--r-- | sql/item_sum.cc | 97 |
1 files changed, 54 insertions, 43 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 11c850f9d5f..8bd3e36b5db 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1344,27 +1344,28 @@ String *Item_sum_udf_str::val_str(String *str) GROUP_CONCAT(DISTINCT expr,...) */ -static int group_concat_key_cmp_with_distinct(void* arg, byte* key1, - byte* key2) +int group_concat_key_cmp_with_distinct(void* arg, byte* key1, + byte* key2) { Item_func_group_concat* item= (Item_func_group_concat*)arg; + for (uint i= 0; i < item->arg_count_field; i++) { - Item *field_item= item->expr[i]; + Item *field_item= item->args[i]; Field *field= field_item->tmp_table_field(); if (field) { - uint offset= field->offset(); + uint offset= field->abs_offset; int res= field->key_cmp(key1 + offset, key2 + offset); /* if key1 and key2 is not equal than field->key_cmp return offset. This - function must return value 1 for this case. + function must return value 1 for this case. */ if (res) return 1; } - } + } return 0; } @@ -1374,9 +1375,10 @@ static int group_concat_key_cmp_with_distinct(void* arg, byte* key1, GROUP_CONCAT(expr,... ORDER BY col,... ) */ -static int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2) +int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2) { Item_func_group_concat* item= (Item_func_group_concat*)arg; + for (uint i=0; i < item->arg_count_order; i++) { ORDER *order_item= item->order[i]; @@ -1384,14 +1386,14 @@ static int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2) Field *field= item->tmp_table_field(); if (field) { - uint offset= field->offset(); + uint offset= field->abs_offset; bool dir= order_item->asc; int res= field->key_cmp(key1 + offset, key2 + offset); if (res) return dir ? res : -res; } - } + } /* We can't return 0 because tree class remove this item as double value. */ @@ -1404,9 +1406,8 @@ static int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2) GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... ) */ -static int group_concat_key_cmp_with_distinct_and_order(void* arg, - byte* key1, - byte* key2) +int group_concat_key_cmp_with_distinct_and_order(void* arg,byte* key1, + byte* key2) { if (!group_concat_key_cmp_with_distinct(arg,key1,key2)) return 0; @@ -1419,24 +1420,23 @@ static int group_concat_key_cmp_with_distinct_and_order(void* arg, item is pointer to Item_func_group_concat */ -static int dump_leaf_key(byte* key, uint32 count __attribute__((unused)), +int dump_leaf_key(byte* key, uint32 count __attribute__((unused)), Item_func_group_concat *group_concat_item) { char buff[MAX_FIELD_WIDTH]; String tmp((char *)&buff,sizeof(buff),default_charset_info); String tmp2((char *)&buff,sizeof(buff),default_charset_info); - + tmp.length(0); for (uint i= 0; i < group_concat_item->arg_show_fields; i++) { - Item *show_item= group_concat_item->expr[i]; + Item *show_item= group_concat_item->args[i]; if (!show_item->const_item()) { Field *f= show_item->tmp_table_field(); - uint offset= f->offset(); char *sv= f->ptr; - f->ptr= (char *)key + offset; + f->ptr= (char *)key + f->abs_offset; String *res= f->val_str(&tmp,&tmp2); group_concat_item->result.append(*res); f->ptr= sv; @@ -1486,9 +1486,14 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct, List<Item> *is_select, SQL_LIST *is_order, String *is_separator) - :Item_sum(), tmp_table_param(0), warning_available(false), - separator(is_separator), tree(&tree_base), table(0), - count_cut_values(0), tree_mode(0), distinct(is_distinct) + :Item_sum(), tmp_table_param(0), max_elements_in_tree(0), warning(0), + warning_available(0), key_length(0), rec_offset(0), + tree_mode(0), distinct(is_distinct), warning_for_row(0), + separator(is_separator), tree(&tree_base), table(0), + order(0), tables_list(0), group_concat_max_len(0), + show_elements(0), arg_count_order(0), arg_count_field(0), + arg_show_fields(0), count_cut_values(0) + { original= 0; quick_group= 0; @@ -1504,16 +1509,12 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct, We need to allocate: args - arg_count+arg_count_order (for possible order items in temporare tables) - expr - arg_count_field order - arg_count_order */ - args= (Item**) sql_alloc(sizeof(Item*)*(arg_count+arg_count_order+ - arg_count_field)+ + args= (Item**) sql_alloc(sizeof(Item*)*(arg_count+arg_count_order)+ sizeof(ORDER*)*arg_count_order); if (!args) - return; // thd->fatal is set - expr= args; - expr+= arg_count+arg_count_order; + return; /* fill args items of show and sort */ int i= 0; @@ -1521,12 +1522,12 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct, Item *item_select; for ( ; (item_select= li++) ; i++) - args[i]= expr[i]= item_select; + args[i]= item_select; if (arg_count_order) { i= 0; - order= (ORDER**)(expr + arg_count_field); + order= (ORDER**)(args + arg_count + arg_count_order); for (ORDER *order_item= (ORDER*) is_order->first; order_item != NULL; order_item= order_item->next) @@ -1587,7 +1588,7 @@ bool Item_func_group_concat::add() bool record_is_null= TRUE; for (uint i= 0; i < arg_show_fields; i++) { - Item *show_item= expr[i]; + Item *show_item= args[i]; if (!show_item->const_item()) { Field *f= show_item->tmp_table_field(); @@ -1603,13 +1604,13 @@ bool Item_func_group_concat::add() null_value= FALSE; if (tree_mode) { - if (!tree_insert(tree, table->record[0], 0,tree->custom_arg)) + if (!tree_insert(tree, table->record[0] + rec_offset, 0, tree->custom_arg)) return 1; } else { if (result.length() <= group_concat_max_len && !warning_for_row) - dump_leaf_key(table->record[0],1, + dump_leaf_key(table->record[0] + rec_offset, 1, (Item_func_group_concat*)this); } return 0; @@ -1642,12 +1643,6 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return 1; maybe_null |= args[i]->maybe_null; } - for (i= 0 ; i < arg_count_field ; i++) - { - if (expr[i]->fix_fields(thd, tables, expr + i) || expr[i]->check_cols(1)) - return 1; - maybe_null |= expr[i]->maybe_null; - } /* Fix fields for order clause in function: GROUP_CONCAT(expr,... ORDER BY col,... ) @@ -1712,12 +1707,25 @@ bool Item_func_group_concat::setup(THD *thd) return 1; table->file->extra(HA_EXTRA_NO_ROWS); table->no_rows= 1; - qsort_cmp2 compare_key; - - tree_mode= distinct || arg_count_order; + + + Field** field, **field_end; + field_end = (field = table->field) + table->fields; + uint offset = 0; + for (key_length = 0; field < field_end; ++field) + { + uint32 length= (*field)->pack_length(); + (*field)->abs_offset= offset; + offset+= length; + key_length += length; + } + rec_offset = table->reclength - key_length; + /* choise function of sort */ + tree_mode= distinct || arg_count_order; + qsort_cmp2 compare_key; if (tree_mode) { if (arg_count_order) @@ -1741,9 +1749,9 @@ bool Item_func_group_concat::setup(THD *thd) */ init_tree(tree, min(thd->variables.max_heap_table_size, thd->variables.sortbuff_size/16), 0, - table->reclength, compare_key, 0, NULL, (void*) this); - max_elements_in_tree= ((table->reclength) ? - thd->variables.max_heap_table_size/table->reclength : 1); + key_length, compare_key, 0, NULL, (void*) this); + max_elements_in_tree= ((key_length) ? + thd->variables.max_heap_table_size/key_length : 1); }; item_thd= thd; @@ -1784,3 +1792,6 @@ String* Item_func_group_concat::val_str(String* str) } return &result; } + + + |