From b789b4f33cdf245d1f582aa755410754b197a693 Mon Sep 17 00:00:00 2001 From: Evgeny Potemkin Date: Wed, 13 Aug 2008 22:24:55 +0400 Subject: [PATCH 1/4] Bug#38195: Incorrect handling of aggregate functions when loose index scan is used causes server crash. When the loose index scan access method is used values of aggregated functions are precomputed by it. Aggregation of such functions shouldn't be performed in this case and functions should be treated as normal ones. The create_tmp_table function wasn't taking this into account and this led to a crash if a query has MIN/MAX aggregate functions and employs temporary table and loose index scan. Now the JOIN::exec and the create_tmp_table functions treat MIN/MAX aggregate functions as normal ones when the loose index scan is used. mysql-test/r/group_min_max.result: Added a test case for the bug#38195. mysql-test/t/group_min_max.test: Added a test case for the bug#38195. sql/sql_select.cc: Bug#38195: Incorrect handling of aggregate functions when loose index scan is used causes server crash. Now the JOIN::exec and the create_tmp_table functions treat MIN/MAX aggregate functions as normal ones when the loose index scan is used. --- mysql-test/r/group_min_max.result | 27 +++++++++++++++++++++++++++ mysql-test/t/group_min_max.test | 12 ++++++++++++ sql/sql_select.cc | 5 ++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index 5982931e677..846e8ece656 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2353,3 +2353,30 @@ a MIN(b) MAX(b) AVG(b) 2 1 3 2.0000 1 1 3 2.0000 DROP TABLE t1; +create table t1 (a int, b int, primary key (a,b), key `index` (a,b)) engine=MyISAM; +insert into t1 (a,b) values (0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(0,7), +(0,8),(0,9),(0,10),(0,11),(0,12),(0,13); +insert into t1 (a,b) select a, max(b)+1 from t1 where a = 0 group by a; +select * from t1; +a b +0 0 +0 1 +0 2 +0 3 +0 4 +0 5 +0 6 +0 7 +0 8 +0 9 +0 10 +0 11 +0 12 +0 13 +0 14 +explain extended select sql_buffer_result a, max(b)+1 from t1 where a = 0 group by a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY,index PRIMARY 4 NULL 6 Using where; Using index for group-by; Using temporary +Warnings: +Note 1003 select sql_buffer_result `test`.`t1`.`a` AS `a`,(max(`test`.`t1`.`b`) + 1) AS `max(b)+1` from `test`.`t1` where (`test`.`t1`.`a` = 0) group by `test`.`t1`.`a` +drop table t1; diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test index 7f2607b513d..196dd3379f9 100644 --- a/mysql-test/t/group_min_max.test +++ b/mysql-test/t/group_min_max.test @@ -916,3 +916,15 @@ SELECT a, MIN(b), MAX(b), AVG(b) FROM t1 GROUP BY a ORDER BY a DESC; SELECT a, MIN(b), MAX(b), AVG(b) FROM t1 GROUP BY a ORDER BY a DESC; DROP TABLE t1; + +# +# Bug#38195: Incorrect handling of aggregate functions when loose index scan is +# used causes server crash. +# +create table t1 (a int, b int, primary key (a,b), key `index` (a,b)) engine=MyISAM; +insert into t1 (a,b) values (0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(0,7), +(0,8),(0,9),(0,10),(0,11),(0,12),(0,13); +insert into t1 (a,b) select a, max(b)+1 from t1 where a = 0 group by a; +select * from t1; +explain extended select sql_buffer_result a, max(b)+1 from t1 where a = 0 group by a; +drop table t1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6de4b296d34..6928effc1a5 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1724,7 +1724,8 @@ JOIN::exec() if (!items1) { items1= items0 + all_fields.elements; - if (sort_and_group || curr_tmp_table->group) + if (sort_and_group || curr_tmp_table->group || + tmp_table_param.precomputed_group_by) { if (change_to_use_tmp_fields(thd, items1, tmp_fields_list1, tmp_all_fields1, @@ -9259,6 +9260,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, MI_COLUMNDEF *recinfo; uint total_uneven_bit_length= 0; bool force_copy_fields= param->force_copy_fields; + /* Treat sum functions as normal ones when loose index scan is used. */ + save_sum_fields|= param->precomputed_group_by; DBUG_ENTER("create_tmp_table"); DBUG_PRINT("enter",("distinct: %d save_sum_fields: %d rows_limit: %lu group: %d", (int) distinct, (int) save_sum_fields, From 368f7f63b2a3ec7726051c061e4d031e9d98ab6b Mon Sep 17 00:00:00 2001 From: Evgeny Potemkin Date: Thu, 14 Aug 2008 23:55:18 +0400 Subject: [PATCH 2/4] Fixed failing test case for the bug#38195. --- mysql-test/r/group_min_max.result | 6 ++---- mysql-test/t/group_min_max.test | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index 846e8ece656..c417a8d3528 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2355,7 +2355,7 @@ a MIN(b) MAX(b) AVG(b) DROP TABLE t1; create table t1 (a int, b int, primary key (a,b), key `index` (a,b)) engine=MyISAM; insert into t1 (a,b) values (0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(0,7), -(0,8),(0,9),(0,10),(0,11),(0,12),(0,13); +(0,8),(0,9),(0,10),(0,11); insert into t1 (a,b) select a, max(b)+1 from t1 where a = 0 group by a; select * from t1; a b @@ -2372,11 +2372,9 @@ a b 0 10 0 11 0 12 -0 13 -0 14 explain extended select sql_buffer_result a, max(b)+1 from t1 where a = 0 group by a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,index PRIMARY 4 NULL 6 Using where; Using index for group-by; Using temporary +1 SIMPLE t1 range PRIMARY,index PRIMARY 4 NULL 5 Using where; Using index for group-by; Using temporary Warnings: Note 1003 select sql_buffer_result `test`.`t1`.`a` AS `a`,(max(`test`.`t1`.`b`) + 1) AS `max(b)+1` from `test`.`t1` where (`test`.`t1`.`a` = 0) group by `test`.`t1`.`a` drop table t1; diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test index 196dd3379f9..60a80ecf9d5 100644 --- a/mysql-test/t/group_min_max.test +++ b/mysql-test/t/group_min_max.test @@ -923,7 +923,7 @@ DROP TABLE t1; # create table t1 (a int, b int, primary key (a,b), key `index` (a,b)) engine=MyISAM; insert into t1 (a,b) values (0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(0,7), -(0,8),(0,9),(0,10),(0,11),(0,12),(0,13); +(0,8),(0,9),(0,10),(0,11); insert into t1 (a,b) select a, max(b)+1 from t1 where a = 0 group by a; select * from t1; explain extended select sql_buffer_result a, max(b)+1 from t1 where a = 0 group by a; From 2b179caf9a5b221e17cb30e1cd93929ba7e5c1cb Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 15 Aug 2008 11:40:05 +0500 Subject: [PATCH 3/4] Fix for bug #34779: crash in checksum table on federated tables with blobs containing nulls Problem: FEDERATED SE improperly stores NULL fields in the record buffer. Fix: store them properly. mysql-test/r/federated.result: Fix for bug #34779: crash in checksum table on federated tables with blobs containing nulls - test result. mysql-test/t/federated.test: Fix for bug #34779: crash in checksum table on federated tables with blobs containing nulls - test case. sql/ha_federated.cc: Fix for bug #34779: crash in checksum table on federated tables with blobs containing nulls - storing a NULL field in the record buffer we must initialize its data as other code may rely on it. --- mysql-test/r/federated.result | 11 +++++++++++ mysql-test/t/federated.test | 22 ++++++++++++++++++++++ sql/ha_federated.cc | 3 +++ 3 files changed, 36 insertions(+) diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result index 685e4d0c335..2c001a9e860 100644 --- a/mysql-test/r/federated.result +++ b/mysql-test/r/federated.result @@ -2071,7 +2071,18 @@ DROP TABLE t1; DROP TABLE t1; CREATE TABLE t1 (a INT) ENGINE=federated CONNECTION='mysql://@:://'; DROP TABLE t1; +CREATE TABLE t1 (a LONGBLOB, b LONGBLOB); +INSERT INTO t1 VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaa', NULL); +CREATE TABLE t1 +(a LONGBLOB, b LONGBLOB) ENGINE=FEDERATED +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1'; +CHECKSUM TABLE t1; +Table Checksum +test.t1 2465757603 +DROP TABLE t1; +DROP TABLE t1; DROP TABLE IF EXISTS federated.t1; DROP DATABASE IF EXISTS federated; DROP TABLE IF EXISTS federated.t1; DROP DATABASE IF EXISTS federated; +End of 5.0 tests diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test index 9e7548a21ed..2d98c51a548 100644 --- a/mysql-test/t/federated.test +++ b/mysql-test/t/federated.test @@ -1750,4 +1750,26 @@ DROP TABLE t1; CREATE TABLE t1 (a INT) ENGINE=federated CONNECTION='mysql://@:://'; DROP TABLE t1; + +# +# Bug #34779: crash in checksum table on federated tables with blobs +# containing nulls +# +connection slave; +CREATE TABLE t1 (a LONGBLOB, b LONGBLOB); +INSERT INTO t1 VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaa', NULL); +connection master; +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 + (a LONGBLOB, b LONGBLOB) ENGINE=FEDERATED + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1'; +CHECKSUM TABLE t1; +connection slave; +DROP TABLE t1; +connection master; +DROP TABLE t1; + + source include/federated_cleanup.inc; + +--echo End of 5.0 tests diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index 9ce5d44534e..b4788dd9c87 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -731,7 +731,10 @@ uint ha_federated::convert_row_to_internal_format(byte *record, old_ptr= (my_ptrdiff_t) (record - table->record[0]); (*field)->move_field(old_ptr); if (!row[x]) + { (*field)->set_null(); + (*field)->reset(); + } else { (*field)->set_notnull(); From 0546add33e294f3468226a7a20125c99f67103fe Mon Sep 17 00:00:00 2001 From: Chad MILLER Date: Fri, 15 Aug 2008 13:55:05 -0400 Subject: [PATCH 4/4] Correcting tree name in bzr config. Should not include team suffix. --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 557df1b1ffe..f79c1cd6319 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.0-bugteam" +tree_name = "mysql-5.0"