Commit 89b1c271 authored by Varun Gupta's avatar Varun Gupta

MDEV-14520: Custom aggregate functions work incorrectly with WITH ROLLUP clause

Queries involving rollup need all aggregate function to have copy_or_same function where we create a copy
of item_sum items for each sum level.
Implemented copy_or_same function for the custom aggregate function class (Item_sum_sp)
parent 7bf4a006
......@@ -1123,3 +1123,33 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
DROP FUNCTION f1;
#
# MDEV-14520: Custom aggregate functions work incorrectly with WITH ROLLUP clause
#
create aggregate function agg_sum(x INT) returns INT
begin
declare z int default 0;
declare continue handler for not found return z;
loop
fetch group next row;
set z= z+x;
end loop;
end|
create table t1 (i int);
insert into t1 values (1),(2),(2),(3);
select i, agg_sum(i) from t1 group by i with rollup;
i agg_sum(i)
1 1
2 4
3 3
NULL 8
#
# Compare with
select i, sum(i) from t1 group by i with rollup;
i sum(i)
1 1
2 4
3 3
NULL 8
drop function agg_sum;
drop table t1;
......@@ -939,3 +939,29 @@ SHOW CREATE TABLE t1;
DROP TABLE t1;
DROP FUNCTION f1;
--echo #
--echo # MDEV-14520: Custom aggregate functions work incorrectly with WITH ROLLUP clause
--echo #
--delimiter |
create aggregate function agg_sum(x INT) returns INT
begin
declare z int default 0;
declare continue handler for not found return z;
loop
fetch group next row;
set z= z+x;
end loop;
end|
--delimiter ;
create table t1 (i int);
insert into t1 values (1),(2),(2),(3);
select i, agg_sum(i) from t1 group by i with rollup;
--echo #
--echo # Compare with
select i, sum(i) from t1 group by i with rollup;
# Cleanup
drop function agg_sum;
drop table t1;
......@@ -2802,6 +2802,17 @@ Item_sp::Item_sp(THD *thd, Name_resolution_context *context_arg,
memset(&sp_mem_root, 0, sizeof(sp_mem_root));
}
Item_sp::Item_sp(THD *thd, Item_sp *item):
context(item->context), m_name(item->m_name),
m_sp(item->m_sp), func_ctx(NULL), sp_result_field(NULL)
{
dummy_table= (TABLE*) thd->calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE) +
sizeof(Query_arena));
dummy_table->s= (TABLE_SHARE*) (dummy_table+1);
sp_query_arena= (Query_arena *) (dummy_table->s + 1);
memset(&sp_mem_root, 0, sizeof(sp_mem_root));
}
const char *
Item_sp::func_name(THD *thd) const
{
......
......@@ -4658,6 +4658,7 @@ class Item_sp
*/
Field *sp_result_field;
Item_sp(THD *thd, Name_resolution_context *context_arg, sp_name *name_arg);
Item_sp(THD *thd, Item_sp *item);
const char *func_name(THD *thd) const;
void cleanup();
bool sp_check_access(THD *thd);
......
......@@ -1269,6 +1269,12 @@ Item_sum_sp::Item_sum_sp(THD *thd, Name_resolution_context *context_arg,
m_sp= sp;
}
Item_sum_sp::Item_sum_sp(THD *thd, Item_sum_sp *item):
Item_sum(thd, item), Item_sp(thd, item)
{
maybe_null= item->maybe_null;
quick_group= item->quick_group;
}
bool
Item_sum_sp::fix_fields(THD *thd, Item **ref)
......@@ -1400,6 +1406,14 @@ Item_sum_sp::func_name() const
return Item_sp::func_name(thd);
}
Item* Item_sum_sp::copy_or_same(THD *thd)
{
Item_sum_sp *copy_item= new (thd->mem_root) Item_sum_sp(thd, this);
copy_item->init_result_field(thd, max_length, maybe_null,
&copy_item->null_value, &copy_item->name);
return copy_item;
}
/***********************************************************************
** reset and add of sum_func
***********************************************************************/
......
......@@ -1292,6 +1292,7 @@ class Item_sum_sp :public Item_sum,
Item_sum_sp(THD *thd, Name_resolution_context *context_arg, sp_name *name,
sp_head *sp, List<Item> &list);
Item_sum_sp(THD *thd, Item_sum_sp *item);
enum Sumfunctype sum_func () const
{
......@@ -1361,6 +1362,7 @@ class Item_sum_sp :public Item_sum,
}
Item *get_copy(THD *thd)
{ return get_item_copy<Item_sum_sp>(thd, this); }
Item *copy_or_same(THD *thd);
};
/* Items to get the value of a stored sum function */
......
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