diff options
author | Sergei Golubchik <sergii@pisem.net> | 2013-07-18 16:46:57 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2013-07-18 16:46:57 +0200 |
commit | 5f6380adde2dac3f32b40339b9b702c0135eb7d6 (patch) | |
tree | 31068acc0b39c208d35d524688a5985831af0447 /sql/item_sum.cc | |
parent | 8a23ae088dc38f591efeab9eccdef5eb9094add9 (diff) | |
parent | 97e640b9ae83e07b444fceede6b0524256c7a3cc (diff) | |
download | mariadb-git-5f6380adde2dac3f32b40339b9b702c0135eb7d6.tar.gz |
10.0-base merge
Diffstat (limited to 'sql/item_sum.cc')
-rw-r--r-- | sql/item_sum.cc | 104 |
1 files changed, 61 insertions, 43 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 92fff032095..bed9499834a 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. +/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. Copyright (c) 2008, 2013 Monty Program Ab This program is free software; you can redistribute it and/or modify @@ -2969,9 +2969,9 @@ int group_concat_key_cmp_with_distinct(void* arg, const void* key1, for (uint i= 0; i < item_func->arg_count_field; i++) { Item *item= item_func->args[i]; - /* - If field_item is a const item then either get_tmp_table_field returns 0 - or it is an item over a const table. + /* + If item is a const item then either get_tmp_table_field returns 0 + or it is an item over a const table. */ if (item->const_item()) continue; @@ -2981,10 +2981,14 @@ int group_concat_key_cmp_with_distinct(void* arg, const void* key1, the temporary table, not the original field */ Field *field= item->get_tmp_table_field(); - int res; + + if (!field) + continue; + uint offset= (field->offset(field->table->record[0]) - field->table->s->null_bytes); - if((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset))) + int res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset); + if (res) return res; } return 0; @@ -3014,27 +3018,29 @@ int group_concat_key_cmp_with_order(void* arg, const void* key1, if (item->const_item()) continue; /* + If item is a const item then either get_tmp_table_field returns 0 + or it is an item over a const table. + */ + if (item->const_item()) + continue; + /* We have to use get_tmp_table_field() instead of real_item()->get_tmp_table_field() because we want the field in the temporary table, not the original field Note that for the case of ROLLUP, field may point to another table - tham grp_item->table. This is howver ok as the table definitions are + tham grp_item->table. This is however ok as the table definitions are the same. */ Field *field= item->get_tmp_table_field(); - /* - If item is a const item then either get_tmp_table_field returns 0 - or it is an item over a const table. - */ - if (field) - { - int res; - uint offset= (field->offset(field->table->record[0]) - - field->table->s->null_bytes); - if ((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset))) - return (*order_item)->asc ? res : -res; - } + if (!field) + continue; + + uint offset= (field->offset(field->table->record[0]) - + field->table->s->null_bytes); + int res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset); + if (res) + return (*order_item)->asc ? res : -res; } /* We can't return 0 because in that case the tree class would remove this @@ -3074,23 +3080,28 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)), for (; arg < arg_end; arg++) { String *res; - if (! (*arg)->const_item()) + /* + We have to use get_tmp_table_field() instead of + real_item()->get_tmp_table_field() because we want the field in + the temporary table, not the original field + We also can't use table->field array to access the fields + because it contains both order and arg list fields. + */ + if ((*arg)->const_item()) + res= (*arg)->val_str(&tmp); + else { - /* - We have to use get_tmp_table_field() instead of - real_item()->get_tmp_table_field() because we want the field in - the temporary table, not the original field - We also can't use table->field array to access the fields - because it contains both order and arg list fields. - */ Field *field= (*arg)->get_tmp_table_field(); - uint offset= (field->offset(field->table->record[0]) - - table->s->null_bytes); - DBUG_ASSERT(offset < table->s->reclength); - res= field->val_str(&tmp, key + offset); + if (field) + { + uint offset= (field->offset(field->table->record[0]) - + table->s->null_bytes); + DBUG_ASSERT(offset < table->s->reclength); + res= field->val_str(&tmp, key + offset); + } + else + res= (*arg)->val_str(&tmp); } - else - res= (*arg)->val_str(&tmp); if (res) result->append(*res); } @@ -3138,11 +3149,12 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)), Item_func_group_concat:: Item_func_group_concat(Name_resolution_context *context_arg, bool distinct_arg, List<Item> *select_list, - SQL_I_List<ORDER> *order_list, String *separator_arg) + const SQL_I_List<ORDER> &order_list, + String *separator_arg) :tmp_table_param(0), separator(separator_arg), tree(0), unique_filter(NULL), table(0), order(0), context(context_arg), - arg_count_order(order_list ? order_list->elements : 0), + arg_count_order(order_list.elements), arg_count_field(select_list->elements), row_count(0), distinct(distinct_arg), @@ -3182,7 +3194,7 @@ Item_func_group_concat(Name_resolution_context *context_arg, if (arg_count_order) { ORDER **order_ptr= order; - for (ORDER *order_item= order_list->first; + for (ORDER *order_item= order_list.first; order_item != NULL; order_item= order_item->next) { @@ -3230,8 +3242,14 @@ Item_func_group_concat::Item_func_group_concat(THD *thd, order= (ORDER **)(tmp + arg_count_order); for (uint i= 0; i < arg_count_order; i++, tmp++) { - memcpy(tmp, item->order[i], sizeof(ORDER)); - tmp->next= i == arg_count_order-1 ? 0 : tmp+1; + /* + Compiler generated copy constructor is used to + to copy all the members of ORDER struct. + It's also necessary to update ORDER::next pointer + so that it points to new ORDER element. + */ + new (tmp) st_order(*(item->order[i])); + tmp->next= (i + 1 == arg_count_order) ? NULL : (tmp + 1); order[i]= tmp; } } @@ -3321,12 +3339,12 @@ bool Item_func_group_concat::add() for (uint i= 0; i < arg_count_field; i++) { Item *show_item= args[i]; - if (!show_item->const_item()) - { - Field *f= show_item->get_tmp_table_field(); - if (f->is_null_in_record((const uchar*) table->record[0])) + if (show_item->const_item()) + continue; + + Field *field= show_item->get_tmp_table_field(); + if (field && field->is_null_in_record((const uchar*) table->record[0])) return 0; // Skip row if it contains null - } } null_value= FALSE; |