summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <igor@olga.mysql.com>2007-02-10 23:55:56 -0800
committerunknown <igor@olga.mysql.com>2007-02-10 23:55:56 -0800
commit3e4f834dfbe4b7be9a53f8207bab7b9e59496ba1 (patch)
tree58b088ea256ea395eff1cb3e1489b63bd9c9aa51
parentce8c0ec29b85f336567cbf183008db89575f1fc8 (diff)
downloadmariadb-git-3e4f834dfbe4b7be9a53f8207bab7b9e59496ba1.tar.gz
Fixed bug #26159.
A wrong order of statements in QUICK_GROUP_MIN_MAX_SELECT::reset caused a crash when a query with DISTINCT was executed by a loose scan for an InnoDB table that had been emptied. mysql-test/r/innodb_mysql.result: Added a test case for bug #26159. mysql-test/t/innodb_mysql.test: Added a test case for bug #26159. sql/opt_range.cc: Fixed bug #26159. A wrong order of statements in QUICK_GROUP_MIN_MAX_SELECT::reset caused a crash when a query with DISTINCT was executed by a loose scan for an InnoDB table that had been emptied. For an empty table quick_prefix_select->reset() was not called at all and thus some important initialization steps were missing.
-rw-r--r--mysql-test/r/innodb_mysql.result27
-rw-r--r--mysql-test/t/innodb_mysql.test26
-rw-r--r--sql/opt_range.cc9
3 files changed, 57 insertions, 5 deletions
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index f150af4b6c2..298fc58ffcb 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -383,6 +383,33 @@ EXPLAIN SELECT SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 128 Using filesort
DROP TABLE t1;
+CREATE TABLE t1 (
+id int NOT NULL,
+name varchar(20) NOT NULL,
+dept varchar(20) NOT NULL,
+age tinyint(3) unsigned NOT NULL,
+PRIMARY KEY (id),
+INDEX (name,dept)
+) ENGINE=InnoDB;
+INSERT INTO t1(id, dept, age, name) VALUES
+(3987, 'cs1', 10, 'rs1'), (3988, 'cs2', 20, 'rs1'), (3995, 'cs3', 10, 'rs2'),
+(3996, 'cs4', 20, 'rs2'), (4003, 'cs5', 10, 'rs3'), (4004, 'cs6', 20, 'rs3'),
+(4011, 'cs7', 10, 'rs4'), (4012, 'cs8', 20, 'rs4'), (4019, 'cs9', 10, 'rs5'),
+(4020, 'cs10', 20, 'rs5'),(4027, 'cs11', 10, 'rs6'),(4028, 'cs12', 20, 'rs6');
+EXPLAIN SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range name name 44 NULL 2 Using where; Using index for group-by
+SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5';
+name dept
+rs5 cs10
+rs5 cs9
+DELETE FROM t1;
+EXPLAIN SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range name name 44 NULL 2 Using where; Using index for group-by
+SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5';
+name dept
+DROP TABLE t1;
show variables like 'innodb_rollback_on_timeout';
Variable_name Value
innodb_rollback_on_timeout OFF
diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test
index 45a2ede091b..c351891d205 100644
--- a/mysql-test/t/innodb_mysql.test
+++ b/mysql-test/t/innodb_mysql.test
@@ -384,6 +384,32 @@ EXPLAIN SELECT SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b;
DROP TABLE t1;
+#
+# Bug#26159: crash for a loose scan of a table that has been emptied
+#
+
+CREATE TABLE t1 (
+ id int NOT NULL,
+ name varchar(20) NOT NULL,
+ dept varchar(20) NOT NULL,
+ age tinyint(3) unsigned NOT NULL,
+ PRIMARY KEY (id),
+ INDEX (name,dept)
+) ENGINE=InnoDB;
+INSERT INTO t1(id, dept, age, name) VALUES
+ (3987, 'cs1', 10, 'rs1'), (3988, 'cs2', 20, 'rs1'), (3995, 'cs3', 10, 'rs2'),
+ (3996, 'cs4', 20, 'rs2'), (4003, 'cs5', 10, 'rs3'), (4004, 'cs6', 20, 'rs3'),
+ (4011, 'cs7', 10, 'rs4'), (4012, 'cs8', 20, 'rs4'), (4019, 'cs9', 10, 'rs5'),
+ (4020, 'cs10', 20, 'rs5'),(4027, 'cs11', 10, 'rs6'),(4028, 'cs12', 20, 'rs6');
+
+EXPLAIN SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5';
+SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5';
+DELETE FROM t1;
+EXPLAIN SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5';
+SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5';
+
+DROP TABLE t1;
+
--source include/innodb_rollback_on_timeout.inc
--echo End of 5.0 tests
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 744d222b833..32cf6860d5c 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -8765,14 +8765,13 @@ int QUICK_GROUP_MIN_MAX_SELECT::reset(void)
DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::reset");
file->extra(HA_EXTRA_KEYREAD); /* We need only the key attributes */
- result= file->ha_index_init(index);
- result= file->index_last(record);
- if (result == HA_ERR_END_OF_FILE)
- DBUG_RETURN(0);
- if (result)
+ if ((result= file->ha_index_init(index)))
DBUG_RETURN(result);
if (quick_prefix_select && quick_prefix_select->reset())
DBUG_RETURN(1);
+ result= file->index_last(record);
+ if (result == HA_ERR_END_OF_FILE)
+ DBUG_RETURN(0);
/* Save the prefix of the last group. */
key_copy(last_prefix, record, index_info, group_prefix_len);