summaryrefslogtreecommitdiff
path: root/sql/item_sum.cc
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-07-18 16:46:57 +0200
committerSergei Golubchik <sergii@pisem.net>2013-07-18 16:46:57 +0200
commit5f6380adde2dac3f32b40339b9b702c0135eb7d6 (patch)
tree31068acc0b39c208d35d524688a5985831af0447 /sql/item_sum.cc
parent8a23ae088dc38f591efeab9eccdef5eb9094add9 (diff)
parent97e640b9ae83e07b444fceede6b0524256c7a3cc (diff)
downloadmariadb-git-5f6380adde2dac3f32b40339b9b702c0135eb7d6.tar.gz
10.0-base merge
Diffstat (limited to 'sql/item_sum.cc')
-rw-r--r--sql/item_sum.cc104
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;