summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <sergefp@mysql.com>2006-08-15 20:33:14 +0400
committerunknown <sergefp@mysql.com>2006-08-15 20:33:14 +0400
commit9907e970aea28ce186e110084c3a4f2d6ac0c602 (patch)
treefc2e555039f9cfa7f5c80b261a3d4f08bacd093f
parent84ece59cefafc7a223c65aa7c763f5e72afaa1fc (diff)
downloadmariadb-git-9907e970aea28ce186e110084c3a4f2d6ac0c602.tar.gz
BUG#21077: Possible crash caused by invalid sequence of handler::* calls:
The crash was caused by invalid sequence of handler::** calls: ha_smth->index_init(); ha_smth->index_next_same(); (2) (2) is an invalid call as it was not preceeded by any 'scan setup' call like index_first() or index_read(). The cause was that QUICK_SELECT::reset() didn't "fully reset" the quick select- current QUICK_RANGE wasn't forgotten, and quick select might attempt to continue reading the range, which would result in the above mentioned invalid sequence of handler calls. 5.x versions are not affected by the bug - they already have the missing "range=NULL" clause. mysql-test/r/innodb_mysql.result: Testcase for BUG#21077 mysql-test/t/innodb_mysql.test: Testcase for BUG#21077 sql/opt_range.h: BUG#21077: Possible crash caused by invalid sequence of handler::* calls: - Make QUICK_SELECT::reset() really reset the quick select
-rw-r--r--mysql-test/r/innodb_mysql.result21
-rw-r--r--mysql-test/t/innodb_mysql.test27
-rw-r--r--sql/opt_range.h2
3 files changed, 49 insertions, 1 deletions
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index 920d7aa42ce..ee4c114087d 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -83,3 +83,24 @@ b a
3 3
3 3
DROP TABLE t1, t2, t3;
+CREATE TABLE `t1` (`id1` INT) ;
+INSERT INTO `t1` (`id1`) VALUES (1),(5),(2);
+CREATE TABLE `t2` (
+`id1` INT,
+`id2` INT NOT NULL,
+`id3` INT,
+`id4` INT NOT NULL,
+UNIQUE (`id2`,`id4`),
+KEY (`id1`)
+) ENGINE=InnoDB;
+INSERT INTO `t2`(`id1`,`id2`,`id3`,`id4`) VALUES
+(1,1,1,0),
+(1,1,2,1),
+(5,1,2,2),
+(6,1,2,3),
+(1,2,2,2),
+(1,2,1,1);
+SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` = 1 AND `id3` = 2);
+id1
+2
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test
index 0b789e1a6d5..a5fe248604f 100644
--- a/mysql-test/t/innodb_mysql.test
+++ b/mysql-test/t/innodb_mysql.test
@@ -90,3 +90,30 @@ SELECT STRAIGHT_JOIN SQL_NO_CACHE t1.b, t1.a FROM t1, t3, t2 WHERE
t3.a = t2.a AND t2.b = t1.a AND t3.b = 1 AND t3.c IN (1, 2)
ORDER BY t1.b LIMIT 5;
DROP TABLE t1, t2, t3;
+
+
+# BUG#21077 (The testcase is not deterministic so correct execution doesn't
+# prove anything) For proof one should track if sequence of ha_innodb::* func
+# calls is correct.
+CREATE TABLE `t1` (`id1` INT) ;
+INSERT INTO `t1` (`id1`) VALUES (1),(5),(2);
+
+CREATE TABLE `t2` (
+ `id1` INT,
+ `id2` INT NOT NULL,
+ `id3` INT,
+ `id4` INT NOT NULL,
+ UNIQUE (`id2`,`id4`),
+ KEY (`id1`)
+) ENGINE=InnoDB;
+
+INSERT INTO `t2`(`id1`,`id2`,`id3`,`id4`) VALUES
+(1,1,1,0),
+(1,1,2,1),
+(5,1,2,2),
+(6,1,2,3),
+(1,2,2,2),
+(1,2,1,1);
+
+SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` = 1 AND `id3` = 2);
+DROP TABLE t1, t2;
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 15f0bf02b34..d2f4452a762 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -86,7 +86,7 @@ public:
QUICK_SELECT(THD *thd, TABLE *table,uint index_arg,bool no_alloc=0);
virtual ~QUICK_SELECT();
- void reset(void) { next=0; it.rewind(); }
+ void reset(void) { next=0; it.rewind(); range= NULL;}
int init()
{
key_part_info= head->key_info[index].key_part;