summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/func_group.result37
-rw-r--r--mysql-test/t/func_group.test40
-rw-r--r--sql/item.cc1
-rw-r--r--sql/item.h2
-rw-r--r--sql/sql_select.cc11
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