Commit 3e4f834d authored by unknown's avatar unknown

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.
parent ce8c0ec2
...@@ -383,6 +383,33 @@ EXPLAIN SELECT SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b; ...@@ -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 id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 128 Using filesort 1 SIMPLE t1 ALL NULL NULL NULL NULL 128 Using filesort
DROP TABLE t1; 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'; show variables like 'innodb_rollback_on_timeout';
Variable_name Value Variable_name Value
innodb_rollback_on_timeout OFF innodb_rollback_on_timeout OFF
......
...@@ -384,6 +384,32 @@ EXPLAIN SELECT SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b; ...@@ -384,6 +384,32 @@ EXPLAIN SELECT SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b;
DROP TABLE t1; 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 --source include/innodb_rollback_on_timeout.inc
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -8765,14 +8765,13 @@ int QUICK_GROUP_MIN_MAX_SELECT::reset(void) ...@@ -8765,14 +8765,13 @@ int QUICK_GROUP_MIN_MAX_SELECT::reset(void)
DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::reset"); DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::reset");
file->extra(HA_EXTRA_KEYREAD); /* We need only the key attributes */ file->extra(HA_EXTRA_KEYREAD); /* We need only the key attributes */
result= file->ha_index_init(index); if ((result= file->ha_index_init(index)))
result= file->index_last(record);
if (result == HA_ERR_END_OF_FILE)
DBUG_RETURN(0);
if (result)
DBUG_RETURN(result); DBUG_RETURN(result);
if (quick_prefix_select && quick_prefix_select->reset()) if (quick_prefix_select && quick_prefix_select->reset())
DBUG_RETURN(1); 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. */ /* Save the prefix of the last group. */
key_copy(last_prefix, record, index_info, group_prefix_len); key_copy(last_prefix, record, index_info, group_prefix_len);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment