summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorgi Kodinov <Georgi.Kodinov@Oracle.com>2010-11-03 16:09:17 +0200
committerGeorgi Kodinov <Georgi.Kodinov@Oracle.com>2010-11-03 16:09:17 +0200
commit7b2e07232a9307220187ee858c7c12a0d899d593 (patch)
tree72015dab42a49c01b928bb1243b9be81273453df
parent39bceaac0295e556a8db5d354315b39dfb0f3ef6 (diff)
parent4cfa91f42c4cde9c35979cd2b9837cb60213d876 (diff)
downloadmariadb-git-7b2e07232a9307220187ee858c7c12a0d899d593.tar.gz
merge
-rw-r--r--configure.in2
-rw-r--r--mysql-test/r/ps.result38
-rw-r--r--mysql-test/suite/innodb/r/innodb_bug57255.result10
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug57255.test36
-rw-r--r--mysql-test/suite/innodb_plugin/r/innodb_bug57255.result10
-rw-r--r--mysql-test/suite/innodb_plugin/t/innodb_bug57255.test36
-rw-r--r--mysql-test/t/ps.test22
-rw-r--r--sql/item_subselect.cc26
-rw-r--r--sql/sql_prepare.cc4
-rw-r--r--storage/innobase/row/row0mysql.c9
-rw-r--r--storage/innodb_plugin/ChangeLog12
-rw-r--r--storage/innodb_plugin/row/row0mysql.c9
12 files changed, 198 insertions, 16 deletions
diff --git a/configure.in b/configure.in
index 4ea978c268e..7fd581af009 100644
--- a/configure.in
+++ b/configure.in
@@ -12,7 +12,7 @@ dnl
dnl When changing the major version number please also check the switch
dnl statement in mysqlbinlog::check_master_version(). You may also need
dnl to update version.c in ndb.
-AC_INIT([MySQL Server], [5.1.52], [], [mysql])
+AC_INIT([MySQL Server], [5.1.54], [], [mysql])
AC_CONFIG_SRCDIR([sql/mysqld.cc])
AC_CANONICAL_SYSTEM
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index f21f1d83acd..84c64a3905a 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -3001,4 +3001,42 @@ EXECUTE stmt;
1
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
+#
+# Bug#54494 crash with explain extended and prepared statements
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1),(2);
+PREPARE stmt FROM 'EXPLAIN EXTENDED SELECT 1 FROM t1 RIGHT JOIN t1 t2 ON 1';
+EXECUTE stmt;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` `t2` left join `test`.`t1` on(1) where 1
+EXECUTE stmt;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` `t2` left join `test`.`t1` on(1) where 1
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+#
+# Bug#54488 crash when using explain and prepared statements with subqueries
+#
+CREATE TABLE t1(f1 INT);
+INSERT INTO t1 VALUES (1),(1);
+PREPARE stmt FROM 'EXPLAIN SELECT 1 FROM t1 WHERE (SELECT (SELECT 1 FROM t1 GROUP BY f1))';
+EXECUTE stmt;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+EXECUTE stmt;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
End of 5.1 tests.
diff --git a/mysql-test/suite/innodb/r/innodb_bug57255.result b/mysql-test/suite/innodb/r/innodb_bug57255.result
new file mode 100644
index 00000000000..d61a0d42ba3
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_bug57255.result
@@ -0,0 +1,10 @@
+create table A(id int not null primary key) engine=innodb;
+create table B(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references A(id) on delete cascade) engine=innodb;
+create table C(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references B(id) on delete cascade) engine=innodb;
+insert into A values(1), (2);
+DELETE FROM A where id = 1;
+DELETE FROM C where f1 = 2;
+DELETE FROM A where id = 1;
+DROP TABLE C;
+DROP TABLE B;
+DROP TABLE A;
diff --git a/mysql-test/suite/innodb/t/innodb_bug57255.test b/mysql-test/suite/innodb/t/innodb_bug57255.test
new file mode 100644
index 00000000000..2b37a0a6092
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_bug57255.test
@@ -0,0 +1,36 @@
+# Test Bug #57255. Cascade deletes that affect different rows should not
+# result in DB_FOREIGN_EXCEED_MAX_CASCADE error
+
+--source include/have_innodb.inc
+
+create table A(id int not null primary key) engine=innodb;
+
+create table B(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references A(id) on delete cascade) engine=innodb;
+
+create table C(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references B(id) on delete cascade) engine=innodb;
+
+insert into A values(1), (2);
+
+--disable_query_log
+let $i=257;
+while ($i)
+{
+insert into B(f1) values(1);
+dec $i;
+}
+let $i=486;
+while ($i)
+{
+insert into C(f1) values(2);
+dec $i;
+}
+--enable_query_log
+
+# Following Deletes should not report error
+DELETE FROM A where id = 1;
+DELETE FROM C where f1 = 2;
+DELETE FROM A where id = 1;
+
+DROP TABLE C;
+DROP TABLE B;
+DROP TABLE A;
diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug57255.result b/mysql-test/suite/innodb_plugin/r/innodb_bug57255.result
new file mode 100644
index 00000000000..d61a0d42ba3
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/r/innodb_bug57255.result
@@ -0,0 +1,10 @@
+create table A(id int not null primary key) engine=innodb;
+create table B(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references A(id) on delete cascade) engine=innodb;
+create table C(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references B(id) on delete cascade) engine=innodb;
+insert into A values(1), (2);
+DELETE FROM A where id = 1;
+DELETE FROM C where f1 = 2;
+DELETE FROM A where id = 1;
+DROP TABLE C;
+DROP TABLE B;
+DROP TABLE A;
diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug57255.test b/mysql-test/suite/innodb_plugin/t/innodb_bug57255.test
new file mode 100644
index 00000000000..96184c355b6
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/t/innodb_bug57255.test
@@ -0,0 +1,36 @@
+# Test Bug #57255. Cascade deletes that affect different rows should not
+# result in DB_FOREIGN_EXCEED_MAX_CASCADE error
+
+--source include/have_innodb_plugin.inc
+
+create table A(id int not null primary key) engine=innodb;
+
+create table B(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references A(id) on delete cascade) engine=innodb;
+
+create table C(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references B(id) on delete cascade) engine=innodb;
+
+insert into A values(1), (2);
+
+--disable_query_log
+let $i=257;
+while ($i)
+{
+insert into B(f1) values(1);
+dec $i;
+}
+let $i=486;
+while ($i)
+{
+insert into C(f1) values(2);
+dec $i;
+}
+--enable_query_log
+
+# Following Deletes should not report error
+DELETE FROM A where id = 1;
+DELETE FROM C where f1 = 2;
+DELETE FROM A where id = 1;
+
+DROP TABLE C;
+DROP TABLE B;
+DROP TABLE A;
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 4390b70e9e9..9b3f3e750e1 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -3079,4 +3079,26 @@ EXECUTE stmt;
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
+--echo #
+--echo # Bug#54494 crash with explain extended and prepared statements
+--echo #
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1),(2);
+PREPARE stmt FROM 'EXPLAIN EXTENDED SELECT 1 FROM t1 RIGHT JOIN t1 t2 ON 1';
+EXECUTE stmt;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#54488 crash when using explain and prepared statements with subqueries
+--echo #
+CREATE TABLE t1(f1 INT);
+INSERT INTO t1 VALUES (1),(1);
+PREPARE stmt FROM 'EXPLAIN SELECT 1 FROM t1 WHERE (SELECT (SELECT 1 FROM t1 GROUP BY f1))';
+EXECUTE stmt;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+
--echo End of 5.1 tests.
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index adce24e7799..1ed36ce7656 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1907,18 +1907,22 @@ int subselect_single_select_engine::exec()
}
if (!select_lex->uncacheable && thd->lex->describe &&
!(join->select_options & SELECT_DESCRIBE) &&
- join->need_tmp && item->const_item())
+ join->need_tmp)
{
- /*
- Force join->join_tmp creation, because this subquery will be replaced
- by a simple select from the materialization temp table by optimize()
- called by EXPLAIN and we need to preserve the initial query structure
- so we can display it.
- */
- select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
- select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
- if (join->init_save_join_tab())
- DBUG_RETURN(1); /* purecov: inspected */
+ item->update_used_tables();
+ if (item->const_item())
+ {
+ /*
+ Force join->join_tmp creation, because this subquery will be replaced
+ by a simple select from the materialization temp table by optimize()
+ called by EXPLAIN and we need to preserve the initial query structure
+ so we can display it.
+ */
+ select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
+ select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
+ if (join->init_save_join_tab())
+ DBUG_RETURN(1); /* purecov: inspected */
+ }
}
if (item->engine_changed)
{
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index d6eb90a57be..5ba375f9710 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -2362,11 +2362,15 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
sl->where= sl->prep_where->copy_andor_structure(thd);
sl->where->cleanup();
}
+ else
+ sl->where= NULL;
if (sl->prep_having)
{
sl->having= sl->prep_having->copy_andor_structure(thd);
sl->having->cleanup();
}
+ else
+ sl->having= NULL;
DBUG_ASSERT(sl->join == 0);
ORDER *order;
/* Fix GROUP list */
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index 99738115cc7..8b770229c16 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -1613,6 +1613,9 @@ row_update_cascade_for_mysql(
trx = thr_get_trx(thr);
+ /* Increment fk_cascade_depth to record the recursive call depth on
+ a single update/delete that affects multiple tables chained
+ together with foreign key relations. */
thr->fk_cascade_depth++;
if (thr->fk_cascade_depth > FK_MAX_CASCADE_DEL) {
@@ -1624,6 +1627,12 @@ run_again:
row_upd_step(thr);
+ /* The recursive call for cascading update/delete happens
+ in above row_upd_step(), reset the counter once we come
+ out of the recursive call, so it does not accumulate for
+ different row deletes */
+ thr->fk_cascade_depth = 0;
+
err = trx->error_state;
/* Note that the cascade node is a subnode of another InnoDB
diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog
index 9033e5557f3..47ee33e062f 100644
--- a/storage/innodb_plugin/ChangeLog
+++ b/storage/innodb_plugin/ChangeLog
@@ -39,10 +39,14 @@
2010-10-11 The InnoDB Team
- * row/row0sel.c:
- Fix Bug#57345 btr_pcur_store_position abort for load with concurrent
- lock/unlock tables
-
+ * row/row0sel.c
+ Fix Bug #57345 btr_pcur_store_position abort for load with
+ concurrent lock/unlock tables
+
+2010-10-06 The InnoDB Team
+ * row/row0mysql.c, innodb_bug57255.result, innodb_bug57255.test
+ Fix Bug #Cascade Delete results in "Got error -1 from storage engine"
+
2010-09-27 The InnoDB Team
* row/row0sel.c, innodb_bug56716.result, innodb_bug56716.test:
diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c
index 827be32bdf7..609533c7647 100644
--- a/storage/innodb_plugin/row/row0mysql.c
+++ b/storage/innodb_plugin/row/row0mysql.c
@@ -1593,6 +1593,9 @@ row_update_cascade_for_mysql(
trx = thr_get_trx(thr);
+ /* Increment fk_cascade_depth to record the recursive call depth on
+ a single update/delete that affects multiple tables chained
+ together with foreign key relations. */
thr->fk_cascade_depth++;
if (thr->fk_cascade_depth > FK_MAX_CASCADE_DEL) {
@@ -1604,6 +1607,12 @@ run_again:
row_upd_step(thr);
+ /* The recursive call for cascading update/delete happens
+ in above row_upd_step(), reset the counter once we come
+ out of the recursive call, so it does not accumulate for
+ different row deletes */
+ thr->fk_cascade_depth = 0;
+
err = trx->error_state;
/* Note that the cascade node is a subnode of another InnoDB