diff options
-rw-r--r-- | mysql-test/r/func_group.result | 37 | ||||
-rw-r--r-- | mysql-test/t/func_group.test | 40 | ||||
-rw-r--r-- | sql/item.cc | 1 | ||||
-rw-r--r-- | sql/item.h | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 11 |
5 files changed, 89 insertions, 2 deletions
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 85ddfaac4e0..d892deba63c 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -1448,4 +1448,41 @@ COUNT(*) 0 SET SQL_MODE=default; DROP TABLE t1; +CREATE TABLE derived1 (a bigint(21)); +INSERT INTO derived1 VALUES (2); +CREATE TABLE D ( +pk int(11) NOT NULL AUTO_INCREMENT, +int_nokey int(11) DEFAULT NULL, +int_key int(11) DEFAULT NULL, +filler blob, +PRIMARY KEY (pk), +KEY int_key (int_key) +); +INSERT INTO D VALUES +(39,40,4,repeat(' X', 42)), +(43,56,4,repeat(' X', 42)), +(47,12,4,repeat(' X', 42)), +(71,28,4,repeat(' X', 42)), +(76,54,4,repeat(' X', 42)), +(83,45,4,repeat(' X', 42)), +(105,53,12,NULL); +SELECT +(SELECT COUNT( int_nokey ) +FROM derived1 AS X +WHERE +X.int_nokey < 61 +GROUP BY pk +LIMIT 1) +FROM D AS X +WHERE X.int_key < 13 +GROUP BY int_nokey LIMIT 1; +(SELECT COUNT( int_nokey ) +FROM derived1 AS X +WHERE +X.int_nokey < 61 +GROUP BY pk +LIMIT 1) +1 +DROP TABLE derived1; +DROP TABLE D; End of 5.0 tests diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index 38779ac1a2f..cfa2e038fa2 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -955,5 +955,45 @@ SET SQL_MODE=default; DROP TABLE t1; +# +# Bug #37348: Crash in or immediately after JOIN::make_sum_func_list +# + +CREATE TABLE derived1 (a bigint(21)); +INSERT INTO derived1 VALUES (2); + + +CREATE TABLE D ( + pk int(11) NOT NULL AUTO_INCREMENT, + int_nokey int(11) DEFAULT NULL, + int_key int(11) DEFAULT NULL, + filler blob, + PRIMARY KEY (pk), + KEY int_key (int_key) +); + +INSERT INTO D VALUES + (39,40,4,repeat(' X', 42)), + (43,56,4,repeat(' X', 42)), + (47,12,4,repeat(' X', 42)), + (71,28,4,repeat(' X', 42)), + (76,54,4,repeat(' X', 42)), + (83,45,4,repeat(' X', 42)), + (105,53,12,NULL); + +SELECT + (SELECT COUNT( int_nokey ) + FROM derived1 AS X + WHERE + X.int_nokey < 61 + GROUP BY pk + LIMIT 1) +FROM D AS X +WHERE X.int_key < 13 +GROUP BY int_nokey LIMIT 1; + +DROP TABLE derived1; +DROP TABLE D; + ### --echo End of 5.0 tests diff --git a/sql/item.cc b/sql/item.cc index 220c72059d1..c284e8b3bf4 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1323,6 +1323,7 @@ public: else Item_ident::print(str); } + virtual Ref_Type ref_type() { return AGGREGATE_REF; } }; diff --git a/sql/item.h b/sql/item.h index 852b0fcc1ba..22eb0c08e2d 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1899,7 +1899,7 @@ class Item_ref :public Item_ident protected: void set_properties(); public: - enum Ref_Type { REF, DIRECT_REF, VIEW_REF, OUTER_REF }; + enum Ref_Type { REF, DIRECT_REF, VIEW_REF, OUTER_REF, AGGREGATE_REF }; Field *result_field; /* Save result here */ Item **ref; Item_ref(Name_resolution_context *context_arg, diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3b4668a3925..777d32ba149 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -14205,6 +14205,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, Item *pos; List_iterator_fast<Item> li(all_fields); Copy_field *copy= NULL; + IF_DBUG(Copy_field *copy_start); res_selected_fields.empty(); res_all_fields.empty(); List_iterator_fast<Item> itr(res_all_fields); @@ -14217,12 +14218,19 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, goto err2; param->copy_funcs.empty(); + IF_DBUG(copy_start= copy); for (i= 0; (pos= li++); i++) { Field *field; char *tmp; Item *real_pos= pos->real_item(); - if (real_pos->type() == Item::FIELD_ITEM) + /* + Aggregate functions can be substituted for fields (by e.g. temp tables). + We need to filter those substituted fields out. + */ + if (real_pos->type() == Item::FIELD_ITEM && + !(real_pos != pos && + ((Item_ref *)pos)->ref_type() == Item_ref::AGGREGATE_REF)) { Item_field *item; if (!(item= new Item_field(thd, ((Item_field*) real_pos)))) @@ -14270,6 +14278,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, goto err; if (copy) { + DBUG_ASSERT (param->field_count > (uint) (copy - copy_start)); copy->set(tmp, item->result_field); item->result_field->move_field(copy->to_ptr,copy->to_null_ptr,1); #ifdef HAVE_purify |