[Commits] 3c379bbb501: MDEV-14520: Custom aggregate functions work incorrectly with WITH ROLLUP clause
revision-id: 3c379bbb501cc60c3817376f230ae7073120539b (mariadb-10.3.0-977-g3c379bbb501) parent(s): 21b12e33594f9f943d1c3678005f034858af2b03 author: Varun Gupta committer: Varun Gupta timestamp: 2018-05-17 17:19:33 +0530 message: 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) --- mysql-test/main/custom_aggregate_functions.result | 30 +++++++++++++++++++++++ mysql-test/main/custom_aggregate_functions.test | 26 ++++++++++++++++++++ sql/item.cc | 11 +++++++++ sql/item.h | 1 + sql/item_sum.cc | 13 ++++++++++ sql/item_sum.h | 2 ++ 6 files changed, 83 insertions(+) diff --git a/mysql-test/main/custom_aggregate_functions.result b/mysql-test/main/custom_aggregate_functions.result index e08c5276ef4..4060d6665f6 100644 --- a/mysql-test/main/custom_aggregate_functions.result +++ b/mysql-test/main/custom_aggregate_functions.result @@ -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; diff --git a/mysql-test/main/custom_aggregate_functions.test b/mysql-test/main/custom_aggregate_functions.test index 8ede846c90c..ab799b48bdb 100644 --- a/mysql-test/main/custom_aggregate_functions.test +++ b/mysql-test/main/custom_aggregate_functions.test @@ -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; diff --git a/sql/item.cc b/sql/item.cc index 6b8a79f9996..69b62b41fe2 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -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 { diff --git a/sql/item.h b/sql/item.h index c1e306d95b6..df6c922f300 100644 --- a/sql/item.h +++ b/sql/item.h @@ -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); diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 607ed0a135a..4499f134e7d 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -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,13 @@ 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, &null_value, &name); + return copy_item; +} + /*********************************************************************** ** reset and add of sum_func ***********************************************************************/ diff --git a/sql/item_sum.h b/sql/item_sum.h index ea8b2f149df..b66f6ab6143 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -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 */
participants (1)
-
varunraiko1803@gmail.com