summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorgi Kodinov <joro@sun.com>2009-02-19 20:30:05 +0200
committerGeorgi Kodinov <joro@sun.com>2009-02-19 20:30:05 +0200
commit901427b2413a8f8c80b4720969d101357da57556 (patch)
tree5e934ca40c0afa37342cc84b5469c0a95bd97c34
parente89fddc63684301a0e958fe54a5917fdbad56877 (diff)
parentcf42f6689fd52da07fd6588d2aaded1f0f39abae (diff)
downloadmariadb-git-901427b2413a8f8c80b4720969d101357da57556.tar.gz
merged 5.0-bugteam -> 5.1-bugteam
-rw-r--r--mysql-test/r/innodb_mysql.result18
-rw-r--r--mysql-test/t/innodb_mysql-master.opt2
-rw-r--r--mysql-test/t/innodb_mysql.test52
-rw-r--r--sql/sql_select.cc36
4 files changed, 95 insertions, 13 deletions
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index 6fcc9415d12..32a828cf82d 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -1683,6 +1683,24 @@ CREATE INDEX i1 on t1 (a(3));
SELECT * FROM t1 WHERE a = 'abcde';
a
DROP TABLE t1;
+connect(localhost,root,,test,12500,/home/kgeorge/mysql/work/B42419-merge-5.1-bugteam/mysql-test/var/tmp/mysqld.1.sock);
+connect(localhost,root,,test,12500,/home/kgeorge/mysql/work/B42419-merge-5.1-bugteam/mysql-test/var/tmp/mysqld.1.sock);
+CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT)
+ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+SET AUTOCOMMIT = 0;
+CREATE TEMPORARY TABLE t1_tmp (b INT);
+INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 3;
+INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 2;
+SET AUTOCOMMIT = 0;
+CREATE TEMPORARY TABLE t2_tmp ( a INT, new_a INT);
+INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53);
+UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1;
+UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2;
+INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 1;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3;
+DROP TABLE t1;
CREATE TABLE foo (a int, b int, c char(10),
PRIMARY KEY (c(3)),
KEY b (b)
diff --git a/mysql-test/t/innodb_mysql-master.opt b/mysql-test/t/innodb_mysql-master.opt
index 205c733455d..c8613e0ccd5 100644
--- a/mysql-test/t/innodb_mysql-master.opt
+++ b/mysql-test/t/innodb_mysql-master.opt
@@ -1 +1 @@
---innodb-lock-wait-timeout=2
+--innodb-lock-wait-timeout=3
diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test
index 21ee440f10b..77140fd85d7 100644
--- a/mysql-test/t/innodb_mysql.test
+++ b/mysql-test/t/innodb_mysql.test
@@ -55,6 +55,57 @@ SELECT * FROM t1 WHERE a = 'abcde';
DROP TABLE t1;
#
+# Bug #42419: Server crash with "Pure virtual method called" on two
+# concurrent connections
+#
+
+connect (c1, localhost, root,,);
+connect (c2, localhost, root,,);
+
+CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT)
+ ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+
+connection c1;
+
+SET AUTOCOMMIT = 0;
+
+CREATE TEMPORARY TABLE t1_tmp (b INT);
+
+INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 3;
+INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 2;
+
+connection c2;
+
+SET AUTOCOMMIT = 0;
+
+CREATE TEMPORARY TABLE t2_tmp ( a INT, new_a INT);
+INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53);
+
+UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1;
+
+--send
+UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2;
+
+--sleep 3
+
+connection c1;
+
+--error ER_LOCK_DEADLOCK
+INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 1;
+
+connection c2;
+
+--reap
+UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3;
+
+connection default;
+disconnect c1;
+disconnect c2;
+DROP TABLE t1;
+
+#
# Bug #37742: HA_EXTRA_KEYREAD flag is set when key contains only prefix of
# requested column
#
@@ -91,6 +142,7 @@ INSERT INTO foo2 SELECT * FROM foo;
DROP TABLE foo, bar, foo2;
+
#
# Bug#41348: INSERT INTO tbl SELECT * FROM temp_tbl overwrites locking type of temp table
#
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 75c11c2ac64..bea748562eb 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2460,11 +2460,12 @@ typedef struct st_sargable_param
*/
static bool
-make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
+make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
DYNAMIC_ARRAY *keyuse_array)
{
int error;
TABLE *table;
+ TABLE_LIST *tables= tables_arg;
uint i,table_count,const_count,key;
table_map found_const_table_map, all_table_map, found_ref, refs;
key_map const_ref, eq_part;
@@ -2502,10 +2503,10 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
table_vector[i]=s->table=table=tables->table;
table->pos_in_table_list= tables;
error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
- if(error)
+ if (error)
{
- table->file->print_error(error, MYF(0));
- DBUG_RETURN(1);
+ table->file->print_error(error, MYF(0));
+ goto error;
}
table->quick_keys.clear_all();
table->reginfo.join_tab=s;
@@ -2601,7 +2602,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
{
join->tables=0; // Don't use join->table
my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
- DBUG_RETURN(1);
+ goto error;
}
s->key_dependent= s->dependent;
}
@@ -2611,7 +2612,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables,
conds, join->cond_equal,
~outer_join, join->select_lex, &sargables))
- DBUG_RETURN(1);
+ goto error;
/* Read tables with 0 or 1 rows (system tables) */
join->const_table_map= 0;
@@ -2627,7 +2628,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
if ((tmp=join_read_const_table(s, p_pos)))
{
if (tmp > 0)
- DBUG_RETURN(1); // Fatal error
+ goto error; // Fatal error
}
else
found_const_table_map|= s->table->map;
@@ -2699,7 +2700,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
if ((tmp= join_read_const_table(s, join->positions+const_count-1)))
{
if (tmp > 0)
- DBUG_RETURN(1); // Fatal error
+ goto error; // Fatal error
}
else
found_const_table_map|= table->map;
@@ -2748,12 +2749,12 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
set_position(join,const_count++,s,start_keyuse);
if (create_ref_for_key(join, s, start_keyuse,
found_const_table_map))
- DBUG_RETURN(1);
+ goto error;
if ((tmp=join_read_const_table(s,
join->positions+const_count-1)))
{
if (tmp > 0)
- DBUG_RETURN(1); // Fatal error
+ goto error; // Fatal error
}
else
found_const_table_map|= table->map;
@@ -2830,7 +2831,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
*s->on_expr_ref ? *s->on_expr_ref : conds,
1, &error);
if (!select)
- DBUG_RETURN(1);
+ goto error;
records= get_quick_record_count(join->thd, select, s->table,
&s->const_keys, join->row_limit);
s->quick=select->quick;
@@ -2876,7 +2877,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
{
optimize_keyuse(join, keyuse_array);
if (choose_plan(join, all_table_map & ~join->const_table_map))
- DBUG_RETURN(TRUE);
+ goto error;
}
else
{
@@ -2886,6 +2887,17 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
}
/* Generate an execution plan from the found optimal join order. */
DBUG_RETURN(join->thd->killed || get_best_combination(join));
+
+error:
+ /*
+ Need to clean up join_tab from TABLEs in case of error.
+ They won't get cleaned up by JOIN::cleanup() because JOIN::join_tab
+ may not be assigned yet by this function (which is building join_tab).
+ Dangling TABLE::reginfo.join_tab may cause part_of_refkey to choke.
+ */
+ for (tables= tables_arg; tables; tables= tables->next_leaf)
+ tables->table->reginfo.join_tab= NULL;
+ DBUG_RETURN (1);
}