Skip to content

Commit 89b1c27

Browse files
committed
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)
1 parent 7bf4a00 commit 89b1c27

File tree

6 files changed

+84
-0
lines changed

6 files changed

+84
-0
lines changed

mysql-test/main/custom_aggregate_functions.result

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,3 +1123,33 @@ t1 CREATE TABLE `t1` (
11231123
) ENGINE=MyISAM DEFAULT CHARSET=latin1
11241124
DROP TABLE t1;
11251125
DROP FUNCTION f1;
1126+
#
1127+
# MDEV-14520: Custom aggregate functions work incorrectly with WITH ROLLUP clause
1128+
#
1129+
create aggregate function agg_sum(x INT) returns INT
1130+
begin
1131+
declare z int default 0;
1132+
declare continue handler for not found return z;
1133+
loop
1134+
fetch group next row;
1135+
set z= z+x;
1136+
end loop;
1137+
end|
1138+
create table t1 (i int);
1139+
insert into t1 values (1),(2),(2),(3);
1140+
select i, agg_sum(i) from t1 group by i with rollup;
1141+
i agg_sum(i)
1142+
1 1
1143+
2 4
1144+
3 3
1145+
NULL 8
1146+
#
1147+
# Compare with
1148+
select i, sum(i) from t1 group by i with rollup;
1149+
i sum(i)
1150+
1 1
1151+
2 4
1152+
3 3
1153+
NULL 8
1154+
drop function agg_sum;
1155+
drop table t1;

mysql-test/main/custom_aggregate_functions.test

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,3 +939,29 @@ SHOW CREATE TABLE t1;
939939
DROP TABLE t1;
940940
DROP FUNCTION f1;
941941

942+
--echo #
943+
--echo # MDEV-14520: Custom aggregate functions work incorrectly with WITH ROLLUP clause
944+
--echo #
945+
946+
--delimiter |
947+
create aggregate function agg_sum(x INT) returns INT
948+
begin
949+
declare z int default 0;
950+
declare continue handler for not found return z;
951+
loop
952+
fetch group next row;
953+
set z= z+x;
954+
end loop;
955+
end|
956+
--delimiter ;
957+
958+
create table t1 (i int);
959+
insert into t1 values (1),(2),(2),(3);
960+
select i, agg_sum(i) from t1 group by i with rollup;
961+
--echo #
962+
--echo # Compare with
963+
select i, sum(i) from t1 group by i with rollup;
964+
965+
# Cleanup
966+
drop function agg_sum;
967+
drop table t1;

sql/item.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2802,6 +2802,17 @@ Item_sp::Item_sp(THD *thd, Name_resolution_context *context_arg,
28022802
memset(&sp_mem_root, 0, sizeof(sp_mem_root));
28032803
}
28042804

2805+
Item_sp::Item_sp(THD *thd, Item_sp *item):
2806+
context(item->context), m_name(item->m_name),
2807+
m_sp(item->m_sp), func_ctx(NULL), sp_result_field(NULL)
2808+
{
2809+
dummy_table= (TABLE*) thd->calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE) +
2810+
sizeof(Query_arena));
2811+
dummy_table->s= (TABLE_SHARE*) (dummy_table+1);
2812+
sp_query_arena= (Query_arena *) (dummy_table->s + 1);
2813+
memset(&sp_mem_root, 0, sizeof(sp_mem_root));
2814+
}
2815+
28052816
const char *
28062817
Item_sp::func_name(THD *thd) const
28072818
{

sql/item.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4658,6 +4658,7 @@ class Item_sp
46584658
*/
46594659
Field *sp_result_field;
46604660
Item_sp(THD *thd, Name_resolution_context *context_arg, sp_name *name_arg);
4661+
Item_sp(THD *thd, Item_sp *item);
46614662
const char *func_name(THD *thd) const;
46624663
void cleanup();
46634664
bool sp_check_access(THD *thd);

sql/item_sum.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,6 +1269,12 @@ Item_sum_sp::Item_sum_sp(THD *thd, Name_resolution_context *context_arg,
12691269
m_sp= sp;
12701270
}
12711271

1272+
Item_sum_sp::Item_sum_sp(THD *thd, Item_sum_sp *item):
1273+
Item_sum(thd, item), Item_sp(thd, item)
1274+
{
1275+
maybe_null= item->maybe_null;
1276+
quick_group= item->quick_group;
1277+
}
12721278

12731279
bool
12741280
Item_sum_sp::fix_fields(THD *thd, Item **ref)
@@ -1400,6 +1406,14 @@ Item_sum_sp::func_name() const
14001406
return Item_sp::func_name(thd);
14011407
}
14021408

1409+
Item* Item_sum_sp::copy_or_same(THD *thd)
1410+
{
1411+
Item_sum_sp *copy_item= new (thd->mem_root) Item_sum_sp(thd, this);
1412+
copy_item->init_result_field(thd, max_length, maybe_null,
1413+
&copy_item->null_value, &copy_item->name);
1414+
return copy_item;
1415+
}
1416+
14031417
/***********************************************************************
14041418
** reset and add of sum_func
14051419
***********************************************************************/

sql/item_sum.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,7 @@ class Item_sum_sp :public Item_sum,
12921292

12931293
Item_sum_sp(THD *thd, Name_resolution_context *context_arg, sp_name *name,
12941294
sp_head *sp, List<Item> &list);
1295+
Item_sum_sp(THD *thd, Item_sum_sp *item);
12951296

12961297
enum Sumfunctype sum_func () const
12971298
{
@@ -1361,6 +1362,7 @@ class Item_sum_sp :public Item_sum,
13611362
}
13621363
Item *get_copy(THD *thd)
13631364
{ return get_item_copy<Item_sum_sp>(thd, this); }
1365+
Item *copy_or_same(THD *thd);
13641366
};
13651367

13661368
/* Items to get the value of a stored sum function */

0 commit comments

Comments
 (0)