summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Glukhov <sergey.glukhov@oracle.com>2012-04-04 13:29:45 +0400
committerSergey Glukhov <sergey.glukhov@oracle.com>2012-04-04 13:29:45 +0400
commit17817a30094aff44fc1fbaf4f39a3f0cbe9a13da (patch)
treecaa9db7fdd17a35c41bd544088379eda89ac165f
parent59e0eb1e2ce244cd35650b615a80887c1d637a8b (diff)
downloadmariadb-git-17817a30094aff44fc1fbaf4f39a3f0cbe9a13da.tar.gz
Bug#11766300 59387: FAILING ASSERTION: CURSOR->POS_STATE == 1997660512 (BTR_PCUR_IS_POSITIONE
Bug#13639204 64111: CRASH ON SELECT SUBQUERY WITH NON UNIQUE INDEX The crash happened due to wrong calculation of key length during creation of reference for sort order index. The problem is that keyuse->used_tables can have OUTER_REF_TABLE_BIT enabled but used_tables parameter(create_ref_for_key() func) does not have it. So key parts which have OUTER_REF_TABLE_BIT are ommited and it could lead to incorrect key length calculation(zero key length).
-rw-r--r--mysql-test/r/subselect_innodb.result60
-rw-r--r--mysql-test/t/subselect_innodb.test56
-rw-r--r--sql/sql_select.cc7
-rw-r--r--storage/innobase/handler/ha_innodb.cc1
-rw-r--r--storage/innodb_plugin/handler/ha_innodb.cc1
5 files changed, 124 insertions, 1 deletions
diff --git a/mysql-test/r/subselect_innodb.result b/mysql-test/r/subselect_innodb.result
index 6c6d563e284..4069958267a 100644
--- a/mysql-test/r/subselect_innodb.result
+++ b/mysql-test/r/subselect_innodb.result
@@ -245,3 +245,63 @@ x
NULL
drop procedure p1;
drop tables t1,t2,t3;
+#
+# Bug #11766300 59387: FAILING ASSERTION: CURSOR->POS_STATE == 1997660512 (BTR_PCUR_IS_POSITIONE
+#
+CREATE TABLE t1 (a INT) ENGINE=INNODB;
+INSERT INTO t1 VALUES (0);
+CREATE TABLE t2 (d BINARY(2), PRIMARY KEY (d(1)), UNIQUE KEY (d)) ENGINE=INNODB;
+SELECT 1 FROM t1 WHERE NOT EXISTS
+(SELECT 1 FROM t2 WHERE d = (SELECT d FROM t2 WHERE a >= 1) ORDER BY d);
+1
+1
+EXPLAIN SELECT 1 FROM t1 WHERE NOT EXISTS
+(SELECT 1 FROM t2 WHERE d = (SELECT d FROM t2 WHERE a >= 1) ORDER BY d);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 1 Using where
+2 DEPENDENT SUBQUERY t2 eq_ref PRIMARY,d d 2 func 1 Using where
+3 DEPENDENT SUBQUERY t2 index NULL d 2 NULL 1 Using where; Using index
+DROP TABLE t2;
+CREATE TABLE t2 (b INT, c INT, UNIQUE KEY (b), UNIQUE KEY (b, c )) ENGINE=INNODB;
+INSERT INTO t2 VALUES (1, 1);
+SELECT 1 FROM t1
+WHERE a != (SELECT 1 FROM t2 WHERE a <=> b OR a > '' AND 6 = 7 ORDER BY b, c);
+1
+DROP TABLE t1, t2;
+#
+# Bug #13639204 64111: CRASH ON SELECT SUBQUERY WITH NON UNIQUE
+# INDEX
+#
+CREATE TABLE t1 (
+id int
+) ENGINE=InnoDB;
+INSERT INTO t1 (id) VALUES (11);
+CREATE TABLE t2 (
+t1_id int,
+position int,
+KEY t1_id (t1_id),
+KEY t1_id_position (t1_id,position)
+) ENGINE=InnoDB;
+EXPLAIN SELECT
+(SELECT position FROM t2
+WHERE t2.t1_id = t1.id
+ORDER BY t2.t1_id , t2.position
+LIMIT 10,1
+) AS maxkey
+FROM t1
+LIMIT 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 Using where
+SELECT
+(SELECT position FROM t2
+WHERE t2.t1_id = t1.id
+ORDER BY t2.t1_id , t2.position
+LIMIT 10,1
+) AS maxkey
+FROM t1
+LIMIT 1;
+maxkey
+NULL
+DROP TABLE t1,t2;
+End of 5.1 tests
diff --git a/mysql-test/t/subselect_innodb.test b/mysql-test/t/subselect_innodb.test
index 573fe0c1810..ce070b454c3 100644
--- a/mysql-test/t/subselect_innodb.test
+++ b/mysql-test/t/subselect_innodb.test
@@ -238,3 +238,59 @@ call p1();
call p1();
drop procedure p1;
drop tables t1,t2,t3;
+
+--echo #
+--echo # Bug #11766300 59387: FAILING ASSERTION: CURSOR->POS_STATE == 1997660512 (BTR_PCUR_IS_POSITIONE
+--echo #
+
+CREATE TABLE t1 (a INT) ENGINE=INNODB;
+INSERT INTO t1 VALUES (0);
+CREATE TABLE t2 (d BINARY(2), PRIMARY KEY (d(1)), UNIQUE KEY (d)) ENGINE=INNODB;
+
+SELECT 1 FROM t1 WHERE NOT EXISTS
+(SELECT 1 FROM t2 WHERE d = (SELECT d FROM t2 WHERE a >= 1) ORDER BY d);
+
+EXPLAIN SELECT 1 FROM t1 WHERE NOT EXISTS
+(SELECT 1 FROM t2 WHERE d = (SELECT d FROM t2 WHERE a >= 1) ORDER BY d);
+
+DROP TABLE t2;
+
+CREATE TABLE t2 (b INT, c INT, UNIQUE KEY (b), UNIQUE KEY (b, c )) ENGINE=INNODB;
+INSERT INTO t2 VALUES (1, 1);
+
+SELECT 1 FROM t1
+WHERE a != (SELECT 1 FROM t2 WHERE a <=> b OR a > '' AND 6 = 7 ORDER BY b, c);
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug #13639204 64111: CRASH ON SELECT SUBQUERY WITH NON UNIQUE
+--echo # INDEX
+--echo #
+CREATE TABLE t1 (
+id int
+) ENGINE=InnoDB;
+INSERT INTO t1 (id) VALUES (11);
+
+CREATE TABLE t2 (
+t1_id int,
+position int,
+KEY t1_id (t1_id),
+KEY t1_id_position (t1_id,position)
+) ENGINE=InnoDB;
+
+let $query=SELECT
+(SELECT position FROM t2
+WHERE t2.t1_id = t1.id
+ORDER BY t2.t1_id , t2.position
+LIMIT 10,1
+) AS maxkey
+FROM t1
+LIMIT 1;
+
+eval EXPLAIN $query;
+eval $query;
+
+DROP TABLE t1,t2;
+
+--echo End of 5.1 tests
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 0d8dc740431..a0390baffaa 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -5793,6 +5793,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
}
keyuse++;
} while (keyuse->table == table && keyuse->key == key);
+ DBUG_ASSERT(length > 0 && keyparts != 0);
} /* not ftkey */
/* set up fieldref */
@@ -13426,6 +13427,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
DBUG_ENTER("test_if_skip_sort_order");
LINT_INIT(ref_key_parts);
+ /* Check that we are always called with first non-const table */
+ DBUG_ASSERT(tab == tab->join->join_tab + tab->join->const_tables);
+
/*
Keys disabled by ALTER TABLE ... DISABLE KEYS should have already
been taken into account.
@@ -13507,7 +13511,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
while (keyuse->key != new_ref_key && keyuse->table == tab->table)
keyuse++;
if (create_ref_for_key(tab->join, tab, keyuse,
- tab->join->const_table_map))
+ (tab->join->const_table_map |
+ OUTER_REF_TABLE_BIT)))
DBUG_RETURN(0);
pick_table_access_method(tab);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index c59c02abe1b..6576016501f 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -4871,6 +4871,7 @@ ha_innobase::index_read(
DBUG_ENTER("index_read");
ut_a(prebuilt->trx == thd_to_trx(user_thd));
+ ut_ad(key_len != 0 || find_flag != HA_READ_KEY_EXACT);
ha_statistic_increment(&SSV::ha_read_key_count);
diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
index d1e9649be07..b8e9ccc72ef 100644
--- a/storage/innodb_plugin/handler/ha_innodb.cc
+++ b/storage/innodb_plugin/handler/ha_innodb.cc
@@ -5575,6 +5575,7 @@ ha_innobase::index_read(
DBUG_ENTER("index_read");
ut_a(prebuilt->trx == thd_to_trx(user_thd));
+ ut_ad(key_len != 0 || find_flag != HA_READ_KEY_EXACT);
ha_statistic_increment(&SSV::ha_read_key_count);