#At file:///export/home/didrik/repo/next-mr-opt-team-wl1393-merge/ based on revid:tor.didriksen@stripped
3257 Tor Didriksen 2010-12-07
Bug #58756 Crash in heap_rrnd on query with HAVING ... IN (subquery) + LIMIT
Bug #58761 Crash in Field::is_null in field.h on subquery in WHERE clause
@ mysql-test/include/order_by.inc
New test case
@ mysql-test/r/bug58756.result
New test case.
@ mysql-test/r/order_by_icp_mrr.result
New test case.
@ mysql-test/r/order_by_none.result
New test case.
@ mysql-test/t/bug58756.test
New test case.
@ sql/filesort.cc
In save_index: allocate and copy record pointers for 'count' keys.
@ sql/sql_select.cc
table->sort.found_records is used in init_read_record(), don't set it to found_rows.
Instead: use tab->records to set thd->limit_found_rows, since filesort()
now always return number of found_rows.
added:
mysql-test/r/bug58756.result
mysql-test/t/bug58756.test
modified:
mysql-test/include/order_by.inc
mysql-test/r/order_by_icp_mrr.result
mysql-test/r/order_by_none.result
sql/filesort.cc
sql/sql_select.cc
=== modified file 'mysql-test/include/order_by.inc'
--- a/mysql-test/include/order_by.inc 2010-11-30 11:54:00 +0000
+++ b/mysql-test/include/order_by.inc 2010-12-07 12:30:31 +0000
@@ -1523,6 +1523,42 @@ DROP VIEW v1, v2;
--echo # end of WL#1393 - Optimizing filesort with small limit
#
+# Bug #58761 Crash in Field::is_null in field.h on subquery in WHERE clause
+#
+CREATE TABLE t1 (
+ pk INT NOT NULL AUTO_INCREMENT,
+ col_int_key INT DEFAULT NULL,
+ col_varchar_key VARCHAR(1) DEFAULT NULL,
+ PRIMARY KEY (pk),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+);
+
+INSERT INTO t1 VALUES (27,7,'x');
+INSERT INTO t1 VALUES (28,6,'m');
+INSERT INTO t1 VALUES (29,4,'c');
+
+CREATE TABLE where_subselect
+ SELECT DISTINCT `pk` AS field1 , `pk` AS field2
+ FROM t1 AS alias1
+ WHERE alias1 . `col_int_key` > 229
+ OR alias1 . `col_varchar_key` IS NOT NULL
+ GROUP BY field1, field2
+;
+
+SELECT *
+FROM where_subselect
+WHERE (field1, field2) IN (
+ SELECT DISTINCT `pk` AS field1 , `pk` AS field2
+ FROM t1 AS alias1
+ WHERE alias1 . `col_int_key` > 229
+ OR alias1 . `col_varchar_key` IS NOT NULL
+ GROUP BY field1, field2
+);
+
+drop table t1;
+drop table where_subselect;
+
+#
# Bug#35844: Covering index for ref access not compatible with ORDER BY list
#
=== added file 'mysql-test/r/bug58756.result'
--- a/mysql-test/r/bug58756.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/bug58756.result 2010-12-07 12:30:31 +0000
@@ -0,0 +1,38 @@
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+CREATE TABLE t1 (
+col_time_key time DEFAULT NULL,
+col_datetime_key datetime DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL,
+KEY col_time_key (col_time_key),
+KEY col_datetime_key (col_datetime_key)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES ('17:53:30','2005-11-10 12:40:29','h');
+INSERT INTO t1 VALUES ('11:35:49','2009-04-25 00:00:00','b');
+INSERT INTO t1 VALUES (NULL,'2002-11-27 00:00:00','s');
+INSERT INTO t1 VALUES ('06:01:40','2004-01-26 20:32:32','e');
+INSERT INTO t1 VALUES ('05:45:11','2007-10-26 11:41:40','j');
+INSERT INTO t1 VALUES ('00:00:00','2005-10-07 00:00:00','e');
+INSERT INTO t1 VALUES ('00:00:00','2000-07-15 05:00:34','f');
+INSERT INTO t1 VALUES ('06:11:01','2000-04-03 16:33:32','v');
+INSERT INTO t1 VALUES ('13:02:46',NULL,'x');
+INSERT INTO t1 VALUES ('21:44:25','2001-04-25 01:26:12','m');
+INSERT INTO t1 VALUES ('22:43:58','2000-12-27 00:00:00','c');
+CREATE TABLE t2 (
+col_time_key time DEFAULT NULL,
+col_datetime_key datetime DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL,
+KEY col_time_key (col_time_key),
+KEY col_datetime_key (col_datetime_key)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES ('11:28:45','2004-10-11 18:13:16','w');
+SELECT col_time_key, col_datetime_key
+FROM
+( SELECT * FROM t1 ) AS table1
+HAVING ( 'r' , 'e' ) IN
+( SELECT col_varchar_nokey , col_varchar_nokey FROM t2 )
+ORDER BY col_datetime_key
+LIMIT 10;
+col_time_key col_datetime_key
+DROP TABLE t1;
+DROP TABLE t2;
=== modified file 'mysql-test/r/order_by_icp_mrr.result'
--- a/mysql-test/r/order_by_icp_mrr.result 2010-12-07 10:27:02 +0000
+++ b/mysql-test/r/order_by_icp_mrr.result 2010-12-07 12:30:31 +0000
@@ -2353,6 +2353,36 @@ DROP TABLE t1, tmp;
DROP VIEW v1, v2;
# end of WL#1393 - Optimizing filesort with small limit
CREATE TABLE t1 (
+pk INT NOT NULL AUTO_INCREMENT,
+col_int_key INT DEFAULT NULL,
+col_varchar_key VARCHAR(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+);
+INSERT INTO t1 VALUES (27,7,'x');
+INSERT INTO t1 VALUES (28,6,'m');
+INSERT INTO t1 VALUES (29,4,'c');
+CREATE TABLE where_subselect
+SELECT DISTINCT `pk` AS field1 , `pk` AS field2
+FROM t1 AS alias1
+WHERE alias1 . `col_int_key` > 229
+OR alias1 . `col_varchar_key` IS NOT NULL
+GROUP BY field1, field2
+;
+SELECT *
+FROM where_subselect
+WHERE (field1, field2) IN (
+SELECT DISTINCT `pk` AS field1 , `pk` AS field2
+FROM t1 AS alias1
+WHERE alias1 . `col_int_key` > 229
+OR alias1 . `col_varchar_key` IS NOT NULL
+GROUP BY field1, field2
+);
+field1 field2
+27 27
+drop table t1;
+drop table where_subselect;
+CREATE TABLE t1 (
id1 INT NULL,
id2 INT NOT NULL,
junk INT NOT NULL,
=== modified file 'mysql-test/r/order_by_none.result'
--- a/mysql-test/r/order_by_none.result 2010-12-06 15:21:08 +0000
+++ b/mysql-test/r/order_by_none.result 2010-12-07 12:30:31 +0000
@@ -2352,6 +2352,36 @@ DROP TABLE t1, tmp;
DROP VIEW v1, v2;
# end of WL#1393 - Optimizing filesort with small limit
CREATE TABLE t1 (
+pk INT NOT NULL AUTO_INCREMENT,
+col_int_key INT DEFAULT NULL,
+col_varchar_key VARCHAR(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+);
+INSERT INTO t1 VALUES (27,7,'x');
+INSERT INTO t1 VALUES (28,6,'m');
+INSERT INTO t1 VALUES (29,4,'c');
+CREATE TABLE where_subselect
+SELECT DISTINCT `pk` AS field1 , `pk` AS field2
+FROM t1 AS alias1
+WHERE alias1 . `col_int_key` > 229
+OR alias1 . `col_varchar_key` IS NOT NULL
+GROUP BY field1, field2
+;
+SELECT *
+FROM where_subselect
+WHERE (field1, field2) IN (
+SELECT DISTINCT `pk` AS field1 , `pk` AS field2
+FROM t1 AS alias1
+WHERE alias1 . `col_int_key` > 229
+OR alias1 . `col_varchar_key` IS NOT NULL
+GROUP BY field1, field2
+);
+field1 field2
+27 27
+drop table t1;
+drop table where_subselect;
+CREATE TABLE t1 (
id1 INT NULL,
id2 INT NOT NULL,
junk INT NOT NULL,
=== added file 'mysql-test/t/bug58756.test'
--- a/mysql-test/t/bug58756.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/bug58756.test 2010-12-07 12:30:31 +0000
@@ -0,0 +1,47 @@
+--source include/have_innodb.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+--enable_warnings
+
+CREATE TABLE t1 (
+ col_time_key time DEFAULT NULL,
+ col_datetime_key datetime DEFAULT NULL,
+ col_varchar_nokey varchar(1) DEFAULT NULL,
+ KEY col_time_key (col_time_key),
+ KEY col_datetime_key (col_datetime_key)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+INSERT INTO t1 VALUES ('17:53:30','2005-11-10 12:40:29','h');
+INSERT INTO t1 VALUES ('11:35:49','2009-04-25 00:00:00','b');
+INSERT INTO t1 VALUES (NULL,'2002-11-27 00:00:00','s');
+INSERT INTO t1 VALUES ('06:01:40','2004-01-26 20:32:32','e');
+INSERT INTO t1 VALUES ('05:45:11','2007-10-26 11:41:40','j');
+INSERT INTO t1 VALUES ('00:00:00','2005-10-07 00:00:00','e');
+INSERT INTO t1 VALUES ('00:00:00','2000-07-15 05:00:34','f');
+INSERT INTO t1 VALUES ('06:11:01','2000-04-03 16:33:32','v');
+INSERT INTO t1 VALUES ('13:02:46',NULL,'x');
+INSERT INTO t1 VALUES ('21:44:25','2001-04-25 01:26:12','m');
+INSERT INTO t1 VALUES ('22:43:58','2000-12-27 00:00:00','c');
+
+CREATE TABLE t2 (
+ col_time_key time DEFAULT NULL,
+ col_datetime_key datetime DEFAULT NULL,
+ col_varchar_nokey varchar(1) DEFAULT NULL,
+ KEY col_time_key (col_time_key),
+ KEY col_datetime_key (col_datetime_key)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+INSERT INTO t2 VALUES ('11:28:45','2004-10-11 18:13:16','w');
+
+SELECT col_time_key, col_datetime_key
+FROM
+( SELECT * FROM t1 ) AS table1
+HAVING ( 'r' , 'e' ) IN
+ ( SELECT col_varchar_nokey , col_varchar_nokey FROM t2 )
+ORDER BY col_datetime_key
+LIMIT 10;
+
+DROP TABLE t1;
+DROP TABLE t2;
=== modified file 'sql/filesort.cc'
--- a/sql/filesort.cc 2010-12-06 09:46:49 +0000
+++ b/sql/filesort.cc 2010-12-07 12:30:31 +0000
@@ -404,6 +404,8 @@ static void make_char_array(FILESORT_INF
{
DBUG_ENTER("make_char_array");
+ DBUG_PRINT("info", ("num_records %u length %u", num_records, length));
+
if (!info->sort_keys)
info->sort_keys=
(uchar**) my_malloc(num_records * (length + sizeof(uchar*)), MYF(0));
@@ -1094,8 +1096,6 @@ static bool save_index(Sort_param *param
my_string_ptr_sort((uchar*) sort_keys, count, param->sort_length);
res_length= param->res_length;
offset= param->rec_length-res_length;
- if ((ha_rows) count > param->max_rows && param->max_rows > 0)
- count=(uint) param->max_rows;
if (!(to= table_sort->record_pointers=
(uchar*) my_malloc(res_length*count, MYF(MY_WME))))
DBUG_RETURN(1); /* purecov: inspected */
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2010-12-06 15:21:08 +0000
+++ b/sql/sql_select.cc 2010-12-07 12:30:31 +0000
@@ -3276,6 +3276,15 @@ JOIN::exec()
select_options & OPTION_FOUND_ROWS
? HA_POS_ERROR : unit->select_limit_cnt;
+ DBUG_PRINT("info", ("has_group_by %d "
+ "curr_join->tables %d "
+ "curr_join->m_select_limit %d "
+ "unit->select_limit_cnt %d",
+ has_group_by,
+ curr_join->tables,
+ (int) curr_join->m_select_limit,
+ (int) unit->select_limit_cnt));
+
if (create_sort_index(thd,
curr_join,
order_arg,
@@ -3314,8 +3323,7 @@ JOIN::exec()
error= do_select(curr_join, curr_fields_list, NULL, procedure);
thd->limit_found_rows= curr_join->send_records;
if (curr_join->order &&
- curr_join->sortorder &&
- curr_join->select_options & OPTION_FOUND_ROWS)
+ curr_join->sortorder)
{
/* Use info provided by filesort. */
DBUG_ASSERT(curr_join->tables > curr_join->const_tables);
@@ -20205,7 +20213,7 @@ create_sort_index(THD *thd, JOIN *join,
filesort_retval= filesort(thd, table, join->sortorder, length,
select, filesort_limit, 0,
&examined_rows, &found_rows);
- table->sort.found_records= found_rows;
+ table->sort.found_records= filesort_retval;
tab->records= found_rows; // For SQL_CALC_ROWS
if (select)
{
Attachment: [text/bzr-bundle] bzr/tor.didriksen@oracle.com-20101207123031-ezu6ec5r5fv3o181.bundle