Loading mysql-test/r/subselect.result +19 −0 Original line number Diff line number Diff line Loading @@ -3905,3 +3905,22 @@ COUNT(*) a 2 2 3 3 DROP TABLE t1,t2; CREATE TABLE t1 (a int, b int); CREATE TABLE t2 (m int, n int); INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4); INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44); SELECT COUNT(*) c, a, (SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a) FROM t1 GROUP BY a; c a (SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a) 2 2 2 3 3 3 1 4 1,1 SELECT COUNT(*) c, a, (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a) FROM t1 GROUP BY a; c a (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a) 2 2 3 3 3 4 1 4 2,2 DROP table t1,t2; mysql-test/t/subselect.test +19 −0 Original line number Diff line number Diff line Loading @@ -2763,3 +2763,22 @@ SELECT COUNT(*), a HAVING (SELECT MIN(m) FROM t2 WHERE m = count(*)) > 1; DROP TABLE t1,t2; # # Bug #27229: GROUP_CONCAT in subselect with COUNT() as an argument # CREATE TABLE t1 (a int, b int); CREATE TABLE t2 (m int, n int); INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4); INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44); SELECT COUNT(*) c, a, (SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a) FROM t1 GROUP BY a; SELECT COUNT(*) c, a, (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a) FROM t1 GROUP BY a; DROP table t1,t2; sql/item.cc +6 −3 Original line number Diff line number Diff line Loading @@ -1261,15 +1261,18 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array, Exception is Item_direct_view_ref which we need to convert to Item_ref to allow fields from view being stored in tmp table. */ Item_aggregate_ref *item_ref; uint el= fields.elements; Item *new_item, *real_itm= real_item(); Item *real_itm= real_item(); ref_pointer_array[el]= real_itm; if (!(new_item= new Item_aggregate_ref(&thd->lex->current_select->context, if (!(item_ref= new Item_aggregate_ref(&thd->lex->current_select->context, ref_pointer_array + el, 0, name))) return; // fatal_error is set if (type() == SUM_FUNC_ITEM) item_ref->depended_from= ((Item_sum *) this)->depended_from(); fields.push_front(real_itm); thd->change_item_tree(ref, new_item); thd->change_item_tree(ref, item_ref); } } Loading sql/item_sum.cc +18 −15 Original line number Diff line number Diff line Loading @@ -61,9 +61,9 @@ bool Item_sum::init_sum_func_check(THD *thd) /* Save a pointer to object to be used in items for nested set functions */ thd->lex->in_sum_func= this; nest_level= thd->lex->current_select->nest_level; nest_level_tables_count= thd->lex->current_select->join->tables; ref_by= 0; aggr_level= -1; aggr_sel= NULL; max_arg_level= -1; max_sum_func_level= -1; return FALSE; Loading Loading @@ -151,7 +151,10 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref) invalid= aggr_level < 0 && !(allow_sum_func & (1 << nest_level)); } if (!invalid && aggr_level < 0) { aggr_level= nest_level; aggr_sel= thd->lex->current_select; } /* By this moment we either found a subquery where the set function is to be aggregated and assigned a value that is >= 0 to aggr_level, Loading Loading @@ -212,7 +215,6 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref) bool Item_sum::register_sum_func(THD *thd, Item **ref) { SELECT_LEX *sl; SELECT_LEX *aggr_sl= NULL; nesting_map allow_sum_func= thd->lex->allow_sum_func; for (sl= thd->lex->current_select->master_unit()->outer_select() ; sl && sl->nest_level > max_arg_level; Loading @@ -222,7 +224,7 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref) { /* Found the most nested subquery where the function can be aggregated */ aggr_level= sl->nest_level; aggr_sl= sl; aggr_sel= sl; } } if (sl && (allow_sum_func & (1 << sl->nest_level))) Loading @@ -233,21 +235,22 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref) The set function will be aggregated in this subquery. */ aggr_level= sl->nest_level; aggr_sl= sl; aggr_sel= sl; } if (aggr_level >= 0) { ref_by= ref; /* Add the object to the list of registered objects assigned to aggr_sl */ if (!aggr_sl->inner_sum_func_list) /* Add the object to the list of registered objects assigned to aggr_sel */ if (!aggr_sel->inner_sum_func_list) next= this; else { next= aggr_sl->inner_sum_func_list->next; aggr_sl->inner_sum_func_list->next= this; next= aggr_sel->inner_sum_func_list->next; aggr_sel->inner_sum_func_list->next= this; } aggr_sl->inner_sum_func_list= this; aggr_sl->with_sum_func= 1; aggr_sel->inner_sum_func_list= this; aggr_sel->with_sum_func= 1; /* Mark Item_subselect(s) as containing aggregate function all the way up Loading @@ -265,11 +268,11 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref) has aggregate functions directly referenced (i.e. not through a sub-select). */ for (sl= thd->lex->current_select; sl && sl != aggr_sl && sl->master_unit()->item; sl && sl != aggr_sel && sl->master_unit()->item; sl= sl->master_unit()->outer_select() ) sl->master_unit()->item->with_sum_func= 1; } thd->lex->current_select->mark_as_dependent(aggr_sl); thd->lex->current_select->mark_as_dependent(aggr_sel); return FALSE; } Loading Loading @@ -299,10 +302,10 @@ Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements), Item_sum::Item_sum(THD *thd, Item_sum *item): Item_result_field(thd, item), arg_count(item->arg_count), aggr_sel(item->aggr_sel), nest_level(item->nest_level), aggr_level(item->aggr_level), quick_group(item->quick_group), used_tables_cache(item->used_tables_cache), forced_const(item->forced_const), nest_level_tables_count(item->nest_level_tables_count) forced_const(item->forced_const) { if (arg_count <= 2) args=tmp_args; Loading Loading @@ -447,7 +450,7 @@ void Item_sum::update_used_tables () /* the aggregate function is aggregated into its local context */ if (aggr_level == nest_level) used_tables_cache |= (1 << nest_level_tables_count) - 1; used_tables_cache |= (1 << aggr_sel->join->tables) - 1; } } Loading sql/item_sum.h +3 −1 Original line number Diff line number Diff line Loading @@ -233,6 +233,7 @@ class Item_sum :public Item_result_field Item_sum *next; /* next in the circular chain of registered objects */ uint arg_count; Item_sum *in_sum_func; /* embedding set function if any */ st_select_lex * aggr_sel; /* select where the function is aggregated */ int8 nest_level; /* number of the nesting level of the set function */ int8 aggr_level; /* nesting level of the aggregating subquery */ int8 max_arg_level; /* max level of unbound column references */ Loading @@ -242,7 +243,6 @@ class Item_sum :public Item_result_field protected: table_map used_tables_cache; bool forced_const; byte nest_level_tables_count; public: Loading Loading @@ -365,6 +365,8 @@ class Item_sum :public Item_result_field bool init_sum_func_check(THD *thd); bool check_sum_func(THD *thd, Item **ref); bool register_sum_func(THD *thd, Item **ref); st_select_lex *depended_from() { return (nest_level == aggr_level ? 0 : aggr_sel); } }; Loading Loading
mysql-test/r/subselect.result +19 −0 Original line number Diff line number Diff line Loading @@ -3905,3 +3905,22 @@ COUNT(*) a 2 2 3 3 DROP TABLE t1,t2; CREATE TABLE t1 (a int, b int); CREATE TABLE t2 (m int, n int); INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4); INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44); SELECT COUNT(*) c, a, (SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a) FROM t1 GROUP BY a; c a (SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a) 2 2 2 3 3 3 1 4 1,1 SELECT COUNT(*) c, a, (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a) FROM t1 GROUP BY a; c a (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a) 2 2 3 3 3 4 1 4 2,2 DROP table t1,t2;
mysql-test/t/subselect.test +19 −0 Original line number Diff line number Diff line Loading @@ -2763,3 +2763,22 @@ SELECT COUNT(*), a HAVING (SELECT MIN(m) FROM t2 WHERE m = count(*)) > 1; DROP TABLE t1,t2; # # Bug #27229: GROUP_CONCAT in subselect with COUNT() as an argument # CREATE TABLE t1 (a int, b int); CREATE TABLE t2 (m int, n int); INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4); INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44); SELECT COUNT(*) c, a, (SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a) FROM t1 GROUP BY a; SELECT COUNT(*) c, a, (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a) FROM t1 GROUP BY a; DROP table t1,t2;
sql/item.cc +6 −3 Original line number Diff line number Diff line Loading @@ -1261,15 +1261,18 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array, Exception is Item_direct_view_ref which we need to convert to Item_ref to allow fields from view being stored in tmp table. */ Item_aggregate_ref *item_ref; uint el= fields.elements; Item *new_item, *real_itm= real_item(); Item *real_itm= real_item(); ref_pointer_array[el]= real_itm; if (!(new_item= new Item_aggregate_ref(&thd->lex->current_select->context, if (!(item_ref= new Item_aggregate_ref(&thd->lex->current_select->context, ref_pointer_array + el, 0, name))) return; // fatal_error is set if (type() == SUM_FUNC_ITEM) item_ref->depended_from= ((Item_sum *) this)->depended_from(); fields.push_front(real_itm); thd->change_item_tree(ref, new_item); thd->change_item_tree(ref, item_ref); } } Loading
sql/item_sum.cc +18 −15 Original line number Diff line number Diff line Loading @@ -61,9 +61,9 @@ bool Item_sum::init_sum_func_check(THD *thd) /* Save a pointer to object to be used in items for nested set functions */ thd->lex->in_sum_func= this; nest_level= thd->lex->current_select->nest_level; nest_level_tables_count= thd->lex->current_select->join->tables; ref_by= 0; aggr_level= -1; aggr_sel= NULL; max_arg_level= -1; max_sum_func_level= -1; return FALSE; Loading Loading @@ -151,7 +151,10 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref) invalid= aggr_level < 0 && !(allow_sum_func & (1 << nest_level)); } if (!invalid && aggr_level < 0) { aggr_level= nest_level; aggr_sel= thd->lex->current_select; } /* By this moment we either found a subquery where the set function is to be aggregated and assigned a value that is >= 0 to aggr_level, Loading Loading @@ -212,7 +215,6 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref) bool Item_sum::register_sum_func(THD *thd, Item **ref) { SELECT_LEX *sl; SELECT_LEX *aggr_sl= NULL; nesting_map allow_sum_func= thd->lex->allow_sum_func; for (sl= thd->lex->current_select->master_unit()->outer_select() ; sl && sl->nest_level > max_arg_level; Loading @@ -222,7 +224,7 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref) { /* Found the most nested subquery where the function can be aggregated */ aggr_level= sl->nest_level; aggr_sl= sl; aggr_sel= sl; } } if (sl && (allow_sum_func & (1 << sl->nest_level))) Loading @@ -233,21 +235,22 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref) The set function will be aggregated in this subquery. */ aggr_level= sl->nest_level; aggr_sl= sl; aggr_sel= sl; } if (aggr_level >= 0) { ref_by= ref; /* Add the object to the list of registered objects assigned to aggr_sl */ if (!aggr_sl->inner_sum_func_list) /* Add the object to the list of registered objects assigned to aggr_sel */ if (!aggr_sel->inner_sum_func_list) next= this; else { next= aggr_sl->inner_sum_func_list->next; aggr_sl->inner_sum_func_list->next= this; next= aggr_sel->inner_sum_func_list->next; aggr_sel->inner_sum_func_list->next= this; } aggr_sl->inner_sum_func_list= this; aggr_sl->with_sum_func= 1; aggr_sel->inner_sum_func_list= this; aggr_sel->with_sum_func= 1; /* Mark Item_subselect(s) as containing aggregate function all the way up Loading @@ -265,11 +268,11 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref) has aggregate functions directly referenced (i.e. not through a sub-select). */ for (sl= thd->lex->current_select; sl && sl != aggr_sl && sl->master_unit()->item; sl && sl != aggr_sel && sl->master_unit()->item; sl= sl->master_unit()->outer_select() ) sl->master_unit()->item->with_sum_func= 1; } thd->lex->current_select->mark_as_dependent(aggr_sl); thd->lex->current_select->mark_as_dependent(aggr_sel); return FALSE; } Loading Loading @@ -299,10 +302,10 @@ Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements), Item_sum::Item_sum(THD *thd, Item_sum *item): Item_result_field(thd, item), arg_count(item->arg_count), aggr_sel(item->aggr_sel), nest_level(item->nest_level), aggr_level(item->aggr_level), quick_group(item->quick_group), used_tables_cache(item->used_tables_cache), forced_const(item->forced_const), nest_level_tables_count(item->nest_level_tables_count) forced_const(item->forced_const) { if (arg_count <= 2) args=tmp_args; Loading Loading @@ -447,7 +450,7 @@ void Item_sum::update_used_tables () /* the aggregate function is aggregated into its local context */ if (aggr_level == nest_level) used_tables_cache |= (1 << nest_level_tables_count) - 1; used_tables_cache |= (1 << aggr_sel->join->tables) - 1; } } Loading
sql/item_sum.h +3 −1 Original line number Diff line number Diff line Loading @@ -233,6 +233,7 @@ class Item_sum :public Item_result_field Item_sum *next; /* next in the circular chain of registered objects */ uint arg_count; Item_sum *in_sum_func; /* embedding set function if any */ st_select_lex * aggr_sel; /* select where the function is aggregated */ int8 nest_level; /* number of the nesting level of the set function */ int8 aggr_level; /* nesting level of the aggregating subquery */ int8 max_arg_level; /* max level of unbound column references */ Loading @@ -242,7 +243,6 @@ class Item_sum :public Item_result_field protected: table_map used_tables_cache; bool forced_const; byte nest_level_tables_count; public: Loading Loading @@ -365,6 +365,8 @@ class Item_sum :public Item_result_field bool init_sum_func_check(THD *thd); bool check_sum_func(THD *thd, Item **ref); bool register_sum_func(THD *thd, Item **ref); st_select_lex *depended_from() { return (nest_level == aggr_level ? 0 : aggr_sel); } }; Loading